⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 marathon.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if((ui32PLLToUse == MAR_SYSCLK_SELECT_PLL0) && (ui32CurSysPll !=MAR_SYSCLK_SELECT_PLL0))
	{
		if(!SetPLL(0, ui32DesiredFreq, &pMSysData->ui32SysClk))
		{
			PVR_DPF((PVR_DBG_ERROR, "ChangeSYSCLK: PLL0 needed but did not lock"));
			if (pMSysData->ui32PixClk > MAR_REFCLK_FREQ)
			{
				/* PLL failed, but PLL1 is closer to what we want than REFCLK, so use that. */
				ui32PLLToUse= MAR_SYSCLK_SELECT_PLL1;
				HostWaitus(250);
				pMSysData->ui32SysClk = pMSysData->ui32PixClk;
			}
		}
	 }

	// now do the prechange code.
	SysPreChangePll();
	
	/***************************************************** Shutdown memories */

	/* Force ODFB into sleep mode (instead of slow mode). This should fix A2/A3 memory refresh problem. */
	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_ODFB_POWERMODE, MAR_ODFB_POWERMODE_MODE_SLEEP);	

	if(pMSysData->ui32SDRAMMode == SYS_SDRAM_POWER_ACTIVE)
	{
		SysSDRAMSetState(SYS_SDRAM_POWER_SLEEP);
		PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
		pMSysData->bSDRAMNeedsWaking = TRUE;
	}

	/*************************************************************************/
	
	if(ui32PLLToUse == MAR_SYSCLK_SELECT_PLL0)
	{
		if(ui32CurSysPll == MAR_SYSCLK_SELECT_PLL0)
		{
			// we have to go to refclock before we can do the changes.
			pMSysData->ui32SysClk = MAR_REFCLK_FREQ;
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYSCLK_SELECT, MAR_SYSCLK_SELECT_REFCLK);
			HostWaitus(250); // FIXME - Wait for SINT_CLKSW to trigger once the clock's settled

			XScaleMMCSetup(MAR_REFCLK_FREQ);

			if(!SetPLL(0, ui32DesiredFreq, &pMSysData->ui32SysClk))
			{
				PVR_DPF((PVR_DBG_ERROR, "ChangeSYSCLK: PLL0 needed but did not lock"));
				if (pMSysData->ui32PixClk > MAR_REFCLK_FREQ)
				{
					/* PLL failed, but PLL1 is closer to what we want than REFCLK, so use that. */
					ui32PLLToUse=MAR_SYSCLK_SELECT_PLL1;
					pMSysData->ui32SysClk = pMSysData->ui32PixClk;
				}
			}
		}
	}

	/*************************************************** Select the new freq */

	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYSCLK_SELECT, ui32PLLToUse);
	HostWaitus(250); // FIXME

	XScaleMMCSetup(pMSysData->ui32SysClk);

	if(ui32PLLToUse != MAR_SYSCLK_SELECT_PLL0)
	{
		DisablePLL(0);	/* Disable system PLL */
	}	

	/************************************************ Work out core dividers */

	pMSysData->ui32MBXDivider = pMSysData->ui32M24VADivider = 1;

	if (pMSysData->ui32SysClk/pMSysData->ui32MBXDivider > MAR_MAXFREQ_MBX)
	{
		for (i=2; i<=4; i++)
			if (pMSysData->ui32SysClk/i <= MAR_MAXFREQ_MBX)
			{
				pMSysData->ui32MBXDivider = i;
				break;
			}

		PVR_DPF((PVR_DBG_WARNING,"ChangeSYSCLK: MBX frequency exceeds max - reducing by divisor of %d",pMSysData->ui32MBXDivider));
	}
				
	if (pMSysData->ui32SysClk/pMSysData->ui32M24VADivider > MAR_MAXFREQ_M24VA)
	{
		for (i=2; i<=4; i++)
			if (pMSysData->ui32SysClk/i <= MAR_MAXFREQ_M24VA) 
			{
				pMSysData->ui32M24VADivider = i;
				break;
			}

		PVR_DPF((PVR_DBG_WARNING,"ChangeSYSCLK: M24VA frequency exceeds max - reducing by divisor of %d",pMSysData->ui32M24VADivider));
	}

	/* Apply new divider settings */
	{
		/* to do this we need to gate out the cores that we are diddling with first, adn then restore them */


		IMG_UINT32 iu32;
		IMG_UINT32 iuCorePower;
		iu32 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_MBXCLK_CONFIG);
		iuCorePower = iu32 & 0x3;
		// turn it off
		WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MBXCLK_CONFIG,0);
		iu32 =  ((pMSysData->ui32MBXDivider-1) << 2);
		iu32 =  iu32| iuCorePower;
		WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MBXCLK_CONFIG, iu32);


		iu32 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG);
		iuCorePower = iu32 & 0x1;
		WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG, 0);
		iu32 = ((pMSysData->ui32M24VADivider-1) << 1);
		iu32 =  iu32| iuCorePower;
		WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG, iu32);
	
  
	}

	/************************************ Setup SDRAM timings amd wake SDRAM */
	
	CalcTimings();					/* Configure SDRAM timings */


