156 lines
3.3 KiB
C
156 lines
3.3 KiB
C
/*************************************************************************
|
||
*
|
||
* 时钟相关函数
|
||
*
|
||
*************************************************************************/
|
||
|
||
|
||
#include "ls1c_regs.h"
|
||
#include "ls1c_public.h"
|
||
|
||
|
||
// 晶振的频率
|
||
#define AHB_CLK (24000000)
|
||
#define APB_CLK (AHB_CLK)
|
||
|
||
|
||
// START_FREQ寄存器bits
|
||
#define M_PLL_SHIFT (8)
|
||
#define M_PLL (0xff << M_PLL_SHIFT) // PLL倍频系数的整数部分
|
||
#define FRAC_N_SHIFT (16)
|
||
#define FRAC_N (0xff << FRAC_N_SHIFT) // PLL倍频系数的小数部分
|
||
#define DIV_SDRAM_SHIFT (0)
|
||
#define DIV_SDRAM (0x3 << DIV_SDRAM_SHIFT)
|
||
|
||
// CLK_DIV_PARAM寄存器bits
|
||
#define DIV_PIX_EN (0x1 << 31)
|
||
#define DIV_PIX (0x7f << 24)
|
||
#define DIV_CAM_EN (0x1 << 23)
|
||
#define DIV_CAM (0x7f << 16)
|
||
#define DIV_CPU_EN (0x1 << 15)
|
||
#define DIV_CPU (0x7f << 8)
|
||
#define DIV_PIX_VALID (0x1 << 5)
|
||
#define DIV_PIX_SEL (0x1 << 4)
|
||
#define DIV_CAM_VALID (0x1 << 3)
|
||
#define DIV_CAM_SEL (0x1 << 2)
|
||
#define DIV_CPU_VALID (0x1 << 1)
|
||
#define DIV_CPU_SEL (0x1 << 0)
|
||
|
||
#define DIV_PIX_SHIFT (24)
|
||
#define DIV_CAM_SHIFT (16)
|
||
#define DIV_CPU_SHIFT (8)
|
||
|
||
|
||
/*
|
||
* 获取PLL频率
|
||
* @ret PLL频率
|
||
*/
|
||
unsigned long clk_get_pll_rate(void)
|
||
{
|
||
unsigned int ctrl;
|
||
unsigned long pll_rate = 0;
|
||
|
||
ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
|
||
pll_rate = (((ctrl & M_PLL) >> M_PLL_SHIFT) + ((ctrl & FRAC_N) >> FRAC_N_SHIFT)) * APB_CLK / 4;
|
||
|
||
return pll_rate;
|
||
}
|
||
|
||
|
||
/*
|
||
* 获取CPU频率
|
||
* @ret CPU频率
|
||
*/
|
||
unsigned long clk_get_cpu_rate(void)
|
||
{
|
||
unsigned long pll_rate, cpu_rate;
|
||
unsigned int ctrl;
|
||
|
||
pll_rate = clk_get_pll_rate();
|
||
ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
|
||
|
||
// 选择时钟来源
|
||
if (DIV_CPU_SEL & ctrl) // pll分频作为时钟信号
|
||
{
|
||
if (DIV_CPU_EN & ctrl)
|
||
{
|
||
cpu_rate = pll_rate / ((ctrl & DIV_CPU) >> DIV_CPU_SHIFT);
|
||
}
|
||
else
|
||
{
|
||
cpu_rate = pll_rate / 2;
|
||
}
|
||
}
|
||
else // bypass模式,晶振作为时钟输入
|
||
{
|
||
cpu_rate = APB_CLK;
|
||
}
|
||
|
||
return cpu_rate;
|
||
}
|
||
|
||
|
||
/*
|
||
* 获取DDR频率
|
||
* @ret DDR频率
|
||
*/
|
||
unsigned long clk_get_ddr_rate(void)
|
||
{
|
||
unsigned long cpu_rate = 0;
|
||
unsigned long ddr_rate = 0;
|
||
unsigned int ctrl;
|
||
|
||
cpu_rate = clk_get_cpu_rate();
|
||
ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
|
||
ctrl = (ctrl & DIV_SDRAM) >> DIV_SDRAM_SHIFT;
|
||
|
||
switch (ctrl)
|
||
{
|
||
case 0:
|
||
ddr_rate = cpu_rate / 2;
|
||
break;
|
||
|
||
case 1:
|
||
ddr_rate = cpu_rate / 4;
|
||
break;
|
||
|
||
case 2:
|
||
case 3:
|
||
ddr_rate = cpu_rate / 3;
|
||
break;
|
||
}
|
||
|
||
return ddr_rate;
|
||
}
|
||
|
||
|
||
/*
|
||
* 获取APB频率
|
||
* @ret APB频率
|
||
*/
|
||
unsigned long clk_get_apb_rate(void)
|
||
{
|
||
return clk_get_ddr_rate();
|
||
}
|
||
|
||
|
||
/*
|
||
* 获取DC频率
|
||
* @ret DC频率
|
||
*/
|
||
unsigned long clk_get_dc_rate(void)
|
||
{
|
||
unsigned long pll_rate, dc_rate;
|
||
unsigned int ctrl;
|
||
|
||
pll_rate = clk_get_pll_rate();
|
||
ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
|
||
|
||
dc_rate = pll_rate / ((ctrl & DIV_PIX) >> DIV_PIX_SHIFT);
|
||
|
||
return dc_rate;
|
||
}
|
||
|
||
|
||
|