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

📄 marathon.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		HostUnMapPhysToLin(pui32ClkCtrl, CLK_REG_MAP_SIZE / HOST_PAGESIZE());
	}

	PVR_DPF((PVR_DBG_MESSAGE, "MARATHON:   XScale MemClk believed to be %dHz.\n", pMSysData->ui32MemClk));
	/* Calculate tSYSPW (see figure 56 of IAS) in terms of XScale memclk */
    /*  2*marathon_sysclk/xcale_memclk, rounding up */
//	ui32SYSPW = (2*pMSysData->ui32MemClk+ui32Freq-1)/pMSysData->ui32SysClk;
	ui32SYSPW = (2*pMSysData->ui32MemClk+ui32Freq-1)/ui32Freq;

	if (pMSysData->bCotulla)
	{
		IMG_UINT32 ui32RDFMap[16] =
			{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 18, 23};

		/* VLIO: tSYSPW = RRR*2 + 1 */
		ui32RRR = ui32SYSPW/2;
		/* VLIO: tSYSPW = RDN + 2 */
		ui32RDN = ui32SYSPW - 2;
		/* VLIO: tSYSPW = RDF + 1 */
		ui32RDF = ui32SYSPW - 1;

		/* SRAM: tSYSPW = RRR*2 + 4 */
		ui32SramRRR = (ui32SYSPW - 2)/2;
		/* SRAM: tSYSPW = RDN + 1 */
		ui32SramRDN = ui32SYSPW - 1;

		if (ui32RDN < 2)
			ui32RDN = 2;
		if (ui32SramRDN <2)
			ui32SramRDN = 2;

		ui32RDF = Remap(ui32RDFMap, ui32RDF);
		if (ui32RDF < 3)
			ui32RDF = 3;
	}
	else
	{
#ifdef BULVERDE_B_STEPPING
		IMG_UINT32 ui32RDNMap[16] = 
			{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 20, 26, 30};
		IMG_UINT32 ui32RDFMap[16] = 
			{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 18, 23};
#else
		IMG_UINT32 ui32RDFMap[16] = 
			{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 20, 26, 30};
#endif

		/* VLIO: tSYSPW = RRR*2 + 1 */
		ui32RRR = ui32SYSPW/2;
		/* VLIO: tSYSPW = RDN*2 */
		ui32RDN = (ui32SYSPW + 1)/2;
		/* VLIO: tSYSPW = RDF + 1 */
		ui32RDF = ui32SYSPW - 1;

		/* SRAM: tSYSPW = RRR*2 + 4 */
		if(ui32SYSPW >= 3)
		{
 			ui32SramRRR = (ui32SYSPW - 3)/2;
		}
		else
		{
			ui32SramRRR = 0;
		}

		/* SRAM: tSYSPW = RDN + 1 */
		ui32SramRDN = ui32SYSPW - 1;

#ifdef BULVERDE_B_STEPPING
		ui32RDN = Remap(ui32RDNMap, ui32RDN);
		ui32SramRDN = Remap(ui32RDNMap, ui32SramRDN);
#endif
		if (ui32RDN < 2)
			ui32RDN = 2;

		ui32RDF = Remap(ui32RDFMap, ui32RDF);
		if (ui32RDF < 3)
			ui32RDF = 3;
	}

	if (ui32RRR > 7)
	{
		PVR_DPF((PVR_DBG_WARNING,"XScaleMMCSetup: VLIO RRR out of spec (want %d, programming 7)", ui32RRR));
		ui32RRR = 7;
	}
	if (ui32SramRRR > 7)
	{
		PVR_DPF((PVR_DBG_WARNING,"XScaleMMCSetup: SRAM RRR out of spec (want %d, programming 7)", ui32SramRRR));
		ui32SramRRR = 7;
	}
	if (ui32RDN > 15)
	{
		PVR_DPF((PVR_DBG_WARNING, "XScaleMMCSetup: VLIO RDN out of spec"));
		ui32RDN = 15;
	}
	if (ui32SramRDN > 15)
	{
		PVR_DPF((PVR_DBG_WARNING,"XScaleMMCSetup: SRAM RDN out of spec"));
		ui32SramRDN = 15;
	}
	if (ui32RDF > 15)
	{
		PVR_DPF((PVR_DBG_WARNING,"XScaleMMCSetup: VLIO RDF out of spec"));
		ui32RDF = 15;
	}

	ui32Val = (ui32RRR << 12) |	(ui32RDN << 8) | (ui32RDF << 4) | 0x4;
	ConfigureChipSelect(pMSysData->ui32VLIOChipSelect, ui32Val, pMSysData);

	if(pMSysData->ui32SRAMChipSelect != -1)
	{
		ui32Val = (ui32SramRRR << 12) |	(ui32SramRDN << 8) | (0xf << 4) | 0x1;
		ConfigureChipSelect(pMSysData->ui32SRAMChipSelect, ui32Val, pMSysData);
	}

	PVR_DPF((PVR_DBG_MESSAGE,"MARATHON: XScaleMMCSetup exited.\n"));

	return(TRUE);
}

