예제 #1
0
static IMG_VOID Init_IRQ_CTRL(PLAT_DATA *psPlatData)
{
	IMG_CPU_PHYADDR	sICRCpuPBase;
	IMG_VOID *pvICRCpuVBase;
	IMG_UINT32 ui32Value;

	/* Map into CPU address space */
	sICRCpuPBase.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(psPlatData->uiICRCpuPAddr);
	pvICRCpuVBase = OSMapPhysToLin(sICRCpuPBase,
							psPlatData->uiICRSize,
							0);

	/* Configure IRQ_CTRL: For Rogue, enable IRQ, set sense to active low */
	ui32Value = OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_IRQ_CTRL);
	ui32Value &= ~EMULATOR_RGX_ICR_REG_IRQ_CTRL_IRQ_HINLO;
	ui32Value |= EMULATOR_RGX_ICR_REG_IRQ_CTRL_IRQ_EN;
	OSWriteHWReg32(pvICRCpuVBase,EMULATOR_RGX_ICR_REG_IRQ_CTRL,	ui32Value);

	/* Flush register write */
	(void) OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_IRQ_CTRL);
	OSWaitus(10);

	PVR_TRACE(("Emulator FPGA image version (ICR_REG_CORE_REVISION): 0x%08x",
			  OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_CORE_REVISION)));

	/* Unmap from CPU address space */
	OSUnMapPhysToLin(pvICRCpuVBase, psPlatData->uiICRSize, 0);
}
예제 #2
0
/*!
******************************************************************************

 @Function	SysCreateVersionString

 @Description Read the version string 

 @Return   IMG_CHAR *  : Version string

******************************************************************************/
static IMG_CHAR *SysCreateVersionString(void)
{
	static IMG_CHAR aszVersionString[100];
	SYS_DATA	*psSysData;
	IMG_UINT32	ui32SGXRevision;
	IMG_INT32	i32Count;
#if !defined(NO_HARDWARE)
	IMG_VOID	*pvRegsLinAddr;

	pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
								   gsSGXDeviceMap.ui32RegsSize,
								   PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
								   IMG_NULL);
	if(!pvRegsLinAddr)
	{
		return IMG_NULL;
	}

#if SGX_CORE_REV == 105
       ui32SGXRevision = 0x10005;
#else
	ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),
								  EUR_CR_CORE_REVISION);
#endif

#else
	ui32SGXRevision = 0;
#endif

	SysAcquireData(&psSysData);

	i32Count = OSSNPrintf(aszVersionString, 100,
						  "SGX revision = %u.%u.%u",
						  (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
							>> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
						  (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
							>> EUR_CR_CORE_REVISION_MINOR_SHIFT),
						  (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
							>> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
						 );

#if !defined(NO_HARDWARE)
	OSUnMapPhysToLin(pvRegsLinAddr,
					 SYS_OMAP5430_SGX_REGS_SIZE,
					 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
					 IMG_NULL);
#endif

	if(i32Count == -1)
	{
		return IMG_NULL;
	}

	return aszVersionString;
}
IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
{
	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
	IMG_BOOL bPowerLock;
#if defined(DEBUG) || defined(TIMING)
	IMG_CPU_PHYADDR TimerRegPhysBase;
	IMG_HANDLE hTimerDisable;
	IMG_UINT32 *pui32TimerDisable;
#endif

	PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));

	DisableSGXClocks(psSysData);

	bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);
	if (bPowerLock)
	{
		PowerLockUnwrap(psSysSpecData);
	}

#if defined(DEBUG) || defined(TIMING)
	TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				&hTimerDisable);
	
	if (pui32TimerDisable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
	}
	else
	{
		*pui32TimerDisable = 0;
		
		OSUnMapPhysToLin(pui32TimerDisable,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				hTimerDisable);
	}

	clk_disable(psSysSpecData->psGPT11_ICK);

	clk_disable(psSysSpecData->psGPT11_FCK);

#endif
	if (bPowerLock)
	{
		PowerLockWrap(psSysSpecData);
	}
}
예제 #4
0
/*!
******************************************************************************

 @Function  ReleaseGPTimer

 @Description Release a GP timer

 @Return   PVRSRV_ERROR

******************************************************************************/
static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
	IMG_HANDLE hTimerDisable;
	IMG_UINT32 *pui32TimerDisable;
	IMG_CPU_PHYADDR TimerRegPhysBase;
#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0)
	{
		return;
	}
#endif
	/* Disable the timer */
	pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				&hTimerDisable);

	if (pui32TimerDisable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
	}
	else
	{
		*pui32TimerDisable = 0;

		OSUnMapPhysToLin(pui32TimerDisable,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				hTimerDisable);
	}
#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
#endif
#if defined(PVR_OMAP4_TIMING_PRCM)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
	clk_disable(psSysSpecData->psGPT11_ICK);
#endif

	clk_disable(psSysSpecData->psGPT11_FCK);
#endif	/* defined(PVR_OMAP4_TIMING_PRCM) */
}
예제 #5
0
PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig)
{
	PVRSRV_DEVICE_CONFIG	*psDevice;
	IMG_CPU_PHYADDR			sWrapperRegsCpuPBase;
	IMG_VOID				*pvWrapperRegs;

	psDevice = &sSysConfig.pasDevices[0];
	sWrapperRegsCpuPBase.uiAddr = psDevice->sRegsCpuPBase.uiAddr + EMULATOR_RGX_REG_WRAPPER_OFFSET;

	/* map emu registers */
	pvWrapperRegs = OSMapPhysToLin(sWrapperRegsCpuPBase,
								   EMULATOR_RGX_REG_WRAPPER_SIZE,
								   0);
	if (pvWrapperRegs == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysDebugDump: Failed to create wrapper register mapping\n"));
		return PVRSRV_ERROR_BAD_MAPPING;
	}

	PVR_LOG(("------[ System Debug ]------"));

#define SYS_EMU_DBG_R32(R)	PVR_LOG(("%-25s   0x%08X", #R ":", OSReadHWReg32(pvWrapperRegs, R)))
#define SYS_EMU_DBG_R64(R)	PVR_LOG(("%-25s 0x%010llX", #R ":", OSReadHWReg64(pvWrapperRegs, R)))

	SYS_EMU_DBG_R32(EMU_CR_PCI_MASTER);

	SYS_EMU_DBG_R64(EMU_CR_WRAPPER_ERROR);

	SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING0);
	SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING1);
	SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING2);
	SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING3);
	
	SYS_EMU_DBG_R32(EMU_CR_MEMORY_LATENCY);

	/* remove mapping */
	OSUnMapPhysToLin(pvWrapperRegs, EMULATOR_RGX_REG_WRAPPER_SIZE, 0);

	return PVRSRV_OK;

}
예제 #6
0
static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
	IMG_HANDLE hTimerDisable;
	IMG_UINT32 *pui32TimerDisable;
	IMG_CPU_PHYADDR TimerRegPhysBase;
#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0)
	{
		return;
	}
#endif
	TimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				&hTimerDisable);

	if (pui32TimerDisable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
	}
	else
	{
		*pui32TimerDisable = 0;

		OSUnMapPhysToLin(pui32TimerDisable,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				hTimerDisable);
	}

#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
#endif

#if defined(PVR_OMAP3_TIMING_PRCM)
	clk_disable(psSysSpecData->psGPT11_ICK);

	clk_disable(psSysSpecData->psGPT11_FCK);
#endif
}
예제 #7
0
static PVRSRV_ERROR SysMapInRegisters(IMG_VOID)
{
	PVRSRV_DEVICE_NODE *psDeviceNodeList;

	/*
		Map the Atlas and PDP registers.
	*/
	gpsSysData->pvSOCRegsBase = OSMapPhysToLin(gsSOCRegsCpuPBase,
	                                           SYS_ATLAS_REG_REGION_SIZE,
	                                           PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
	                                           IMG_NULL);

	if (gpsSysData->pvSOCRegsBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysPrePowerState: Failed to map SOC Register base"));
		return PVRSRV_ERROR_REGISTER_BASE_NOT_SET;
	}

	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__)
			/*
			 * SysLocateDevices will have reallocated the dummy
			 * registers.
			 */
			PVR_ASSERT(gsSGXRegsCPUVAddr);

			psDevInfo->pvRegsBaseKM = gsSGXRegsCPUVAddr;
#else
			if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS))
			{
				/* Remap Regs */
				psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
									 gsSGXDeviceMap.ui32RegsSize,
									 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
									 IMG_NULL);

				if (!psDevInfo->pvRegsBaseKM)
				{
					PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in regs\n"));
					return PVRSRV_ERROR_BAD_MAPPING;
				}
				SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
			}
#endif	/* #if defined(NO_HARDWARE) && defined(__linux__) */

			psDevInfo->ui32RegSize   = gsSGXDeviceMap.ui32RegsSize;
			psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase;

#if defined(SGX_FEATURE_HOST_PORT)
			if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
			{
				if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP))
				{
					/* Map Host Port */
					psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase,
														     gsSGXDeviceMap.ui32HPSize,
														     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
														     IMG_NULL);
					if (!psDevInfo->pvHostPortBaseKM)
					{
						PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n"));
						return PVRSRV_ERROR_BAD_MAPPING;
					}
					SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
				}
				psDevInfo->ui32HPSize  = gsSGXDeviceMap.ui32HPSize;
				psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase;
			}
#endif /* #if defined(SGX_FEATURE_HOST_PORT) */
		}

		psDeviceNodeList = psDeviceNodeList->psNext;
	}

	return PVRSRV_OK;
}
예제 #8
0
/*!
******************************************************************************

 @Function  AcquireGPTimer

 @Description Acquire a GP timer

 @Return   PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
#if defined(PVR_OMAP4_TIMING_PRCM)
	struct clk *psCLK;
	IMG_INT res;
	struct clk *sys_ck;
	IMG_INT rate;
#endif
	PVRSRV_ERROR eError;

	IMG_CPU_PHYADDR sTimerRegPhysBase;
	IMG_HANDLE hTimerEnable;
	IMG_UINT32 *pui32TimerEnable;

	PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0);

	psCLK = clk_get(NULL, "sgx_fck");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));
		return;
	}

	clk_enable(psCLK);


	psCLK = clk_get(NULL, "sgx_ick");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));
		return;
	}

	clk_enable(psCLK);

#if defined(PVR_OMAP4_TIMING_PRCM)
	
	psCLK = clk_get(NULL, "gpt6_fck");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
		goto ExitError;
	}
	psSysSpecData->psGPT11_FCK = psCLK;

	psCLK = clk_get(NULL, "gpt6_ick");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
		goto ExitError;
	}
	psSysSpecData->psGPT11_ICK = psCLK;

	sys_ck = clk_get(NULL, "sys_ck");
	if (IS_ERR(sys_ck))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));
		goto ExitError;
	}

	if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)
	{
		PVR_TRACE(("Setting GPTIMER11 parent to System Clock"));
		res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);
		if (res < 0)
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));
		goto ExitError;
		}
	}

	rate = clk_get_rate(psSysSpecData->psGPT11_FCK);
	PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));

	res = clk_enable(psSysSpecData->psGPT11_FCK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
		goto ExitError;
	}

	res = clk_enable(psSysSpecData->psGPT11_ICK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
		goto ExitDisableGPT11FCK;
	}
#endif	/* defined(PVR_OMAP4_TIMING_PRCM) */

	/* Set the timer to non-posted mode */
	sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	if(!(*pui32TimerEnable & 4))
	{
		PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));

		/* Set posted mode */
		*pui32TimerEnable |= 4;
	}

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

	/* Enable the timer */
	sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	/* Enable and set autoreload on overflow */
	*pui32TimerEnable = 3;

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

	psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase;

	eError = PVRSRV_OK;

	goto Exit;

ExitDisableGPT11ICK:
#if defined(PVR_OMAP4_TIMING_PRCM)
	clk_disable(psSysSpecData->psGPT11_ICK);
ExitDisableGPT11FCK:
	clk_disable(psSysSpecData->psGPT11_FCK);
ExitError:
#endif	/* defined(PVR_OMAP4_TIMING_PRCM) */
	eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
Exit:
	return eError;
}
예제 #9
0
static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap,
				struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size)
{
	u32 ui32PTPageCount;
	u32 ui32PDIndex;
	u32 i;
	u32 *pui32PDEntry;
	struct MMU_PT_INFO **ppsPTInfoList;
	struct SYS_DATA *psSysData;
	struct IMG_DEV_VIRTADDR sHighDevVAddr;

	PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE));

	if (SysAcquireData(&psSysData) != PVRSRV_OK)
		return IMG_FALSE;

	ui32PDIndex =
	    DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);

	if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) <
	    (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) {

		sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
	} else {
		sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size +
					(1 << (SGX_MMU_PAGE_SHIFT +
					       SGX_MMU_PT_SHIFT)) - 1;
	}

	ui32PTPageCount =
	    sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);

	ui32PTPageCount -= ui32PDIndex;

	pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr;
	pui32PDEntry += ui32PDIndex;

	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];

	PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount);
	PDUMPCOMMENT("Page directory mods (page count == %08X)",
		     ui32PTPageCount);

	for (i = 0; i < ui32PTPageCount; i++) {
		if (ppsPTInfoList[i] == NULL) {
			if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				   sizeof(struct MMU_PT_INFO),
				   (void **) &ppsPTInfoList[i], NULL)
					!= PVRSRV_OK) {
				PVR_DPF(PVR_DBG_ERROR,
					"_DeferredAllocPagetables: "
					"ERROR call to OSAllocMem failed");
				return IMG_FALSE;
			}
			OSMemSet(ppsPTInfoList[i], 0,
				 sizeof(struct MMU_PT_INFO));
		}

		if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL &&
		    ppsPTInfoList[i]->PTPageCpuVAddr == NULL) {
			struct IMG_CPU_PHYADDR sCpuPAddr;
			struct IMG_DEV_PHYADDR sDevPAddr;

			PVR_ASSERT(pui32PDEntry[i] == 0);

			if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->
			    psLocalDevMemArena == NULL) {
				if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE |
						     PVRSRV_HAP_KERNEL_ONLY,
					     SGX_MMU_PAGE_SIZE,
					     SGX_MMU_PAGE_SIZE,
					     (void **)&ppsPTInfoList[i]->
						PTPageCpuVAddr,
					     &ppsPTInfoList[i]->
						hPTPageOSMemHandle) !=
				    PVRSRV_OK) {
					PVR_DPF(PVR_DBG_ERROR,
					   "_DeferredAllocPagetables: "
					   "ERROR call to OSAllocPages failed");
					return IMG_FALSE;
				}

				if (ppsPTInfoList[i]->PTPageCpuVAddr) {
					sCpuPAddr =
					    OSMapLinToCPUPhys(ppsPTInfoList[i]->
							      PTPageCpuVAddr);
				} else {
					sCpuPAddr =
					    OSMemHandleToCpuPAddr(
						ppsPTInfoList[i]->
							  hPTPageOSMemHandle,
						0);
				}
				sDevPAddr =
				    SysCpuPAddrToDevPAddr
					    (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
			} else {
				struct IMG_SYS_PHYADDR sSysPAddr;

				if (RA_Alloc(pMMUHeap->psDevArena->
				     psDeviceMemoryHeapInfo->psLocalDevMemArena,
				     SGX_MMU_PAGE_SIZE, NULL, 0,
				     SGX_MMU_PAGE_SIZE,
				     &(sSysPAddr.uiAddr)) != IMG_TRUE) {
					PVR_DPF(PVR_DBG_ERROR,
					       "_DeferredAllocPagetables: "
					       "ERROR call to RA_Alloc failed");
					return IMG_FALSE;
				}

				sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
				ppsPTInfoList[i]->PTPageCpuVAddr =
				    (void __force *)
				    OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE,
						   PVRSRV_HAP_WRITECOMBINE |
						   PVRSRV_HAP_KERNEL_ONLY,
						   &ppsPTInfoList[i]->
						   hPTPageOSMemHandle);
				if (!ppsPTInfoList[i]->PTPageCpuVAddr) {
					PVR_DPF(PVR_DBG_ERROR,
					     "_DeferredAllocPagetables: "
					     "ERROR failed to map page tables");
					return IMG_FALSE;
				}

				sDevPAddr = SysCpuPAddrToDevPAddr
					    (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);

			}


			OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0,
				 SGX_MMU_PAGE_SIZE);

			PDUMPMALLOCPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr,
					     PDUMP_PT_UNIQUETAG);

			PDUMPPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr,
				       SGX_MMU_PAGE_SIZE, IMG_TRUE,
				       PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);

			switch (pMMUHeap->psDevArena->DevMemHeapType) {
			case DEVICE_MEMORY_HEAP_SHARED:
			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
				{
					struct MMU_CONTEXT *psMMUContext =
					    (struct MMU_CONTEXT *)pMMUHeap->
						    psMMUContext->psDevInfo->
							    pvMMUContextList;

					while (psMMUContext) {
						pui32PDEntry =
						    (u32 *)psMMUContext->
								pvPDCpuVAddr;
						pui32PDEntry += ui32PDIndex;

						pui32PDEntry[i] =
						    sDevPAddr.uiAddr |
							SGX_MMU_PDE_VALID;

						PDUMPPAGETABLE
						    ((void *)&pui32PDEntry[i],
						     sizeof(u32), IMG_FALSE,
						     PDUMP_PD_UNIQUETAG,
						     PDUMP_PT_UNIQUETAG);

						psMMUContext =
						    psMMUContext->psNext;
					}
					break;
				}
			case DEVICE_MEMORY_HEAP_PERCONTEXT:
			case DEVICE_MEMORY_HEAP_KERNEL:
				{
					pui32PDEntry[i] = sDevPAddr.uiAddr |
							     SGX_MMU_PDE_VALID;

					PDUMPPAGETABLE((void *)&pui32PDEntry[i],
						       sizeof(u32), IMG_FALSE,
						       PDUMP_PD_UNIQUETAG,
						       PDUMP_PT_UNIQUETAG);

					break;
				}
			default:
				{
					PVR_DPF(PVR_DBG_ERROR,
						"_DeferredAllocPagetables: "
						"ERROR invalid heap type");
					return IMG_FALSE;
				}
			}


			MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->
						     psDevInfo);
		} else {

			PVR_ASSERT(pui32PDEntry[i] != 0);
		}
	}

	return IMG_TRUE;
}
예제 #10
0
static IMG_BOOL
ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
{
	IMG_VOID *pvCpuVAddr;

	if(pBuf->CpuVAddr)
	{
		OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
	}
	else if(pMapping->eCpuMemoryOrigin == hm_contiguous
			|| pMapping->eCpuMemoryOrigin == hm_wrapped)
	{
		pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
									ui32Bytes,
									PVRSRV_HAP_KERNEL_ONLY
									| (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
									IMG_NULL);
		if(!pvCpuVAddr)
		{
			PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
			return IMG_FALSE;
		}
		OSMemSet(pvCpuVAddr, 0, ui32Bytes);
		OSUnMapPhysToLin(pvCpuVAddr,
						 ui32Bytes,
						 PVRSRV_HAP_KERNEL_ONLY
						 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
						 IMG_NULL);
	}
	else
	{
		IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
		IMG_SIZE_T ui32CurrentOffset = 0;
		IMG_CPU_PHYADDR CpuPAddr;

		
		PVR_ASSERT(pBuf->hOSMemHandle);

		while(ui32BytesRemaining > 0)
		{
			IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
			CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
			
			if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
			{
				ui32BlockBytes =
					MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
			}

			pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
										ui32BlockBytes,
										PVRSRV_HAP_KERNEL_ONLY
										| (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
										IMG_NULL);
			if(!pvCpuVAddr)
			{
				PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
				return IMG_FALSE;
			}
			OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
			OSUnMapPhysToLin(pvCpuVAddr,
							 ui32BlockBytes,
							 PVRSRV_HAP_KERNEL_ONLY
							 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
							 IMG_NULL);

			ui32BytesRemaining -= ui32BlockBytes;
			ui32CurrentOffset += ui32BlockBytes;
		}
	}

	return IMG_TRUE;
}
예제 #11
0
PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
{
	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
	struct clk *psCLK;
	IMG_INT res;
	PVRSRV_ERROR eError;

#if defined(DEBUG) || defined(TIMING)
	IMG_INT rate;
	struct clk *sys_ck;
	IMG_CPU_PHYADDR     TimerRegPhysBase;
	IMG_HANDLE hTimerEnable;
	IMG_UINT32 *pui32TimerEnable;

#endif	

	PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));

	if (!psSysSpecData->bSysClocksOneTimeInit)
	{
		mutex_init(&psSysSpecData->sPowerLock);

		atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);

		psCLK = clk_get(NULL, SGX_PARENT_CLOCK);
		if (IS_ERR(psCLK))
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));
			goto ExitError;
		}
		psSysSpecData->psCORE_CK = psCLK;

		psCLK = clk_get(NULL, "sgx_fck");
		if (IS_ERR(psCLK))
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));
			goto ExitError;
		}
		psSysSpecData->psSGX_FCK = psCLK;

		psCLK = clk_get(NULL, "sgx_ick");
		if (IS_ERR(psCLK))
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));
			goto ExitError;
		}
		psSysSpecData->psSGX_ICK = psCLK;

#if defined(DEBUG)
		psCLK = clk_get(NULL, "mpu_ck");
		if (IS_ERR(psCLK))
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock"));
			goto ExitError;
		}
		psSysSpecData->psMPU_CK = psCLK;
#endif
		res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK);
		if (res < 0)
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));
			goto ExitError;
		}

		psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
	}

#if defined(DEBUG) || defined(TIMING)
	
	psCLK = clk_get(NULL, "gpt11_fck");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
		goto ExitUnRegisterConstraintNotifications;
	}
	psSysSpecData->psGPT11_FCK = psCLK;

	psCLK = clk_get(NULL, "gpt11_ick");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
		goto ExitUnRegisterConstraintNotifications;
	}
	psSysSpecData->psGPT11_ICK = psCLK;

	sys_ck = clk_get(NULL, "sys_ck");
	if (IS_ERR(sys_ck))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));
		goto ExitUnRegisterConstraintNotifications;
	}

	if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)
	{
		PVR_TRACE(("Setting GPTIMER11 parent to System Clock"));
		res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);
		if (res < 0)
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));
		goto ExitUnRegisterConstraintNotifications;
		}
	}

	rate = clk_get_rate(psSysSpecData->psGPT11_FCK);
	PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));

	res = clk_enable(psSysSpecData->psGPT11_FCK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
		goto ExitUnRegisterConstraintNotifications;
	}

	res = clk_enable(psSysSpecData->psGPT11_ICK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
		goto ExitDisableGPT11FCK;
	}

	
	TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_TSICR_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	rate = *pui32TimerEnable;
	if(!(rate & 4))
	{
		PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));

		
		*pui32TimerEnable = rate | 4;
	}

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

	
	TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	
	*pui32TimerEnable = 3;

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

#endif 

	eError = PVRSRV_OK;
	goto Exit;

#if defined(DEBUG) || defined(TIMING)
ExitDisableGPT11ICK:
	clk_disable(psSysSpecData->psGPT11_ICK);
ExitDisableGPT11FCK:
	clk_disable(psSysSpecData->psGPT11_FCK);
ExitUnRegisterConstraintNotifications:
#endif	
ExitError:
	eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE;
