📄 marsys.c
字号:
/*******************************************************************************
* Name : marsys.c
* Title : Marathon system specific routines
* Author : PowerVR
* Created : 23rd May 2002
*
* Copyright : 2002 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : Device specific functions
*
* Platform : WinCE/Marathon
*
* Modifications:-
* $Log: marsys.c $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*******************************************************************************/
#pragma optimize( "", off )
#ifdef SUPPORT_MARATHON_DEVICE
/* enable inline functions to write to the fast regs */
#define USE_INLINE_FASTREGS
#include "services_headers.h"
#include "syscommon.h"
#define DEFINE_MEMORY_TABLES
#include "marmemory.h"
#include "marathon.h"
#include "pdpdefs.h"
#include "mbx1defs.h"
#undef UNREFERENCED_PARAMETER
#include <windows.h>
#ifndef MARATHON_INTEGRATION_BSP
#include <oemioctl.h>
#endif
#include <nkintr.h>
#ifndef MARATHON_INTEGRATION_BSP
#include <oalintr.h>
#endif
#include "regpaths.h"
// For debugging purpose only -
// Destroying LM contents to emulate sleep with Marathon turning off on re-wored Berrydale
// Note: LM size is adjustable (different from platform to platform)
#define DESTROY_LM 1
#define LM_SIZE 16*1024*1024
/*****************************************************************************/
static IMG_UINT32 CalculatePWMValues(IMG_UINT32 ui32Period, IMG_UINT32 ui32DutyCycle,
IMG_PUINT32 pui32PreScale,
IMG_PUINT32 pui32PeriodControl,
IMG_PUINT32 pui32DCControl);
static void ProgramLCDConfig();
static void GetChipSelectBaseAddress(IMG_UINT32 ui32ChipSelect, IMG_UINT32* pui32PhysBaseAddress);
IMG_BOOL SysSRAMOverflowDetected();
#define CONTROL_BACKLIGHT_WITHOUT_GPIOS 1
/*!
******************************************************************************
@Function SysCoreQuery
@Description
queries clock state of the specified core
@Input ui32Core - id of core to disable
@Return TRUE - on, FALSE off
******************************************************************************/
IMG_BOOL SysCoreQuery(IMG_UINT32 ui32Core)
{
PSYS_SPECIFIC_DATA pMSysData;
IMG_BOOL bRet = IMG_FALSE;
GET_MARATHON_SYS_DATA(pMSysData);
#ifdef MAR_NO_CLOCKCONTROL
return(TRUE); /* Of course it's on... */
#endif
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
switch (ui32Core)
{
case DEV_CGCORE_MBX_2D:
bRet = pMSysData->b2DEnabled;
break;
case DEV_CGCORE_MBX_ASYNC_2D:
bRet = pMSysData->bAsync2DEnabled;
break;
case DEV_CGCORE_MBX_TA:
bRet = pMSysData->bTAEnabled;
break;
case DEV_CGCORE_MBX_3D:
bRet = pMSysData->b3DEnabled;
break;
case DEV_CGCORE_M24VA:
PDUMPSCRIPT("---- SysCoreQuery M24VA");
PDUMPSCRIPT("RDW :REG_MSOC:%08X", MAR_M24CLK_CONFIG);
bRet = (ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_M24CLK_CONFIG) == MAR_M24CLK_CONFIG_ON);
break;
case DEV_CGCORE_PDP_GRAPHICS:
PDUMPSCRIPT("---- SysCoreQuery PDP Graphics");
PDUMPSCRIPT("RDW :REG_MSOC:%08X", MAR_PIXCLK_CONFIG);
bRet = (ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_PIXCLK_CONFIG) == MAR_PIXCLK_CONFIG_ON);
break;
case DEV_CGCORE_PDP_OVERLAY:
PDUMPSCRIPT("---- SysCoreQuery PDP Overlay");
PDUMPSCRIPT("RDW :REG_MSOC:%08X", MAR_VIDCLK_CONFIG);
bRet = (ReadHWReg(pMSysData->pvLinRegBaseAddr, MAR_VIDCLK_CONFIG) == MAR_VIDCLK_CONFIG_ON);
break;
default:
PVR_DPF((PVR_DBG_ERROR,"SysCoreQuery - *UNKNOWN*"));
break;
}
PDUMPREGMBX;
return(bRet);
}
/*!
******************************************************************************
@Function SysGlobalDisableInterrupts
@Description disable all SOC interrupts
@Return none
******************************************************************************/
IMG_VOID SysGlobalDisableInterrupts()
{
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
PDUMPSCRIPT("---- SysGlobalDisableInterrupts start");
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x000F);
PDUMPSCRIPT("---- SysGlobalDisableInterrupts fini");
PDUMPREGMBX;
}
/*!
******************************************************************************
@Function SysGlobalEnableInterrupts
@Description enable all SOC interrupts
@Return none
******************************************************************************/
IMG_VOID SysGlobalEnableInterrupts()
{
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
PDUMPSCRIPT("---- SysGlobalEnableInterrupts start");
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x800F);
PDUMPSCRIPT("---- SysGlobalEnableInterrupts fini");
PDUMPREGMBX;
}
/*****************************************************************************
FUNCTION : SysSetPWM
PURPOSE : Called to set thePulseWidth Modulation stuff.
PARAMETERS : IMG_UINT32 ui32PWM Port to program
IMG_UINT32 ui32Period In nanoseconds
IMG_UINT32 ui32DutyCycle Percentage
RETURNS : OutputPeriod
*****************************************************************************/
IMG_UINT32 SysSetPWM(IMG_UINT32 ui32PWM, IMG_UINT32 ui32Period, IMG_UINT32 ui32DutyCycle)
{
IMG_UINT32 ui32Prescale, ui32Control;
IMG_UINT32 ui32Output;
IMG_UINT32 ui32Duty;
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
PDUMPSCRIPT("---- SysSetPWM start");
PDUMPREGTAG(PDUMPTAGS_REG_MSOC, 0);
ui32Output = CalculatePWMValues(ui32Period, ui32DutyCycle, &ui32Prescale, &ui32Control, &ui32Duty);
if(ui32Output)
{
ui32Prescale -= 1;
ui32Control -= 1;
if(ui32PWM == 0) // use PWM zero registers
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CR0, ui32Prescale);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_DCR0, ui32DutyCycle);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_PCR0, ui32Control);
#ifndef CONTROL_BACKLIGHT_WITHOUT_GPIOS
/* Configure GPIO0 as output */
{
IMG_UINT32 ui32GPIOReg;
ui32GPIOReg = ReadHWReg(pMSysData->pvLinRegBaseAddr, 0x06C);
ui32GPIOReg |= 0x01;
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x06C, ui32GPIOReg); /* GPIO0 is output */
}
if (ui32DutyCycle == 0) /* Turn off PWM */
{ /* Is there a more power-efficient solution? */
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x074, 0x01); /* GPIO0 is low */
}
else /* Turn on PWM */
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x070, 0x01);
}
#endif
}
else
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_CR1, ui32Prescale);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_DCR1, ui32Duty);
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_PWM_PCR1, ui32Control);
#ifndef CONTROL_BACKLIGHT_WITHOUT_GPIOS
/* Configure GPIO1 as output */
{
IMG_UINT32 ui32GPIOReg;
ui32GPIOReg = ReadHWReg(pMSysData->pvLinRegBaseAddr, 0x06C);
ui32GPIOReg |= 0x02;
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x06C, ui32GPIOReg); /* GPIO1 is output */
}
if (ui32DutyCycle == 0) /* Turn off PWM */
{
/* Is there a more power-efficient solution? */
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x074, 0x02); /* GPIO1 is low */
}
else /* Turn on PWM */
{
WriteHWReg(pMSysData->pvLinRegBaseAddr, 0x070, 0x02);
}
#endif
}
}
else
{
PVR_DPF((PVR_DBG_ERROR,"Unable to set up the PWM registers!"));
}
PDUMPSCRIPT("---- SysSetPWM fini");
PDUMPREGMBX;
return(ui32Output);
}
/*****************************************************************************
FUNCTION : CalculatePWMValues
PURPOSE : Calculates the Pulse width modulation values.
PARAMETERS : IMG_UINT32 ui32Period, IMG_UINT32 ui32DutyCycle,
IMG_PUINT32 pui32PreScale,
IMG_PUINT32 pui32PeriodControl, IMG_PUINT32 pui32DCControl
RETURNS : OutputPeriod
*****************************************************************************/
static IMG_UINT32 CalculatePWMValues(IMG_UINT32 ui32Period, IMG_UINT32 ui32DutyCycle,
IMG_PUINT32 pui32PreScale,
IMG_PUINT32 pui32PeriodControl,
IMG_PUINT32 pui32DCControl)
{
IMG_UINT32 ui32Op;
IMG_UINT32 ui32PreScale, ui32PeriodControl;
#ifdef SLEEP_MARATHON_OFF
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
#endif
*pui32PreScale = 0;
*pui32PeriodControl = 0;
if(ui32Period > PWM_MAX_PERIOD)
{
return(0);
}
if(ui32Period < TREFCLK)
{
return(0);
}
ui32Op = ui32Period/TREFCLK;
ui32PreScale = (ui32Op + PWM_MAX_PCONTROL - 1) / PWM_MAX_PCONTROL; // Round Up!
ui32PeriodControl = ui32Op / ui32PreScale;
ui32Op = TREFCLK * ui32PreScale * ui32PeriodControl;
*pui32PreScale = ui32PreScale;
*pui32PeriodControl = ui32PeriodControl;
// now to handle the duty cycle
if(ui32DutyCycle)
{
*pui32DCControl = ((*pui32PeriodControl - 1) * ui32DutyCycle) / 100;
}
else
{
*pui32DCControl = 0;
}
#ifdef SLEEP_MARATHON_OFF
if(pMSysData->bSleepSupport && pMSysData->bSDRAMNeedsWaking)
{
*pui32PreScale = pMSysData->pSaveRegister->ui32PWMCR0;
*pui32DCControl = pMSysData->pSaveRegister->ui32PWMDCR0;
*pui32PeriodControl = pMSysData->pSaveRegister->ui32PWMPCR0;
pMSysData->bSDRAMNeedsWaking = FALSE;
}
#endif
return(ui32Op);
}
IMG_BOOL DisablePLL(IMG_UINT32 ui32PLL)
{
IMG_UINT32 ui32Reg;
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
switch(ui32PLL)
{
case 0: ui32Reg = MAR_PLL0_CTL; break;
case 1: ui32Reg = MAR_PLL1_CTL; break;
default:
PVR_DPF((PVR_DBG_ERROR,"DisablePLL: Illegal PLL specified"));
return(FALSE);
}
PDUMPSCRIPT("---- DisablePLL start");
WriteHWReg(pMSysData->pvLinRegBaseAddr, ui32Reg, 0);
PDUMPSCRIPT("---- DisablePLL fini");
return(TRUE);
}
/************************* State transition functions ************************/
/*****************************************************************************
FUNCTION : TransitionRunToRunSlow
PURPOSE : Change power mode from run to run slowly
PARAMETERS : N/A
RETURNS : N/A
NOTES : In Standby all cores are active running at lowest possible freq
*****************************************************************************/
static void TransitionRunToRunSlow()
{
PSYS_SPECIFIC_DATA pMSysData;
SYS_DATA *psSysData;
IMG_UINT32 ui32SysClk = MAR_REFCLK_FREQ;
SysAcquireData(&psSysData);
pMSysData = (PSYS_SPECIFIC_DATA) psSysData->pvSysSpecificData;
if(pMSysData->eMode != PowerRun)
{
PVR_DPF((PVR_DBG_ERROR, "TransitionRunToRunSlow: illegal entry mode"));
return;
}
PDUMPSCRIPT("---- TransitionRunToRunSlow start");
/* Disable all interrupts */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x000F);
if(SysCoreQuery(DEV_CGCORE_PDP_OVERLAY))
{
ui32SysClk = pMSysData->ui32PixClk*2;
}
else
{
/* adjust freq to suit 24/32 Bpp primary surface */
PVRSRV_DEV_INFO *psDevInfo = psSysData->psDevInfoList;
if ((psDevInfo) &&
((psDevInfo->sDeviceSpecific.sDisplay.sPrimarySurface.ePixelFormat == PVRSRV_PIXEL_FORMAT_RGB888) ||
(psDevInfo->sDeviceSpecific.sDisplay.sPrimarySurface.ePixelFormat == PVRSRV_PIXEL_FORMAT_ARGB8888)))
{
/* strange - x2 is not enough to prevent the desktop tearing near the
* physical botton of the screen with an angle 0x 0x5A */
ui32SysClk = (MAR_REFCLK_FREQ * 2) + (MAR_REFCLK_FREQ / 4);
}
}
ChangeSYSCLK(ui32SysClk);
/* Enable all interrupts */
WriteHWReg(pMSysData->pvLinRegBaseAddr, MAR_MINT_ENABLE, 0x800F);
PDUMPSCRIPT("---- TransitionRunToRunSlow fini");
pMSysData->eMode = PowerRunSlow;
}
/*****************************************************************************
FUNCTION : TransitionRunSlowToRun
PURPOSE : Does state change from D2 to D0
PARAMETERS :
RETURNS :
*****************************************************************************/
void TransitionRunSlowToRun()
{
PSYS_SPECIFIC_DATA pMSysData;
GET_MARATHON_SYS_DATA(pMSysData);
if(pMSysData->eMode != PowerRunSlow)
{
PVR_DPF((PVR_DBG_ERROR,"TransitionRunSlowToRun: illegal entry state"));
return;
}
PDUMPSCRIPT("---- TransitionStandbyToRun start");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -