1 From 2741304648dbdab7697d7758166a582b5291c53d Mon Sep 17 00:00:00 2001
2 From: Matthias Schiffer <mschiffer@universe-factory.net>
3 Date: Sat, 23 Jun 2018 15:08:56 +0200
4 Subject: [PATCH 10/33] MIPS: ath79: add support for QCA953x QCA956x TP9343
6 This patch adds support for 2 new types of QCA silicon. TP9343 is
7 essentially the same as the QCA956X but is licensed by TPLink.
9 Signed-off-by: Weijie Gao <hackpascal@gmail.com>
10 Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
11 Signed-off-by: John Crispin <john@phrozen.org>
13 arch/mips/ath79/clock.c | 193 +++++++++++++++++++++++++++++++
14 arch/mips/ath79/common.c | 8 ++
15 arch/mips/ath79/early_printk.c | 4 +
16 arch/mips/ath79/setup.c | 34 +++++-
17 arch/mips/include/asm/mach-ath79/ath79.h | 33 ++++++
18 5 files changed, 269 insertions(+), 3 deletions(-)
20 --- a/arch/mips/ath79/clock.c
21 +++ b/arch/mips/ath79/clock.c
22 @@ -355,6 +355,91 @@ static void __init ar934x_clocks_init(vo
26 +static void __init qca953x_clocks_init(void)
28 + unsigned long ref_rate;
29 + unsigned long cpu_rate;
30 + unsigned long ddr_rate;
31 + unsigned long ahb_rate;
32 + u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
33 + u32 cpu_pll, ddr_pll;
36 + bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
37 + if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
38 + ref_rate = 40 * 1000 * 1000;
40 + ref_rate = 25 * 1000 * 1000;
42 + pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG);
43 + out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
44 + QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
45 + ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
46 + QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
47 + nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) &
48 + QCA953X_PLL_CPU_CONFIG_NINT_MASK;
49 + frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
50 + QCA953X_PLL_CPU_CONFIG_NFRAC_MASK;
52 + cpu_pll = nint * ref_rate / ref_div;
53 + cpu_pll += frac * (ref_rate >> 6) / ref_div;
54 + cpu_pll /= (1 << out_div);
56 + pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG);
57 + out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
58 + QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
59 + ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
60 + QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
61 + nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) &
62 + QCA953X_PLL_DDR_CONFIG_NINT_MASK;
63 + frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
64 + QCA953X_PLL_DDR_CONFIG_NFRAC_MASK;
66 + ddr_pll = nint * ref_rate / ref_div;
67 + ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
68 + ddr_pll /= (1 << out_div);
70 + clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG);
72 + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
73 + QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
75 + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
76 + cpu_rate = ref_rate;
77 + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
78 + cpu_rate = cpu_pll / (postdiv + 1);
80 + cpu_rate = ddr_pll / (postdiv + 1);
82 + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
83 + QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
85 + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
86 + ddr_rate = ref_rate;
87 + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
88 + ddr_rate = ddr_pll / (postdiv + 1);
90 + ddr_rate = cpu_pll / (postdiv + 1);
92 + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
93 + QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
95 + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
96 + ahb_rate = ref_rate;
97 + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
98 + ahb_rate = ddr_pll / (postdiv + 1);
100 + ahb_rate = cpu_pll / (postdiv + 1);
102 + ath79_add_sys_clkdev("ref", ref_rate);
103 + ath79_add_sys_clkdev("cpu", cpu_rate);
104 + ath79_add_sys_clkdev("ddr", ddr_rate);
105 + ath79_add_sys_clkdev("ahb", ahb_rate);
107 + clk_add_alias("wdt", NULL, "ref", NULL);
108 + clk_add_alias("uart", NULL, "ref", NULL);
111 static void __init qca955x_clocks_init(void)
113 unsigned long ref_rate;
114 @@ -440,6 +525,110 @@ static void __init qca955x_clocks_init(v
115 clk_add_alias("uart", NULL, "ref", NULL);
118 +static void __init qca956x_clocks_init(void)
120 + unsigned long ref_rate;
121 + unsigned long cpu_rate;
122 + unsigned long ddr_rate;
123 + unsigned long ahb_rate;
124 + u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv;
125 + u32 cpu_pll, ddr_pll;
129 + * QCA956x timer init workaround has to be applied right before setting
130 + * up the clock. Else, there will be no jiffies
134 + misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
135 + misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
136 + ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc);
138 + bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
139 + if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40)
140 + ref_rate = 40 * 1000 * 1000;
142 + ref_rate = 25 * 1000 * 1000;
144 + pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG);
145 + out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
146 + QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
147 + ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
148 + QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
150 + pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG);
151 + nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
152 + QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
153 + hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
154 + QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
155 + lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
156 + QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
158 + cpu_pll = nint * ref_rate / ref_div;
159 + cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
160 + cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
161 + cpu_pll /= (1 << out_div);
163 + pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG);
164 + out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
165 + QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
166 + ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
167 + QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
168 + pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG);
169 + nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
170 + QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
171 + hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
172 + QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
173 + lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
174 + QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
176 + ddr_pll = nint * ref_rate / ref_div;
177 + ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
178 + ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
179 + ddr_pll /= (1 << out_div);
181 + clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG);
183 + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
184 + QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
186 + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
187 + cpu_rate = ref_rate;
188 + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
189 + cpu_rate = ddr_pll / (postdiv + 1);
191 + cpu_rate = cpu_pll / (postdiv + 1);
193 + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
194 + QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
196 + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
197 + ddr_rate = ref_rate;
198 + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
199 + ddr_rate = cpu_pll / (postdiv + 1);
201 + ddr_rate = ddr_pll / (postdiv + 1);
203 + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
204 + QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
206 + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
207 + ahb_rate = ref_rate;
208 + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
209 + ahb_rate = ddr_pll / (postdiv + 1);
211 + ahb_rate = cpu_pll / (postdiv + 1);
213 + ath79_add_sys_clkdev("ref", ref_rate);
214 + ath79_add_sys_clkdev("cpu", cpu_rate);
215 + ath79_add_sys_clkdev("ddr", ddr_rate);
216 + ath79_add_sys_clkdev("ahb", ahb_rate);
218 + clk_add_alias("wdt", NULL, "ref", NULL);
219 + clk_add_alias("uart", NULL, "ref", NULL);
222 void __init ath79_clocks_init(void)
225 @@ -450,8 +639,12 @@ void __init ath79_clocks_init(void)
226 ar933x_clocks_init();
227 else if (soc_is_ar934x())
228 ar934x_clocks_init();
229 + else if (soc_is_qca953x())
230 + qca953x_clocks_init();
231 else if (soc_is_qca955x())
232 qca955x_clocks_init();
233 + else if (soc_is_qca956x() || soc_is_tp9343())
234 + qca956x_clocks_init();
238 --- a/arch/mips/ath79/common.c
239 +++ b/arch/mips/ath79/common.c
240 @@ -103,8 +103,12 @@ void ath79_device_reset_set(u32 mask)
241 reg = AR933X_RESET_REG_RESET_MODULE;
242 else if (soc_is_ar934x())
243 reg = AR934X_RESET_REG_RESET_MODULE;
244 + else if (soc_is_qca953x())
245 + reg = QCA953X_RESET_REG_RESET_MODULE;
246 else if (soc_is_qca955x())
247 reg = QCA955X_RESET_REG_RESET_MODULE;
248 + else if (soc_is_qca956x() || soc_is_tp9343())
249 + reg = QCA956X_RESET_REG_RESET_MODULE;
253 @@ -131,8 +135,12 @@ void ath79_device_reset_clear(u32 mask)
254 reg = AR933X_RESET_REG_RESET_MODULE;
255 else if (soc_is_ar934x())
256 reg = AR934X_RESET_REG_RESET_MODULE;
257 + else if (soc_is_qca953x())
258 + reg = QCA953X_RESET_REG_RESET_MODULE;
259 else if (soc_is_qca955x())
260 reg = QCA955X_RESET_REG_RESET_MODULE;
261 + else if (soc_is_qca956x() || soc_is_tp9343())
262 + reg = QCA956X_RESET_REG_RESET_MODULE;
266 --- a/arch/mips/ath79/early_printk.c
267 +++ b/arch/mips/ath79/early_printk.c
268 @@ -76,8 +76,12 @@ static void prom_putchar_init(void)
269 case REV_ID_MAJOR_AR9341:
270 case REV_ID_MAJOR_AR9342:
271 case REV_ID_MAJOR_AR9344:
272 + case REV_ID_MAJOR_QCA9533:
273 + case REV_ID_MAJOR_QCA9533_V2:
274 case REV_ID_MAJOR_QCA9556:
275 case REV_ID_MAJOR_QCA9558:
276 + case REV_ID_MAJOR_TP9343:
277 + case REV_ID_MAJOR_QCA956X:
278 _prom_putchar = prom_putchar_ar71xx;
281 --- a/arch/mips/ath79/setup.c
282 +++ b/arch/mips/ath79/setup.c
283 @@ -60,6 +60,7 @@ static void __init ath79_detect_sys_type
289 id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
290 major = id & REV_ID_MAJOR_MASK;
291 @@ -152,6 +153,17 @@ static void __init ath79_detect_sys_type
292 rev = id & AR934X_REV_ID_REVISION_MASK;
295 + case REV_ID_MAJOR_QCA9533_V2:
300 + case REV_ID_MAJOR_QCA9533:
301 + ath79_soc = ATH79_SOC_QCA9533;
303 + rev = id & QCA953X_REV_ID_REVISION_MASK;
306 case REV_ID_MAJOR_QCA9556:
307 ath79_soc = ATH79_SOC_QCA9556;
309 @@ -164,14 +176,30 @@ static void __init ath79_detect_sys_type
310 rev = id & QCA955X_REV_ID_REVISION_MASK;
313 + case REV_ID_MAJOR_QCA956X:
314 + ath79_soc = ATH79_SOC_QCA956X;
316 + rev = id & QCA956X_REV_ID_REVISION_MASK;
319 + case REV_ID_MAJOR_TP9343:
320 + ath79_soc = ATH79_SOC_TP9343;
322 + rev = id & QCA956X_REV_ID_REVISION_MASK;
326 panic("ath79: unknown SoC, id:0x%08x", id);
329 - ath79_soc_rev = rev;
331 + ath79_soc_rev = rev;
333 - if (soc_is_qca955x())
334 - sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
335 + if (soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x())
336 + sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u",
338 + else if (soc_is_tp9343())
339 + sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u",
342 sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
343 --- a/arch/mips/include/asm/mach-ath79/ath79.h
344 +++ b/arch/mips/include/asm/mach-ath79/ath79.h
345 @@ -32,8 +32,11 @@ enum ath79_soc_type {
356 extern enum ath79_soc_type ath79_soc;
357 @@ -100,6 +103,16 @@ static inline int soc_is_ar934x(void)
358 return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
361 +static inline int soc_is_qca9533(void)
363 + return ath79_soc == ATH79_SOC_QCA9533;
366 +static inline int soc_is_qca953x(void)
368 + return soc_is_qca9533();
371 static inline int soc_is_qca9556(void)
373 return ath79_soc == ATH79_SOC_QCA9556;
374 @@ -115,6 +128,26 @@ static inline int soc_is_qca955x(void)
375 return soc_is_qca9556() || soc_is_qca9558();
378 +static inline int soc_is_tp9343(void)
380 + return ath79_soc == ATH79_SOC_TP9343;
383 +static inline int soc_is_qca9561(void)
385 + return ath79_soc == ATH79_SOC_QCA956X;
388 +static inline int soc_is_qca9563(void)
390 + return ath79_soc == ATH79_SOC_QCA956X;
393 +static inline int soc_is_qca956x(void)
395 + return soc_is_qca9561() || soc_is_qca9563();
398 void ath79_ddr_wb_flush(unsigned int reg);
399 void ath79_ddr_set_pci_windows(void);