static PVRSRV_ERROR SysUnmapRegisters(IMG_VOID) { PVRSRV_DEVICE_NODE *psDeviceNodeList; psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice; if (psDeviceNodeList->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_SGX) { #if !(defined(NO_HARDWARE) && defined(__linux__)) /* Unmap Regs */ if (psDevInfo->pvRegsBaseKM) { OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } #endif /* #if !(defined(NO_HARDWARE) && defined(__linux__)) */ psDevInfo->pvRegsBaseKM = IMG_NULL; psDevInfo->ui32RegSize = 0; psDevInfo->sRegsPhysBase.uiAddr = 0; #if defined(SGX_FEATURE_HOST_PORT) if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT) { /* Unmap Host Port */ if (psDevInfo->pvHostPortBaseKM) { OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, gsSGXDeviceMap.ui32HPSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP); psDevInfo->pvHostPortBaseKM = IMG_NULL; } psDevInfo->ui32HPSize = 0; psDevInfo->sHPSysPAddr.uiAddr = 0; } #endif /* #if defined(SGX_FEATURE_HOST_PORT) */ } psDeviceNodeList = psDeviceNodeList->psNext; } #if defined(NO_HARDWARE) PVR_ASSERT(gsSGXRegsCPUVAddr); OSBaseFreeContigMemory(SYS_SGX_REG_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REG_MEM); gsSGXRegsCPUVAddr = IMG_NULL; #endif /* Unmap the Atlas and PDP registers */ if (gpsSysData->pvSOCRegsBase) { OSUnMapPhysToLin(gpsSysData->pvSOCRegsBase, SYS_ATLAS_REG_REGION_SIZE, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); gpsSysData->pvSOCRegsBase = IMG_NULL; } return PVRSRV_OK; }
/*! ****************************************************************************** @Function SysInitialise @Description Initialises kernel services at 'driver load' time @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; #if !defined(PVR_NO_OMAP_TIMER) IMG_CPU_PHYADDR TimerRegPhysBase; #endif #if !defined(SGX_DYNAMIC_TIMING_INFO) SGX_TIMING_INFORMATION* psTimingInfo; #endif gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysSpecificData = &gsSysSpecificData; OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); gpsSysData->pvSysSpecificData = gpsSysSpecificData; eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; /* init device ID's */ for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #if !defined(SGX_DYNAMIC_TIMING_INFO) /* Set up timing information*/ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; #endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #endif /* Setup the Source Clock Divider value */ gpsSysSpecificData->ui32SrcClockDiv = 3; /* Locate the devices within the system, specifying the physical addresses of each devices components (regs, mem, ports etc.) */ eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); eError = SysPMRuntimeRegister(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); eError = SysDvfsInitialize(gpsSysSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); /* Register devices with the system This also sets up their memory maps/heaps */ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); /* Once all devices are registered, specify the backing store and, if required, customise the memory heap config */ psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { /* perform any OEM SOC address space customisations here */ switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; /* specify the backing store to use for the devices MMU PT/PDs - the PT/PDs are always UMA in this system */ psDeviceNode->psLocalDevMemArena = IMG_NULL; /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; /* specify the backing store for all SGX heaps */ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; } gpsSGXDevNode = psDeviceNode; gsSysSpecificData.psSGXDevNode = psDeviceNode; break; } default: PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); return PVRSRV_ERROR_INIT_FAILURE; } /* advance to next device */ psDeviceNode = psDeviceNode->psNext; } eError = EnableSystemClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) /* SGX defaults to D3 power state */ DisableSGXClocks(gpsSysData); #endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ #if !defined(PVR_NO_OMAP_TIMER) #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; #else TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; #endif gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; gpsSysData->hSOCTimerRegisterOSMemHandle = 0; if (TimerRegPhysBase.uiAddr != 0) { OSReservePhys(TimerRegPhysBase, 4, PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, IMG_NULL, (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, &gpsSysData->hSOCTimerRegisterOSMemHandle); } #endif /* !defined(PVR_NO_OMAP_TIMER) */ 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; }
PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; #if !defined(SGX_DYNAMIC_TIMING_INFO) SGX_TIMING_INFORMATION* psTimingInfo; #endif gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysSpecificData = &gsSysSpecificData; OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); gpsSysData->pvSysSpecificData = gpsSysSpecificData; mutex_init(&gpsSysSpecificData->sPowerLock); atomic_set(&gpsSysSpecificData->sSGXClocksEnabled, 0); gpsSysSpecificData->pCPMHandle = cpm_pwc_get(PWC_GPU); if (!gpsSysSpecificData->pCPMHandle) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to get GPU power handle")); return PVRSRV_ERROR_UNKNOWN_POWER_STATE; } gpsSysSpecificData->psSGXClock = clk_get(NULL, "gpu"); if (IS_ERR(gpsSysSpecificData->psSGXClock)) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to get GPU clock")); return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; } /* #if defined(SUPPORT_DRI_DRM) */ /* /\* Save the pci_dev structure pointer from module.c *\/ */ /* PVR_ASSERT(gpsPVRLDMDev != IMG_NULL); */ /* gsSysSpecificData.psPCIDev = gpsPVRLDMDev; */ /* #endif */ /* #if defined(SUPPORT_DRI_DRM) */ /* /\* Save the DRM device structure pointer *\/ */ /* PVR_ASSERT(gpsPVRDRMDev != IMG_NULL); */ /* gsSysSpecificData.psDRMDev = gpsPVRDRMDev; */ /* #endif */ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #if !defined(SGX_DYNAMIC_TIMING_INFO) psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; #endif psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #endif eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); eError = SysDvfsInitialize(gpsSysSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; psDeviceNode->psLocalDevMemArena = IMG_NULL; psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; } gpsSGXDevNode = psDeviceNode; gsSysSpecificData.psSGXDevNode = psDeviceNode; break; } default: PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); return PVRSRV_ERROR_INIT_FAILURE; } psDeviceNode = psDeviceNode->psNext; } eError = EnableSystemClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #endif eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) DisableSGXClocks(gpsSysData); #endif return PVRSRV_OK; }
PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; #if !defined(PVR_NO_OMAP_TIMER) IMG_CPU_PHYADDR TimerRegPhysBase; #endif #if !defined(SGX_DYNAMIC_TIMING_INFO) SGX_TIMING_INFORMATION* psTimingInfo; #endif gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysSpecificData = &gsSysSpecificData; OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); gpsSysData->pvSysSpecificData = gpsSysSpecificData; eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #if !defined(SGX_DYNAMIC_TIMING_INFO) psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; #endif psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #endif gpsSysSpecificData->ui32SrcClockDiv = 3; eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); #if 0 eError = SysPMRuntimeRegister(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); #endif eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; psDeviceNode->psLocalDevMemArena = IMG_NULL; psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; } gpsSGXDevNode = psDeviceNode; gsSysSpecificData.psSGXDevNode = psDeviceNode; break; } default: PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); return PVRSRV_ERROR_INIT_FAILURE; } psDeviceNode = psDeviceNode->psNext; } eError = EnableSystemClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #endif eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) DisableSGXClocks(gpsSysData); #endif #if !defined(PVR_NO_OMAP_TIMER) #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; #else TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; #endif gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; gpsSysData->hSOCTimerRegisterOSMemHandle = 0; if (TimerRegPhysBase.uiAddr != 0) { OSReservePhys(TimerRegPhysBase, 4, PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, IMG_NULL, (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, &gpsSysData->hSOCTimerRegisterOSMemHandle); } #endif return PVRSRV_OK; }
/***********************************************************************//** * 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; }
/***********************************************************************//** * Perform hardware initialisation at driver load time * * @returns PVRSRV_OK for success, or failure code **************************************************************************/ PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; SGX_TIMING_INFORMATION *psTimingInfo; gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysData->pvSysSpecificData = &gsSysSpecificData; gsSysSpecificData.ui32SysSpecificData = 0; #if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) /* Save the pci_dev structure pointer from module.c */ PVR_ASSERT(gpsPVRLDMDev != IMG_NULL); gsSysSpecificData.psPCIDev = gpsPVRLDMDev; #endif #if defined(SUPPORT_DRI_DRM) /* Save the DRM device structure pointer */ PVR_ASSERT(gpsPVRDRMDev != IMG_NULL); gsSysSpecificData.psDRMDev = gpsPVRDRMDev; #endif eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENVDATA); /* Set up timing information*/ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else /* defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) */ psTimingInfo->bEnableActivePM = IMG_FALSE; #endif /* defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) */ eError = PCIInitDev(gpsSysData); if (eError != PVRSRV_OK) { SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; /* init device ID's */ for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; SysPowerMaybeInit(gpsSysData); eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); goto errorExit; } /* * Locate the devices within the system and get the * physical addresses of each */ eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_LOCATEDEV); /* * Register devices with the system * This also sets up their memory maps/heaps */ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_REGSGXDEV); #if defined(SUPPORT_MSVDX) eError = PVRSRVRegisterDevice(gpsSysData, MSVDXRegisterDevice, DEVICE_MSVDX_INTERRUPT, &gui32MSVDXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register VXD device!")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_REGVXDDEV); #endif /* * Once all devices are registered, specify the backing store * and, if required, customise the memory heap config */ psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { /* perform any OEM SOC address space customisations here */ switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; /* * Specify the backing store to use for the devices MMU PT/PDs */ psDeviceNode->psLocalDevMemArena = IMG_NULL; /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; /* specify the backing store for all SGX heaps */ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; #if defined(OEM_CUSTOMISE) /* if required, modify the memory config */ #endif } break; } #if defined(SUPPORT_MSVDX) case PVRSRV_DEVICE_TYPE_MSVDX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; /* specify the backing store to use for the devices MMU PT/PDs */ psDeviceNode->psLocalDevMemArena = IMG_NULL; /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; /* specify the backing store for all SGX heaps */ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; #if defined(OEM_CUSTOMISE) /* if required, modify the memory config */ #endif } break; } #endif default: break; } /* advance to next device */ psDeviceNode = psDeviceNode->psNext; } /* * Initialise all devices managed by us */ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise SGX!")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_INITSGXDEV); #ifdef SUPPORT_MSVDX eError = PVRSRVInitialiseDevice(gui32MSVDXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise VXD!")); goto errorExit; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_INITVXDDEV); #endif /* All fine! */ return eError; errorExit: /* Error occurred - shut down everything and return */ SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; }
/***********************************************************************//** * Unmap the CPU virtual memory from the registers * * @returns PVRSRV_OK for success, or failure code **************************************************************************/ static PVRSRV_ERROR SysUnmapRegisters(void) { PVRSRV_DEVICE_NODE *psDeviceNodeList; psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { switch (psDeviceNodeList->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) psDeviceNodeList->pvDevice; #if !defined(NO_HARDWARE) /* Unmap Regs */ if (psDevInfo->pvRegsBaseKM) { OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } #endif psDevInfo->pvRegsBaseKM = IMG_NULL; psDevInfo->ui32RegSize = 0; psDevInfo->sRegsPhysBase.uiAddr = 0; break; } #ifdef SUPPORT_MSVDX case PVRSRV_DEVICE_TYPE_MSVDX: { PVRSRV_MSVDXDEV_INFO *psDevInfo = (PVRSRV_MSVDXDEV_INFO *) psDeviceNodeList->pvDevice; #if !defined(NO_HARDWARE) if (psDevInfo->pvRegsBaseKM) { OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, psDevInfo->ui32RegSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS); } #endif psDevInfo->pvRegsBaseKM = IMG_NULL; psDevInfo->ui32RegSize = 0; psDevInfo->sRegsPhysBase.uiAddr = 0; break; } #endif /* SUPPORT_MSVDX */ default: /* Ignore unknowns */ break; } psDeviceNodeList = psDeviceNodeList->psNext; } #if defined(NO_HARDWARE) #if defined(SUPPORT_MSVDX) if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_MSVDX_REGS)) { PVR_ASSERT(gsMSVDXDeviceMap); OSBaseFreeContigMemory(MSVDX_REG_SIZE, gsMSVDXDeviceMap.sRegsCpuVBase, gsMSVDXDeviceMap.sRegsCpuPBase); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_MSVDX_REGS); } #endif /* defined(SUPPORT_MSVDX) */ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_SGX_REGS)) { OSBaseFreeContigMemory(SYS_SGX_REG_SIZE, gsSGXDeviceMap.pvRegsCpuVBase, gsSGXDeviceMap.sRegsCpuPBase); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_SGX_REGS); } #endif /* defined(NO_HARDWARE) */ #if !defined(NO_HARDWARE) if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_SOC_REGS_MAPPED)) { OSUnMapPhysToLin(gsSOCDeviceMap.sRegsCpuVBase, SYS_SOC_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_SOC_REGS_MAPPED); } #endif return PVRSRV_OK; }
PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i = 0; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; SGX_TIMING_INFORMATION* psTimingInfo; #if defined(PVR_MDFLD_SYS_MSVDX_AND_TOPAZ) struct drm_psb_private *dev_priv = (struct drm_psb_private *) gpDrmDevice->dev_private; #endif gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysData->pvSysSpecificData = &gsSysSpecificData; gsSysSpecificData.ui32SysSpecificData = 0; #if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) PVR_ASSERT(gpsPVRLDMDev != IMG_NULL); gsSysSpecificData.psPCIDev = gpsPVRLDMDev; #endif #if defined(SUPPORT_DRI_DRM) PVR_ASSERT(gpsPVRDRMDev != IMG_NULL); gsSysSpecificData.psDRMDev = gpsPVRDRMDev; #endif eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; #endif psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; eError = PCIInitDev(gpsSysData); if (eError != PVRSRV_OK) { SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; psDeviceNode->psLocalDevMemArena = IMG_NULL; psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; #ifdef OEM_CUSTOMISE #endif } #if defined(SUPPORT_DRI_DRM_EXT) gpsSGXDevNode = psDeviceNode; #endif break; } #if defined(PVR_MDFLD_SYS_MSVDX_AND_TOPAZ) case PVRSRV_DEVICE_TYPE_MSVDX: break; case PVRSRV_DEVICE_TYPE_TOPAZ: break; #endif default: { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); return PVRSRV_ERROR_INIT_FAILURE; } } psDeviceNode = psDeviceNode->psNext; } PDUMPINIT(); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PDUMP_INIT); eError = PVRSRVInitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_SGX_INITIALISED); #if defined(PVR_MDFLD_SYS_MSVDX_AND_TOPAZ) eError = PVRSRVInitialiseDevice (gui32MRSTMSVDXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } if (IS_MDFLD(gpDrmDevice) && !dev_priv->topaz_disabled) { eError = PVRSRVInitialiseDevice (gui32MRSTTOPAZDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } } #endif return PVRSRV_OK; }
static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; IMG_UINT32 ui32MaxOffset = MRST_MAX_OFFSET; #if defined(SUPPORT_DRI_DRM_EXT) if (!IS_MDFLD(psSysSpecData->psDRMDev) && !IS_MRST(psSysSpecData->psDRMDev) && !IS_POULSBO(psSysSpecData->psDRMDev)) { PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device not supported")); return PVRSRV_ERROR_NOT_SUPPORTED; } psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, 0); ui32MaxOffset = (IS_MRST(psSysSpecData->psDRMDev) || IS_MDFLD(psSysSpecData->psDRMDev)) ? MRST_MAX_OFFSET : 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; }
PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) { #if !defined(SUPPORT_DRI_DRM_EXT) PVRSRV_ERROR eError = PVRSRV_OK; if (eNewPowerState != gpsSysData->eCurrentPowerState) { if ((gpsSysData->eCurrentPowerState == PVRSRV_SYS_POWER_STATE_D3) && (eNewPowerState < PVRSRV_SYS_POWER_STATE_D3)) { eError = OSPCIResumeDev(gsSysSpecificData.hSGXPCI); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSPCIResumeDev failed (%d)", eError)); return eError; } eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to locate devices")); return eError; } eError = SysMapInRegisters(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to map in registers")); return eError; } #if defined(SYS_USING_INTERRUPTS) if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) { eError = OSInstallSystemLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallSystemLISR failed to install ISR (%d)", eError)); } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_LISR_INSTALLED); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); } #endif if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_IRQ_DISABLE)) { SysEnableInterrupts(gpsSysData); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_IRQ_ENABLED); SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_IRQ_DISABLE); } } } return eError; #else PVR_UNREFERENCED_PARAMETER(eNewPowerState); return PVRSRV_ERROR_NOT_SUPPORTED; #endif }
static PVRSRV_ERROR SysUnmapRegisters(IMG_VOID) { PVRSRV_DEVICE_NODE *psDeviceNodeList; psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { switch (psDeviceNodeList->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice; #if !(defined(NO_HARDWARE) && defined(__linux__)) if (psDevInfo->pvRegsBaseKM) { OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } #endif psDevInfo->pvRegsBaseKM = IMG_NULL; psDevInfo->ui32RegSize = 0; psDevInfo->sRegsPhysBase.uiAddr = 0; #if defined(SGX_FEATURE_HOST_PORT) if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT) { if (psDevInfo->pvHostPortBaseKM) { OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, gsSGXDeviceMap.ui32HPSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP); psDevInfo->pvHostPortBaseKM = IMG_NULL; } psDevInfo->ui32HPSize = 0; psDevInfo->sHPSysPAddr.uiAddr = 0; } #endif break; } default: break; } psDeviceNodeList = psDeviceNodeList->psNext; } #if !(defined(NO_HARDWARE) || defined(__linux__)) OSUnMapPhysToLin(gsPoulsboRegsCPUVaddr, POULSBO_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); OSUnMapPhysToLin(gsPoulsboDisplayRegsCPUVaddr, POULSBO_DISPLAY_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); #endif return PVRSRV_OK; }