/*****************************************************************************
 FUNCTION	: ConfigureChipSelect
    
 PURPOSE	: Identify which MSCx register must be written to configure the 
              specified chip select. Copy the configuration bits (ui32MemoryConfig)
			  to either the upper or lower 16-bits of the MSCx register as 
			  appropriate.

 PARAMETERS	: IMG_UINT32 ui32ChipSelect
			  IMG_UINT32 ui32MemoryConfig
			  PSYS_SPECIFIC_DATA pMSysData 
 RETURNS	: 
*****************************************************************************/
static void ConfigureChipSelect(IMG_UINT32 ui32ChipSelect, IMG_UINT32 ui32MemoryConfig, PSYS_SPECIFIC_DATA pMSysData)
{
	volatile IMG_UINT32 *pui32Reg = 0;
	IMG_UINT32 ui32MSC;

	/* Make sure that the chip select is within the permitted range. */
	PVR_ASSERT((ui32ChipSelect >= 0));
	PVR_ASSERT((ui32ChipSelect <= 5));

	/* Find the MSCx register corresponding to the requested chip select. */
	pui32Reg = (pMSysData->pui32MemCtrl)+2+(ui32ChipSelect/2);

	/* Read contents of the MSCx register. */
	ui32MSC = *pui32Reg;

	if(ui32ChipSelect % 2)
	{
		/* If ChipSelect is an odd number, prepare to write to the upper 16 bits of the MSCx register. */
		ui32MSC = (ui32MSC & 0x0000ffff) | (ui32MemoryConfig << 16);
	}
	else
	{
		/* If ChipSelect is an even number, prepare to write to the lower 16 bits of the MSCx register. */
		ui32MSC = (ui32MSC & 0xffff0000) | ui32MemoryConfig;
	}

	/* Write back to the MSCx register. */
	*pui32Reg = ui32MSC;
}


#if REDUCE_FREQ_IN_DISP_REFRESH
/*****************************************************************************
 FUNCTION	: SysQuickChangeSYSCLK
    
 PURPOSE	: Change Marathon System Clock while entering
 			: and exiting Display Refresh

 PARAMETERS	: PSYS_SPECIFIC_DATA pMSysData
 			: BOOL bSlow
 ****************************************************************************/

void SysQuickChangeSYSCLK(PSYS_SPECIFIC_DATA pMSysData, BOOL bSlow)
{	//---------- Quick Core Clock Switch
	DWORD dwPLL;
	DWORD dwODFBModeVal = (pMSysData->bODFBPowerModeActiveLow) ?
		MAR_ODFB_POWERMODE_MODE_ACTIVE_LOW :
		MAR_ODFB_POWERMODE_MODE_ACTIVE;

	if (bSlow)
	{
		dwODFBModeVal |= MAR_ODFB_POWERMODE_SLOW_LOW; 
		dwPLL = MAR_SYSCLK_SELECT_PLL1;		// Use PLL1 (PixClk) as SysClk Source
	}
	else 
	{
		dwODFBModeVal |= (pMSysData->ui32SysClk < MAR_ODFB_FREQ_THRESHOLD) ?		
			MAR_ODFB_POWERMODE_SLOW_LOW :
			MAR_ODFB_POWERMODE_SLOW_HIGH;		
		
		dwPLL = MAR_SYSCLK_SELECT_PLL0;		// Use PLL0 (Full Speed) as SysClk Source
	}
	
	// Start Switch Over ---- This section should complete within ~200uS to avoid user-seen flash
	SysPreChangePll(TRUE); // Waits for VSync, so the next steps are not seen by user

	// SET ODFB (on-chip RAM) Mode (required prior to chaning SYSCLK PLL
	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_ODFB_POWERMODE, MAR_ODFB_POWERMODE_MODE_SLEEP);

	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYSCLK_SELECT, dwPLL);
	HostWaitus(3); // Need to wait after switching SysClk Source for more than 2.5us
	
	// Wake ODFB (on-chip RAM) 
	WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_ODFB_POWERMODE, dwODFBModeVal);

	SysPostChangePll(TRUE);		
	// End Switch Over ------------

}	//---------- End Quick Core Clock Switch
	

