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

📄 dvm.c

📁 intel xscale pxa270的完整wince4.2 BSP包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* these are DVM APIs. They are being used to set voltage and frequency dynamically
    Get the current frequency state and voltage level, another very important thing
	is to implement DVM policy which takes information from system and decides when
	and how to change frequency and voltage to minimze the power consumption on the 
	fly, but still meet performance requirement. Current code refers Joe's PWR_I2C 
	code and Beth's frequency change code
*/

#include<windows.h>
#include<bvd1.h>
#include<bvd1bd.h>
#include<nkintr.h>
#include<oalintr.h>
#include"DVM.h"
#include "timerbvd.h"

extern XSC1ChangeVoltage(void);
extern XSC1ReadCLKCFG(void);
extern void XSC1EnterTurbo(void);
extern void XSC1ExitTurbo(void);
extern void XSC1FreqChange(unsigned long);
void SetCoreVoltage(DWORD dacValue);
FREQ_STATUS GetCurrentFrequencyStatus( );
void SetCoreFrequency(int LMult, int NMult, int run_mode_flag, int fastbus_mode_flag);

//volatile PWR_I2C_REG			*PWRI2CReg;
volatile XLLP_CLKMGR_T          *v_pClkReg;
volatile XLLP_GPIO_T	 *v_pGPIOReg = (volatile XLLP_GPIO_T *) GPIO_BASE_U_VIRTUAL;
volatile unsigned long  *PCFR =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x1C);
volatile unsigned long  *PVCR =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x40);
volatile unsigned long  *PCMD =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x80);
volatile unsigned long  *PCMD0 =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x80);
volatile unsigned long  *PCMD1 =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x84);
volatile unsigned long  *PCMD2 =  (volatile unsigned long *)(PWR_BASE_U_VIRTUAL + 0x88);
volatile I2C_REG *I2C = (I2C_REG *)(PWR_BASE_U_VIRTUAL + 0x180);

#define		OSCR0_TICKS_1MS			3250

/***********************************************************************************
//function Name: DVM_Init
//Functionality: Initialize PWR I2C and allocate memory for the I2C structure
//Argument:      None
//Return:        void
//Comment: This format is just for bare metal test, later for OS, it is not necessary
/***********************************************************************************/
void DVM_Init(void)
{
   
//	PWRI2CReg = (volatile PWR_I2C_REG *)(PWR_BASE_U_VIRTUAL + 0x180);
	v_pClkReg = (volatile XLLP_CLKMGR_T *)CLK_BASE_U_VIRTUAL;
	//volatile PCFR =  (volatile int *)(PWR_BASE_U_VIRTUAL + 0x1C);
    
	//Enable PWERI2C clock
	v_pClkReg->cken |=0x1 << 15;    //XLLP_CLKEN_PWRI2C;
	
    v_pClkReg->cken |=0x1 << 14;    //XLLP_CLKEN_I2C;

	*PCFR |= 0x60;
	//v_pDriverGlobals->uninit_misc.idletime = 2;
	 //SetCoreVoltage(280);
 //	SetCoreFrequency(8, 4, 1, 0);
	
#ifdef USING_DVM
	       SetCoreFrequency(16, 3, 1, 0);
         
	     
#endif

}

/************************************************************************************
//Function Name: GetCurrentFrequencyStatus
//Functionality: return the content from CCSR
//Argument:     
//Return: content of CCSR
//Comment: For later use in OS, it needs v_pClkReg as one argument
/************************************************************************************/

FREQ_STATUS GetCurrentFrequencyStatus( )
{
   FREQ_STATUS    temp;
   unsigned long  CLKCFGValue = 0;
   volatile XLLP_CLKMGR_T   *v_pClkReg = (volatile XLLP_CLKMGR_T *)CLK_BASE_U_VIRTUAL;
  //lpWriteDebugStringFunc(TEXT("GetCurrentFrequencyStatus...\r\n"));
//    temp.CPDIS = (v_pClkReg->ccsr & 0x80000000);
//	temp.PDDIS = (v_pClkReg->ccsr & 0x40000000);
	temp.LMulti = v_pClkReg->ccsr & 0x0000001F;
	temp.NMulti = (v_pClkReg->ccsr & 0x00000380)>>7;
    //NKDbgPrintfW(TEXT("before initiate new frequency ccsr 0x%x\r\n"), v_pClkReg->ccsr);
	CLKCFGValue = XSC1ReadCLKCFG();
	temp.fastbus_mode = (CLKCFGValue & 0x8)>>3;
	temp.turbo_mode = (CLKCFGValue & 0x1);
    //lpWriteDebugStringFunc(TEXT("core frequency  is %d MHZ\r\n"), (13 *temp.LMulti));
    //EdbgOutputDebugString ("Exit GetCurrentFrequencyStatus\r\n");
	return temp;
}