Exit:
	return eError;
}
예제 #12
0
PVRSRV_ERROR SysInitialise(IMG_VOID)
{
	IMG_UINT32			i;
	PVRSRV_ERROR		eError;
	PVRSRV_DEVICE_NODE	*psDeviceNode;
	IMG_CPU_PHYADDR		TimerRegPhysBase;
#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;
	}

	TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
	gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
	gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
	OSReservePhys(TimerRegPhysBase,
				  4,
				  PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
				  (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
				  &gpsSysData->hSOCTimerRegisterOSMemHandle);

#if !defined(SGX_DYNAMIC_TIMING_INFO)

	psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
	if (mpu_opps[vdd1_max_level].rate == MAX_FREQ_ES_1_2)
	{
		psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED_ES_1_2;
	}
	else
	{
		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 defined(SGX_OCP_REGS_ENABLED)
	{
		IMG_SYS_PHYADDR sOCPRegsSysPBase;
		IMG_CPU_PHYADDR sOCPRegsCpuPBase;

		sOCPRegsSysPBase.uiAddr	= SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE;
		sOCPRegsCpuPBase		= SysSysPAddrToCpuPAddr(sOCPRegsSysPBase);

		gpvOCPRegsLinAddr		= OSMapPhysToLin(sOCPRegsCpuPBase,
												 SYS_OMAP3430_OCP_REGS_SIZE,
												 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
												 IMG_NULL);

		if (gpvOCPRegsLinAddr == IMG_NULL)
		{
			PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to map OCP registers"));
			return PVRSRV_ERROR_BAD_MAPPING;
		}
		SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_OCPREGS);
	}
#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

	dump_omap34xx_clocks();

	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;
}
예제 #13
0
/*!
******************************************************************************

 @Function	PVRSRVSaveRestoreLiveSegments

 @Input pArena - the arena the segment was originally allocated from.
        pbyBuffer - the system memory buffer set to null to get the size needed.
        puiBufSize - size of system memory buffer.
        bSave - IMG_TRUE if a save is required

 @Description
	Function to save or restore Resources Live segments

******************************************************************************/
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
														IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
{
	IMG_SIZE_T         uiBytesSaved = 0;
	IMG_PVOID          pvLocalMemCPUVAddr;
	RA_SEGMENT_DETAILS sSegDetails;

	if (hArena == IMG_NULL)
	{
		return (PVRSRV_ERROR_INVALID_PARAMS);
	}

	sSegDetails.uiSize = 0;
	sSegDetails.sCpuPhyAddr.uiAddr = 0;
	sSegDetails.hSegment = 0;

	/* walk the arena segments and write live one to the  buffer */
	while (RA_GetNextLiveSegment(hArena, &sSegDetails))
	{
		if (pbyBuffer == IMG_NULL)
		{
			/* calc buffer required */
			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
		}
		else
		{
			if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
			{
				return (PVRSRV_ERROR_OUT_OF_MEMORY);
			}

			PVR_DPF((
                PVR_DBG_MESSAGE, 
                "PVRSRVSaveRestoreLiveSegments: Base " CPUPADDR_FMT " size %" SIZE_T_FMT_LEN "x", 
                sSegDetails.sCpuPhyAddr.uiAddr, 
                sSegDetails.uiSize));

			/* Map the device's local memory area onto the host. */
			pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
									sSegDetails.uiSize,
									PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
									IMG_NULL);
			if (pvLocalMemCPUVAddr == IMG_NULL)
			{
				PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
				return (PVRSRV_ERROR_OUT_OF_MEMORY);
			}

			if (bSave)
			{
				/* write segment size then segment data */
				OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
				pbyBuffer += sizeof(sSegDetails.uiSize);

				OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
				pbyBuffer += sSegDetails.uiSize;
			}
			else
			{
				IMG_UINT32 uiSize;
				/* reag segment size and validate */
				OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));

				if (uiSize != sSegDetails.uiSize)
				{
					PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
				}
				else
				{
					pbyBuffer += sizeof(sSegDetails.uiSize);

					OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
					pbyBuffer += sSegDetails.uiSize;
				}
			}


			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;

			OSUnMapPhysToLin(pvLocalMemCPUVAddr,
		                     sSegDetails.uiSize,
		                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		                     IMG_NULL);
		}
	}

	if (pbyBuffer == IMG_NULL)
	{
		*puiBufSize = uiBytesSaved;
	}

	return (PVRSRV_OK);
}
예제 #14
0
enum PVRSRV_ERROR PVRSRVSaveRestoreLiveSegments(void *hArena, u8 *pbyBuffer,
					   u32 *puiBufSize, IMG_BOOL bSave)
{
	u32 uiBytesSaved = 0;
	void *pvLocalMemCPUVAddr;
	struct RA_SEGMENT_DETAILS sSegDetails;

	if (hArena == NULL)
		return PVRSRV_ERROR_INVALID_PARAMS;

	sSegDetails.uiSize = 0;
	sSegDetails.sCpuPhyAddr.uiAddr = 0;
	sSegDetails.hSegment = NULL;

	while (RA_GetNextLiveSegment(hArena, &sSegDetails))
		if (pbyBuffer == NULL) {
			uiBytesSaved +=
			    sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
		} else {
			if ((uiBytesSaved + sizeof(sSegDetails.uiSize) +
			     sSegDetails.uiSize) > *puiBufSize)
				return PVRSRV_ERROR_OUT_OF_MEMORY;

			PVR_DPF(PVR_DBG_MESSAGE,
				 "PVRSRVSaveRestoreLiveSegments: "
				 "Base %08x size %08x",
				 sSegDetails.sCpuPhyAddr.uiAddr,
				 sSegDetails.uiSize);

			pvLocalMemCPUVAddr = (void __force *)
			    OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
					   sSegDetails.uiSize,
					   PVRSRV_HAP_KERNEL_ONLY |
					   PVRSRV_HAP_UNCACHED, NULL);
			if (pvLocalMemCPUVAddr == NULL) {
				PVR_DPF(PVR_DBG_ERROR,
					 "PVRSRVSaveRestoreLiveSegments: "
					 "Failed to map local memory to host");
				return PVRSRV_ERROR_OUT_OF_MEMORY;
			}

			if (bSave) {
				OSMemCopy(pbyBuffer, &sSegDetails.uiSize,
					  sizeof(sSegDetails.uiSize));
				pbyBuffer += sizeof(sSegDetails.uiSize);

				OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr,
					  sSegDetails.uiSize);
				pbyBuffer += sSegDetails.uiSize;
			} else {
				u32 uiSize;

				OSMemCopy(&uiSize, pbyBuffer,
					  sizeof(sSegDetails.uiSize));

				if (uiSize != sSegDetails.uiSize) {
					PVR_DPF(PVR_DBG_ERROR,
						"PVRSRVSaveRestoreLiveSegments:"
						" Segment size error");
				} else {
					pbyBuffer += sizeof(sSegDetails.uiSize);

					OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer,
						  sSegDetails.uiSize);
					pbyBuffer += sSegDetails.uiSize;
				}
			}

			uiBytesSaved +=
			    sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;

			OSUnMapPhysToLin((void __force __iomem *)
							pvLocalMemCPUVAddr,
					 sSegDetails.uiSize,
					 PVRSRV_HAP_KERNEL_ONLY |
					 PVRSRV_HAP_UNCACHED, NULL);
		}

	if (pbyBuffer == NULL)
		*puiBufSize = uiBytesSaved;

	return PVRSRV_OK;
}
예제 #15
0
IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
{
	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
	IMG_BOOL bPowerLock;
#if defined(DEBUG) || defined(TIMING)
	IMG_CPU_PHYADDR TimerRegPhysBase;
	IMG_HANDLE hTimerDisable;
	IMG_UINT32 *pui32TimerDisable;
#endif	

	PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));

	
	DisableSGXClocks(psSysData);

	bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);
	if (bPowerLock)
	{
		
		PowerLockUnwrap(psSysSpecData);
	}