/*****************************************************************************
 FUNCTION	: SysSDRAMSetStateWithFreqChanges
    
 PURPOSE	: Set SDRAM power mode and change Marathon core frequency

 PARAMETERS	: ui32Mode - mode to set
			  
 RETURNS	: 
*****************************************************************************/

void SysSDRAMSetStateWithFreqChanges(IMG_UINT32 ui32Mode)
{
	IMG_UINT32					ui32Val;
	PSYS_SPECIFIC_DATA			pMSysData;
		
	GET_MARATHON_SYS_DATA(pMSysData);
	
	switch (ui32Mode) 
	{
		case SYS_SDRAM_POWER_SLEEP:
			WriteHWReg(pMSysData->pvLinRegBaseAddr,
					   MC_POWERDOWN_CONTROL,
					   MC_POWERDOWN_CONTROL_SELF_REFRESH);			
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SDCLK_CONFIG, MAR_SDCLK_CONFIG_OFF); /* wt: Hardware say invalid */

			SysQuickChangeSYSCLK(pMSysData, TRUE);

#ifdef LOCAL_MEMORY_SELF_REFRESH
#ifdef LOCAL_MEMORY_SELF_REFRESH_TESTING
			SysWriteLEDData(0x22);
#endif // LOCAL_MEMORY_SELF_REFRESH_TESTING
#endif // LOCAL_MEMORY_SELF_REFRESH			
			pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_SLEEP;
			break;

		case SYS_SDRAM_POWER_ACTIVE:
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SDCLK_CONFIG, MAR_SDCLK_CONFIG_ON);
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MC_POWERDOWN_CONTROL, MC_POWERDOWN_CONTROL_ACTIVE);
			SysQuickChangeSYSCLK(pMSysData, FALSE);

			pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_ACTIVE;

			/* Dummy read access to the SDRAM address space to trigger the statechange to ACTIVE */
			ui32Val	= *pMSysData->pui32SDRAMDummyArea;
#ifdef LOCAL_MEMORY_SELF_REFRESH
#ifdef LOCAL_MEMORY_SELF_REFRESH_TESTING
			SysWriteLEDData(0x11);
#endif // LOCAL_MEMORY_SELF_REFRESH_TESTING
#endif // LOCAL_MEMORY_SELF_REFRESH
			break;

		default:
			PVR_DPF((PVR_DBG_ERROR, "SysSDRAMSetStateWithFreqChanges - Invalid state - Only Active and Sleep are supported"));
			break;
	}	
}
#endif //REDUCE_FREQ_IN_DISP_REFRESH


/*****************************************************************************
 FUNCTION	: SysSDRAMSetState
    
 PURPOSE	: Set SDRAM power mode

 PARAMETERS	: ui32Mode - mode to set
			  
 RETURNS	: 
*****************************************************************************/

void SysSDRAMSetState(IMG_UINT32 ui32Mode)
{
	IMG_UINT32					ui32Val;
	PSYS_SPECIFIC_DATA			pMSysData;

	GET_MARATHON_SYS_DATA(pMSysData);

	PDUMPSCRIPT("---- SetSDRAMSetState");
	PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);

	switch (ui32Mode) 
	{
		case SYS_SDRAM_POWER_SLEEP:
			PVR_DPF((PVR_DBG_MESSAGE, "SysSDRAMSetState - SLEEP"));
			WriteHWReg(pMSysData->pvLinRegBaseAddr,
					   MC_POWERDOWN_CONTROL,
					   MC_POWERDOWN_CONTROL_SELF_REFRESH);
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SDCLK_CONFIG, MAR_SDCLK_CONFIG_OFF);

#ifdef LOCAL_MEMORY_SELF_REFRESH
#ifdef LOCAL_MEMORY_SELF_REFRESH_TESTING
			SysWriteLEDData(0x22);
#endif // LOCAL_MEMORY_SELF_REFRESH_TESTING
#endif // LOCAL_MEMORY_SELF_REFRESH
			pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_SLEEP;
			break;

		case SYS_SDRAM_POWER_SHUTDOWN:
			PVR_DPF((PVR_DBG_MESSAGE, "SysSDRAMSetState - SHUTDOWN"));
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MC_POWERDOWN_CONTROL, MC_POWERDOWN_CONTROL_SHUTDOWN);

			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SDCLK_CONFIG, MAR_SDCLK_CONFIG_OFF);
			pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_SHUTDOWN;
			break;

		case SYS_SDRAM_POWER_ACTIVE:
			PVR_DPF((PVR_DBG_MESSAGE, "SysSDRAMSetState - ACTIVE"));
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SDCLK_CONFIG, MAR_SDCLK_CONFIG_ON);
			WriteHWReg(pMSysData->pvLinRegBaseAddr, MC_POWERDOWN_CONTROL, MC_POWERDOWN_CONTROL_ACTIVE);

			pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_ACTIVE;

			//FIXME, do we need to snsure that the following line is not optimised out on a release build
			/* Dummy read access to the SDRAM address space to trigger the statechange to ACTIVE */
			ui32Val	= *pMSysData->pui32SDRAMDummyArea;
