Exemplo n.º 1
0
static status_t
InitCommon(int fileDesc)
{
	// Initialization function used by primary and cloned accelerants.

	gInfo.deviceFileDesc = fileDesc;

	// Get area ID of shared data from driver.

	area_id sharedArea;
	status_t result = ioctl(gInfo.deviceFileDesc, ATI_GET_SHARED_DATA,
		&sharedArea, sizeof(sharedArea));
	if (result != B_OK)
		return result;

	gInfo.sharedInfoArea = clone_area("ATI shared info", (void**)&(gInfo.sharedInfo),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, sharedArea);
	if (gInfo.sharedInfoArea < 0)
		return gInfo.sharedInfoArea;	// sharedInfoArea has error code

	gInfo.regsArea = clone_area("ATI regs area", (void**)&(gInfo.regs),
		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea);
	if (gInfo.regsArea < 0) {
		delete_area(gInfo.sharedInfoArea);
		return gInfo.regsArea;		// regsArea has error code
	}

	// Set pointers to various device specific functions.

	if (RAGE128_FAMILY(gInfo.sharedInfo->chipType))
		Rage128_SetFunctionPointers();
	else if (MACH64_FAMILY(gInfo.sharedInfo->chipType))
		Mach64_SetFunctionPointers();
	else
		return B_ERROR;		// undefined chip type code

	return B_OK;
}
Exemplo n.º 2
0
static status_t
InitDevice(DeviceInfo& di)
{
	// Perform initialization and mapping of the device, and return B_OK if
	// sucessful;  else, return error code.

	// Get the table of VESA modes that the chip supports.  Note that we will
	// need this table only for chips that are currently connected to a laptop
	// display or a monitor connected via a DVI interface.

	size_t vesaModeTableSize = 0;
	VesaMode* vesaModes = (VesaMode*)get_boot_item(VESA_MODES_BOOT_INFO,
		&vesaModeTableSize);

	size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;

	// Create the area for shared info with NO user-space read or write
	// permissions, to prevent accidental damage.

	di.sharedArea = create_area("ATI shared info",
		(void**) &(di.sharedInfo),
		B_ANY_KERNEL_ADDRESS,
		ROUND_TO_PAGE_SIZE(sharedSize + vesaModeTableSize),
		B_FULL_LOCK, 0);
	if (di.sharedArea < 0)
		return di.sharedArea;	// return error code

	SharedInfo& si = *(di.sharedInfo);

	memset(&si, 0, sharedSize);

	if (vesaModes != NULL) {
		si.vesaModeTableOffset = sharedSize;
		si.vesaModeCount = vesaModeTableSize / sizeof(VesaMode);

		memcpy((uint8*)&si + si.vesaModeTableOffset, vesaModes,
			vesaModeTableSize);
	}

	pci_info& pciInfo = di.pciInfo;

	si.vendorID = pciInfo.vendor_id;
	si.deviceID = pciInfo.device_id;
	si.revision = pciInfo.revision;
	si.chipType = di.pChipInfo->chipType;
	strcpy(si.chipName, di.pChipInfo->chipName);

	TRACE("Chip revision: 0x%x\n", si.revision);

	// 264GT has two chip versions.  If version is non-zero, chip is 264GTB.

	if (si.chipType == MACH64_264GT && si.revision & 0x7)
		si.chipType = MACH64_264GTB;

	// 264VT has two chip versions.  If version is non-zero, chip is 264VTB.

	if (si.chipType == MACH64_264VT && si.revision & 0x7)
		si.chipType = MACH64_264VTB;

	status_t status = MapDevice(di);

	// If device mapped without any error, get the bios parameters from the
	// chip's BIOS ROM.

	if (status >= 0) {
		if (MACH64_FAMILY(si.chipType)) {
			uint8 clockType;
			Mach64_GetBiosParameters(di, clockType);

			// All chips supported by this driver should have an internal clock.
			// If the clock is not an internal clock, the video chip is not
			// supported.

			if (clockType != M64_CLOCK_INTERNAL) {
				TRACE("Video chip clock type %d not supported\n", clockType);
				status = B_UNSUPPORTED;
			}
		}
		else if (RAGE128_FAMILY(si.chipType))
			Rage128_GetBiosParameters(di);
	}

	if (status < 0) {
		delete_area(di.sharedArea);
		di.sharedArea = -1;
		di.sharedInfo = NULL;
		return status;		// return error code
	}

	InitInterruptHandler(di);

	TRACE("Interrupt assigned:  %s\n", si.bInterruptAssigned ? "yes" : "no");
	return B_OK;
}
Exemplo n.º 3
0
static status_t
MapDevice(DeviceInfo& di)
{
	SharedInfo& si = *(di.sharedInfo);
	pci_info& pciInfo = di.pciInfo;

	// Enable memory mapped IO and bus master.

	SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2)
		| PCI_command_io | PCI_command_memory | PCI_command_master);

	// Map the video memory.

	phys_addr_t videoRamAddr = pciInfo.u.h0.base_registers[0];
	uint32 videoRamSize = pciInfo.u.h0.base_register_sizes[0];
	si.videoMemPCI = videoRamAddr;
	char frameBufferAreaName[] = "ATI frame buffer";

	si.videoMemArea = map_physical_memory(
		frameBufferAreaName,
		videoRamAddr,
		videoRamSize,
		B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
		B_READ_AREA + B_WRITE_AREA,
		(void**)&(si.videoMemAddr));

	if (si.videoMemArea < 0) {
		// Try to map this time without write combining.
		si.videoMemArea = map_physical_memory(
			frameBufferAreaName,
			videoRamAddr,
			videoRamSize,
			B_ANY_KERNEL_BLOCK_ADDRESS,
			B_READ_AREA + B_WRITE_AREA,
			(void**)&(si.videoMemAddr));
	}

	if (si.videoMemArea < 0)
		return si.videoMemArea;

	// Map the MMIO register area.

	phys_addr_t regsBase = pciInfo.u.h0.base_registers[2];
	uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[2];

	// If the register area address or size is not in the PCI info, it should
	// be at the end of the video memory.  Check if it is there.

	if (MACH64_FAMILY(si.chipType) && (regsBase == 0 || regAreaSize == 0)) {
		uint32 regsOffset = 0x7ff000;	// offset to regs area in video memory
		uint32 regs = uint32(si.videoMemAddr) + regsOffset;
		uint32 chipInfo = *((vuint32*)(regs + M64_CONFIG_CHIP_ID));

		if (si.deviceID != (chipInfo & M64_CFG_CHIP_TYPE)) {
			// Register area not found;  delete any other areas that were
			// created.
			delete_area(si.videoMemArea);
			si.videoMemArea = -1;
			TRACE("Mach64 register area not found\n");
			return B_ERROR;
		}

		// Adjust params for creating register area below.

		regsBase = videoRamAddr + regsOffset;
		regAreaSize = 0x1000;
		TRACE("Register address is at end of frame buffer memory at 0x%lx\n",
			uint32(regsBase));
	}

	si.regsArea = map_physical_memory("ATI mmio registers",
		regsBase,
		regAreaSize,
		B_ANY_KERNEL_ADDRESS,
		0,		// neither read nor write, to hide it from user space apps
		(void**)&di.regs);

	// If there was an error, delete other areas.
	if (si.regsArea < 0) {
		delete_area(si.videoMemArea);
		si.videoMemArea = -1;
	}

	return si.regsArea;
}