#if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS)
	{
		int res;

		PVR_TRACE(("DisableSystemClocks: Removing SGX OPP constraint"));

		
		res = constraint_remove(psSysSpecData->pVdd2Handle);
		if (res != 0)
		{
			PVR_DPF((PVR_DBG_WARNING, "DisableSystemClocks: constraint_remove failed (%d)", res));
		}
	}
#endif

#if defined(CONSTRAINT_NOTIFICATIONS)
	UnRegisterConstraintNotifications();
#endif

#if defined(DEBUG) || defined(TIMING)
	
	TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				&hTimerDisable);

	if (pui32TimerDisable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
	}
	else
	{
		*pui32TimerDisable = 0;

		OSUnMapPhysToLin(pui32TimerDisable,
				4,
				PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
				hTimerDisable);
	}

	clk_disable(psSysSpecData->psGPT11_ICK);

	clk_disable(psSysSpecData->psGPT11_FCK);

#endif 
#if defined(CONSTRAINT_NOTIFICATIONS)
	constraint_put(psSysSpecData->pVdd2Handle);
#endif
	if (bPowerLock)
	{
		PowerLockWrap(psSysSpecData);
	}
}
예제 #16
0
PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
{
	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
	struct clk *psCLK;
	IMG_INT res;
	PVRSRV_ERROR eError;
	IMG_BOOL bPowerLock;

#if defined(DEBUG) || defined(TIMING)
	IMG_INT rate;
	struct clk *sys_ck;
	IMG_CPU_PHYADDR     TimerRegPhysBase;
	IMG_HANDLE hTimerEnable;
	IMG_UINT32 *pui32TimerEnable;

#endif	

	PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));

	if (!psSysSpecData->bSysClocksOneTimeInit)
	{
		bPowerLock = IMG_FALSE;

		spin_lock_init(&psSysSpecData->sPowerLock);
		atomic_set(&psSysSpecData->sPowerLockCPU, -1);
		spin_lock_init(&psSysSpecData->sNotifyLock);
		atomic_set(&psSysSpecData->sNotifyLockCPU, -1);

		atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
                
		psCLK = clk_get(NULL, "sgx_ck");
		
                if (IS_ERR(psCLK))
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));
			goto ExitError;
		}
		psSysSpecData->psSGX_FCK = psCLK;

		psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
	}
	else
	{
		
		bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);
		if (bPowerLock)
		{
			PowerLockUnwrap(psSysSpecData);
		}
	}

#if defined(CONSTRAINT_NOTIFICATIONS)
	psSysSpecData->pVdd2Handle = constraint_get(PVRSRV_MODNAME, &cnstr_id_vdd2);
	if (IS_ERR(psSysSpecData->pVdd2Handle))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get VDD2 constraint handle"));
		goto ExitError;
	}

	RegisterConstraintNotifications();
#endif

#if defined(DEBUG) || defined(TIMING)
        if(cpu_is_ti816x()) {
                psCLK = clk_get(NULL, "gpt6_fck");
        } else {
                psCLK = clk_get(NULL, "gpt7_fck");
        }
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
		goto ExitUnRegisterConstraintNotifications;
	}
	psSysSpecData->psGPT11_FCK = psCLK;

        if(cpu_is_ti816x()) {
                psCLK = clk_get(NULL, "gpt6_ick");
        } else {
                psCLK = clk_get(NULL, "gpt7_ick");
        }
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
		goto ExitUnRegisterConstraintNotifications;
	}
	psSysSpecData->psGPT11_ICK = psCLK;

	rate = clk_get_rate(psSysSpecData->psGPT11_FCK);
	PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));

	res = clk_enable(psSysSpecData->psGPT11_FCK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
		goto ExitUnRegisterConstraintNotifications;
	}

	res = clk_enable(psSysSpecData->psGPT11_ICK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
		goto ExitDisableGPT11FCK;
	}

	
	TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_TSICR_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	rate = *pui32TimerEnable;
	if(!(rate & 4))
	{
		PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));

		
		*pui32TimerEnable = rate | 4;
	}

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

	
	TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	
	*pui32TimerEnable = 3;

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);

#endif 

#if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS)
	PVR_TRACE(("EnableSystemClocks: Setting SGX OPP constraint"));

	
	res = constraint_set(psSysSpecData->pVdd2Handle, max_vdd2_opp);
	if (res != 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: constraint_set failed (%d)", res));
		goto ExitConstraintSetFailed;
	}
#endif
	eError = PVRSRV_OK;
	goto Exit;

#if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS)
ExitConstraintSetFailed:
#endif
#if defined(DEBUG) || defined(TIMING)
ExitDisableGPT11ICK:
	clk_disable(psSysSpecData->psGPT11_ICK);
ExitDisableGPT11FCK:
	clk_disable(psSysSpecData->psGPT11_FCK);
ExitUnRegisterConstraintNotifications:
#endif	
#if defined(CONSTRAINT_NOTIFICATIONS)
	UnRegisterConstraintNotifications();
	constraint_put(psSysSpecData->pVdd2Handle);
#endif
Exit:
	if (bPowerLock)
	{
		PowerLockWrap(psSysSpecData);
	}

ExitError:
	eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE;
	return eError;
}
예제 #17
0
static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
#if defined(PVR_OMAP3_TIMING_PRCM)
	struct clk *psCLK;
	IMG_INT res;
	struct clk *sys_ck;
	IMG_INT rate;
#endif
	PVRSRV_ERROR eError;

	IMG_CPU_PHYADDR sTimerRegPhysBase;
	IMG_HANDLE hTimerEnable;
	IMG_UINT32 *pui32TimerEnable;
#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0);
#endif


#if defined(PVR_OMAP3_TIMING_PRCM)

	psCLK = clk_get(NULL, "gpt7_fck");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
		goto ExitError;
	}
	psSysSpecData->psGPT11_FCK = psCLK;

	psCLK = clk_get(NULL, "gpt7_ick");
	if (IS_ERR(psCLK))
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
		goto ExitError;
	}
	psSysSpecData->psGPT11_ICK = psCLK;

	rate = clk_get_rate(psSysSpecData->psGPT11_FCK);
	PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));

	res = clk_enable(psSysSpecData->psGPT11_FCK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
		goto ExitError;
	}

	res = clk_enable(psSysSpecData->psGPT11_ICK);
	if (res < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
		goto ExitDisableGPT11FCK;
	}
#endif


	sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_TSICR_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	if(!(*pui32TimerEnable & 4))
	{
		PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));


		*pui32TimerEnable |= 4;
	}

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);


	sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_ENABLE_SYS_PHYS_BASE;
	pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
                  4,
                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
                  &hTimerEnable);

	if (pui32TimerEnable == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
		goto ExitDisableGPT11ICK;
	}

	*pui32TimerEnable = 3;

	OSUnMapPhysToLin(pui32TimerEnable,
		    4,
		    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		    hTimerEnable);
#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
	psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase;
#endif

	eError = PVRSRV_OK;

	goto Exit;

ExitDisableGPT11ICK:
#if defined(PVR_OMAP3_TIMING_PRCM)
	clk_disable(psSysSpecData->psGPT11_ICK);
ExitDisableGPT11FCK:
	clk_disable(psSysSpecData->psGPT11_FCK);
ExitError:
#endif
	eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
Exit:
	return eError;
}
예제 #18
0
/*!
******************************************************************************

 @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;
	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

	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;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);

	/* 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;

#ifdef __linux__
	eError = PCIInitDev(gpsSysData);
	if (eError != PVRSRV_OK)
	{
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PCINIT);
#endif

	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"));
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}

	/*
		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"));
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);

	/*
		Map the Atlas and PDP registers.
	*/
	gpsSysData->pvSOCRegsBase = OSMapPhysToLin(gsSOCRegsCpuPBase,
											   SYS_ATLAS_REG_REGION_SIZE,
	                                           PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
	                                           IMG_NULL);

	/*
		Do some initial register setup
	*/
	eError = SysInitRegisters();
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysInitRegisters: Failed to initialise registers"));
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITREG);

