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

📄 marsys.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************
* 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 + -