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

📄 hw_pmu.c

📁 RK27驱动
💻 C
字号:
/*********************************************************************************
*		   Copyright (C),2004-2005,  Fuzhou Rockchip Co.,Ltd.
*							  All Rights Reserved
*									 V1.00
* FileName : 	Hw_pmu.c
* Author	: 	lzy
* Description: 
* History	 :		  
*			<author>		<time>	   <version>	   <desc>
*			 lzy		   07/6/29 	  1.0			 ORG
*
*********************************************************************************/
#include "include.h"
#include "hw_include.h"
#include "hw_scu.h"
#include "hw_pll.h"
#define PMU

#define ARM_IDLE_FREQ    24
extern UINT16 gSysState;

const PMU_TABLE_t Pmu_Tabel_Entry[PMU_MODULE_MAX] =
{
    {PMU_DUMMY,                 0,  0},
    {PMU_IDLE,                 ARM_IDLE_FREQ,  0},
    {PMU_INIT,                 192,  0 },
    {PMU_MEDIALIBUPDATE,                 192,  0 },
    {PMU_MAINMENU,        12,  0},
    {PMU_BROWER,           40,  0},
    {PMU_MP3,                  60,  0},
    {PMU_WMA,                 80,  0},
    {PMU_WAV,                 24,  0},
    {PMU_APE,                  Max_ARM_Freq,  0},
    {PMU_FLAC,                 60,  0},
    {PMU_RA,                    60,  0},
    {PMU_AAC,                  80,  0},
    {PMU_OGG,                  48,  0},
    {PMU_EQ,                    70,  0},
    {PMU_RECORDADPCM,  96,  0},
    {PMU_RECORDMP3,       48,  0},
    
    {PMU_VIDEOLOW,         100,  80},
    {PMU_VIDEOMED,          120,  120},
    {PMU_VIDEOHIGH,         192,  180},
    
    {PMU_RVLOW,             100,  80},
    {PMU_RVMED,             120,  120},
    {PMU_RVHIGH,            200,  0},
    
    //{PMU_PICTURE,           100,  150},
    {PMU_BMP,               100,  0},
    {PMU_JPEG,              100,  150},
    {PMU_GIF,               100,  0},
    {PMU_TXT,                  24,  0},
    {PMU_FM,                    0,  0},
    {PMU_STOPWATCH,             40,  0},
    
    {PMU_GAME,                60,  0},    
    {PMU_USB,                  200,  0},
    {PMU_BLON,                60,  0},
    {PMU_LCD_UPDATE,          20,  0}
};

static INT64U Module_list = 0;

/**************************************************************************
* 函数名称:  PMU_ChangeFreq
* 函数描述:  设置各个模块使用的时钟
* 入口参数:  armfreq:
                            dspfreq:
                            hclk_div:
                            pclk_div:
* 出口参数:  无
* 返回值:       无
* 注释:             
***************************************************************************/
static UINT32 PMU_SetFreq(INT64U module_list)
{

    UINT32 armfreq=0, dspfreq=0;
    UINT32 hclk_div,pclk_div;
    UINT32 hclk, pclk,i,j;

    if(!module_list)
        module_list = PMU_IDLE;
    
    for (i = 0; i<64; i++)
        {
        if(module_list &((INT64U)((INT64U)1<<i)))
            {
            armfreq += Pmu_Tabel_Entry[i].ARM_FREQ;
            dspfreq += Pmu_Tabel_Entry[i].DSP_FREQ;
            }
        }
	
    if(module_list & (1<<PMU_BLON))
        {
        hclk_div  = HCLK_DIV1;
        pclk_div =  PCLK_DIV2;
        }
    else
        {
        hclk_div = HCLK_DIV2;
        pclk_div = PCLK_DIV2;
        }

    armfreq -= ARM_IDLE_FREQ;

#ifndef DRIVER_ONLY
    FlashTimingCfg(100);
    LcdCtrl_McuIFWaitTimeSet(100);
#endif

    if((armfreq>133)&&(armfreq<=160))//主频需求高一般总线不能过低,ahb在133mhz时会有一个波谷,故,人为调高一些
        armfreq=160;               //功耗会相应的高一些

    Pll_SetARMFreq(armfreq, hclk_div, pclk_div);
    
    hclk = Pll_get_ahb_freq();

#ifndef DRIVER_ONLY
    FlashTimingCfg( hclk);
    LcdCtrl_McuIFWaitTimeSet(hclk);
#endif

    pclk = Pll_get_apb_freq();

    PWM_UpdateAllApbFreq(pclk);
    ADC_SetFreq(pclk);
    Timer_SetFreq(pclk);
    WDT_SetFreq(pclk);
    

    if(dspfreq)
        {
        if( Pll_get_dsp_freq())
            {
#if 0
//如已有软件在DSP 中运行
            Scu_ClockDisable(DSP_CLOCK);
            Pll_SetDSPFreq(dspfreq);
            Scu_ClockEnable(DSP_CLOCK);
#endif
            }
        else
            {
// 原DSP 不运行
            Scu_ClockDisable(DSP_CLOCK);
            Scu_ModuleReset(DSP_C_RESET, TRUE);
            Scu_ModuleReset(DSP_P_RESET, TRUE);
            USDELAY(10);
            Pll_SetDSPFreq(dspfreq);
            USDELAY(10);
            Scu_ClockEnable(DSP_CLOCK);
            USDELAY(10);
            Scu_ModuleReset(DSP_P_RESET, FALSE);			
            }
        }
    else
        {
// 关闭DSP     
        Scu_ModuleReset(DSP_C_RESET, TRUE);
 //       Scu_ModuleReset(DSP_P_RESET, TRUE);
        USDELAY(10);
        Scu_ClockDisable(DSP_CLOCK);
        Pll_PowerDown(PLL_DSP);
        }

    return module_list;

}