#if defined(READ_TCF_HOST_MEM_SIGNATURE)
	SysTestTCFHostMemSig(gsSGXDeviceMap.sRegsCpuPBase,
						 gsSGXDeviceMap.sLocalMemCpuPBase);
#endif

	/*
		Register devices with the system
		This also sets up their memory maps/heaps
	*/
	eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
								  SysGetSGXInterruptBit(), &gui32SGXDeviceID);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);

	/*
		A given SOC may have 0 to n local device memory blocks.
		It is assumed device local memory blocks will be either
		specific to each device or shared among one or more services
		managed devices.
		Note: no provision is made for a single device having more
		than one local device memory blocks. If required we must
		add new types,
		e.g.PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG0
			PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG1
	*/

	/*
		Create Local Device Page Managers for each device memory block.
		We'll use an RA to do the management
		(only one for the emulator)
	*/
	gpsSysData->apsLocalDevMemArena[0] = RA_Create ("TestChipDeviceMemory",
													gsSGXDeviceMap.sLocalMemSysPBase.uiAddr,
													gsSGXDeviceMap.ui32LocalMemSize,
													IMG_NULL,
													HOST_PAGESIZE(),
													IMG_NULL,
													IMG_NULL,
													IMG_NULL,
													IMG_NULL);

	if (gpsSysData->apsLocalDevMemArena[0] == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to create local dev mem allocator!"));
		SysDeinitialise(gpsSysData);
		gpsSysData = IMG_NULL;
		return eError;
	}
	SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_RA_ARENA);

	/*
		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 device's MMU PT/PDs */
				psDeviceNode->psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0];

				/* useful pointers */
				psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
				psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;

				/* specify the backing store for all SGX heaps */
				for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
				{
					/*
						specify the backing store type
						(all local device mem noncontig) for test chip
					*/
					psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG;

					/*
						map the device memory allocator(s) onto
						the device memory heaps as required
					*/
					psDeviceMemoryHeap[i].psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0];

#ifdef OEM_CUSTOMISE
					/* if required, modify the memory config */
#endif
				}
				break;
			}
			default:
				break;
		}

		/* advance to next device */
		psDeviceNode = psDeviceNode->psNext;
	}

	/*
		Initialise all devices 'managed' by services:
	*/
	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_ENABLE_INITDEV);

	return PVRSRV_OK;
}
예제 #19
0
static PVRSRV_ERROR SysCreateVersionString(SYS_DATA *psSysData)
{
    IMG_UINT32 ui32MaxStrLen;
    PVRSRV_ERROR eError;
    IMG_INT32 i32Count;
    IMG_CHAR *pszVersionString;
    IMG_UINT32 ui32SGXRevision = 0;
	IMG_VOID *pvSGXRegs;

	pvSGXRegs = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
											 gsSGXDeviceMap.ui32RegsSize,
											 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
											 IMG_NULL);

	if (pvSGXRegs != IMG_NULL)
	{
            ui32SGXRevision = OSReadHWReg(pvSGXRegs, EUR_CR_CORE_REVISION);
	     OSUnMapPhysToLin(pvSGXRegs,
												gsSGXDeviceMap.ui32RegsSize,
												PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
												IMG_NULL);
	}
	else
	{
	     PVR_DPF((PVR_DBG_ERROR,"SysCreateVersionString: Couldn't map SGX registers"));
	}

    ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
    eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
                          ui32MaxStrLen + 1,
                          (IMG_PVOID *)&pszVersionString,
                          IMG_NULL,
			  "Version String");
    if(eError != PVRSRV_OK)
    {
		return eError;
    }

    i32Count = OSSNPrintf(pszVersionString, ui32MaxStrLen + 1,
                           "SGX revision = %u.%u.%u",
                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
                            >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
                            >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
                            >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
                           );
    if(i32Count == -1)
    {
        ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
                    ui32MaxStrLen + 1,
                    pszVersionString,
                    IMG_NULL);

		return PVRSRV_ERROR_INVALID_PARAMS;
    }

    psSysData->pszVersionString = pszVersionString;

    return PVRSRV_OK;
}
예제 #20
0
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
														IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
{
	IMG_SIZE_T         uiBytesSaved = 0;
	IMG_PVOID          pvLocalMemCPUVAddr;
	RA_SEGMENT_DETAILS sSegDetails;

	if (hArena == IMG_NULL)
	{
		return (PVRSRV_ERROR_INVALID_PARAMS);
	}

	sSegDetails.uiSize = 0;
	sSegDetails.sCpuPhyAddr.uiAddr = 0;
	sSegDetails.hSegment = 0;

	
	while (RA_GetNextLiveSegment(hArena, &sSegDetails))
	{
		if (pbyBuffer == IMG_NULL)
		{
			
			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
		}
		else
		{
			if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
			{
				return (PVRSRV_ERROR_OUT_OF_MEMORY);
			}

			PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));

			
			pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
									sSegDetails.uiSize,
									PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
									IMG_NULL);
			if (pvLocalMemCPUVAddr == IMG_NULL)
			{
				PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
				return (PVRSRV_ERROR_OUT_OF_MEMORY);
			}

			if (bSave)
			{
				
				OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
				pbyBuffer += sizeof(sSegDetails.uiSize);

				OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
				pbyBuffer += sSegDetails.uiSize;
			}
			else
			{
				IMG_UINT32 uiSize;
				
				OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));

				if (uiSize != sSegDetails.uiSize)
				{
					PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
				}
				else
				{
					pbyBuffer += sizeof(sSegDetails.uiSize);

					OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
					pbyBuffer += sSegDetails.uiSize;
				}
			}


			uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;

			OSUnMapPhysToLin(pvLocalMemCPUVAddr,
		                     sSegDetails.uiSize,
		                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
		                     IMG_NULL);
		}
	}

	if (pbyBuffer == IMG_NULL)
	{
		*puiBufSize = uiBytesSaved;
	}

	return (PVRSRV_OK);
}
static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
{
#if defined(NO_HARDWARE)
	PVRSRV_ERROR eError;
	IMG_CPU_PHYADDR sCpuPAddr;
#else
#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
	struct resource *dev_res;
	int dev_irq;
#endif
#endif

	PVR_UNREFERENCED_PARAMETER(psSysData);

	
	gsSGXDeviceMap.ui32Flags = 0x0;
	
#if defined(NO_HARDWARE)
	
	
	gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE;

	eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize,
									 &gsSGXRegsCPUVAddr,
									 &sCpuPAddr);
	if(eError != PVRSRV_OK)
	{
		return eError;
	}
	gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
	gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
#if defined(__linux__)
	
	gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
#else
	
	gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;
#endif

	OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize);

	


	gsSGXDeviceMap.ui32IRQ = 0;

#else 
#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
	
	dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0);
	if (dev_res == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__));
		return PVRSRV_ERROR_INVALID_DEVICE;
	}

	dev_irq = platform_get_irq(gpsPVRLDMDev, 0);
	if (dev_irq < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq));
		return PVRSRV_ERROR_INVALID_DEVICE;
	}
	
	gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start;
	gsSGXDeviceMap.sRegsCpuPBase =
		SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
	PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr));

	gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start);
	PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize));

	gsSGXDeviceMap.ui32IRQ = dev_irq;
	PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ));
#else	
	gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_TI335x_SGX_REGS_SYS_PHYS_BASE;
	gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
	gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE;

	gsSGXDeviceMap.ui32IRQ = SYS_TI335x_SGX_IRQ;

#endif	
#if defined(SGX_OCP_REGS_ENABLED)
	gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
	gsSGXDeviceMap.ui32RegsSize,
											 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
											 IMG_NULL);

	if (gsSGXRegsCPUVAddr == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers"));
		return PVRSRV_ERROR_BAD_MAPPING;
	}

	
	gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
	gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr;