#ifdef ADJUSTWRITECOMBINING
	//
	// If XScale Mem Clock Period >= (Marathon Sys Clock Period + 7.5 ns)/2,
	// then write combining is allowed.
	//
	if((1/(float)(pMSysData->ui32MemClk)) <
		(((1/(float)(pMSysData->ui32SysClk)) + .0000000075)/2.0))
//	if(pMSysData->ui32SysClk<pMSysData->ui32MemClk)
	{
		HostDisableWriteCombining();
	}
	else
	{
		HostEnableWriteCombining();
	}
#endif

	/* Wake SDRAM */
	if(pMSysData->bSDRAMNeedsWaking) 
	{
		SysSDRAMSetState(SYS_SDRAM_POWER_ACTIVE);
		PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
#ifdef SLEEP_MARATHON_OFF
		if (!pMSysData->bSleepSupport)
#endif
		{
			pMSysData->bSDRAMNeedsWaking = FALSE;
		}
	}

	/* Wake on-chip RAM */
	if (pMSysData->bODFBPowerModeActiveLow)
	{
		ui32Val = MAR_ODFB_POWERMODE_MODE_ACTIVE_LOW;
	}
	else
	{
		ui32Val = MAR_ODFB_POWERMODE_MODE_ACTIVE;
	}

	if(pMSysData->ui32SysClk < MAR_ODFB_FREQ_THRESHOLD)
		ui32Val |= MAR_ODFB_POWERMODE_SLOW_LOW;
	else
		ui32Val |= MAR_ODFB_POWERMODE_SLOW_HIGH;

	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_ODFB_POWERMODE, ui32Val);

	SysPostChangePll();

	PDUMPSCRIPT("---- ChangeSYSCLK fini");
}

/*****************************************************************************/

static IMG_UINT32 Remap(IMG_UINT32 *pui32Map, IMG_UINT32 ui32Val)
{
	IMG_UINT32 i;

	for (i = 0; i <= 15; i++)
	{
		if (pui32Map[i] >= ui32Val)
			{
				ui32Val = i;
				break;
			}
	}

	return(ui32Val);
}

