static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; IMG_UINT32 ui32MaxOffset = POULSBO_MAX_OFFSET; #if defined(SUPPORT_DRI_DRM_EXT) psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, 0); ui32MaxOffset = POULSBO_MAX_OFFSET; #else #if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI); #else psSysSpecData->hSGXPCI = OSPCIAcquireDev(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI); #endif #endif if (!psSysSpecData->hSGXPCI) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device")); return PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV); PVR_TRACE(("PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX))); #if defined(SGX_FEATURE_HOST_PORT) PVR_TRACE(("Host Port region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX))); #endif if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) < ui32MaxOffset) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough")); return PVRSRV_ERROR_PCI_REGION_TOO_SMALL; } if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE); #if defined(SGX_FEATURE_HOST_PORT) if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Host Port region not available")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE); #endif return PVRSRV_OK; }
static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { IMG_UINT32 ui32BaseAddr = 0; IMG_UINT32 ui32IRQ = 0; #if defined(SGX_FEATURE_HOST_PORT) IMG_UINT32 ui32HostPortAddr = 0; #endif SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) struct drm_psb_private *dev_priv = (struct drm_psb_private *) gpDrmDevice->dev_private; #endif ui32BaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX); #if defined(SGX_FEATURE_HOST_PORT) ui32HostPortAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX); #endif if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ")); return PVRSRV_ERROR_INVALID_DEVICE; } PVR_TRACE(("ui32BaseAddr: %08X", ui32BaseAddr)); #if defined(SGX_FEATURE_HOST_PORT) PVR_TRACE(("ui32HostPortAddr: %08X", ui32HostPortAddr)); #endif PVR_TRACE(("IRQ: %d", ui32IRQ)); gsSGXDeviceMap.ui32Flags = 0x0; gsSGXDeviceMap.ui32IRQ = ui32IRQ; #if defined(SUPPORT_DRI_DRM_EXT) gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + SGX_REGS_OFFSET; #else gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + SGX_REGS_OFFSET; #endif gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE; #if defined(SGX_FEATURE_HOST_PORT) gsSGXDeviceMap.ui32Flags = SGX_HOSTPORT_PRESENT; gsSGXDeviceMap.sHPSysPBase.uiAddr = ui32HostPortAddr; gsSGXDeviceMap.sHPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sHPSysPBase); gsSGXDeviceMap.ui32HPSize = SYS_SGX_HP_SIZE; #endif #if defined(MRST_SLAVEPORT) gsSGXDeviceMap.sSPSysPBase.uiAddr = ui32BaseAddr + MRST_SGX_SP_OFFSET; gsSGXDeviceMap.sSPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sSPSysPBase); gsSGXDeviceMap.ui32SPSize = SGX_SP_SIZE; #endif gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32LocalMemSize = 0; #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) gsSGXDeviceMap.sExtSysCacheRegsDevPBase.uiAddr = SYS_EXT_SYS_CACHE_GBL_INV_REG_OFFSET; gsSGXDeviceMap.ui32ExtSysCacheRegsSize = SGX_EXT_SYSTEM_CACHE_REGS_SIZE; MDFLD_GL3_WRITE(gsSGXDeviceMap.sExtSysCacheRegsDevPBase.uiAddr, MDFLD_GL3_USE_WRT_INVAL); #endif #if !defined(NO_HARDWARE) { IMG_SYS_PHYADDR sPoulsboRegsCpuPBase; sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_REGS_OFFSET; gsPoulsboRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase), POULSBO_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_DISPLAY_REGS_OFFSET; gsPoulsboDisplayRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase), POULSBO_DISPLAY_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } #endif #if defined(PDUMP) { static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif return PVRSRV_OK; }
/*! ****************************************************************************** @Function SysLocateDevices @Description specifies devices in the systems memory map @Input psSysData - sys data @Return PVRSRV_ERROR : ******************************************************************************/ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { IMG_UINT32 ui32AtlasRegBaseAddr, ui32SGXRegBaseAddr, ui32SGXMemBaseAddr; IMG_UINT32 ui32IRQ; IMG_UINT32 ui32DeviceID = SYS_SGX_DEV_DEVICE_ID; #if defined(NO_HARDWARE) IMG_CPU_PHYADDR sCpuPAddr; #endif #ifdef __linux__ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #endif #if !defined(__linux__) || defined(NO_HARDWARE) PVRSRV_ERROR eError; #endif #ifdef __linux__ ui32AtlasRegBaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_ATLAS_REG_PCI_BASENUM); ui32SGXRegBaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_SGX_REG_PCI_BASENUM); ui32SGXMemBaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_SGX_MEM_PCI_BASENUM); if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ")); return PVRSRV_ERROR_INVALID_DEVICE; } PVR_TRACE(("IRQ: %d", ui32IRQ)); #else /* __linux__ */ PCICONFIG_SPACE sPCISpace; PVR_UNREFERENCED_PARAMETER(psSysData); eError = FindPCIDevice(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, &sPCISpace); if (eError == PVRSRV_OK) { /* Get the regions from base address register 0, 1, 2 */ ui32AtlasRegBaseAddr = sPCISpace.u.aui32PCISpace[SYS_ATLAS_REG_PCI_OFFSET]; ui32SGXRegBaseAddr = sPCISpace.u.aui32PCISpace[SYS_SGX_REG_PCI_OFFSET]; ui32SGXMemBaseAddr = sPCISpace.u.aui32PCISpace[SYS_SGX_MEM_PCI_OFFSET]; } else { #if defined (SYS_SGX_DEV1_DEVICE_ID) ui32DeviceID = SYS_SGX_DEV1_DEVICE_ID; eError = FindPCIDevice(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID, &sPCISpace); if (eError == PVRSRV_OK) { /* Get the regions from base address register 0, 1, 2 */ ui32AtlasRegBaseAddr = sPCISpace.u.aui32PCISpace[SYS_ATLAS_REG_PCI_OFFSET]; ui32SGXRegBaseAddr = sPCISpace.u.aui32PCISpace[SYS_SGX_REG_PCI_OFFSET]; ui32SGXMemBaseAddr = sPCISpace.u.aui32PCISpace[SYS_SGX_MEM_PCI_OFFSET]; } else #endif { PVR_DPF((PVR_DBG_ERROR,"Couldn't find PCI device")); return PVRSRV_ERROR_INVALID_DEVICE; } } PVR_DPF((PVR_DBG_MESSAGE,"Found - DevID %04X Ven Id 0x%04X SSDevId %04X SSVenId %04X", sPCISpace.u.aui16PCISpace[SYS_SGX_DEV_ID_16_PCI_OFFSET], sPCISpace.u.aui16PCISpace[SYS_SGX_VEN_ID_16_PCI_OFFSET], sPCISpace.u.aui16PCISpace[SYS_SGX_SSDEV_ID_16_PCI_OFFSET], sPCISpace.u.aui16PCISpace[SYS_SGX_SSVEN_ID_16_PCI_OFFSET])); ui32IRQ = (IMG_UINT32)sPCISpace.u.aui8PCISpace[SYS_SGX_IRQ_8_PCI_OFFSET]; #endif /* __linux__ */ /* Atlas registers */ gsSOCRegsCpuPBase.uiAddr = ui32AtlasRegBaseAddr; /* SGX Device: */ gsSGXDeviceMap.ui32Flags = 0x0; #if defined(NO_HARDWARE) /* No hardware registers */ eError = OSBaseAllocContigMemory(SYS_SGX_REG_SIZE, &gsSGXRegsCPUVAddr, &sCpuPAddr); if(eError != PVRSRV_OK) { return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REG_MEM); gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_SGX_REG_SIZE); #if defined(__linux__) /* Indicate the registers are already mapped */ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; #else /* * FIXME: Could we just use the virtual address returned by * OSBaseAllocContigMemory? */ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; #endif #else /* defined(NO_HARDWARE) */ /* Hardware registers */ gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32SGXRegBaseAddr + SYS_SGX_REG_OFFSET; #endif /* defined(NO_HARDWARE) */ /* Common register setup */ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SYS_SGX_REG_SIZE; /* Local Device Memory Region: (present) */ gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = ui32SGXMemBaseAddr; gsSGXDeviceMap.sLocalMemDevPBase = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, gsSGXDeviceMap.sLocalMemSysPBase); gsSGXDeviceMap.sLocalMemCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sLocalMemSysPBase); #if defined (SYS_SGX_DEV1_DEVICE_ID) if(ui32DeviceID == SYS_SGX_DEV1_DEVICE_ID) { gsSGXDeviceMap.ui32LocalMemSize = SYS_SGX_DEV1_LOCALMEM_FOR_SGX_RESERVE_SIZE; } else #endif { gsSGXDeviceMap.ui32LocalMemSize = SYS_SGX_DEV_LOCALMEM_FOR_SGX_RESERVE_SIZE; } #if defined(SGX_FEATURE_HOST_PORT) /* HostPort: */ gsSGXDeviceMap.ui32Flags |= SGX_HOSTPORT_PRESENT; gsSGXDeviceMap.sHPSysPBase.uiAddr = ui32SGXMemBaseAddr + 0x10000000; gsSGXDeviceMap.sHPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sHPSysPBase); gsSGXDeviceMap.ui32HPSize = SYS_SGX_HP_SIZE; #endif /* device interrupt IRQ */ gsSGXDeviceMap.ui32IRQ = ui32IRQ; #if defined(PDUMP) { /* Initialise memory region name for pdumping. * This could just as well be SGXMEM on the RefPCI Test Chip system * since it uses LMA. But since there will only be 1 device we can * represent it as UMA in the pdump. */ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif return PVRSRV_OK; }
/*! ****************************************************************************** @Function PCIInitDev @Description Initialise the PCI device for subsequent use. @Input psSysData : System data @Return PVRSRV_ERROR ******************************************************************************/ static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, HOST_PCI_INIT_FLAG_BUS_MASTER); #else /* Old Test chip ID and Emulator board */ psSysSpecData->hSGXPCI = OSPCIAcquireDev(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, HOST_PCI_INIT_FLAG_BUS_MASTER); #if defined (SYS_SGX_DEV1_DEVICE_ID) if (!psSysSpecData->hSGXPCI) { PVR_TRACE(("PCIInitDev: Trying alternative PCI device ID")); psSysSpecData->hSGXPCI = OSPCIAcquireDev(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID, HOST_PCI_INIT_FLAG_BUS_MASTER); } #endif #endif /* defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) */ if (!psSysSpecData->hSGXPCI) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device")); return PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_PCI_DEV); PVR_TRACE(("Atlas Reg PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_ATLAS_REG_PCI_BASENUM), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, SYS_ATLAS_REG_PCI_BASENUM))); /* Check the address range is large enough. */ if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, SYS_ATLAS_REG_PCI_BASENUM) < SYS_ATLAS_REG_REGION_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough (atlas reg)")); return PVRSRV_ERROR_PCI_REGION_TOO_SMALL; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, SYS_ATLAS_REG_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available (atlas reg)")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_PCI_ATL); PVR_TRACE(("SGX Reg/SP PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_SGX_REG_PCI_BASENUM), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, SYS_SGX_REG_PCI_BASENUM))); /* Check the address range is large enough. */ if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, SYS_SGX_REG_PCI_BASENUM) < SYS_SGX_REG_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough (SGX reg)")); return PVRSRV_ERROR_PCI_REGION_TOO_SMALL; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, SYS_SGX_REG_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available (SGX reg) ")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_PCI_REG); PVR_TRACE(("SGX Mem PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, SYS_SGX_MEM_PCI_BASENUM), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, SYS_SGX_MEM_PCI_BASENUM))); /* Check the address range is large enough. */ if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, SYS_SGX_MEM_PCI_BASENUM) < SYS_SGX_MEM_REGION_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough")); return PVRSRV_ERROR_PCI_REGION_TOO_SMALL; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, SYS_SGX_MEM_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_PCI_MEM); return PVRSRV_OK; }
/* PCIInitDev */ static PVRSRV_ERROR PCIInitDev(PLAT_DATA *psPlatData) { PVRSRV_DEVICE_CONFIG *psDevice = &sSysConfig.pasDevices[0]; PVRSRV_ERROR eError; #if defined (LMA) IMG_UINT32 uiLMACpuPAddr; IMG_UINT32 uiLMASize; #endif psPlatData->hRGXPCI = OSPCIAcquireDev(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV_DEVICE_ID, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI); if (!psPlatData->hRGXPCI) { psPlatData->hRGXPCI = OSPCIAcquireDev(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV1_DEVICE_ID, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI); } if (!psPlatData->hRGXPCI) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device")); eError = PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND; goto e0; } psPlatData->uiICRCpuPAddr = OSPCIAddrRangeStart(psPlatData->hRGXPCI, EMULATOR_RGX_ICR_PCI_BASENUM); psPlatData->uiICRSize = OSPCIAddrRangeLen(psPlatData->hRGXPCI, EMULATOR_RGX_ICR_PCI_BASENUM); /* Check the address range is large enough. */ if (psPlatData->uiICRSize < EMULATOR_RGX_ICR_PCI_REGION_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough (Emu reg) (was 0x%08x, required 0x%08x)", psPlatData->uiICRSize, EMULATOR_RGX_ICR_PCI_REGION_SIZE)); eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL; goto e1; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_ICR_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available (Emu reg)")); eError = PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; goto e1; } psDevice->sRegsCpuPBase.uiAddr = OSPCIAddrRangeStart(psPlatData->hRGXPCI, EMULATOR_RGX_REG_PCI_BASENUM); psDevice->ui32RegsSize = OSPCIAddrRangeLen(psPlatData->hRGXPCI, EMULATOR_RGX_REG_PCI_BASENUM); /* Check the address range is large enough. */ if (psDevice->ui32RegsSize < EMULATOR_RGX_REG_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough (RGX reg) (was 0x%08x, required 0x%08x)", psDevice->ui32RegsSize, EMULATOR_RGX_REG_SIZE)); eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL; goto e2; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_REG_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available (RGX reg) ")); eError = PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; goto e2; } #if defined (LMA) uiLMACpuPAddr = OSPCIAddrRangeStart(psPlatData->hRGXPCI, EMULATOR_RGX_MEM_PCI_BASENUM); uiLMASize = OSPCIAddrRangeLen(psPlatData->hRGXPCI, EMULATOR_RGX_MEM_PCI_BASENUM); /* Setup the RGX heap */ gsPhysHeapConfig[0].sStartAddr.uiAddr = uiLMACpuPAddr; gsPhysHeapConfig[0].uiSize = uiLMASize - RESERVE_DC_MEM_SIZE; /* Setup the DC heap */ gsPhysHeapConfig[1].sStartAddr.uiAddr = uiLMACpuPAddr + gsPhysHeapConfig[0].uiSize; gsPhysHeapConfig[1].uiSize = RESERVE_DC_MEM_SIZE; /* Check the address range is large enough. */ if (uiLMASize < EMULATOR_RGX_MEM_REGION_SIZE) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough (was 0x%08x, required 0x%08x)", uiLMASize, EMULATOR_RGX_MEM_REGION_SIZE)); eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL; goto e3; } /* Reserve the address range */ if (OSPCIRequestAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_MEM_PCI_BASENUM) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available")); eError = PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; goto e3; } #endif if (OSPCIIRQ(psPlatData->hRGXPCI, &psDevice->ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Couldn't get IRQ")); eError = PVRSRV_ERROR_INVALID_DEVICE; goto e4; } #if defined (LMA) /* Save this info for later use */ psPlatData->uiLMACpuPAddr = uiLMACpuPAddr; psPlatData->uiLMASize = uiLMASize; #endif /* Reset the emulator design */ eError = EmuReset(psDevice->sRegsCpuPBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Couldn't reset emulator")); goto e4; } /* Init IRC IRQ_CTRL register */ Init_IRQ_CTRL(psPlatData); return PVRSRV_OK; e4: #if defined (LMA) OSPCIReleaseAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_MEM_PCI_BASENUM); e3: #endif OSPCIReleaseAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_REG_PCI_BASENUM); e2: OSPCIReleaseAddrRange(psPlatData->hRGXPCI, EMULATOR_RGX_ICR_PCI_BASENUM); e1: OSPCIReleaseDev(psPlatData->hRGXPCI); e0: return eError; }
/* PCIInitDev */ static PVRSRV_ERROR PCIInitDev(PLAT_DATA *psPlatData) { PVRSRV_DEVICE_CONFIG *psDevice = &sSysConfig.pasDevices[0]; PVRSRV_ERROR eError; IMG_UINT32 ui32MaxOffset; IMG_UINT32 ui32BaseAddr = 0; psPlatData->psDRMDev = gpsPVRDRMDev; if (!psPlatData->psDRMDev) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: DRM device not initialized")); return PVRSRV_ERROR_NOT_SUPPORTED; } if (!IS_MRFLD(psPlatData->psDRMDev)) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device 0x%08x not supported", psPlatData->psDRMDev->pci_device)); return PVRSRV_ERROR_NOT_SUPPORTED; } psPlatData->hRGXPCI = OSPCISetDev((IMG_VOID *)psPlatData->psDRMDev->pdev, 0); if (!psPlatData->hRGXPCI) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device")); return PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND; } ui32MaxOffset = OSPCIAddrRangeLen(psPlatData->hRGXPCI, 0); if (ui32MaxOffset < (RGX_REG_OFFSET + RGX_REG_SIZE)) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region 0x%08x isn't big enough", ui32MaxOffset)); return PVRSRV_ERROR_PCI_REGION_TOO_SMALL; } PVR_DPF((PVR_DBG_WARNING,"PCIInitDev: Device memory region len 0x%08x", ui32MaxOffset)); /* Reserve the address range */ if (OSPCIRequestAddrRange(psPlatData->hRGXPCI, 0) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available")); return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE; } ui32BaseAddr = OSPCIAddrRangeStart(psPlatData->hRGXPCI, 0); if (OSPCIIRQ(psPlatData->hRGXPCI, &psDevice->ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Couldn't get IRQ")); eError = PVRSRV_ERROR_INVALID_DEVICE; goto e4; } PVR_DPF((PVR_DBG_WARNING, "PCIInitDev: BaseAddr 0x%08x, EndAddr 0x%llx, IRQ %d", ui32BaseAddr, OSPCIAddrRangeEnd(psPlatData->hRGXPCI, 0), psDevice->ui32IRQ)); psDevice->sRegsCpuPBase.uiAddr = ui32BaseAddr + RGX_REG_OFFSET; psDevice->ui32RegsSize = RGX_REG_SIZE; PVR_DPF((PVR_DBG_WARNING, "PCIInitDev: sRegsCpuPBase 0x%llx, size 0x%x", psDevice->sRegsCpuPBase.uiAddr, psDevice->ui32RegsSize)); return PVRSRV_OK; e4: OSPCIReleaseAddrRange(psPlatData->hRGXPCI, 0); OSPCIReleaseDev(psPlatData->hRGXPCI); return eError; }
/***********************************************************************//** * Locate and describe our devices on the PCI bus * * Fills out the device map for all devices we know aout and control * * @returns PVRSRV_OK for success, or failure code **************************************************************************/ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { IMG_UINT32 ui32IRQ = 0; #if !defined(NO_HARDWARE) SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #else PVRSRV_ERROR eError; #endif /************************ * SOC Setup * ************************/ #if !defined(NO_HARDWARE) /* Get the regions from the base address register */ gsSOCDeviceMap.sRegsSysPBase.uiAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, CEDARVIEW_ADDR_RANGE_INDEX); PVR_TRACE(("uiBaseAddr: " SYSPADDR_FMT, gsSOCDeviceMap.sRegsSysPBase.uiAddr)); /* Convert it to a CPU physical address */ gsSOCDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSOCDeviceMap.sRegsSysPBase); /* * And map in the system registers. */ gsSOCDeviceMap.sRegsCpuVBase = OSMapPhysToLin(gsSOCDeviceMap.sRegsCpuPBase, SYS_SOC_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_SOC_REGS_MAPPED); #endif /************************ * SGX Setup * ************************/ #if !defined(NO_HARDWARE) gsSGXDeviceMap.sRegsSysPBase.uiAddr = gsSOCDeviceMap.sRegsSysPBase.uiAddr + SYS_SGX_REG_OFFSET; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); /* device interrupt IRQ */ if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ")); return PVRSRV_ERROR_INVALID_DEVICE; } PVR_TRACE(("IRQ: %d", ui32IRQ)); #else /* !defined(NO_HARDWARE) */ /* * With no hardware, allocate contiguous memory to emulate the registers */ eError = OSBaseAllocContigMemory(SYS_SGX_REG_SIZE, &(gsSGXDeviceMap.pvRegsCpuVBase), &(gsSGXDeviceMap.sRegsCpuPBase)); if(eError != PVRSRV_OK) { return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_SGX_REGS); OSMemSet(gsSGXDeviceMap.pvRegsCpuVBase, 0, SYS_SGX_REG_SIZE); gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); #endif /* !defined(NO_HARDWARE) */ /* * Other setup */ gsSGXDeviceMap.ui32Flags = 0x0; gsSGXDeviceMap.ui32RegsSize = SYS_SGX_REG_SIZE; gsSGXDeviceMap.ui32IRQ = ui32IRQ; /* * Local Device Memory Region is never present */ gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32LocalMemSize = 0; #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = SYSTEM_PDUMP_NAME; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /************************ * VXD Setup * ************************/ #if defined(SUPPORT_MSVDX) #if !defined(NO_HARDWARE) gsMSVDXDeviceMap.sRegsSysPBase.uiAddr = gsSOCDeviceMap.sRegsSysPBase.uiAddr + SYS_MSVDX_REG_OFFSET; gsMSVDXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsMSVDXDeviceMap.sRegsSysPBase); #else /* No hardware registers */ eError = OSBaseAllocContigMemory(MSVDX_REG_SIZE, &(gsMSVDXDeviceMap.sRegsCpuVBase), &(gsMSVDXDeviceMap.sRegsCpuPBase)); if(eError != PVRSRV_OK) { return eError; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_DUMMY_MSVDX_REGS); OSMemSet(gsMSVDXDeviceMap.sRegsCpuVBase, 0, MSVDX_REG_SIZE); gsMSVDXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsMSVDXDeviceMap.sRegsCpuPBase); #endif /* NO_HARDWARE */ /* Common setup */ gsMSVDXDeviceMap.ui32RegsSize = MSVDX_REG_SIZE; /* * No local device memory region */ gsMSVDXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsMSVDXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsMSVDXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsMSVDXDeviceMap.ui32LocalMemSize = 0; /* * device interrupt IRQ */ gsMSVDXDeviceMap.ui32IRQ = ui32IRQ; #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = SYSTEM_PDUMP_NAME; gsMSVDXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /* defined(PDUMP) */ #endif /* defined(SUPPORT_MSVDX) */ PVR_DPF((PVR_DBG_MESSAGE, "SGX registers base physical address: 0x" SYSPADDR_FMT, gsSGXDeviceMap.sRegsSysPBase.uiAddr)); #if defined(SUPPORT_MSVDX) PVR_DPF((PVR_DBG_MESSAGE, "VXD registers base physical address: 0x" SYSPADDR_FMT, gsMSVDXDeviceMap.sRegsSysPBase.uiAddr)); #endif return PVRSRV_OK; }