/************************************************************************************
//Function Name: SetCoreFrequency
//Functionality: Set core frequency
//Argument:     LMult - Multiplier of Run Mode
//              NMult - Multiplier of Turbo Mode
//              mode  - Run mode or turbo mode or fast-bus mode
//Return:       None
//Comment:For the time being, I am not sure whether mode change and frequency change
//        could happen simultaneously, we assum it. If it doesn't, we update it later
//        According to the SPECS, if you do the frequency change, system bus clock
//        will be stopped for a while, but in turbo mode, system bus clcok doesn't stop,
//        you don't need to concern about the LCD controller and memory controller 
//Core frequency change sequence

/************************************************************************************/
void SetCoreFrequency(int LMult, int NMult, int run_mode_flag, int fastbus_mode_flag)
{
	volatile XLLP_CLKMGR_T   *v_pClkReg = (volatile XLLP_CLKMGR_T *)CLK_BASE_U_VIRTUAL;
	int newCLKCFGValue = 0;
    unsigned long  CLKCFGValue = 0;
	int turbo_mode, i = 0;
//	 FREQ_STATUS    temp;
   
 
    lpWriteDebugStringFunc(TEXT("SetCoreFrequency...\r\n"));
     //EdbgOutputDebugString("Enter Core Voltage change run mode flag  %d\r\n", run_mode_flag);
//	 v_pGPIOReg->GPDR1 |= XLLP_GPIO_BIT_MMCLK;				// set the direction for MMCCLK
//     v_pGPIOReg->GAFR1_L &=~XLLP_GPIO_AF_BIT_MMCLK_MASK;

//     v_pGPIOReg->GPCR1 = XLLP_GPIO_BIT_MMCLK;
	 // msWait(100);
//	  v_pGPIOReg->GPSR1 = XLLP_GPIO_BIT_MMCLK;
	// msWait(100);
   //  EdbgOutputDebugString("GPIO32, after toggle to low 0x%x\r\n",v_pGPIOReg->GPLR1); 
//	 v_pGPIOReg->GPCR1 = XLLP_GPIO_BIT_SSPEXTCLK2;
	 //First read CLKCFG to figure out which mode it is in
    CLKCFGValue = XSC1ReadCLKCFG();
	lpWriteDebugStringFunc(TEXT("after read CLCKCFG \r\n"));
    turbo_mode = (CLKCFGValue & 0x1);
	//disable all interrupts
//	INTERRUPTS_OFF();

	//set up the new frequency mulitipliers, N and L

	v_pClkReg->cccr = (NMult<<7) | LMult;
     NKDbgPrintfW(TEXT("before initiate new frequency cccr 0x%x\r\n"), v_pClkReg->cccr);
	//set up the new CLKCFG value, for an new frequency 

	 newCLKCFGValue =(0x2 | (fastbus_mode_flag<<3) | run_mode_flag);
//	 EdbgOutputDebugString("newCLKCFGValue  %x\r\n", newCLKCFGValue);
	//Gracefully suspend LCD controller if in RUN mode or fast_bus mode
	//it is not necssary for Turbo mode because system bus is not disabled
	//for Turbo mode

     if (LMult > 15)
     {
          newCLKCFGValue = 0x2;     // B= 0 (Normal), F=1
     }

	//Program the CLKCFG (CP14, reigster 6) for frequency change
	//parameter is mask to use for CLKCFG register
     
//	 EdbgOutputDebugString("GPIO32, after toggle to high 0x%x\r\n",v_pGPIOReg->GPLR1); 
    lpWriteDebugStringFunc(TEXT("before initiate new frequency \r\n"));
	INTERRUPTS_OFF();
	XSC1FreqChange(newCLKCFGValue);
	INTERRUPTS_ON();
    NKDbgPrintfW(TEXT("after initiate new frequency ccsr 0x%x\r\n"), v_pClkReg->ccsr);
	lpWriteDebugStringFunc(TEXT("after initiate new frequency %d\r\n"));


}