/**************************************************************************
* 函数名称:  PMU_EnterModule
* 函数描述:  根据系统模块设置系统时钟
* 入口参数:  PMU_MODULE_t 模块名称
* 出口参数:  无
* 返回值:        无
* 注释:             
***************************************************************************/
UINT32 PMU_EnterModule(PMU_MODULE_t modulename)
{
#ifdef PMU

    unsigned int pmuid;
    unsigned int i = modulename;

    pmuid = Pmu_Tabel_Entry[modulename].PMU_ID;
    
    if(modulename != pmuid)
        {
         for (i =0; i<PMU_MODULE_MAX; i++)
            {
            pmuid = Pmu_Tabel_Entry[i].PMU_ID;
            if(pmuid == modulename)
                {
                break;
                }
            }
        }

    if(PMU_MODULE_MAX == i)
        return FALSE;

//if already enter this module, no switch PMU again then return
    if(Module_list & (INT64U)((INT64U)1<<i))
        return Module_list;
    
//to prevent enter function again, lock OS schedule
#ifndef DRIVER_ONLY 
    OSSchedLock();
#endif   

    Module_list |= (INT64U)(1<<i);

      PMU_SetFreq(Module_list);
#ifndef DRIVER_ONLY 
      OSSchedUnlock();
#endif   
return Module_list;


#endif
}

/**************************************************************************
* 函数名称:  PMU_ExitModule
* 函数描述:  根据系统模块设置系统时钟
* 入口参数:  
* 出口参数:  无
* 返回值:       无
* 注释:             
***************************************************************************/
UINT32 PMU_ExitModule(PMU_MODULE_t modulename)
{

#ifdef PMU
    unsigned int pmuid;
    unsigned int i = modulename;

    pmuid = Pmu_Tabel_Entry[modulename].PMU_ID;
    
    if(modulename != pmuid)
        {
         for (i=0; i<PMU_MODULE_MAX; i++)
            {
            pmuid = Pmu_Tabel_Entry[i].PMU_ID;
            if(pmuid == modulename)
                {
                break;
                }
            }
        }
    
    if(PMU_MODULE_MAX == i)
        return FALSE;
    
//if already exit this module, no switch PMU again then return
    if(Module_list & (INT64U)((INT64U)1<<i))
        {
//to prevent enter function again, lock OS schedule
#ifndef DRIVER_ONLY 
        OSSchedLock();
#endif   
        Module_list &=  ~(INT64U)((INT64U)1<<i);
        PMU_SetFreq(Module_list);
#ifndef DRIVER_ONLY 
        OSSchedUnlock();
#endif   
        }
        return Module_list;
    
#endif


}

/**************************************************************************
* 函数名称:  PMU_PoweOnInit
* 函数描述:  初始化PMU 模块,关闭不需要的模块时钟
* 入口参数:  
* 出口参数:  无
* 返回值:       无
* 注释:             由于关闭部分时钟,此函数必须先调用
***************************************************************************/
void PMU_PowerOnInit(void)
{
#ifdef PMU
    UINT32 config = 0;
    
    config = OTP_CLK_DIS
                |DSP_CLK_DIS
                |UHC_CLK_DIS
                |VIP_HCLK_DIS
                |VIP_CLK_DIS
                |SPI_CLK_DIS
                |HSADC_CLK_DIS
                |HSADC_HCLK_DIS
                |RTC_CLK_DIS
        #ifndef _DEBUG_
                |UART0_CLK_DIS
                |UART1_CLK_DIS
        #endif
                ;
    
//                |SDMMC_CLK_DIS    
   pSCUReg->SCU_CLKCFG = config;

    Module_list = 1<<PMU_IDLE;
    
    PMU_EnterModule(PMU_INIT);
    
    Pll_PowerDown(PLL_AUX);
#endif    
}

/**************************************************************************
* 函数名称:  PMU_GetState
* 函数描述:  获取当前PMU 的模块状况
* 入口参数:  
* 出口参数:  无
* 返回值:       Module_list 模块列表
* 注释:             
***************************************************************************/
INT64U PMU_GetState(void)
{
    return Module_list;
}

/**************************************************************************
* 函数名称:  PMU_SDEnable
* 函数描述:  开启SD/MMC 时钟
* 入口参数:  
* 出口参数:  无
* 返回值:       无
* 注释:             
***************************************************************************/
void PMU_SDEnable(void)
{
    Scu_ClockEnable(SDMMC_CLOCK);
}

/**************************************************************************
* 函数名称:  PMU_SDDisable
* 函数描述:  关闭SD/MMC 时钟
* 入口参数:  
* 出口参数:  无
* 返回值:       无
* 注释:             
***************************************************************************/
void PMU_SDDisable(void)
{
    Scu_ClockDisable(SDMMC_CLOCK);
}



⌨️ 快捷键说明

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