1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2017-09-06 勤为本 first version 9 */ 10 11 12 #include "ls1c_regs.h" 13 #include "ls1c_public.h" 14 15 16 // 晶振的频率 17 #define AHB_CLK (24000000) 18 #define APB_CLK (AHB_CLK) 19 20 21 // START_FREQ寄存器bits 22 #define M_PLL_SHIFT (8) 23 #define M_PLL (0xff << M_PLL_SHIFT) // PLL倍频系数的整数部分 24 #define FRAC_N_SHIFT (16) 25 #define FRAC_N (0xff << FRAC_N_SHIFT) // PLL倍频系数的小数部分 26 #define DIV_SDRAM_SHIFT (0) 27 #define DIV_SDRAM (0x3 << DIV_SDRAM_SHIFT) 28 29 // CLK_DIV_PARAM寄存器bits 30 #define DIV_PIX_EN (0x1 << 31) 31 #define DIV_PIX (0x7f << 24) 32 #define DIV_CAM_EN (0x1 << 23) 33 #define DIV_CAM (0x7f << 16) 34 #define DIV_CPU_EN (0x1 << 15) 35 #define DIV_CPU (0x7f << 8) 36 #define DIV_PIX_VALID (0x1 << 5) 37 #define DIV_PIX_SEL (0x1 << 4) 38 #define DIV_CAM_VALID (0x1 << 3) 39 #define DIV_CAM_SEL (0x1 << 2) 40 #define DIV_CPU_VALID (0x1 << 1) 41 #define DIV_CPU_SEL (0x1 << 0) 42 43 #define DIV_PIX_SHIFT (24) 44 #define DIV_CAM_SHIFT (16) 45 #define DIV_CPU_SHIFT (8) 46 47 48 /* 49 * 获取PLL频率 50 * @ret PLL频率 51 */ clk_get_pll_rate(void)52unsigned long clk_get_pll_rate(void) 53 { 54 unsigned int ctrl; 55 unsigned long pll_rate = 0; 56 57 ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ); 58 pll_rate = (((ctrl & M_PLL) >> M_PLL_SHIFT) + ((ctrl & FRAC_N) >> FRAC_N_SHIFT)) * APB_CLK / 4; 59 60 return pll_rate; 61 } 62 63 64 /* 65 * 获取CPU频率 66 * @ret CPU频率 67 */ clk_get_cpu_rate(void)68unsigned long clk_get_cpu_rate(void) 69 { 70 unsigned long pll_rate, cpu_rate; 71 unsigned int ctrl; 72 73 pll_rate = clk_get_pll_rate(); 74 ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM); 75 76 // 选择时钟来源 77 if (DIV_CPU_SEL & ctrl) // pll分频作为时钟信号 78 { 79 if (DIV_CPU_EN & ctrl) 80 { 81 cpu_rate = pll_rate / ((ctrl & DIV_CPU) >> DIV_CPU_SHIFT); 82 } 83 else 84 { 85 cpu_rate = pll_rate / 2; 86 } 87 } 88 else // bypass模式,晶振作为时钟输入 89 { 90 cpu_rate = APB_CLK; 91 } 92 93 return cpu_rate; 94 } 95 96 97 /* 98 * 获取DDR频率 99 * @ret DDR频率 100 */ clk_get_ddr_rate(void)101unsigned long clk_get_ddr_rate(void) 102 { 103 unsigned long cpu_rate = 0; 104 unsigned long ddr_rate = 0; 105 unsigned int ctrl; 106 107 cpu_rate = clk_get_cpu_rate(); 108 ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ); 109 ctrl = (ctrl & DIV_SDRAM) >> DIV_SDRAM_SHIFT; 110 111 switch (ctrl) 112 { 113 case 0: 114 ddr_rate = cpu_rate / 2; 115 break; 116 117 case 1: 118 ddr_rate = cpu_rate / 4; 119 break; 120 121 case 2: 122 case 3: 123 ddr_rate = cpu_rate / 3; 124 break; 125 } 126 127 return ddr_rate; 128 } 129 130 131 /* 132 * 获取APB频率 133 * @ret APB频率 134 */ clk_get_apb_rate(void)135unsigned long clk_get_apb_rate(void) 136 { 137 return clk_get_ddr_rate(); 138 } 139 140 141 /* 142 * 获取DC频率 143 * @ret DC频率 144 */ clk_get_dc_rate(void)145unsigned long clk_get_dc_rate(void) 146 { 147 unsigned long pll_rate, dc_rate; 148 unsigned int ctrl; 149 150 pll_rate = clk_get_pll_rate(); 151 ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM); 152 153 dc_rate = pll_rate / ((ctrl & DIV_PIX) >> DIV_PIX_SHIFT); 154 155 return dc_rate; 156 } 157 158 159 160