#ifdef LOCAL_MEMORY_SELF_REFRESH
#ifdef LOCAL_MEMORY_SELF_REFRESH_TESTING
			SysWriteLEDData(0x11);
#endif // LOCAL_MEMORY_SELF_REFRESH_TESTING
#endif // LOCAL_MEMORY_SELF_REFRESH
			break;

		default:
			PVR_DPF((PVR_DBG_ERROR, "SysSDRAMSetState - *UNKNOWN*"));
			break;
	}

	PDUMPREGMBX;
}

/*****************************************************************************
 FUNCTION	: SysPostChangePll
    
 PURPOSE	: Restore the PDP address generator and sync control regs to their
				State before the prechange pll call

 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/
IMG_VOID SysPostChangePll()
{
	PSYS_SPECIFIC_DATA pMSysData;

	GET_MARATHON_SYS_DATA(pMSysData);

/* Reenable the address generators */
	WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_STR1BASE + DISPLAY_REG_OFFSET,pMSysData->ui32Str1);
	WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_STR2BASE + DISPLAY_REG_OFFSET,pMSysData->ui32Str2);
	WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_CURBASE + DISPLAY_REG_OFFSET,pMSysData->ui32Str3);


}

/*****************************************************************************
 FUNCTION	: SysPreChangePll
    
 PURPOSE	: Store the PDP address generator and sync control regs to allow
				recovery after we have done pll setting stuff

 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/
IMG_VOID SysPreChangePll()
{
	IMG_UINT32 ui32FrontPorch , ui32ActiveLine;
	PSYS_SPECIFIC_DATA pMSysData;

	GET_MARATHON_SYS_DATA(pMSysData);



/*---------------------------------------------------------------------------------------------------------------------------------------------------------**
** 	Ok we are moving the DAC pre and post pll behaviour into here so as to minimize the amount of time that the address generator is turned off            **
** 	We want to wait until the end of the display i.e. wait for the current line to be >= front porch start this will give us maximum time to do the change **
** 	Obviously we only need to do this if any of the sync gens are active.                                                                                  **
**---------------------------------------------------------------------------------------------------------------------------------------------------------*/

	pMSysData->ui32Str1=ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_STR1BASE + DISPLAY_REG_OFFSET);
	pMSysData->ui32Str2=ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_STR2BASE + DISPLAY_REG_OFFSET);
	pMSysData->ui32Str3=ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_CURBASE + DISPLAY_REG_OFFSET);
	pMSysData->ui32Sync=ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_SYNCCTRL + DISPLAY_REG_OFFSET);
	ui32FrontPorch = 	ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_VT3 + DISPLAY_REG_OFFSET) >>16;

	if((pMSysData->ui32Sync & 0x80000000)&&(( pMSysData->ui32Str1 & 0x80000000)||(pMSysData->ui32Str2 & 0x80000000)||(pMSysData->ui32Str3 & 0x80000000)))
	{
		// first wait until we are less than the front porch start
		do
		{
			ui32ActiveLine = ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_LINECOUNT + DISPLAY_REG_OFFSET);
		}while(ui32ActiveLine>ui32FrontPorch);
		// Then wait for it becoming greater, this gives us the most time for a flicker free update
		do
		{
			ui32ActiveLine = ReadHWReg(pMSysData->pvLinRegBaseAddr,PDP_LINECOUNT + DISPLAY_REG_OFFSET);
		}while(ui32ActiveLine<ui32FrontPorch);

		/* turn off the address generators */
		WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_STR1BASE + DISPLAY_REG_OFFSET, pMSysData->ui32Str1&~0x80000000);
		WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_STR2BASE + DISPLAY_REG_OFFSET, pMSysData->ui32Str2&~0x80000000);
		WriteHWReg(pMSysData->pvLinRegBaseAddr, PDP_CURBASE + DISPLAY_REG_OFFSET, pMSysData->ui32Str3&~0x80000000);
	}



}



#endif /* SUPPORT_MARATHON */

⌨️ 快捷键说明

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