blob: d71c94e1718a5f30c3c912ea5c6cae4c1a948a3a [file] [log] [blame]
Rosy Songbd905c32019-03-16 09:24:44 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
4 */
5
6#include <common.h>
Simon Glass85d65312019-12-28 10:44:58 -07007#include <clock_legacy.h>
Rosy Songbd905c32019-03-16 09:24:44 +08008#include <asm/io.h>
9#include <asm/addrspace.h>
10#include <asm/types.h>
11#include <mach/ar71xx_regs.h>
12#include <mach/ath79.h>
13#include <wait_bit.h>
14
15#define PLL_SRIF_DPLL2_KI_LSB 29
16#define PLL_SRIF_DPLL2_KI_MASK 0x60000000
17#define PLL_SRIF_DPLL2_KI_SET(x) \
18 (((x) << PLL_SRIF_DPLL2_KI_LSB) & PLL_SRIF_DPLL2_KI_MASK)
19#define PLL_SRIF_DPLL2_KD_LSB 25
20#define PLL_SRIF_DPLL2_KD_MASK 0x1e000000
21#define PLL_SRIF_DPLL2_KD_SET(x) \
22 (((x) << PLL_SRIF_DPLL2_KD_LSB) & PLL_SRIF_DPLL2_KD_MASK)
23#define PLL_SRIF_DPLL2_PLL_PWD_LSB 22
24#define PLL_SRIF_DPLL2_PLL_PWD_MASK 0x00400000
25#define PLL_SRIF_DPLL2_PLL_PWD_SET(x) \
26 (((x) << PLL_SRIF_DPLL2_PLL_PWD_LSB) & PLL_SRIF_DPLL2_PLL_PWD_MASK)
27#define PLL_SRIF_DPLL2_OUTDIV_LSB 19
28#define PLL_SRIF_DPLL2_OUTDIV_MASK 0x00380000
29#define PLL_SRIF_DPLL2_OUTDIV_SET(x) \
30 (((x) << PLL_SRIF_DPLL2_OUTDIV_LSB) & PLL_SRIF_DPLL2_OUTDIV_MASK)
31#define PLL_SRIF_DPLL2_PHASE_SHIFT_LSB 12
32#define PLL_SRIF_DPLL2_PHASE_SHIFT_MASK 0x0007f000
33#define PLL_SRIF_DPLL2_PHASE_SHIFT_SET(x) \
34 (((x) << PLL_SRIF_DPLL2_PHASE_SHIFT_LSB) & PLL_SRIF_DPLL2_PHASE_SHIFT_MASK)
35#define CPU_PLL_CONFIG_PLLPWD_LSB 30
36#define CPU_PLL_CONFIG_PLLPWD_MASK 0x40000000
37#define CPU_PLL_CONFIG_PLLPWD_SET(x) \
38 (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK)
39#define CPU_PLL_CONFIG_OUTDIV_LSB 19
40#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00380000
41#define CPU_PLL_CONFIG_OUTDIV_SET(x) \
42 (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK)
43#define CPU_PLL_CONFIG_RANGE_LSB 17
44#define CPU_PLL_CONFIG_RANGE_MASK 0x00060000
45#define CPU_PLL_CONFIG_RANGE_SET(x) \
46 (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK)
47#define CPU_PLL_CONFIG_REFDIV_LSB 12
48#define CPU_PLL_CONFIG_REFDIV_MASK 0x0001f000
49#define CPU_PLL_CONFIG_REFDIV_SET(x) \
50 (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK)
51#define CPU_PLL_CONFIG1_NINT_LSB 18
52#define CPU_PLL_CONFIG1_NINT_MASK 0x07fc0000
53#define CPU_PLL_CONFIG1_NINT_SET(x) \
54 (((x) << CPU_PLL_CONFIG1_NINT_LSB) & CPU_PLL_CONFIG1_NINT_MASK)
55#define CPU_PLL_DITHER1_DITHER_EN_LSB 31
56#define CPU_PLL_DITHER1_DITHER_EN_MASK 0x80000000
57#define CPU_PLL_DITHER1_DITHER_EN_SET(x) \
58 (((x) << CPU_PLL_DITHER1_DITHER_EN_LSB) & CPU_PLL_DITHER1_DITHER_EN_MASK)
59#define CPU_PLL_DITHER1_UPDATE_COUNT_LSB 24
60#define CPU_PLL_DITHER1_UPDATE_COUNT_MASK 0x3f000000
61#define CPU_PLL_DITHER1_UPDATE_COUNT_SET(x) \
62 (((x) << CPU_PLL_DITHER1_UPDATE_COUNT_LSB) & CPU_PLL_DITHER1_UPDATE_COUNT_MASK)
63#define CPU_PLL_DITHER1_NFRAC_STEP_LSB 18
64#define CPU_PLL_DITHER1_NFRAC_STEP_MASK 0x00fc0000
65#define CPU_PLL_DITHER1_NFRAC_STEP_SET(x) \
66 (((x) << CPU_PLL_DITHER1_NFRAC_STEP_LSB) & CPU_PLL_DITHER1_NFRAC_STEP_MASK)
67#define CPU_PLL_DITHER1_NFRAC_MIN_LSB 0
68#define CPU_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
69#define CPU_PLL_DITHER1_NFRAC_MIN_SET(x) \
70 (((x) << CPU_PLL_DITHER1_NFRAC_MIN_LSB) & CPU_PLL_DITHER1_NFRAC_MIN_MASK)
71#define CPU_PLL_DITHER2_NFRAC_MAX_LSB 0
72#define CPU_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
73#define CPU_PLL_DITHER2_NFRAC_MAX_SET(x) \
74 (((x) << CPU_PLL_DITHER2_NFRAC_MAX_LSB) & CPU_PLL_DITHER2_NFRAC_MAX_MASK)
75#define DDR_PLL_CONFIG_PLLPWD_LSB 30
76#define DDR_PLL_CONFIG_PLLPWD_MASK 0x40000000
77#define DDR_PLL_CONFIG_PLLPWD_SET(x) \
78 (((x) << DDR_PLL_CONFIG_PLLPWD_LSB) & DDR_PLL_CONFIG_PLLPWD_MASK)
79#define DDR_PLL_CONFIG_OUTDIV_LSB 23
80#define DDR_PLL_CONFIG_OUTDIV_MASK 0x03800000
81#define DDR_PLL_CONFIG_OUTDIV_SET(x) \
82 (((x) << DDR_PLL_CONFIG_OUTDIV_LSB) & DDR_PLL_CONFIG_OUTDIV_MASK)
83#define DDR_PLL_CONFIG_RANGE_LSB 21
84#define DDR_PLL_CONFIG_RANGE_MASK 0x00600000
85#define DDR_PLL_CONFIG_RANGE_SET(x) \
86 (((x) << DDR_PLL_CONFIG_RANGE_LSB) & DDR_PLL_CONFIG_RANGE_MASK)
87#define DDR_PLL_CONFIG_REFDIV_LSB 16
88#define DDR_PLL_CONFIG_REFDIV_MASK 0x001f0000
89#define DDR_PLL_CONFIG_REFDIV_SET(x) \
90 (((x) << DDR_PLL_CONFIG_REFDIV_LSB) & DDR_PLL_CONFIG_REFDIV_MASK)
91#define DDR_PLL_CONFIG1_NINT_LSB 18
92#define DDR_PLL_CONFIG1_NINT_MASK 0x07fc0000
93#define DDR_PLL_CONFIG1_NINT_SET(x) \
94 (((x) << DDR_PLL_CONFIG1_NINT_LSB) & DDR_PLL_CONFIG1_NINT_MASK)
95#define DDR_PLL_DITHER1_DITHER_EN_LSB 31
96#define DDR_PLL_DITHER1_DITHER_EN_MASK 0x80000000
97#define DDR_PLL_DITHER1_DITHER_EN_SET(x) \
98 (((x) << DDR_PLL_DITHER1_DITHER_EN_LSB) & DDR_PLL_DITHER1_DITHER_EN_MASK)
99#define DDR_PLL_DITHER1_UPDATE_COUNT_LSB 27
100#define DDR_PLL_DITHER1_UPDATE_COUNT_MASK 0x78000000
101#define DDR_PLL_DITHER1_UPDATE_COUNT_SET(x) \
102 (((x) << DDR_PLL_DITHER1_UPDATE_COUNT_LSB) & DDR_PLL_DITHER1_UPDATE_COUNT_MASK)
103#define DDR_PLL_DITHER1_NFRAC_STEP_LSB 20
104#define DDR_PLL_DITHER1_NFRAC_STEP_MASK 0x07f00000
105#define DDR_PLL_DITHER1_NFRAC_STEP_SET(x) \
106 (((x) << DDR_PLL_DITHER1_NFRAC_STEP_LSB) & DDR_PLL_DITHER1_NFRAC_STEP_MASK)
107#define DDR_PLL_DITHER1_NFRAC_MIN_LSB 0
108#define DDR_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
109#define DDR_PLL_DITHER1_NFRAC_MIN_SET(x) \
110 (((x) << DDR_PLL_DITHER1_NFRAC_MIN_LSB) & DDR_PLL_DITHER1_NFRAC_MIN_MASK)
111#define DDR_PLL_DITHER2_NFRAC_MAX_LSB 0
112#define DDR_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
113#define DDR_PLL_DITHER2_NFRAC_MAX_SET(x) \
114 (((x) << DDR_PLL_DITHER2_NFRAC_MAX_LSB) & DDR_PLL_DITHER2_NFRAC_MAX_MASK)
115#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB 24
116#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK 0x01000000
117#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(x) \
118 (((x) << CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK)
119#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB 21
120#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK 0x00200000
121#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(x) \
122 (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK)
123#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB 20
124#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK 0x00100000
125#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(x) \
126 (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK)
127#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB 15
128#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK 0x000f8000
129#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(x) \
130 (((x) << CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK)
131#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB 10
132#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK 0x00007c00
133#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(x) \
134 (((x) << CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK)
135#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB 5
136#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK 0x000003e0
137#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(x) \
138 (((x) << CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK)
139#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB 4
140#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK 0x00000010
141#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(x) \
142 (((x) << CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK)
143#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB 3
144#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK 0x00000008
145#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(x) \
146 (((x) << CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK)
147#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB 2
148#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK 0x00000004
149#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(x) \
150 (((x) << CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK)
151
152#define CPU_PLL_CONFIG1_NINT_VAL CPU_PLL_CONFIG1_NINT_SET(0x1f)
153#define CPU_PLL_CONFIG_REF_DIV_VAL CPU_PLL_CONFIG_REFDIV_SET(0x1)
154#define CPU_PLL_CONFIG_RANGE_VAL CPU_PLL_CONFIG_RANGE_SET(0)
155#define CPU_PLL_CONFIG_OUT_DIV_VAL1 CPU_PLL_CONFIG_OUTDIV_SET(0)
156#define CPU_PLL_CONFIG_OUT_DIV_VAL2 CPU_PLL_CONFIG_OUTDIV_SET(0)
157#define CPU_PLL_DITHER1_VAL CPU_PLL_DITHER1_DITHER_EN_SET(0) | \
158 CPU_PLL_DITHER1_NFRAC_MIN_SET(0) | \
159 CPU_PLL_DITHER1_NFRAC_STEP_SET(0) | \
160 CPU_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
161#define CPU_PLL_DITHER2_VAL CPU_PLL_DITHER2_NFRAC_MAX_SET(0x0)
162#define DDR_PLL_CONFIG1_NINT_VAL DDR_PLL_CONFIG1_NINT_SET(0x1a)
163#define DDR_PLL_CONFIG_REF_DIV_VAL DDR_PLL_CONFIG_REFDIV_SET(0x1)
164#define DDR_PLL_CONFIG_RANGE_VAL DDR_PLL_CONFIG_RANGE_SET(0)
165#define DDR_PLL_CONFIG_OUT_DIV_VAL1 DDR_PLL_CONFIG_OUTDIV_SET(0)
166#define DDR_PLL_CONFIG_OUT_DIV_VAL2 DDR_PLL_CONFIG_OUTDIV_SET(0)
167#define DDR_PLL_DITHER1_VAL DDR_PLL_DITHER1_DITHER_EN_SET(0) | \
168 DDR_PLL_DITHER1_NFRAC_MIN_SET(0) | \
169 DDR_PLL_DITHER1_NFRAC_STEP_SET(0) | \
170 DDR_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
171#define DDR_PLL_DITHER2_VAL DDR_PLL_DITHER2_NFRAC_MAX_SET(0x0)
172#define AHB_CLK_FROM_DDR CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(0)
173#define CPU_AND_DDR_CLK_FROM_DDR \
174 CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(0)
175#define CPU_AND_DDR_CLK_FROM_CPU \
176 CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(0)
177#define CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL \
178 CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(0x2)
179#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV \
180 CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(0)
181#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV \
182 CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(0)
183
184static inline void set_val(u32 _reg, u32 _mask, u32 _val)
185{
186 void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
187 AR71XX_PLL_SIZE, MAP_NOCACHE);
188 writel((readl(pll_regs + _reg) & (~(_mask))) | _val, pll_regs + _reg);
189}
190
191#define cpu_pll_set(_mask, _val) \
192 set_val(QCA956X_PLL_CPU_CONFIG_REG, _mask, _val)
193
194#define ddr_pll_set(_mask, _val) \
195 set_val(QCA956X_PLL_DDR_CONFIG_REG, _mask, _val)
196
197#define cpu_ddr_control_set(_mask, _val) \
198 set_val(QCA956X_PLL_CLK_CTRL_REG, _mask, _val)
199
200DECLARE_GLOBAL_DATA_PTR;
201
202static u32 qca956x_get_xtal(void)
203{
204 u32 val;
205
206 val = ath79_get_bootstrap();
207 if (val & QCA956X_BOOTSTRAP_REF_CLK_40)
208 return 40000000;
209 else
210 return 25000000;
211}
212
213int get_serial_clock(void)
214{
215 return qca956x_get_xtal();
216}
217
218void qca956x_pll_init(void)
219{
220 void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE,
221 QCA956X_SRIF_SIZE, MAP_NOCACHE);
222 void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
223 AR71XX_PLL_SIZE, MAP_NOCACHE);
224
225 /* 8.16.2 Baseband DPLL2 */
226 writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
227 PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(1) |
228 PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_BB_DPLL2_REG);
229
230 /* 8.16.2 PCIE DPLL2 */
231 writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
232 PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(3) |
233 PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_PCIE_DPLL2_REG);
234
235 /* 8.16.2 DDR DPLL2 */
236 writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
237 PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
238 srif_regs + QCA956X_SRIF_DDR_DPLL2_REG);
239
240 /* 8.16.2 CPU DPLL2 */
241 writel(PLL_SRIF_DPLL2_KI_SET(1) | PLL_SRIF_DPLL2_KD_SET(7) |
242 PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
243 srif_regs + QCA956X_SRIF_CPU_DPLL2_REG);
244
245 /* pll_bypass_set */
246 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
247 CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1));
248 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
249 CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1));
250 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
251 CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
252
253 /* init_cpu_pll */
254 cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(1));
255 cpu_pll_set(CPU_PLL_CONFIG_REFDIV_MASK, CPU_PLL_CONFIG_REF_DIV_VAL);
256 cpu_pll_set(CPU_PLL_CONFIG_RANGE_MASK, CPU_PLL_CONFIG_RANGE_VAL);
257 cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL1);
258 set_val(QCA956X_PLL_CPU_CONFIG1_REG, CPU_PLL_CONFIG1_NINT_MASK, \
259 CPU_PLL_CONFIG1_NINT_VAL);
260
261 /* init_ddr_pll */
262 ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(1));
263 ddr_pll_set(DDR_PLL_CONFIG_REFDIV_MASK, DDR_PLL_CONFIG_REF_DIV_VAL);
264 ddr_pll_set(DDR_PLL_CONFIG_RANGE_MASK, DDR_PLL_CONFIG_RANGE_VAL);
265 ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL1);
266 set_val(QCA956X_PLL_DDR_CONFIG1_REG, DDR_PLL_CONFIG1_NINT_MASK,
267 DDR_PLL_CONFIG1_NINT_VAL);
268
269 /* init_ahb_pll */
270 writel(CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL | AHB_CLK_FROM_DDR |
271 CPU_AND_DDR_CLK_FROM_DDR | CPU_AND_DDR_CLK_FROM_CPU |
272 CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV | CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV |
273 CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) |
274 CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) |
275 CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1), pll_regs + QCA956X_PLL_CLK_CTRL_REG);
276
277 /* ddr_pll_dither_unset */
278 writel(DDR_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_DDR_DIT_FRAC_REG);
279 writel(DDR_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_DDR_DIT2_FRAC_REG);
280
281 /* cpu_pll_dither_unset */
282 writel(CPU_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_CPU_DIT_FRAC_REG);
283 writel(CPU_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_CPU_DIT2_FRAC_REG);
284
285 /* pll_pwd_unset */
286 cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0));
287 ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0));
288
289 /* outdiv_unset */
290 cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2);
291 ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2);
292
293 /* pll_bypass_unset */
294 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
295 CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0));
296 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
297 CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0));
298 cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
299 CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0));
300
301 while (readl(pll_regs + QCA956X_PLL_CPU_CONFIG_REG) & 0x8000000)
302 /* NOP */;
303
304 while (readl(pll_regs + QCA956X_PLL_DDR_CONFIG_REG) & 0x8000000)
305 /* NOP */;
306}
307
308int get_clocks(void)
309{
310 void __iomem *regs;
311 u32 ref_rate, cpu_rate, ddr_rate, ahb_rate;
312 u32 out_div, ref_div, postdiv, nint, hfrac, lfrac, clk_ctrl;
313 u32 pll, cpu_pll, ddr_pll, misc;
314
315 /*
316 * QCA956x timer init workaround has to be applied right before setting
317 * up the clock. Else, there will be no jiffies
318 */
319 regs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
320 MAP_NOCACHE);
321 misc = readl(regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
322 misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
323 writel(misc, regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
324
325 regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
326 MAP_NOCACHE);
327 pll = readl(regs + QCA956X_PLL_CPU_CONFIG_REG);
328 out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
329 QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
330 ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
331 QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
332
333 pll = readl(regs + QCA956X_PLL_CPU_CONFIG1_REG);
334 nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
335 QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
336 hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
337 QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
338 lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
339 QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
340
341 ref_rate = qca956x_get_xtal();
342
343 cpu_pll = nint * ref_rate / ref_div;
344 cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
345 cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
346 cpu_pll /= (1 << out_div);
347
348 pll = readl(regs + QCA956X_PLL_DDR_CONFIG_REG);
349 out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
350 QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
351 ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
352 QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
353 pll = readl(regs + QCA956X_PLL_DDR_CONFIG1_REG);
354 nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
355 QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
356 hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
357 QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
358 lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
359 QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
360
361 ddr_pll = nint * ref_rate / ref_div;
362 ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
363 ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
364 ddr_pll /= (1 << out_div);
365
366 clk_ctrl = readl(regs + QCA956X_PLL_CLK_CTRL_REG);
367
368 postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
369 QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
370
371 if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
372 cpu_rate = ref_rate;
373 else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
374 cpu_rate = ddr_pll / (postdiv + 1);
375 else
376 cpu_rate = cpu_pll / (postdiv + 1);
377
378 postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
379 QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
380
381 if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
382 ddr_rate = ref_rate;
383 else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
384 ddr_rate = cpu_pll / (postdiv + 1);
385 else
386 ddr_rate = ddr_pll / (postdiv + 1);
387
388 postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
389 QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
390
391 if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
392 ahb_rate = ref_rate;
393 else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
394 ahb_rate = ddr_pll / (postdiv + 1);
395 else
396 ahb_rate = cpu_pll / (postdiv + 1);
397
398 gd->cpu_clk = cpu_rate;
399 gd->mem_clk = ddr_rate;
400 gd->bus_clk = ahb_rate;
401
402 debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n",
403 cpu_rate, ddr_rate, ahb_rate);
404
405 return 0;
406}
407
408ulong get_bus_freq(ulong dummy)
409{
410 if (!gd->bus_clk)
411 get_clocks();
412 return gd->bus_clk;
413}
414
415ulong get_ddr_freq(ulong dummy)
416{
417 if (!gd->mem_clk)
418 get_clocks();
419 return gd->mem_clk;
420}