#endif
#endif 

#if defined(PDUMP)
	{
		
		static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
		gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
	}
#endif

	


	return PVRSRV_OK;
}
static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping,
			u32 ui32Bytes, u32 ui32Flags)
{
	void *pvCpuVAddr;

	if (pBuf->CpuVAddr) {
		OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
	} else if (pMapping->eCpuMemoryOrigin == hm_contiguous ||
		   pMapping->eCpuMemoryOrigin == hm_wrapped) {
		pvCpuVAddr = (void __force *)OSMapPhysToLin(pBuf->CpuPAddr,
					    ui32Bytes,
					    PVRSRV_HAP_KERNEL_ONLY |
					    (ui32Flags &
					       PVRSRV_HAP_CACHETYPE_MASK),
					    NULL);
		if (!pvCpuVAddr) {
			PVR_DPF(PVR_DBG_ERROR, "ZeroBuf: "
				"OSMapPhysToLin for contiguous buffer failed");
			return IMG_FALSE;
		}
		OSMemSet(pvCpuVAddr, 0, ui32Bytes);
		OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, ui32Bytes,
				 PVRSRV_HAP_KERNEL_ONLY |
				    (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
				 NULL);
	} else {
		u32 ui32BytesRemaining = ui32Bytes;
		u32 ui32CurrentOffset = 0;
		struct IMG_CPU_PHYADDR CpuPAddr;

		PVR_ASSERT(pBuf->hOSMemHandle);

		while (ui32BytesRemaining > 0) {
			u32 ui32BlockBytes =
			    MIN(ui32BytesRemaining, HOST_PAGESIZE());
			CpuPAddr =
			    OSMemHandleToCpuPAddr(pBuf->hOSMemHandle,
						  ui32CurrentOffset);

			if (CpuPAddr.uiAddr & (HOST_PAGESIZE() - 1))
				ui32BlockBytes =
				    MIN(ui32BytesRemaining,
					HOST_PAGEALIGN(CpuPAddr.uiAddr) -
					CpuPAddr.uiAddr);

			pvCpuVAddr = (void __force *)OSMapPhysToLin(CpuPAddr,
						    ui32BlockBytes,
						    PVRSRV_HAP_KERNEL_ONLY |
						     (ui32Flags &
						     PVRSRV_HAP_CACHETYPE_MASK),
						    NULL);
			if (!pvCpuVAddr) {
				PVR_DPF(PVR_DBG_ERROR, "ZeroBuf: "
					"OSMapPhysToLin while "
				       "zeroing non-contiguous memory FAILED");
				return IMG_FALSE;
			}
			OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
			OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr,
					 ui32BlockBytes,
					 PVRSRV_HAP_KERNEL_ONLY |
					   (ui32Flags &
					    PVRSRV_HAP_CACHETYPE_MASK),
					 NULL);

			ui32BytesRemaining -= ui32BlockBytes;
			ui32CurrentOffset += ui32BlockBytes;
		}
	}

	return IMG_TRUE;
}
예제 #23
0
/***********************************************************************//**
 * Map the CPU physical backing for the registers to CPU virtual memory
 * so we can write to it from the host
 *
 * @returns PVRSRV_OK for success, or failure code
 **************************************************************************/
static PVRSRV_ERROR SysMapInRegisters(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)
			if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS))
			{
				/* Remap Regs */
				psDevInfo->pvRegsBaseKM =
					OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
								   gsSGXDeviceMap.ui32RegsSize,
								   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
								   IMG_NULL);

				if (!psDevInfo->pvRegsBaseKM)
				{
					PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in regs\n"));
					return PVRSRV_ERROR_BAD_MAPPING;
				}
				SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
			}
#else	/* !defined(NO_HARDWARE) */
			/*
			 * SysLocateDevices will have reallocated the dummy
			 * registers.
			 */
			psDevInfo->pvRegsBaseKM = gsSGXDeviceMap.pvRegsCpuVBase;
#endif	/* !defined(NO_HARDWARE) */
			psDevInfo->ui32RegSize   = gsSGXDeviceMap.ui32RegsSize;
			psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase;
			break;
		}
#if defined(SUPPORT_MSVDX)
		case PVRSRV_DEVICE_TYPE_MSVDX:
		{
			PVRSRV_MSVDXDEV_INFO *psDevInfo = (PVRSRV_MSVDXDEV_INFO *)
				psDeviceNodeList->pvDevice;
#if !defined(NO_HARDWARE)
			if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS))
			{
				/* Remap registers */
				psDevInfo->pvRegsBaseKM =
					OSMapPhysToLin(gsMSVDXDeviceMap.sRegsCpuPBase,
								   gsMSVDXDeviceMap.ui32RegsSize,
								   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
								   IMG_NULL);
				if (!psDevInfo->pvRegsBaseKM)
				{
					PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map MSVDX registers\n"));
					return PVRSRV_ERROR_BAD_MAPPING;
				}
				SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS);
			}
#else	/* !defined(NO_HARDWARE) */
			/*
			 * SysLocateDevices will have reallocated the dummy
			 * registers.
			 */
			psDevInfo->pvRegsBaseKM = gsMSVDXDeviceMap.sRegsCpuVBase;
#endif	/* !defined(NO_HARDWARE) */
			psDevInfo->ui32RegSize = gsMSVDXDeviceMap.ui32RegsSize;
			psDevInfo->sRegsPhysBase = gsMSVDXDeviceMap.sRegsSysPBase;
			break;
		}
#endif	/* SUPPORT_MSVDX */
		default:
			/* Ignore any other (unknown) devices */
			break;
		}

		psDeviceNodeList = psDeviceNodeList->psNext;
	}

	return PVRSRV_OK;
}
예제 #24
0
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;
}
예제 #25
0
enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode,
			    struct MMU_CONTEXT **ppsMMUContext,
			    struct IMG_DEV_PHYADDR *psPDDevPAddr)
{
	u32 *pui32Tmp;
	u32 i;
	void *pvPDCpuVAddr;
	struct IMG_DEV_PHYADDR sPDDevPAddr;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_SYS_PHYADDR sSysPAddr;
	struct MMU_CONTEXT *psMMUContext;
	void *hPDOSMemHandle;
	struct SYS_DATA *psSysData;
	struct PVRSRV_SGXDEV_INFO *psDevInfo;

	PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise");

	if (SysAcquireData(&psSysData) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: ERROR call to SysAcquireData failed");
		return PVRSRV_ERROR_GENERIC;
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		   sizeof(struct MMU_CONTEXT), (void **) &psMMUContext, NULL)
			!= PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: ERROR call to OSAllocMem failed");
		return PVRSRV_ERROR_GENERIC;
	}
	OSMemSet(psMMUContext, 0, sizeof(struct MMU_CONTEXT));

	psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
	psMMUContext->psDevInfo = psDevInfo;

	psMMUContext->psDeviceNode = psDeviceNode;

	if (psDeviceNode->psLocalDevMemArena == NULL) {
		if (OSAllocPages
		    (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
		     SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr,
		     &hPDOSMemHandle) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR call to OSAllocPages failed");
			goto err1;
		}

		if (pvPDCpuVAddr)
			sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr);
		else
			sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
		sPDDevPAddr =
		    SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
	} else {
		if (RA_Alloc(psDeviceNode->psLocalDevMemArena,
			     SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE,
			     &(sSysPAddr.uiAddr)) != IMG_TRUE) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR call to RA_Alloc failed");

			goto err1;
		}

		sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
		sPDDevPAddr =
		    SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
		pvPDCpuVAddr = (void __force *)
		    OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE,
				   PVRSRV_HAP_WRITECOMBINE |
				   PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle);
		if (!pvPDCpuVAddr) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR failed to map page tables");

			goto err2;
		}
	}

	PDUMPCOMMENT("Alloc page directory");

	PDUMPMALLOCPAGETABLE(pvPDCpuVAddr, PDUMP_PD_UNIQUETAG);

	if (pvPDCpuVAddr) {
		pui32Tmp = (u32 *) pvPDCpuVAddr;
	} else {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: pvPDCpuVAddr invalid");
		goto err3;
	}

	for (i = 0; i < SGX_MMU_PD_SIZE; i++)
		pui32Tmp[i] = 0;

	PDUMPCOMMENT("Page directory contents");
	PDUMPPAGETABLE(pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE,
		       PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);

	psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
	psMMUContext->sPDDevPAddr = sPDDevPAddr;
	psMMUContext->hPDOSMemHandle = hPDOSMemHandle;

	*ppsMMUContext = psMMUContext;

	*psPDDevPAddr = sPDDevPAddr;

	psMMUContext->psNext = (struct MMU_CONTEXT *)
						psDevInfo->pvMMUContextList;
	psDevInfo->pvMMUContextList = (void *) psMMUContext;


	return PVRSRV_OK;