int GetInt()
{
	char szDottedD[24];
	WORD cwNumChars = 0;
	UINT16 InChar = 0;

	while(!((InChar == 0x0d) || (InChar == 0x0a)))
	{
		InChar = OEMReadDebugByte();
		if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA) 
		{
			// If it's a number or a period, add it to the string
			if (InChar >= '0' && InChar <= '9') 
			{
				if (cwNumChars < 23) 
				{
					szDottedD[cwNumChars++] = (char)InChar;
					OEMWriteDebugByte((BYTE)InChar);
				}
			}
			// If it's a backspace, back up
			else if (InChar == 8) 
			{
				if (cwNumChars > 0) 
				{
					cwNumChars--;
					OEMWriteDebugByte((BYTE)InChar);
				}
			}
		}
	}

	// If it's a carriage return with an empty string, don't change anything.
	if (cwNumChars) 
	{
		return atoi(szDottedD);
	}
	return 0;
}
void GetCoreVoltage()
{
	DWORD CoreVoltage;
//	EdbgOutputDebugString ( "\r\nEnter desired DAC value for Core Voltage [0-1023]: ");

	{
	 CoreVoltage = GetInt();
	}
//	EdbgOutputDebugString ("\n");

	if (CoreVoltage > 1023)
	{
	  CoreVoltage = 1023;
	} 
	else if (CoreVoltage < 0)
	{
	  CoreVoltage = 0;
	}
	SetCoreVoltage(CoreVoltage);
	
}

/********************************************************************************
//Function Name: SetCoreVoltage
//Functionality: Report the value of core voltage
//Argument:      None
//Return:        the core voltage value
//Comment:
/********************************************************************************/
void SetCoreVoltage(DWORD dacValue)
{

   // lpWriteDebugStringFunc(TEXT("SetCoreVoltage...\r\n"));
	I2C->ISAR = 0x0; // Set Slave address
	I2C->ICR =  0x0;	 // Clear interrupts in ICR
	I2C->ICR = (I2C_IUE | I2C_SCLE); // Enable I2C unit, and enable clock output
	I2C->IDBR = 0x40; // Set D/A's slave address and enable write mode
	I2C->ICR = (I2C_IUE | I2C_SCLE | I2C_START | I2C_TB); // Send START and then TRANSMIT the byte.
	

	while((I2C->ISR & I2C_ITE) != I2C_ITE); // Wait for ITE to go high

	I2C->ISR = I2C_ITE; // Write the ITE bit to clear it.

	I2C->IDBR = 0x0; // Command 
	I2C->ICR = (I2C_IUE | I2C_SCLE | I2C_TB); // Clear START, STOP, set TB
	while((I2C->ISR & I2C_ITE) != I2C_ITE); // Wait for ITE to go high
	I2C->ISR = I2C_ITE; // Write the ITE bit to clear it.
    
	I2C->IDBR = dacValue & 0x000000FF; // LSB 
//	EdbgOutputDebugString("Enters here - LSB I2C->IDBR = %x\r\n",I2C->IDBR);
	I2C->ICR = (I2C_IUE | I2C_SCLE | I2C_TB); // Clear START, STOP, set TB
	while((I2C->ISR & I2C_ITE) != I2C_ITE); // Wait for ITE to go high
	I2C->ISR = I2C_ITE; // Write the ITE bit to clear it.
    I2C->IDBR = (dacValue & 0x0000FF00) >> 8; // MSB

//	EdbgOutputDebugString("Enters here - MSB I2C->IDBR = %x\r\n",I2C->IDBR);
	I2C->ICR = (I2C_IUE | I2C_SCLE | I2C_TB); // Clear START, STOP, set TB
	while((I2C->ISR & I2C_ITE) != I2C_ITE); // Wait for ITE to go high
	I2C->ISR = I2C_ITE; // Write the ITE bit to clear it.



	I2C->ICR = (I2C_IUE | I2C_SCLE | I2C_STOP | I2C_TB);
	while((I2C->ISR & I2C_ITE) != I2C_ITE); // Wait for ITE to go high
	I2C->ISR = I2C_ITE; // Write the ITE bit to clear it.
//	EdbgOutputDebugString("Enters here - I2C->ISR = %x\r\n",I2C->ISR);

}


void ClearAllSQC(void)
{
	int i =0;
	for(i=0; i<32; i++)
		*(PCMD + 4 * i)  &= ~PCMD_SQC;
}

void ClearAllMBC(void)

⌨️ 快捷键说明

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