1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Keystone2: pll initialization
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2012-2014
5*4882a593Smuzhiyun * Texas Instruments Incorporated, <www.ti.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <asm/arch/clock.h>
12*4882a593Smuzhiyun #include <asm/arch/clock_defs.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun /* DEV and ARM speed definitions as specified in DEVSPEED register */
15*4882a593Smuzhiyun int __weak speeds[DEVSPEED_NUMSPDS] = {
16*4882a593Smuzhiyun SPD1000,
17*4882a593Smuzhiyun SPD1200,
18*4882a593Smuzhiyun SPD1350,
19*4882a593Smuzhiyun SPD1400,
20*4882a593Smuzhiyun SPD1500,
21*4882a593Smuzhiyun SPD1400,
22*4882a593Smuzhiyun SPD1350,
23*4882a593Smuzhiyun SPD1200,
24*4882a593Smuzhiyun SPD1000,
25*4882a593Smuzhiyun SPD800,
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun const struct keystone_pll_regs keystone_pll_regs[] = {
29*4882a593Smuzhiyun [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
30*4882a593Smuzhiyun [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
31*4882a593Smuzhiyun [TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1},
32*4882a593Smuzhiyun [DDR3A_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
33*4882a593Smuzhiyun [DDR3B_PLL] = {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1},
34*4882a593Smuzhiyun [UART_PLL] = {KS2_UARTPLLCTL0, KS2_UARTPLLCTL1},
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun
pll_pa_clk_sel(void)37*4882a593Smuzhiyun inline void pll_pa_clk_sel(void)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun setbits_le32(keystone_pll_regs[PASS_PLL].reg1, CFG_PLLCTL1_PAPLL_MASK);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
wait_for_completion(const struct pll_init_data * data)42*4882a593Smuzhiyun static void wait_for_completion(const struct pll_init_data *data)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun int i;
45*4882a593Smuzhiyun for (i = 0; i < 100; i++) {
46*4882a593Smuzhiyun sdelay(450);
47*4882a593Smuzhiyun if (!(pllctl_reg_read(data->pll, stat) & PLLSTAT_GOSTAT_MASK))
48*4882a593Smuzhiyun break;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun
bypass_main_pll(const struct pll_init_data * data)52*4882a593Smuzhiyun static inline void bypass_main_pll(const struct pll_init_data *data)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC_MASK |
55*4882a593Smuzhiyun PLLCTL_PLLEN_MASK);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* 4 cycles of reference clock CLKIN*/
58*4882a593Smuzhiyun sdelay(340);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
configure_mult_div(const struct pll_init_data * data)61*4882a593Smuzhiyun static void configure_mult_div(const struct pll_init_data *data)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun u32 pllm, plld, bwadj;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun pllm = data->pll_m - 1;
66*4882a593Smuzhiyun plld = (data->pll_d - 1) & CFG_PLLCTL0_PLLD_MASK;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* Program Multiplier */
69*4882a593Smuzhiyun if (data->pll == MAIN_PLL)
70*4882a593Smuzhiyun pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
73*4882a593Smuzhiyun CFG_PLLCTL0_PLLM_MASK,
74*4882a593Smuzhiyun pllm << CFG_PLLCTL0_PLLM_SHIFT);
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* Program BWADJ */
77*4882a593Smuzhiyun bwadj = (data->pll_m - 1) >> 1; /* Divide pllm by 2 */
78*4882a593Smuzhiyun clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
79*4882a593Smuzhiyun CFG_PLLCTL0_BWADJ_MASK,
80*4882a593Smuzhiyun (bwadj << CFG_PLLCTL0_BWADJ_SHIFT) &
81*4882a593Smuzhiyun CFG_PLLCTL0_BWADJ_MASK);
82*4882a593Smuzhiyun bwadj = bwadj >> CFG_PLLCTL0_BWADJ_BITS;
83*4882a593Smuzhiyun clrsetbits_le32(keystone_pll_regs[data->pll].reg1,
84*4882a593Smuzhiyun CFG_PLLCTL1_BWADJ_MASK, bwadj);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* Program Divider */
87*4882a593Smuzhiyun clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
88*4882a593Smuzhiyun CFG_PLLCTL0_PLLD_MASK, plld);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
configure_main_pll(const struct pll_init_data * data)91*4882a593Smuzhiyun void configure_main_pll(const struct pll_init_data *data)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun u32 tmp, pllod, i, alnctl_val = 0;
94*4882a593Smuzhiyun u32 *offset;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun pllod = data->pll_od - 1;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* 100 micro sec for stabilization */
99*4882a593Smuzhiyun sdelay(210000);
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun tmp = pllctl_reg_read(data->pll, secctl);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /* Check for Bypass */
104*4882a593Smuzhiyun if (tmp & SECCTL_BYPASS_MASK) {
105*4882a593Smuzhiyun setbits_le32(keystone_pll_regs[data->pll].reg1,
106*4882a593Smuzhiyun CFG_PLLCTL1_ENSAT_MASK);
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun bypass_main_pll(data);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* Powerdown and powerup Main Pll */
111*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, secctl, SECCTL_BYPASS_MASK);
112*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
113*4882a593Smuzhiyun /* 5 micro sec */
114*4882a593Smuzhiyun sdelay(21000);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
117*4882a593Smuzhiyun } else {
118*4882a593Smuzhiyun bypass_main_pll(data);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun configure_mult_div(data);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* Program Output Divider */
124*4882a593Smuzhiyun pllctl_reg_rmw(data->pll, secctl, SECCTL_OP_DIV_MASK,
125*4882a593Smuzhiyun ((pllod << SECCTL_OP_DIV_SHIFT) & SECCTL_OP_DIV_MASK));
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /* Program PLLDIVn */
128*4882a593Smuzhiyun wait_for_completion(data);
129*4882a593Smuzhiyun for (i = 0; i < PLLDIV_MAX; i++) {
130*4882a593Smuzhiyun if (i < 3)
131*4882a593Smuzhiyun offset = pllctl_reg(data->pll, div1) + i;
132*4882a593Smuzhiyun else
133*4882a593Smuzhiyun offset = pllctl_reg(data->pll, div4) + (i - 3);
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun if (divn_val[i] != -1) {
136*4882a593Smuzhiyun __raw_writel(divn_val[i] | PLLDIV_ENABLE_MASK, offset);
137*4882a593Smuzhiyun alnctl_val |= BIT(i);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (alnctl_val) {
142*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, alnctl, alnctl_val);
143*4882a593Smuzhiyun /*
144*4882a593Smuzhiyun * Set GOSET bit in PLLCMD to initiate the GO operation
145*4882a593Smuzhiyun * to change the divide
146*4882a593Smuzhiyun */
147*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GOSTAT_MASK);
148*4882a593Smuzhiyun wait_for_completion(data);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* Reset PLL */
152*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
153*4882a593Smuzhiyun sdelay(21000); /* Wait for a minimum of 7 us*/
154*4882a593Smuzhiyun pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
155*4882a593Smuzhiyun sdelay(105000); /* Wait for PLL Lock time (min 50 us) */
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /* Enable PLL */
158*4882a593Smuzhiyun pllctl_reg_clrbits(data->pll, secctl, SECCTL_BYPASS_MASK);
159*4882a593Smuzhiyun pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN_MASK);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
configure_secondary_pll(const struct pll_init_data * data)162*4882a593Smuzhiyun void configure_secondary_pll(const struct pll_init_data *data)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun int pllod = data->pll_od - 1;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /* Enable Glitch free bypass for ARM PLL */
167*4882a593Smuzhiyun if (cpu_is_k2hk() && data->pll == TETRIS_PLL)
168*4882a593Smuzhiyun clrbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun /* Enable Bypass mode */
171*4882a593Smuzhiyun setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_ENSAT_MASK);
172*4882a593Smuzhiyun setbits_le32(keystone_pll_regs[data->pll].reg0,
173*4882a593Smuzhiyun CFG_PLLCTL0_BYPASS_MASK);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun configure_mult_div(data);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /* Program Output Divider */
178*4882a593Smuzhiyun clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
179*4882a593Smuzhiyun CFG_PLLCTL0_CLKOD_MASK,
180*4882a593Smuzhiyun (pllod << CFG_PLLCTL0_CLKOD_SHIFT) &
181*4882a593Smuzhiyun CFG_PLLCTL0_CLKOD_MASK);
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /* Reset PLL */
184*4882a593Smuzhiyun setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
185*4882a593Smuzhiyun /* Wait for 5 micro seconds */
186*4882a593Smuzhiyun sdelay(21000);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun /* Select the Output of PASS PLL as input to PASS */
189*4882a593Smuzhiyun if (data->pll == PASS_PLL && cpu_is_k2hk())
190*4882a593Smuzhiyun pll_pa_clk_sel();
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun clrbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
193*4882a593Smuzhiyun /* Wait for 500 * REFCLK cucles * (PLLD + 1) */
194*4882a593Smuzhiyun sdelay(105000);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Switch to PLL mode */
197*4882a593Smuzhiyun clrbits_le32(keystone_pll_regs[data->pll].reg0,
198*4882a593Smuzhiyun CFG_PLLCTL0_BYPASS_MASK);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /* Select the Output of ARM PLL as input to ARM */
201*4882a593Smuzhiyun if (cpu_is_k2hk() && data->pll == TETRIS_PLL)
202*4882a593Smuzhiyun setbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
init_pll(const struct pll_init_data * data)205*4882a593Smuzhiyun void init_pll(const struct pll_init_data *data)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun if (data->pll == MAIN_PLL)
208*4882a593Smuzhiyun configure_main_pll(data);
209*4882a593Smuzhiyun else
210*4882a593Smuzhiyun configure_secondary_pll(data);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun * This is required to provide a delay between multiple
214*4882a593Smuzhiyun * consequent PPL configurations
215*4882a593Smuzhiyun */
216*4882a593Smuzhiyun sdelay(210000);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
init_plls(void)219*4882a593Smuzhiyun void init_plls(void)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun struct pll_init_data *data;
222*4882a593Smuzhiyun int pll;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun for (pll = MAIN_PLL; pll < MAX_PLL_COUNT; pll++) {
225*4882a593Smuzhiyun data = get_pll_init_data(pll);
226*4882a593Smuzhiyun if (data)
227*4882a593Smuzhiyun init_pll(data);
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
get_max_speed(u32 val,u32 speed_supported,int * spds)231*4882a593Smuzhiyun static int get_max_speed(u32 val, u32 speed_supported, int *spds)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun int speed;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* Left most setbit gives the speed */
236*4882a593Smuzhiyun for (speed = DEVSPEED_NUMSPDS; speed >= 0; speed--) {
237*4882a593Smuzhiyun if ((val & BIT(speed)) & speed_supported)
238*4882a593Smuzhiyun return spds[speed];
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* If no bit is set, return minimum speed */
242*4882a593Smuzhiyun if (cpu_is_k2g())
243*4882a593Smuzhiyun return SPD200;
244*4882a593Smuzhiyun else
245*4882a593Smuzhiyun return SPD800;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
read_efuse_bootrom(void)248*4882a593Smuzhiyun static inline u32 read_efuse_bootrom(void)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun if (cpu_is_k2hk() && (cpu_revision() <= 1))
251*4882a593Smuzhiyun return __raw_readl(KS2_REV1_DEVSPEED);
252*4882a593Smuzhiyun else
253*4882a593Smuzhiyun return __raw_readl(KS2_EFUSE_BOOTROM);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
get_max_arm_speed(int * spds)256*4882a593Smuzhiyun int get_max_arm_speed(int *spds)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun u32 armspeed = read_efuse_bootrom();
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun armspeed = (armspeed & DEVSPEED_ARMSPEED_MASK) >>
261*4882a593Smuzhiyun DEVSPEED_ARMSPEED_SHIFT;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun return get_max_speed(armspeed, ARM_SUPPORTED_SPEEDS, spds);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
get_max_dev_speed(int * spds)266*4882a593Smuzhiyun int get_max_dev_speed(int *spds)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun u32 devspeed = read_efuse_bootrom();
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun devspeed = (devspeed & DEVSPEED_DEVSPEED_MASK) >>
271*4882a593Smuzhiyun DEVSPEED_DEVSPEED_SHIFT;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun return get_max_speed(devspeed, DEV_SUPPORTED_SPEEDS, spds);
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /**
277*4882a593Smuzhiyun * pll_freq_get - get pll frequency
278*4882a593Smuzhiyun * @pll: pll identifier
279*4882a593Smuzhiyun */
pll_freq_get(int pll)280*4882a593Smuzhiyun static unsigned long pll_freq_get(int pll)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun unsigned long mult = 1, prediv = 1, output_div = 2;
283*4882a593Smuzhiyun unsigned long ret;
284*4882a593Smuzhiyun u32 tmp, reg;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun if (pll == MAIN_PLL) {
287*4882a593Smuzhiyun ret = get_external_clk(sys_clk);
288*4882a593Smuzhiyun if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN_MASK) {
289*4882a593Smuzhiyun /* PLL mode */
290*4882a593Smuzhiyun tmp = __raw_readl(KS2_MAINPLLCTL0);
291*4882a593Smuzhiyun prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
292*4882a593Smuzhiyun mult = ((tmp & CFG_PLLCTL0_PLLM_HI_MASK) >>
293*4882a593Smuzhiyun CFG_PLLCTL0_PLLM_SHIFT |
294*4882a593Smuzhiyun (pllctl_reg_read(pll, mult) &
295*4882a593Smuzhiyun PLLM_MULT_LO_MASK)) + 1;
296*4882a593Smuzhiyun output_div = ((pllctl_reg_read(pll, secctl) &
297*4882a593Smuzhiyun SECCTL_OP_DIV_MASK) >>
298*4882a593Smuzhiyun SECCTL_OP_DIV_SHIFT) + 1;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun ret = ret / prediv / output_div * mult;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun } else {
303*4882a593Smuzhiyun switch (pll) {
304*4882a593Smuzhiyun case PASS_PLL:
305*4882a593Smuzhiyun ret = get_external_clk(pa_clk);
306*4882a593Smuzhiyun reg = KS2_PASSPLLCTL0;
307*4882a593Smuzhiyun break;
308*4882a593Smuzhiyun case TETRIS_PLL:
309*4882a593Smuzhiyun ret = get_external_clk(tetris_clk);
310*4882a593Smuzhiyun reg = KS2_ARMPLLCTL0;
311*4882a593Smuzhiyun break;
312*4882a593Smuzhiyun case DDR3A_PLL:
313*4882a593Smuzhiyun ret = get_external_clk(ddr3a_clk);
314*4882a593Smuzhiyun reg = KS2_DDR3APLLCTL0;
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun case DDR3B_PLL:
317*4882a593Smuzhiyun ret = get_external_clk(ddr3b_clk);
318*4882a593Smuzhiyun reg = KS2_DDR3BPLLCTL0;
319*4882a593Smuzhiyun break;
320*4882a593Smuzhiyun case UART_PLL:
321*4882a593Smuzhiyun ret = get_external_clk(uart_clk);
322*4882a593Smuzhiyun reg = KS2_UARTPLLCTL0;
323*4882a593Smuzhiyun break;
324*4882a593Smuzhiyun default:
325*4882a593Smuzhiyun return 0;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun tmp = __raw_readl(reg);
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (!(tmp & CFG_PLLCTL0_BYPASS_MASK)) {
331*4882a593Smuzhiyun /* Bypass disabled */
332*4882a593Smuzhiyun prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
333*4882a593Smuzhiyun mult = ((tmp & CFG_PLLCTL0_PLLM_MASK) >>
334*4882a593Smuzhiyun CFG_PLLCTL0_PLLM_SHIFT) + 1;
335*4882a593Smuzhiyun output_div = ((tmp & CFG_PLLCTL0_CLKOD_MASK) >>
336*4882a593Smuzhiyun CFG_PLLCTL0_CLKOD_SHIFT) + 1;
337*4882a593Smuzhiyun ret = ((ret / prediv) * mult) / output_div;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun return ret;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
ks_clk_get_rate(unsigned int clk)344*4882a593Smuzhiyun unsigned long ks_clk_get_rate(unsigned int clk)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun unsigned long freq = 0;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun switch (clk) {
349*4882a593Smuzhiyun case core_pll_clk:
350*4882a593Smuzhiyun freq = pll_freq_get(CORE_PLL);
351*4882a593Smuzhiyun break;
352*4882a593Smuzhiyun case pass_pll_clk:
353*4882a593Smuzhiyun freq = pll_freq_get(PASS_PLL);
354*4882a593Smuzhiyun break;
355*4882a593Smuzhiyun case tetris_pll_clk:
356*4882a593Smuzhiyun if (!cpu_is_k2e())
357*4882a593Smuzhiyun freq = pll_freq_get(TETRIS_PLL);
358*4882a593Smuzhiyun break;
359*4882a593Smuzhiyun case ddr3a_pll_clk:
360*4882a593Smuzhiyun freq = pll_freq_get(DDR3A_PLL);
361*4882a593Smuzhiyun break;
362*4882a593Smuzhiyun case ddr3b_pll_clk:
363*4882a593Smuzhiyun if (cpu_is_k2hk())
364*4882a593Smuzhiyun freq = pll_freq_get(DDR3B_PLL);
365*4882a593Smuzhiyun break;
366*4882a593Smuzhiyun case uart_pll_clk:
367*4882a593Smuzhiyun if (cpu_is_k2g())
368*4882a593Smuzhiyun freq = pll_freq_get(UART_PLL);
369*4882a593Smuzhiyun break;
370*4882a593Smuzhiyun case sys_clk0_1_clk:
371*4882a593Smuzhiyun case sys_clk0_clk:
372*4882a593Smuzhiyun freq = pll_freq_get(CORE_PLL) / pll0div_read(1);
373*4882a593Smuzhiyun break;
374*4882a593Smuzhiyun case sys_clk1_clk:
375*4882a593Smuzhiyun return pll_freq_get(CORE_PLL) / pll0div_read(2);
376*4882a593Smuzhiyun break;
377*4882a593Smuzhiyun case sys_clk2_clk:
378*4882a593Smuzhiyun freq = pll_freq_get(CORE_PLL) / pll0div_read(3);
379*4882a593Smuzhiyun break;
380*4882a593Smuzhiyun case sys_clk3_clk:
381*4882a593Smuzhiyun freq = pll_freq_get(CORE_PLL) / pll0div_read(4);
382*4882a593Smuzhiyun break;
383*4882a593Smuzhiyun case sys_clk0_2_clk:
384*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 2;
385*4882a593Smuzhiyun break;
386*4882a593Smuzhiyun case sys_clk0_3_clk:
387*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 3;
388*4882a593Smuzhiyun break;
389*4882a593Smuzhiyun case sys_clk0_4_clk:
390*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 4;
391*4882a593Smuzhiyun break;
392*4882a593Smuzhiyun case sys_clk0_6_clk:
393*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 6;
394*4882a593Smuzhiyun break;
395*4882a593Smuzhiyun case sys_clk0_8_clk:
396*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 8;
397*4882a593Smuzhiyun break;
398*4882a593Smuzhiyun case sys_clk0_12_clk:
399*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 12;
400*4882a593Smuzhiyun break;
401*4882a593Smuzhiyun case sys_clk0_24_clk:
402*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk0_clk) / 24;
403*4882a593Smuzhiyun break;
404*4882a593Smuzhiyun case sys_clk1_3_clk:
405*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk1_clk) / 3;
406*4882a593Smuzhiyun break;
407*4882a593Smuzhiyun case sys_clk1_4_clk:
408*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk1_clk) / 4;
409*4882a593Smuzhiyun break;
410*4882a593Smuzhiyun case sys_clk1_6_clk:
411*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk1_clk) / 6;
412*4882a593Smuzhiyun break;
413*4882a593Smuzhiyun case sys_clk1_12_clk:
414*4882a593Smuzhiyun freq = ks_clk_get_rate(sys_clk1_clk) / 12;
415*4882a593Smuzhiyun break;
416*4882a593Smuzhiyun default:
417*4882a593Smuzhiyun break;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun return freq;
421*4882a593Smuzhiyun }
422