📄 marathon.c
字号:
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 + -