/*****************************************************************************
 FUNCTION	: XScaleMMCSetup
    
 PURPOSE	: Setup memory controller to allow Marathon to be accessed

 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

#define MEMC_REG_MAP_SIZE			(4*1024)	// 4K
#define MEMC_REG_PHYSICAL_ADDR		(0x48000000)

#define CLK_REG_MAP_SIZE            (4*1024)
#define CLK_REG_PHYSICAL_ADDR       (0x41300000)
#define BULVERDE_REFCLK             13000000
#define COTULLA_REFCLK				 3686400     

#define XSCALE_CPUID_G_SHIFT 13
#define XSCALE_CPUID_R_SHIFT 10
#define XSCALE_CPUID_ID_SHIFT 4

#define XSCALE_CPUID_G_MASK   (0x7 << XSCALE_CPUID_G_SHIFT)
#define XSCALE_CPUID_R_MASK   (0x7 << XSCALE_CPUID_R_SHIFT)
#define XSCALE_CPUID_ID_MASK  (0x3F << XSCALE_CPUID_ID_SHIFT)
#define XSCALE_CPUID_REV_MASK (0xF)

#define XSCALE_COTULLA_G  (0x1 << XSCALE_CPUID_G_SHIFT)
#define XSCALE_BULVERDE_G (0x2 << XSCALE_CPUID_G_SHIFT)

IMG_BOOL XScaleMMCSetup(IMG_UINT32 ui32Freq)
{
	IMG_UINT32 ui32SYSPW, ui32RRR, ui32RDN, ui32RDF;
	IMG_UINT32 ui32SramRRR, ui32SramRDN;
	IMG_UINT32 ui32Val;
	volatile IMG_UINT32 *pui32Reg = 0;

	PSYS_SPECIFIC_DATA			pMSysData;

	GET_MARATHON_SYS_DATA(pMSysData);

#if REDUCE_FREQ_IN_DISP_REFRESH
	// Adjust 2700G Core Frequency when in Display Refresh:
	// To allow quick switching to run Marathon's SysClk @ PixClk speed
	// the XScale Mem Controller must assume Marthon is running slow all
	// the time, so the RRR, RDN, RDF values
	if (ui32Freq > pMSysData->ui32PixClk)
	{
		ui32Freq = pMSysData->ui32PixClk;
	}
#endif //REDUCE_FREQ_IN_DISP_REFRESH

	PVR_DPF((PVR_DBG_MESSAGE, "MARATHON: XScaleMMCSetup entered for freq %d.\n", ui32Freq));

	if (!pMSysData->pui32MemCtrl)
	{
#ifdef MARATHON_INTEGRATION_BSP
		IMG_UINT32	ui32L;
		IMG_UINT32	*pui32ClkCtrl;
		//CPUIdInfo sCPUID;
		IMG_UINT32 ui32Ret, ui32RetBytes;
		//IMG_UINT32 ui32CPUID;
		IMG_CPU_PHYADDR sPhysAddr;
		PROCESSOR_INFO procinfo;

		sPhysAddr.uiAddr = MEMC_REG_PHYSICAL_ADDR;
		pMSysData->pui32MemCtrl = (IMG_UINT32 *) HostMapPhysToLin(sPhysAddr, 
																  MEMC_REG_MAP_SIZE,
																  CACHETYPE_UNCACHED);

		//ui32Ret = KernelIoControl(IOCTL_GET_CPU_ID,
		//						(void *)&sCPUID, sizeof(sCPUID),
		//						(void *)&ui32CPUID, sizeof(ui32CPUID),
		//						&ui32RetBytes);
		ui32Ret = KernelIoControl( IOCTL_PROCESSOR_INFORMATION, 0, 0,
			&procinfo, sizeof( procinfo ), &ui32RetBytes );
			
		//if (ui32Ret && (ui32RetBytes == sizeof(ui32CPUID)))
		{
		//	pMSysData->bCotulla = ((ui32CPUID & XSCALE_CPUID_G_MASK) == XSCALE_COTULLA_G);
		}
		//else
		{
		//	PVR_DPF((PVR_DBG_ERROR, "XScaleMMCSetup: can't identify processor - assuming bulverde"));
		//	pMSysData->bCotulla = FALSE;
		}

		//PROCESSOR_NAME   (L"PXA27x")
		//PROCESSOR_CORE   (L"ARM920T")	
		// if( L"PXA27x" == procinfo.szProcessorName )
		{
			PVR_DPF((PVR_DBG_ERROR, "XScaleMMCSetup: can't identify processor - assuming bulverde"));
			pMSysData->bCotulla = FALSE;
		}
#else
		IMG_UINT32	ui32L;
		IMG_UINT32	*pui32ClkCtrl;
		CPUIdInfo sCPUID;
		IMG_UINT32 ui32CPUID, ui32Ret, ui32RetBytes;
		IMG_CPU_PHYADDR sPhysAddr;

		sPhysAddr.uiAddr = MEMC_REG_PHYSICAL_ADDR;
		pMSysData->pui32MemCtrl = (IMG_UINT32 *) HostMapPhysToLin(sPhysAddr, 
																  MEMC_REG_MAP_SIZE,
																  CACHETYPE_UNCACHED);

		ui32Ret = KernelIoControl(IOCTL_GET_CPU_ID,
								(void *)&sCPUID, sizeof(sCPUID),
								(void *)&ui32CPUID, sizeof(ui32CPUID),
								&ui32RetBytes);
		if (ui32Ret && (ui32RetBytes == sizeof(ui32CPUID)))
		{
			pMSysData->bCotulla = ((ui32CPUID & XSCALE_CPUID_G_MASK) == XSCALE_COTULLA_G);
		}
		else
		{
			PVR_DPF((PVR_DBG_ERROR, "XScaleMMCSetup: can't identify processor - assuming bulverde"));
			pMSysData->bCotulla = FALSE;
		}







#endif
		sPhysAddr.uiAddr = CLK_REG_PHYSICAL_ADDR;
		pui32ClkCtrl = (IMG_UINT32 *) HostMapPhysToLin(sPhysAddr, 
											           CLK_REG_MAP_SIZE,
											           CACHETYPE_UNCACHED);

		ui32L = *pui32ClkCtrl & 0x1F;
		if (pMSysData->bCotulla)
		{
			switch (ui32L)
			{
				case 1:
					pMSysData->ui32MemClk = COTULLA_REFCLK*27;
					break;
				case 3:
					pMSysData->ui32MemClk = COTULLA_REFCLK*36;
					break;
				case 5:
				default:
					pMSysData->ui32MemClk = COTULLA_REFCLK*45;
					break;
			}
		}
		else
		{   /* Bulverde processor */

			/* Read CCCR[A] (bit 25 or CCCR). This indicates whether alternate settings for MEMC clock
			should be used. */
			IMG_UINT32 ui32CCCR_A = *pui32ClkCtrl & (0x1 << 25); 

			if (ui32CCCR_A == 0)       /* Do not use alternate setting for MEMC clock. */
			{
				IMG_UINT32 ui32M = 1;

				if (ui32L < 2) ui32L=2; /* Bottoms out at 2 */

				if ((ui32L >= 11) && (ui32L <= 20))
					ui32M = 2;
				else if ((ui32L >= 21) && (ui32L <= 31))
					ui32M = 4;

				pMSysData->ui32MemClk = (BULVERDE_REFCLK*ui32L)/ui32M;
			}
			else  /* Use alternate setting for MEMC clock - it is set to System Bus Frequency. */
			{	
#ifdef MARATHON_INTEGRATION_BSP
				//FREQ_STATUS ui32CLKCFGReg;
				IMG_UINT32 ui32FastBusMode = 0;
				IMG_UINT32 ui32BR;
				//IMG_UINT32 ui32RetBytes, ui32Ret;

				/* Need to access CLKCFG register in order to establish Fast-Bus Mode. */
				//ui32Ret = KernelIoControl(IOCTL_GET_FREQUENCY,
				//						  NULL, 0,
				//						 (void *)&ui32CLKCFGReg, sizeof(FREQ_STATUS),
				//						 &ui32RetBytes);

				//if (ui32Ret == 0)
				{			
					/* KernelIOControl has failed - assume that system bus is not in fast-bus mode */
				//	ui32FastBusMode = 0;
				//	PVR_DPF((PVR_DBG_ERROR, "XScaleMMCSetup: KernelIoControl failed for IOCTL_GET_FREQUENCY.\n"));
				//	PVR_ASSERT(ui32Ret);
				}
				//else
				{
				//	ui32FastBusMode = ui32CLKCFGReg.fastbus_mode;
				}
				ui32FastBusMode = ( _MoveFromCoprocessor( 14, 0, 6, 0, 0 ) & 0x8 ) >> 3;

#else
				FREQ_STATUS ui32CLKCFGReg;
				IMG_UINT32 ui32FastBusMode = 0;
				IMG_UINT32 ui32BR;
				IMG_UINT32 ui32RetBytes, ui32Ret;

				/* Need to access CLKCFG register in order to establish Fast-Bus Mode. */
				ui32Ret = KernelIoControl(IOCTL_GET_FREQUENCY,
										  NULL, 0,
										 (void *)&ui32CLKCFGReg, sizeof(FREQ_STATUS),
										 &ui32RetBytes);

				if (ui32Ret == 0)
				{			
					/* KernelIOControl has failed - assume that system bus is not in fast-bus mode */
					ui32FastBusMode = 0;
					PVR_DPF((PVR_DBG_ERROR, "XScaleMMCSetup: KernelIoControl failed for IOCTL_GET_FREQUENCY.\n"));
					PVR_ASSERT(ui32Ret);
				}
				else
				{
					ui32FastBusMode = ui32CLKCFGReg.fastbus_mode;
				}

#endif
				/* See Bulverde Developer's Manual (Core Clock Configuration Registers).
				BR must be set to 1 when in fast-bus mode and 2 when not in fast-bus mode. */
				ui32BR = ui32FastBusMode ? 1 : 2;

				/* Set MemClk frequency to System Bus Frequency. */
				pMSysData->ui32MemClk = (BULVERDE_REFCLK * ui32L) / ui32BR;
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -