📄 marsys.c
字号:
/* Disable all interrupts */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x000F);
/********* Re-assert core freq and ensure pixel clock is setup correctly */
pMSysData->ui32SysClk = pMSysData->ui32CoreClock; //Not quite right
if(pMSysData->ui32PixClk)
{
SysPreChangePll();
SysSetPixClkFrequency(pMSysData->ui32PixClk);
ChangeSYSCLK(pMSysData->ui32SysClk);
SysPostChangePll();
}
else
{
ChangeSYSCLK(pMSysData->ui32SysClk);
}
/* Enable all interrupts */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x800F);
#ifdef SLEEP_MARATHON_OFF
/* Re-initialize Marathon needs to be done last */
if (pMSysData->bSleepSupport)
{
MarathonBoot();
}
#endif
pMSysData->eMode = PowerRun;
PDUMPSCRIPT("---- TransitionRunSlowToRun fini");
}
/*****************************************************************************
FUNCTION : TransitionRunSlowToSleep
PURPOSE : Change power mode from standby to sleep
PARAMETERS : N/A
RETURNS : N/A
NOTES : In Sleep all cores are inactive, running at ref freq, internal
and external memories are shutdown and will loss state.
Marathon is still powered and register state is maintained
*****************************************************************************/
static void TransitionRunSlowToSleep()
{
PSYS_SPECIFIC_DATA pMSysData;
#ifdef DESTROY_LM
IMG_CPU_PHYADDR sPhysAddr;
IMG_PVOID pvLinBaseAddr;
IMG_UINT32 ui32Size;
#endif
GET_MARATHON_SYS_DATA(pMSysData);
#ifdef DESTROY_LM
// Get virtual address of LM
ui32Size = LM_SIZE;
sPhysAddr.uiAddr = pMSysData->ui32PhysBase;
pvLinBaseAddr = HostMapPhysToLin(sPhysAddr, ui32Size, CACHETYPE_UNCACHED);
#endif
if (pMSysData->eMode != PowerRunSlow)
{
PVR_DPF((PVR_DBG_ERROR,"TransitionRunSlowToSleep: illegal entry mode"));
return;
}
PDUMPSCRIPT("---- TransitionStandbyToSleep start");
/* Return the SetPixclock to 0 , as PDP only does this in a Post D3 power state */
pMSysData->ui32PixClk = 0;
ChangeSYSCLK(MAR_REFCLK_FREQ);
PVR_ASSERT(pMSysData->ui32SysClk == MAR_REFCLK_FREQ);
PVR_ASSERT(pMSysData->ui32PixClk == 0);
/******************************* Shutdown internal and external memories */
/* Shutdown on die frame buffer */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_ODFB_POWERMODE, MAR_ODFB_POWERMODE_MODE_SHUTDOWN);
if(pMSysData->ui32SDRAMMode != SYS_SDRAM_POWER_SHUTDOWN)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MEMCLK_CONFIG, MAR_MEMCLK_CONFIG_ON);
SysSDRAMSetState(SYS_SDRAM_POWER_ACTIVE);
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
SysSDRAMSetState(SYS_SDRAM_POWER_SHUTDOWN);
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
/* turn on timeout counter to catch any reg accesses to mem */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYS_CONFIG, (ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYS_CONFIG) | 0x0000FF00));
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MEMCLK_CONFIG, MAR_MEMCLK_CONFIG_OFF);
pMSysData->bSDRAMNeedsWaking = TRUE; /* Need to wake memories when returning from sleep */
}
#ifdef SLEEP_MARATHON_OFF
if (pMSysData->bSleepSupport)
{
// Save all registers for system state
pMSysData->pSaveRegister->ui32ClkMBX = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_MBXCLK_CONFIG);
pMSysData->pSaveRegister->ui32ClkM24VA = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG);
pMSysData->pSaveRegister->ui32ClkPDP_GP = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PIXCLK_CONFIG);
pMSysData->pSaveRegister->ui32ClkPDP_OP = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_VIDCLK_CONFIG);
pMSysData->pSaveRegister->ui32LCDConfig = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_LCD_CONFIG);
pMSysData->pSaveRegister->ui32PWMConfig = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CFG);
pMSysData->pSaveRegister->ui32PWMCR0 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CR0);
pMSysData->pSaveRegister->ui32PWMDCR0 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_DCR0);
pMSysData->pSaveRegister->ui32PWMPCR0 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_PCR0);
pMSysData->pSaveRegister->ui32PWMCR1 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CR1);
pMSysData->pSaveRegister->ui32PWMDCR1 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_DCR1);
pMSysData->pSaveRegister->ui32PWMPCR1 = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_PCR1);
pMSysData->pSaveRegister->ui32BondConfig = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_BOND_CFG);
pMSysData->pSaveRegister->ui32VAINTMask = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_VAINT_MASK);
pMSysData->pSaveRegister->ui32GfxINTEnable = ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_GFXINT_ENABLE);
}
#endif
#ifdef DESTROY_LM
// Wipe out the contents of LM
HostMemSet(pvLinBaseAddr, 0x0, ui32Size);
#endif
PDUMPSCRIPT("---- TransitionRunSlowToSleep fini");
pMSysData->eMode = PowerSleep;
}
/*****************************************************************************
FUNCTION : TransitionSleepToRunSlow
PURPOSE : Change power mode from sleep to run slow
PARAMETERS : N/A
RETURNS : N/A
NOTES : In Sleep all cores are inactive, running at ref freq, internal
and external memories are shutdown and will loss state.
Marathon is still powered and register state is maintained
*****************************************************************************/
static void TransitionSleepToRunSlow()
{
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
if(pMSysData->eMode != PowerSleep)
{
PVR_DPF((PVR_DBG_ERROR,"TransitionSleepToRunSlow: illegal entry state"));
return;
}
/* start marathon so that its registers can be accessed */
XScaleMMCSetup(pMSysData->ui32SysClk);
PDUMPSCRIPT("---- TransitionSleepToRunSlow start");
/********************************************************* Gate-in cores */
#ifdef SLEEP_MARATHON_OFF
if (pMSysData->bSleepSupport)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MBXCLK_CONFIG, pMSysData->pSaveRegister->ui32ClkMBX); /* MBX */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG, pMSysData->pSaveRegister->ui32ClkM24VA); /* M24VA */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PIXCLK_CONFIG, pMSysData->pSaveRegister->ui32ClkPDP_GP);/* PDP */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_VIDCLK_CONFIG, pMSysData->pSaveRegister->ui32ClkPDP_OP);
}
#endif
/********************************** Take internal memory out of shutdown */
if (pMSysData->bODFBPowerModeActiveLow)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr,
MAR_ODFB_POWERMODE,
MAR_ODFB_POWERMODE_MODE_ACTIVE_LOW | MAR_ODFB_POWERMODE_SLOW_LOW);
}
else
{
WriteHWReg(pMSysData->pvLinRegBaseAddr,
MAR_ODFB_POWERMODE,
MAR_ODFB_POWERMODE_MODE_ACTIVE | MAR_ODFB_POWERMODE_SLOW_LOW);
}
/***************************************** switch into self refresh mode */
if(pMSysData->bSDRAMNeedsWaking)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MEMCLK_CONFIG, MAR_MEMCLK_CONFIG_ON);
SysSDRAMSetState(SYS_SDRAM_POWER_ACTIVE);
}
/* turnoff Timeout counter */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYS_CONFIG, (ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_SYS_CONFIG) & 0x00FF));
#ifdef SLEEP_MARATHON_OFF
/* Restore all registers being saved */
if (pMSysData->bSleepSupport)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_LCD_CONFIG, pMSysData->pSaveRegister->ui32LCDConfig);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CFG, pMSysData->pSaveRegister->ui32PWMConfig);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_BOND_CFG, pMSysData->pSaveRegister->ui32BondConfig);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_GFXINT_ENABLE, pMSysData->pSaveRegister->ui32GfxINTEnable);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_VAINT_MASK, pMSysData->pSaveRegister->ui32VAINTMask);
}
#endif
pMSysData->eMode = PowerRunSlow;
PDUMPSCRIPT("---- TransitionSleepToRunSlow fini");
}
/*****************************************************************************
FUNCTION : SysSetPowerState
PURPOSE : Change power mode
PARAMETERS : PVR_POWER_STATE eState
RETURNS : N/A
*****************************************************************************/
#ifdef SUPPORT_POWER_STATE
void SysSetPowerState(PVR_POWER_STATE eState)
{
SYS_DATA *psSysData;
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
SysAcquireData(&psSysData);
PDUMPSCRIPT("---- SysSetPowerState start");
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
switch (eState)
{
case PVRSRV_POWER_STATE_D0:/*PowerRun:*/
if (pMSysData->eMode == PowerSleep)
{
TransitionSleepToRunSlow();
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x800F); //Enable INTs
TransitionRunSlowToRun();
}
if(pMSysData->eMode == PowerRunSlow)
{
TransitionRunSlowToRun();
}
break;
case PVRSRV_POWER_STATE_D1:
case PVRSRV_POWER_STATE_D2:
if(pMSysData->eMode == PowerSleep)
{
TransitionSleepToRunSlow();
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x800F); //Enable INTs
}
if (pMSysData->eMode == PowerRun)
{
/* Is the overlay on, it is if bit 31 is set in the overlay base register */
DWORD dwValue = ReadHWReg(pMSysData->pvLinRegBaseAddr, PDP_STR2BASE + DISPLAY_REG_OFFSET);
if ((dwValue & (1 << 31)) == 0)
{
/* Overlay off */
TransitionRunToRunSlow();
}
}
break;
case PVRSRV_POWER_STATE_D3:/*PowerSleep:*/
if(pMSysData->eMode == PowerRun)
{
TransitionRunToRunSlow();
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x000F); //Disable INTs
TransitionRunSlowToSleep();
}
if(pMSysData->eMode == PowerRunSlow)
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x000F); //Disable INTs
TransitionRunSlowToSleep();
}
break;
default:
PVR_DPF((PVR_DBG_MESSAGE,"SysSetPowerState: unknown power state %d", eState));
break;
}
PDUMPSCRIPT("---- SysSetPowerState fini");
PDUMPREGMBX;
}
#endif
/*****************************************************************************
FUNCTION : SysBoot
PURPOSE : Reset and initialise Chip
PARAMETERS :
RETURNS : Error state
*****************************************************************************/
PVRSRV_ERROR SysBoot()
{
IMG_UINT32 ui32SDRAMMemoryTypeInx = 0;
IMG_UINT32 ui32HardwiredSRAMBondStatus = 0;
IMG_UINT32 ui32MarSocId = 0;
IMG_BOOL bBondConfigOverride = FALSE;
IMG_CPU_PHYADDR sPhysAddr;
HKEY hConfig = (HKEY)INVALID_HANDLE_VALUE;
ULONG ulValue;
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
PDUMPSCRIPT("---- SysBoot start");
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
/********************************************* Initialise System data */
HostMemSet(pMSysData, 0, sizeof(*pMSysData));
#ifdef SLEEP_MARATHON_OFF
HostAllocMem(PVRSRV_HOST_NON_PAGEABLE_HEAP,
(sizeof (REGISTERS_DATA)),
&pMSysData->pSaveRegister,
0);
HostMemSet(pMSysData->pSaveRegister, 0, sizeof(REGISTERS_DATA));
#endif
pMSysData->ui32CoreClock = SYSCLK_BOOT_VAL;
pMSysData->ui32VLIOChipSelect = 5;
pMSysData->bConfigPrefetch = FALSE;
pMSysData->bConfigTimeout = FALSE;
pMSysData->bConfigSRAM = TRUE;
pMSysData->ui32SRAMChipSelect = 1;
#ifdef MAR_NO_CLOCKCONTROL
pMSysData->b3DEnabled = TRUE; /** Fake it **/
pMSysData->b2DEnabled = TRUE; /** Fake it **/
#endif
#ifdef LOCAL_MEMORY_SELF_REFRESH
// Set up defaults to help us manage local memory power
pMSysData->bM24VAEnabled = IMG_FALSE; // Is video enabled?
pMSysData->bOverlayEnabled = IMG_FALSE; // Is Overlay enabled?
pMSysData->uiLocalMemoryUsers = 0; // How many people using LM
pMSysData->bUseLocalMemorySelfRefresh = TRUE; // Use this feature
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "UseSelfRefresh", &ulValue ))
{
pMSysData->bUseLocalMemorySelfRefresh = ulValue;
}
pMSysData->uiLocalMemoryTimeout = DEFAULT_LOCAL_MEMORY_TIMEOUT;
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "LocalMemoryTimeout", &ulValue ))
{
pMSysData->uiLocalMemoryTimeout = ulValue;
if(pMSysData->uiLocalMemoryTimeout < LOCAL_MEMORY_MINIMUM_DELAY)
{
pMSysData->uiLocalMemoryTimeout = LOCAL_MEMORY_MINIMUM_DELAY;
}
}
// Create event to signal that we're not using local memory.
// No place to destroy this that I've found - potential memory leak.
HostCreateEvent(&(pMSysData->hLocalMemoryIdleEvent));
#endif // LOCAL_MEMORY_SELF_REFRESH
pMSysData->ui32SysClk = MAR_REFCLK_FREQ; /* MUST always be reference clock value */
pMSysData->ui32PixClk = MAR_REFCLK_FREQ; /* MUST already be reference clock value */
pMSysData->ui32MBXDivider = 1;
pMSysData->ui32M24VADivider = 1;
pMSysData->ui32PixClkDivider = 1;
pMSysData->ui32SDRAMMode = SYS_SDRAM_POWER_SHUTDOWN;
pMSysData->eMode = PowerSleep;
pMSysData->bODFBPowerModeActiveLow = IMG_FALSE;
/* Setup memory type */
pMSysData->pMemConfig = gAllMemConfigs[0];
if(pMSysData->ui32CoreClock > pMSysData->pMemConfig->ui32MaxFreq)
{
/* Limit the clock to the fastest the SDRAM will go */
pMSysData->ui32CoreClock = pMSysData->pMemConfig->ui32MaxFreq;
}
/*********************** Read configuration overrides from the registry */
/* Get VLIO chip select. */
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "VLIOChipSelect", &ulValue ))
{
pMSysData->ui32VLIOChipSelect = ulValue;
}
/* Get Base Address to match VLIO chip select and copy it to ui32PhysBase. */
GetChipSelectBaseAddress(pMSysData->ui32VLIOChipSelect, &pMSysData->ui32PhysBase);
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "SRAMChipSelect", &ulValue ))
{
pMSysData->ui32SRAMChipSelect = ulValue;
}
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "Prefetch", &ulValue ))
{
pMSysData->bConfigPrefetch = ulValue ? TRUE : FALSE;
}
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "Timeout", &ulValue ))
{
pMSysData->bConfigTimeout = ulValue ? TRUE : FALSE;
}
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "SPAccessViaVLIO", &ulValue ))
{
pMSysData->bConfigSRAM = ulValue ? FALSE : TRUE;
}
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "BondConfig", &ulValue ))
{
bBondConfigOverride = TRUE;
pMSysData->ui32BondConfig = ulValue;
}
#ifdef SLEEP_MARATHON_OFF
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "SpecialSleep", &ulValue ))
{
pMSysData->bSleepSupport = ulValue ? IMG_TRUE : IMG_FALSE;
}
#endif
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "SDRAMMemType", &ulValue ))
{
ui32SDRAMMemoryTypeInx = ulValue;
pMSysData->pMemConfig = gAllMemConfigs[ui32SDRAMMemoryTypeInx];
if(pMSysData->ui32CoreClock > pMSysData->pMemConfig->ui32MaxFreq)
{
/* Limit the clock to the fastest the SDRAM will go */
pMSysData->ui32CoreClock = pMSysData->pMemConfig->ui32MaxFreq;
}
}
if(HostReadRegistryInt( 0, POWERVR_REG_ROOT, "CoreClock", &ulValue ))
{
/* Note that this can override the SDRAM limitations */
pMSysData->ui32CoreClock = ulValue;
PVR_DPF((PVR_DBG_WARNING,"REGISTRY: Core Clock frequency will be %dHz\n",pMSysData->ui32CoreClock));
}
/*************************************** Print out configuration options */
PVR_DPF((PVR_DBG_MESSAGE,"MARATHON PREFETCH %hs", pMSysData->bConfigPrefetch ? "ON" : "OFF"));
PVR_DPF((PVR_DBG_MESSAGE,"MARATHON TIMEOUT %hs", pMSysData->bConfigTimeout ? "ON" : "OFF"));
PVR_DPF((PVR_DBG_MESSAGE,"MARATHON SRAM %hs", pMSysData->bConfigSRAM ? "ON" : "OFF"));
PVR_DPF((PVR_DBG_MESSAGE,"MARATHON SDRAM INX %d", ui32SDRAMMemoryTypeInx));
/*************************************************************************/
XScaleMMCSetup(MAR_REFCLK_FREQ); /* Setup XScale memory controller */
/* Map in Marathon registers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -