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

📄 dvm.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
字号:
/* 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 "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "systypes.h"
#include "dm_errors.h"
#include "dm_edit.h"
#include "xsuart.h"
#include "dm_serialInOut.h"
#include "xllp_clkmgr.h"
#include "xllp_gpio.h"
#include "xllp_pm.h"
#include "xllp_intc.h"
#include "xllp_memctrl.h"
#include "boardControl.h"
#include "i2c.h"
#include "DVM.h"

P_XLLP_INTC_T   intReg	= (P_XLLP_INTC_T)0x40D00000;
P_XLLP_CLKMGR_T clkReg 	= (P_XLLP_CLKMGR_T)0x41300000;
P_XLLP_GPIO_T	gpioReg = (P_XLLP_GPIO_T ) 0x40E00000;
P_POST_I2C_T 	PI2C 	= (P_POST_I2C_T)PWR_I2C_BASE;
P_XLLP_PWRMGR_T pwrMgr	= (P_XLLP_PWRMGR_T)0x40F00000;
XLLP_MEMORY_CONTROL_REGISTER_T * memContrl = (XLLP_MEMORY_CONTROL_REGISTER_T * )0x48000000; 




/***********************************************************************************
//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 DVMInit(void)
{
   
	//Enable PWERI2C clock
	clkReg->cken |=XLLP_CLKEN_PWRI2C;    //XLLP_CLKEN_PWRI2C;
	
	pwrMgr->PCFR |= PCFR_PI2C;


}

/***********************************************************************************
//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 DVMPwrdwn(void)
{
   
	//disable PWERI2C clock
	clkReg->cken &=~XLLP_CLKEN_PWRI2C;    //XLLP_CLKEN_PWRI2C;
	
	pwrMgr->PCFR &= ~PCFR_PI2C;


}
 
/********************************************************************************
//Function Name: SetCoreVoltage
//Functionality: Report the value of core voltage
//Argument:      None
//Return:        the core voltage value
//Comment:
********************************************************************************/
UINT SetCoreVoltage(UINT16 dacValue)
{
    UINT errorLog=0;
	I2C_TX seq;
	XLLP_UINT8_T voltageChange[3];
	XLLP_UINT32_T returnVal=0;
  
	PI2C->ISAR = 0x0; // Set Slave address
	PI2C->ICR =  0x0;	 // Clear interrupts in ICR
 	PI2C->ICR = (POST_ICR_UIE | POST_ICR_SCLEA); // Enable I2C unit, and enable clock output

	voltageChange[0] = 0x0;
	voltageChange[1] = dacValue & 0xff;				  
	voltageChange[2] = (dacValue & 0xff00) >> 8;

	seq.dev_id = 0x40;
	seq.data_len = sizeof(voltageChange);
	seq.data = voltageChange;
  
    if((returnVal = i2c_write(PI2C, intReg, &seq))!= ERR_T_NONE)
    {	
        XllpUtilityOutputError(returnVal);
        LOGERRORX(errorLog, 
                ERR_L_DVM, ERR_TS_I2C_WRITE, DAC_VAL, ERR_T_NOTRANSMIT,  
                0, 0, 0);
        return(errorLog);
    }  	

	return 0;
}


UINT8 AsciiToDecTrans(char d)
{
	if((d > 47)&&(d < 58))
		return(d - 48);
return 0;
}

UINT16 GetInput(INT keyCount)
{                    
    CHAR key;
	INT32 newVolt=0;
	INT placeSpot;
    UartContextT * ctxP = GetPointerToSystemUart();
    volatile UartRegsT * uartP = (UartRegsT *)ctxP->regsP;

    ctxP->clearRxUartFnP(ctxP);
	if(keyCount== 3)
	 	placeSpot=100;
	else
	if(keyCount== 2)
	 	placeSpot=10;
	else
	if(keyCount== 1)
	 	placeSpot=1;

    while (keyCount--)
    {
        while (ctxP->readUartFnP(ctxP, (PCHAR)&key, 1) == 0);
            // Toggle RTS signal
        uartP->MCR ^= MCR_RTS;

            // Translate the key
        key &= 0xff; 
        printf("%c", key); 
        newVolt += (AsciiToDecTrans(key) * placeSpot);			
		placeSpot  = placeSpot/10;
    }

    return newVolt;

}


/********************************************************************************
//Function Name: DVMSetVolt
//Functionality: Report the value of core voltage
//Argument:      None
//Return:        the core voltage value
//Comment:
********************************************************************************/
void KDVMSetVolt(PVOID arg, PCHAR param)
{
    CHAR string[80];
    PCHAR tokenP;
	INT32 newVoltage=0;
	INT i, placeSpot=100;
    if (param)
    {
        // Copy the arguments so not to alter the original string.
        strcpy(string, param);

        // Get first token.
        tokenP = strtok(string, " ,\n");

        for(i=0;i<3;i++)
		{
            newVoltage += (AsciiToDecTrans(tokenP[i]) * placeSpot);			
		    placeSpot  = placeSpot/10;
		}
    }
    else
    { 
        printf (" User! Enter a new voltage >>");
        newVoltage = GetInput(3);
	}

  DVMSetVolt(newVoltage);
}


void DVMSetVolt(UINT16 newVoltage)
{
  DVMInit();
  SetCoreVoltage(newVoltage);
  DVMPwrdwn();

}

void KDVMSetVoltFreq(PVOID arg, PCHAR param)
{
    CHAR string[80];
    PCHAR tokenP;
	INT32 newVoltage=0;
	INT i, placeSpot=100;
    UINT32 newFreq=0;
    UINT16 lMultipler=0;

    if (param)
    {
        // Copy the arguments so not to alter the original string.
        strcpy(string, param);

        // Get first token.
        tokenP = strtok(string, " ,\n");

        for(i=0;i<3;i++)
		{
            newVoltage += (AsciiToDecTrans(tokenP[i]) * placeSpot);			
		    placeSpot  = placeSpot/10;
		}
		placeSpot=100;
        tokenP = strtok(NULL, " ,\n");

        for(i=0;i<3;i++)
		{
            newFreq += (AsciiToDecTrans(tokenP[i]) * placeSpot);			
		    placeSpot  = placeSpot/10;
		}
        
       
    }
    else
    { 
        printf (" User! Enter a new voltage >>");
        newVoltage = GetInput(3);
        printf ("\r\n User! Enter a new freqency  >>");
        newFreq = GetInput(3);
	}
  
    lMultipler = newFreq/13;
    ComboChange(lMultipler,0x2, newVoltage, 0);
}


void ComboChange(INT LMult, INT TMult, UINT16 DACValue, UINT fBus)
{
	UINT8 dataArray[3];
    UINT ReadPointer = 0;
	dataArray[0] = 0;  //Command 0
	dataArray[1] = (DACValue & 0x000000FF);
	dataArray[2] = (DACValue & 0x0000FF00)>>8;

	//set up the new frequency mulitipliers, N and L
	clkReg->cken |=XLLP_CLKEN_PWRI2C;    //XLLP_CLKEN_PWRI2C;
	clkReg->cccr = (((TMult & 0x7)<<7) | (LMult & 0x1f));

    //votlage change configureation
	pwrMgr->PVCR = 0;
//	pwrMgr->PCFR = 0;

	pwrMgr->PCFR &= ~PCFR_FVC;  
    pwrMgr->PVCR &= 0xFFFFF07F; //no delay is necessary
	pwrMgr->PVCR &= 0xFFFFFF80;    //clear slave address
	pwrMgr->PVCR |= 0x20;         //set slave address

	pwrMgr->PVCR &= 0xFE0FFFFF;   //clear read pointer 0
	pwrMgr->PVCR |= (ReadPointer<<20);
	//DCE and SQC are not necessary for single command 
 	ClearAllSQC();        //Sequence configuration is not necessary
	ClearAllDCE();       //Clear DCE bit

	ClearAllMBC( );     //Clear all MBC bit first
   
	 //indicate the last byte of this command is holded in this register
	pwrMgr->PCMDn[2] &= ~PCMDn_MBC;

	//programming the command data bit 
	pwrMgr->PCMDn[0] &= 0xFFFFFF00;
	pwrMgr->PCMDn[0] |= (dataArray[0] | PCMDn_MBC | PCMDn_LC);
	pwrMgr->PCMDn[1] &= 0xFFFFFF00;
	pwrMgr->PCMDn[1] |= ( dataArray[1] | PCMDn_MBC | PCMDn_LC);
	pwrMgr->PCMDn[2] &= 0xFFFFFF00;
	pwrMgr->PCMDn[2] |= ( dataArray[2] | PCMDn_LC);


	pwrMgr->PCFR |= (PCFR_PI2C|PCFR_FVC);    //PCFR_PI2C_EN;  //enable Pwr I2C 

	if(fBus == 1)
		InitiateFcs(1, 1);
	else
		InitiateFcs(1, 0);
		
	clkReg->cken &=~XLLP_CLKEN_PWRI2C;    //XLLP_CLKEN_PWRI2C;

	WriteHexLeds(clkReg->ccsr);
}

