blob: 1fcb6917783ce1b157feb83210263fa48239f428 [file] [log] [blame]
Gabor Juhosd4a67d92011-01-04 21:28:14 +01001/*
2 * Atheros AR71XX/AR724X/AR913X common routines
3 *
Gabor Juhos88896122012-03-14 10:45:22 +01004 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
Gabor Juhosd4a67d92011-01-04 21:28:14 +01005 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
6 *
Gabor Juhos88896122012-03-14 10:45:22 +01007 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8 *
Gabor Juhosd4a67d92011-01-04 21:28:14 +01009 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/err.h>
18#include <linux/clk.h>
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020019#include <linux/clkdev.h>
Alban Bedel411520a2015-04-19 14:30:04 +020020#include <linux/clk-provider.h>
Gabor Juhosd4a67d92011-01-04 21:28:14 +010021
Gabor Juhos97541cc2012-09-08 14:02:21 +020022#include <asm/div64.h>
23
Gabor Juhosd4a67d92011-01-04 21:28:14 +010024#include <asm/mach-ath79/ath79.h>
25#include <asm/mach-ath79/ar71xx_regs.h>
26#include "common.h"
27
28#define AR71XX_BASE_FREQ 40000000
29#define AR724X_BASE_FREQ 5000000
30#define AR913X_BASE_FREQ 5000000
31
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020032static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
33{
34 struct clk *clk;
35 int err;
36
Alban Bedel411520a2015-04-19 14:30:04 +020037 clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate);
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020038 if (!clk)
39 panic("failed to allocate %s clock structure", id);
40
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020041 err = clk_register_clkdev(clk, id, NULL);
42 if (err)
43 panic("unable to register %s clock device", id);
44}
Gabor Juhosd4a67d92011-01-04 21:28:14 +010045
46static void __init ar71xx_clocks_init(void)
47{
Gabor Juhos6612a682013-08-28 10:41:46 +020048 unsigned long ref_rate;
49 unsigned long cpu_rate;
50 unsigned long ddr_rate;
51 unsigned long ahb_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010052 u32 pll;
53 u32 freq;
54 u32 div;
55
Gabor Juhos6612a682013-08-28 10:41:46 +020056 ref_rate = AR71XX_BASE_FREQ;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010057
58 pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
59
Alban Bedel626a0692015-04-19 14:30:02 +020060 div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +020061 freq = div * ref_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010062
63 div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +020064 cpu_rate = freq / div;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010065
66 div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +020067 ddr_rate = freq / div;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010068
69 div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
Gabor Juhos6612a682013-08-28 10:41:46 +020070 ahb_rate = cpu_rate / div;
71
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020072 ath79_add_sys_clkdev("ref", ref_rate);
73 ath79_add_sys_clkdev("cpu", cpu_rate);
74 ath79_add_sys_clkdev("ddr", ddr_rate);
75 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhosd4a67d92011-01-04 21:28:14 +010076
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +020077 clk_add_alias("wdt", NULL, "ahb", NULL);
78 clk_add_alias("uart", NULL, "ahb", NULL);
Gabor Juhosd4a67d92011-01-04 21:28:14 +010079}
80
81static void __init ar724x_clocks_init(void)
82{
Gabor Juhos6612a682013-08-28 10:41:46 +020083 unsigned long ref_rate;
84 unsigned long cpu_rate;
85 unsigned long ddr_rate;
86 unsigned long ahb_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010087 u32 pll;
88 u32 freq;
89 u32 div;
90
Gabor Juhos6612a682013-08-28 10:41:46 +020091 ref_rate = AR724X_BASE_FREQ;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010092 pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
93
Alban Bedel626a0692015-04-19 14:30:02 +020094 div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
Gabor Juhos6612a682013-08-28 10:41:46 +020095 freq = div * ref_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +010096
97 div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
98 freq *= div;
99
Gabor Juhos6612a682013-08-28 10:41:46 +0200100 cpu_rate = freq;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100101
102 div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +0200103 ddr_rate = freq / div;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100104
105 div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
Gabor Juhos6612a682013-08-28 10:41:46 +0200106 ahb_rate = cpu_rate / div;
107
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200108 ath79_add_sys_clkdev("ref", ref_rate);
109 ath79_add_sys_clkdev("cpu", cpu_rate);
110 ath79_add_sys_clkdev("ddr", ddr_rate);
111 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100112
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200113 clk_add_alias("wdt", NULL, "ahb", NULL);
114 clk_add_alias("uart", NULL, "ahb", NULL);
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100115}
116
117static void __init ar913x_clocks_init(void)
118{
Gabor Juhos6612a682013-08-28 10:41:46 +0200119 unsigned long ref_rate;
120 unsigned long cpu_rate;
121 unsigned long ddr_rate;
122 unsigned long ahb_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100123 u32 pll;
124 u32 freq;
125 u32 div;
126
Gabor Juhos6612a682013-08-28 10:41:46 +0200127 ref_rate = AR913X_BASE_FREQ;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100128 pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
129
Alban Bedel626a0692015-04-19 14:30:02 +0200130 div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK);
Gabor Juhos6612a682013-08-28 10:41:46 +0200131 freq = div * ref_rate;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100132
Gabor Juhos6612a682013-08-28 10:41:46 +0200133 cpu_rate = freq;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100134
135 div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +0200136 ddr_rate = freq / div;
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100137
138 div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
Gabor Juhos6612a682013-08-28 10:41:46 +0200139 ahb_rate = cpu_rate / div;
140
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200141 ath79_add_sys_clkdev("ref", ref_rate);
142 ath79_add_sys_clkdev("cpu", cpu_rate);
143 ath79_add_sys_clkdev("ddr", ddr_rate);
144 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100145
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200146 clk_add_alias("wdt", NULL, "ahb", NULL);
147 clk_add_alias("uart", NULL, "ahb", NULL);
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100148}
149
Gabor Juhos04225e12011-06-20 21:26:04 +0200150static void __init ar933x_clocks_init(void)
151{
Gabor Juhos6612a682013-08-28 10:41:46 +0200152 unsigned long ref_rate;
153 unsigned long cpu_rate;
154 unsigned long ddr_rate;
155 unsigned long ahb_rate;
Gabor Juhos04225e12011-06-20 21:26:04 +0200156 u32 clock_ctrl;
157 u32 cpu_config;
158 u32 freq;
159 u32 t;
160
161 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
162 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
Gabor Juhos6612a682013-08-28 10:41:46 +0200163 ref_rate = (40 * 1000 * 1000);
Gabor Juhos04225e12011-06-20 21:26:04 +0200164 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200165 ref_rate = (25 * 1000 * 1000);
Gabor Juhos04225e12011-06-20 21:26:04 +0200166
167 clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
168 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
Gabor Juhos6612a682013-08-28 10:41:46 +0200169 cpu_rate = ref_rate;
170 ahb_rate = ref_rate;
171 ddr_rate = ref_rate;
Gabor Juhos04225e12011-06-20 21:26:04 +0200172 } else {
173 cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
174
175 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
176 AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
Gabor Juhos6612a682013-08-28 10:41:46 +0200177 freq = ref_rate / t;
Gabor Juhos04225e12011-06-20 21:26:04 +0200178
179 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
180 AR933X_PLL_CPU_CONFIG_NINT_MASK;
181 freq *= t;
182
183 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
184 AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
185 if (t == 0)
186 t = 1;
187
188 freq >>= t;
189
190 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
191 AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +0200192 cpu_rate = freq / t;
Gabor Juhos04225e12011-06-20 21:26:04 +0200193
194 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
195 AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +0200196 ddr_rate = freq / t;
Gabor Juhos04225e12011-06-20 21:26:04 +0200197
198 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
199 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
Gabor Juhos6612a682013-08-28 10:41:46 +0200200 ahb_rate = freq / t;
Gabor Juhos04225e12011-06-20 21:26:04 +0200201 }
202
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200203 ath79_add_sys_clkdev("ref", ref_rate);
204 ath79_add_sys_clkdev("cpu", cpu_rate);
205 ath79_add_sys_clkdev("ddr", ddr_rate);
206 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhos6612a682013-08-28 10:41:46 +0200207
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200208 clk_add_alias("wdt", NULL, "ahb", NULL);
209 clk_add_alias("uart", NULL, "ref", NULL);
Gabor Juhos04225e12011-06-20 21:26:04 +0200210}
211
Gabor Juhos97541cc2012-09-08 14:02:21 +0200212static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
213 u32 frac, u32 out_div)
214{
215 u64 t;
216 u32 ret;
217
Gabor Juhos837f0362013-08-28 10:41:43 +0200218 t = ref;
Gabor Juhos97541cc2012-09-08 14:02:21 +0200219 t *= nint;
220 do_div(t, ref_div);
221 ret = t;
222
Gabor Juhos837f0362013-08-28 10:41:43 +0200223 t = ref;
Gabor Juhos97541cc2012-09-08 14:02:21 +0200224 t *= nfrac;
225 do_div(t, ref_div * frac);
226 ret += t;
227
228 ret /= (1 << out_div);
229 return ret;
230}
231
Gabor Juhos88896122012-03-14 10:45:22 +0100232static void __init ar934x_clocks_init(void)
233{
Gabor Juhos6612a682013-08-28 10:41:46 +0200234 unsigned long ref_rate;
235 unsigned long cpu_rate;
236 unsigned long ddr_rate;
237 unsigned long ahb_rate;
Gabor Juhos97541cc2012-09-08 14:02:21 +0200238 u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
Gabor Juhos88896122012-03-14 10:45:22 +0100239 u32 cpu_pll, ddr_pll;
240 u32 bootstrap;
Gabor Juhos97541cc2012-09-08 14:02:21 +0200241 void __iomem *dpll_base;
242
243 dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
Gabor Juhos88896122012-03-14 10:45:22 +0100244
245 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
Ralf Baechle70342282013-01-22 12:59:30 +0100246 if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
Gabor Juhos6612a682013-08-28 10:41:46 +0200247 ref_rate = 40 * 1000 * 1000;
Gabor Juhos88896122012-03-14 10:45:22 +0100248 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200249 ref_rate = 25 * 1000 * 1000;
Gabor Juhos88896122012-03-14 10:45:22 +0100250
Gabor Juhos97541cc2012-09-08 14:02:21 +0200251 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
252 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
253 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
254 AR934X_SRIF_DPLL2_OUTDIV_MASK;
255 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
256 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
257 AR934X_SRIF_DPLL1_NINT_MASK;
258 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
259 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
260 AR934X_SRIF_DPLL1_REFDIV_MASK;
261 frac = 1 << 18;
262 } else {
263 pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
264 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
265 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
266 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
267 AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
268 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
269 AR934X_PLL_CPU_CONFIG_NINT_MASK;
270 nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
271 AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
272 frac = 1 << 6;
273 }
Gabor Juhos88896122012-03-14 10:45:22 +0100274
Gabor Juhos6612a682013-08-28 10:41:46 +0200275 cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
Gabor Juhos97541cc2012-09-08 14:02:21 +0200276 nfrac, frac, out_div);
Gabor Juhos88896122012-03-14 10:45:22 +0100277
Gabor Juhos97541cc2012-09-08 14:02:21 +0200278 pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
279 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
280 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
281 AR934X_SRIF_DPLL2_OUTDIV_MASK;
282 pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
283 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
284 AR934X_SRIF_DPLL1_NINT_MASK;
285 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
286 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
287 AR934X_SRIF_DPLL1_REFDIV_MASK;
288 frac = 1 << 18;
289 } else {
290 pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
291 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
292 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
293 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
294 AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
295 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
296 AR934X_PLL_DDR_CONFIG_NINT_MASK;
297 nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
298 AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
299 frac = 1 << 10;
300 }
Gabor Juhos88896122012-03-14 10:45:22 +0100301
Gabor Juhos6612a682013-08-28 10:41:46 +0200302 ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
Gabor Juhos97541cc2012-09-08 14:02:21 +0200303 nfrac, frac, out_div);
Gabor Juhos88896122012-03-14 10:45:22 +0100304
305 clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
306
307 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
308 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
309
310 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200311 cpu_rate = ref_rate;
Gabor Juhos88896122012-03-14 10:45:22 +0100312 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200313 cpu_rate = cpu_pll / (postdiv + 1);
Gabor Juhos88896122012-03-14 10:45:22 +0100314 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200315 cpu_rate = ddr_pll / (postdiv + 1);
Gabor Juhos88896122012-03-14 10:45:22 +0100316
317 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
318 AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
319
320 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200321 ddr_rate = ref_rate;
Gabor Juhos88896122012-03-14 10:45:22 +0100322 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200323 ddr_rate = ddr_pll / (postdiv + 1);
Gabor Juhos88896122012-03-14 10:45:22 +0100324 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200325 ddr_rate = cpu_pll / (postdiv + 1);
Gabor Juhos88896122012-03-14 10:45:22 +0100326
327 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
328 AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
329
330 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200331 ahb_rate = ref_rate;
Gabor Juhos88896122012-03-14 10:45:22 +0100332 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200333 ahb_rate = ddr_pll / (postdiv + 1);
Gabor Juhos88896122012-03-14 10:45:22 +0100334 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200335 ahb_rate = cpu_pll / (postdiv + 1);
336
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200337 ath79_add_sys_clkdev("ref", ref_rate);
338 ath79_add_sys_clkdev("cpu", cpu_rate);
339 ath79_add_sys_clkdev("ddr", ddr_rate);
340 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhos88896122012-03-14 10:45:22 +0100341
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200342 clk_add_alias("wdt", NULL, "ref", NULL);
343 clk_add_alias("uart", NULL, "ref", NULL);
Gabor Juhos97541cc2012-09-08 14:02:21 +0200344
345 iounmap(dpll_base);
Gabor Juhos88896122012-03-14 10:45:22 +0100346}
347
Gabor Juhos41583c02013-02-15 13:38:17 +0000348static void __init qca955x_clocks_init(void)
349{
Gabor Juhos6612a682013-08-28 10:41:46 +0200350 unsigned long ref_rate;
351 unsigned long cpu_rate;
352 unsigned long ddr_rate;
353 unsigned long ahb_rate;
Gabor Juhos41583c02013-02-15 13:38:17 +0000354 u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
355 u32 cpu_pll, ddr_pll;
356 u32 bootstrap;
357
358 bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
359 if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
Gabor Juhos6612a682013-08-28 10:41:46 +0200360 ref_rate = 40 * 1000 * 1000;
Gabor Juhos41583c02013-02-15 13:38:17 +0000361 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200362 ref_rate = 25 * 1000 * 1000;
Gabor Juhos41583c02013-02-15 13:38:17 +0000363
364 pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
365 out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
366 QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
367 ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
368 QCA955X_PLL_CPU_CONFIG_REFDIV_MASK;
369 nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) &
370 QCA955X_PLL_CPU_CONFIG_NINT_MASK;
371 frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
372 QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
373
Gabor Juhos6612a682013-08-28 10:41:46 +0200374 cpu_pll = nint * ref_rate / ref_div;
375 cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
Gabor Juhos41583c02013-02-15 13:38:17 +0000376 cpu_pll /= (1 << out_div);
377
378 pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
379 out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
380 QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
381 ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
382 QCA955X_PLL_DDR_CONFIG_REFDIV_MASK;
383 nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) &
384 QCA955X_PLL_DDR_CONFIG_NINT_MASK;
385 frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
386 QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
387
Gabor Juhos6612a682013-08-28 10:41:46 +0200388 ddr_pll = nint * ref_rate / ref_div;
389 ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
Gabor Juhos41583c02013-02-15 13:38:17 +0000390 ddr_pll /= (1 << out_div);
391
392 clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
393
394 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
395 QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
396
397 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200398 cpu_rate = ref_rate;
Gabor Juhos41583c02013-02-15 13:38:17 +0000399 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200400 cpu_rate = ddr_pll / (postdiv + 1);
Gabor Juhos41583c02013-02-15 13:38:17 +0000401 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200402 cpu_rate = cpu_pll / (postdiv + 1);
Gabor Juhos41583c02013-02-15 13:38:17 +0000403
404 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
405 QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
406
407 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200408 ddr_rate = ref_rate;
Gabor Juhos41583c02013-02-15 13:38:17 +0000409 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200410 ddr_rate = cpu_pll / (postdiv + 1);
Gabor Juhos41583c02013-02-15 13:38:17 +0000411 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200412 ddr_rate = ddr_pll / (postdiv + 1);
Gabor Juhos41583c02013-02-15 13:38:17 +0000413
414 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
415 QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
416
417 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
Gabor Juhos6612a682013-08-28 10:41:46 +0200418 ahb_rate = ref_rate;
Gabor Juhos41583c02013-02-15 13:38:17 +0000419 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
Gabor Juhos6612a682013-08-28 10:41:46 +0200420 ahb_rate = ddr_pll / (postdiv + 1);
Gabor Juhos41583c02013-02-15 13:38:17 +0000421 else
Gabor Juhos6612a682013-08-28 10:41:46 +0200422 ahb_rate = cpu_pll / (postdiv + 1);
423
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200424 ath79_add_sys_clkdev("ref", ref_rate);
425 ath79_add_sys_clkdev("cpu", cpu_rate);
426 ath79_add_sys_clkdev("ddr", ddr_rate);
427 ath79_add_sys_clkdev("ahb", ahb_rate);
Gabor Juhos41583c02013-02-15 13:38:17 +0000428
Gabor Juhos2c4f1ac2013-08-28 10:41:47 +0200429 clk_add_alias("wdt", NULL, "ref", NULL);
430 clk_add_alias("uart", NULL, "ref", NULL);
Gabor Juhos41583c02013-02-15 13:38:17 +0000431}
432
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100433void __init ath79_clocks_init(void)
434{
435 if (soc_is_ar71xx())
436 ar71xx_clocks_init();
437 else if (soc_is_ar724x())
438 ar724x_clocks_init();
439 else if (soc_is_ar913x())
440 ar913x_clocks_init();
Gabor Juhos04225e12011-06-20 21:26:04 +0200441 else if (soc_is_ar933x())
442 ar933x_clocks_init();
Gabor Juhos88896122012-03-14 10:45:22 +0100443 else if (soc_is_ar934x())
444 ar934x_clocks_init();
Gabor Juhos41583c02013-02-15 13:38:17 +0000445 else if (soc_is_qca955x())
446 qca955x_clocks_init();
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100447 else
448 BUG();
Gabor Juhosd4a67d92011-01-04 21:28:14 +0100449}
450
Gabor Juhos23107802013-08-28 10:41:44 +0200451unsigned long __init
452ath79_get_sys_clk_rate(const char *id)
453{
454 struct clk *clk;
455 unsigned long rate;
456
457 clk = clk_get(NULL, id);
458 if (IS_ERR(clk))
459 panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
460
461 rate = clk_get_rate(clk);
462 clk_put(clk);
463
464 return rate;
465}