err3:
	if (psDeviceNode->psLocalDevMemArena)
		OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr,
				 SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE |
					PVRSRV_HAP_KERNEL_ONLY,
				 hPDOSMemHandle);
err2:
	if (!psDeviceNode->psLocalDevMemArena)
		OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
			    SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle);
	else
		RA_Free(psDeviceNode->psLocalDevMemArena,
			sSysPAddr.uiAddr, IMG_FALSE);
err1:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT),
		  psMMUContext, NULL);

	return PVRSRV_ERROR_GENERIC;
}
예제 #26
0
static PVRSRV_ERROR SysMapInRegisters(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 (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS))
			{
				psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
									 gsSGXDeviceMap.ui32RegsSize,
									 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
									 IMG_NULL);

				if (!psDevInfo->pvRegsBaseKM)
				{
					PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in SGX registers\n"));
					return PVRSRV_ERROR_BAD_MAPPING;
				}
				SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
			}
			psDevInfo->ui32RegSize   = gsSGXDeviceMap.ui32RegsSize;
			psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase;

#if defined(SGX_FEATURE_HOST_PORT)
			if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
			{
				if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP))
				{

					psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase,
														     gsSGXDeviceMap.ui32HPSize,
														     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
														     IMG_NULL);
					if (!psDevInfo->pvHostPortBaseKM)
					{
						PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n"));
						return PVRSRV_ERROR_BAD_MAPPING;
					}
					SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
				}
				psDevInfo->ui32HPSize  = gsSGXDeviceMap.ui32HPSize;
				psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase;
			}
#endif
			break;
		}
		default:
			break;
		}
		psDeviceNodeList = psDeviceNodeList->psNext;
	}

	return PVRSRV_OK;
}
예제 #27
0
/*
	EmuReset
*/
static PVRSRV_ERROR EmuReset(IMG_CPU_PHYADDR	sRegsCpuPBase)
{
	IMG_CPU_PHYADDR	sWrapperRegsCpuPBase;
	IMG_VOID		*pvWrapperRegs;
	IMG_UINT32		ui32MemLatency;
	
	sWrapperRegsCpuPBase.uiAddr = sRegsCpuPBase.uiAddr + EMULATOR_RGX_REG_WRAPPER_OFFSET;
	
	/*
		Create a temporary mapping of the wrapper registers in order to reset
		the emulator design.
	*/
	pvWrapperRegs = OSMapPhysToLin(sWrapperRegsCpuPBase,
								   EMULATOR_RGX_REG_WRAPPER_SIZE,
								   0);
	if (pvWrapperRegs == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"EmuReset: Failed to create wrapper register mapping\n"));
		return PVRSRV_ERROR_BAD_MAPPING;
	}

	/*
		Set the memory latency. This needs to be done before the soft reset to ensure
		it applies to all aspects of the emulator.
	*/
	ui32MemLatency = EmuMemLatencyGet();
	if (ui32MemLatency != 0)
	{
		PVR_LOG(("EmuReset: Mem latency = 0x%X", ui32MemLatency));
	}
	OSWriteHWReg32(pvWrapperRegs, EMU_CR_MEMORY_LATENCY, ui32MemLatency);
	(void) OSReadHWReg32(pvWrapperRegs, EMU_CR_MEMORY_LATENCY);

	/*
		Emu reset.
	*/
	OSWriteHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET, EMU_CR_SOFT_RESET_SYS_EN|EMU_CR_SOFT_RESET_MEM_EN|EMU_CR_SOFT_RESET_CORE_EN);
	/* Flush register write */
	(void) OSReadHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET);
	OSWaitus(10);

	OSWriteHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET, 0x0);
	/* Flush register write */
	(void) OSReadHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET);
	OSWaitus(10);

#if !defined(LMA)
	/* If we're UMA then enable bus mastering */
	OSWriteHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER, EMU_CR_PCI_MASTER_MODE_EN);
#else
	/* otherwise disable it: the emu regbank is not resetable */
	OSWriteHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER, 0x0);
#endif

	/* Flush register write */
	(void) OSReadHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER);

	/*
		Remove the temporary register mapping.
	*/
	OSUnMapPhysToLin(pvWrapperRegs, EMULATOR_RGX_REG_WRAPPER_SIZE, 0);

	return PVRSRV_OK;
}
예제 #28
0
/*!
******************************************************************************

 @Function	SysLocateDevices

 @Description	Specifies devices in the systems memory map

 @Input		psSysData - sys data

 @Return	PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
{
#if defined(NO_HARDWARE)
	PVRSRV_ERROR eError;
	IMG_CPU_PHYADDR sCpuPAddr;
#else
#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
	struct resource *dev_res;
	int dev_irq;
#endif
#endif

	PVR_UNREFERENCED_PARAMETER(psSysData);

	/* SGX Device: */
	gsSGXDeviceMap.ui32Flags = 0x0;

#if defined(NO_HARDWARE)
	/*
	 * For no hardware, allocate some contiguous memory for the
	 * register block.
	 */

	/* Registers */
	gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE;

	eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize,
									 &gsSGXRegsCPUVAddr,
									 &sCpuPAddr);
	if(eError != PVRSRV_OK)
	{
		return eError;
	}
	gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
	gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
#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

	OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize);

	/*
		device interrupt IRQ
		Note: no interrupts available on no hardware system
	*/
	gsSGXDeviceMap.ui32IRQ = 0;

#else /* defined(NO_HARDWARE) */
#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
	/* get the resource and IRQ through platform resource API */
	dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0);
	if (dev_res == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__));
		return PVRSRV_ERROR_INVALID_DEVICE;
	}

	dev_irq = platform_get_irq(gpsPVRLDMDev, 0);
	if (dev_irq < 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq));
		return PVRSRV_ERROR_INVALID_DEVICE;
	}

	gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start;
	gsSGXDeviceMap.sRegsCpuPBase =
		SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
	PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr));

#if defined(SGX544) && defined(SGX_FEATURE_MP)
	/* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */
	gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE;
#else
	gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start);
#endif
	PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize));

	gsSGXDeviceMap.ui32IRQ = dev_irq;
	PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ));
#else	/* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */
	gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3630_SGX_REGS_SYS_PHYS_BASE;
	gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
	gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE;

	gsSGXDeviceMap.ui32IRQ = SYS_OMAP3630_SGX_IRQ;

#endif	/* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */
#if defined(SGX_OCP_REGS_ENABLED)
	gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
	gsSGXDeviceMap.ui32RegsSize,
											 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
											 IMG_NULL);

	if (gsSGXRegsCPUVAddr == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers"));
		return PVRSRV_ERROR_BAD_MAPPING;
	}

	/* Indicate the registers are already mapped */
	gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
	gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr;
#endif
#endif /* defined(NO_HARDWARE) */

#if defined(PDUMP)
	{
		/* initialise memory region name for pdumping */
		static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
		gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
	}
#endif

	/* add other devices here: */


	return PVRSRV_OK;
}
예제 #29
0
/***********************************************************************//**
 * 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;
}