void ClearAllSQC(void)
{
	int i =0;
	for(i=0; i<32; i++)
	 	pwrMgr->PCMDn[i]  &= ~PCMDn_SQC;
}

void ClearAllMBC(void)
{
	int i =0;
	for(i=0; i<32; i++)
	   pwrMgr->PCMDn[i] &= ~PCMDn_MBC;
}

void ClearAllDCE(void)
{
	int i =0;
	for(i=0; i<32; i++)
	   pwrMgr->PCMDn[i]  &= ~PCMDn_DCE;
}

void KDVMTFreqChange(PVOID arg, PCHAR param)
{
    CHAR string[80];
    PCHAR tokenP;
    UINT16 newVoltage=0;
    UINT32 newFreq=0;
    UINT16 lMultipler=0;
    UINT16 tMultipler=0;
	UINT fastBus=0, memclkdivtwo=0;
	int i=0, placeSpot=100;;

    // Check for parameters.
    if (param)
    {
        // Copy the arguments so not to alter the original string.
        strcpy(string, param);

        // Get first token for new voltage.
        tokenP = strtok(string, " ,\n");

        for(i=0;i<3;i++)
		{
            newVoltage += (AsciiToDecTrans(tokenP[i]) * placeSpot);			
		    placeSpot  = placeSpot/10;
		}
		placeSpot=100;
        tokenP = strtok(NULL, " ,\n");

        // Get next token for new frequency.
        for(i=0;i<3;i++)
		{
            newFreq += (AsciiToDecTrans(tokenP[i]) * placeSpot);			
		    placeSpot  = placeSpot/10;
		}
        i=0;
        // Get next token for turbo multiplier.
        tokenP = strtok(NULL, " ,\n");


        tMultipler = (AsciiToDecTrans(tokenP[i]));			

        // Get next token for fast bus.
        tokenP = strtok(NULL, " ,\n");

        fastBus = (AsciiToDecTrans(tokenP[i]));			
       
        // Get next token for setting memclk / 2 or not.
        tokenP = strtok(NULL, " ,\n");

        memclkdivtwo = (AsciiToDecTrans(tokenP[i]));			

	}
	else
	{
	    printf (" User! Enter a new voltage >>");
	    newVoltage = GetInput(3);
	    printf ("\r\n User! Enter a new freqency >>");
	    newFreq = GetInput(3);

	    printf ("\r\n User! Enter a Turbo Multipler (ex. 2 - 6) >>");
	    tMultipler = GetInput(1);
	   
	    printf ("\r\n User! Set FastBus?\r\n");
		if(GetUserResponse(YESNO))
			fastBus = 1;

	    printf (" User! Set SDClk (CLK_MEM/2) freqency?\r\n");
		if(GetUserResponse(YESNO))
		   memclkdivtwo=1;	

				
	}
    
    lMultipler = newFreq/13;
   	ComboChange(lMultipler, tMultipler, newVoltage, fastBus);

    if(memclkdivtwo)
 	    memContrl->MDREFR |= 0x4000;	
	else
	    memContrl->MDREFR &= ~0x4000;	

}


⌨️ 快捷键说明

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