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