📄 hw_pmu.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 + -