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

📄 hw_pmu.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 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,                  54,  0},
    {PMU_MP3H,                  58,  0},
    {PMU_WMA,                 80,  0},
    {PMU_WAV,                 24,  0},
    {PMU_APE,                  Max_ARM_Freq,  0},
    {PMU_FLAC,                 64,  0},
    {PMU_RA,                    60,  0},
    {PMU_AAC,                  80,  0},
    {PMU_OGG,                  80,  0},
    {PMU_EQ,                    70,  0},
    {PMU_RECORDADPCM,  96,  0},
    {PMU_RECORDMP3,       48,  0},

    {PMU_VIDEOLOWLL, 10, 70},   //chang 031421
    {PMU_VIDEOLOWL, 20, 80},
    {PMU_VIDEOLOW,          120,  0}, // {PMU_VIDEOLOW,          120,  100},  // text
    {PMU_VIDEOMEDLOW,       120,  100},// {PMU_VIDEOMEDLOW,       120,  120},
    {PMU_VIDEOMED,          120,  140}, // {PMU_VIDEOMED,          120,  140},
    {PMU_VIDEOMEDHIGH,      132,  140},               // {PMU_VIDEOMEDHIGH,      132,  140},
    {PMU_VIDEOHIGH,         140,  176},  //{PMU_VIDEOHIGH,         140,  176},
    {PMU_VIDEOTVOUT,         Max_ARM_Freq,  0},

    {PMU_RVLOW,             100,  80},
    {PMU_RVMED,             120,  120},
    {PMU_RVHIGH,            200,  0},
    {PMU_BMP,               100,  0},
    {PMU_JPEG,              100,  150},
    {PMU_GIF,               100,  0},
    {PMU_TXT,                  24,  0},
    {PMU_FM,                    0,  0},
    {PMU_STOPWATCH,             40,  0},
#if ROCK_CAMERA
    {PMU_CAMLOW,             140,  120}, //camera
    {PMU_CAMHIGH,            200,  176},
#endif
    {PMU_GAME,                60,  0},
    {PMU_USB,                  96,  0},

#ifdef RGB_PANEL
    {PMU_BLON,                90,  0},  //根据屏大小再做调节
#else
    {PMU_BLON,                60,  0},
#endif

    {PMU_LCD_UPDATE,          20,  0}
};
/**************************************************************************
* 函数名称:  PMU_SDFreqSatisfy
* 函数描述:  为满足sd卡的clock不小于15mHz,需要保证pclk在30--50mHz或60mHz以上
* 入口参数:
* 出口参数:  无
* 返回值:    无
* 注释:      将arm主频分为一下几个区间:
             Freq<30:       系统基本在idle状态或无读卡动作,不需调整
             30<Freq<50:    强制Pdiv = 1,Hdiv = 1
             50<Freq<60:    Freq = 60
             60<Freq<100:   if(Pdiv==Hdiv==2)Pdiv=1
             100<Freq<120:  Freq = 120
             120<Freq<240:  频率设置函数会限制Pdiv==Hdiv==2,Pclk>30
***************************************************************************/
#define PMU_SDFREQ_MINLIMIT 20
#define PMU_APBFREQ_MINLIMIT (PMU_SDFREQ_MINLIMIT<<1)

void PMU_SDFreqSatisfy(UINT32* ArmFreq, UINT32* Hdiv, UINT32* Pdiv)
{
#if 0
    if ((*ArmFreq > PMU_APBFREQ_MINLIMIT) && (*ArmFreq < 60))
        *ArmFreq = 60;
    if ((*ArmFreq > (PMU_APBFREQ_MINLIMIT << 1)) && (*ArmFreq < 120))
        *ArmFreq = 120;
    if ((*ArmFreq > 30) && (*ArmFreq < PMU_APBFREQ_MINLIMIT))
    {
        *Hdiv = HCLK_DIV1;
        *Pdiv = PCLK_DIV1;
    }
    if ((*ArmFreq > 60) && (*ArmFreq < (PMU_APBFREQ_MINLIMIT << 1)))
    {
        if ((*Hdiv == HCLK_DIV2) && (*Pdiv == PCLK_DIV2))
            *Pdiv = PCLK_DIV1;
    }
#endif
}

ALIGN(8) 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;
        }
    }
    PMU_SDFreqSatisfy(&armfreq, &hclk_div, &pclk_div);
    if (module_list & ((INT64U)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);
    Screen_SetMcuIFWaitTime(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);
    Screen_SetMcuIFWaitTime(hclk);
#endif
    SDRAM_SetFreq(hclk);
    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_ClockEnable(DWDMA_CLOCK);
            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;

}

void Pmu_SetBit64(INT64U* module_list, UINT16 BitCnt)
{
    UINT32 * P2MList = (UINT32*)module_list;
    if (BitCnt > 32)
    {
        BitCnt -= 32;
        *P2MList |= BitCnt;
    }
    else
        *(++P2MList) |= BitCnt;

}
void Pmu_ClrBit64(INT64U* module_list, UINT16 BitCnt)
{
    UINT32 * P2MList = (UINT32*)module_list;
    if (BitCnt > 32)
    {
        BitCnt -= 32;
        *P2MList &= ~BitCnt;
    }
    else
        *(++P2MList) &= ~BitCnt;
}
/**************************************************************************
* 函数名称:  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)((INT64U)1 << i);
    //Pmu_SetBit64(&Module_list,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_ClrBit64(&Module_list,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 + -