Rebased from upstream / out of band repository.
[librecmc/librecmc.git] / target / linux / ath79 / patches-4.14 / 0010-MIPS-ath79-add-support-for-QCA953x-QCA956x-TP9343.patch
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
5
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.
8
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>
12 ---
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(-)
19
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
23         iounmap(dpll_base);
24  }
25  
26 +static void __init qca953x_clocks_init(void)
27 +{
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;
34 +       u32 bootstrap;
35 +
36 +       bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
37 +       if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
38 +               ref_rate = 40 * 1000 * 1000;
39 +       else
40 +               ref_rate = 25 * 1000 * 1000;
41 +
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;
51 +
52 +       cpu_pll = nint * ref_rate / ref_div;
53 +       cpu_pll += frac * (ref_rate >> 6) / ref_div;
54 +       cpu_pll /= (1 << out_div);
55 +
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;
65 +
66 +       ddr_pll = nint * ref_rate / ref_div;
67 +       ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
68 +       ddr_pll /= (1 << out_div);
69 +
70 +       clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG);
71 +
72 +       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
73 +                 QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
74 +
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);
79 +       else
80 +               cpu_rate = ddr_pll / (postdiv + 1);
81 +
82 +       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
83 +                 QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
84 +
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);
89 +       else
90 +               ddr_rate = cpu_pll / (postdiv + 1);
91 +
92 +       postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
93 +                 QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
94 +
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);
99 +       else
100 +               ahb_rate = cpu_pll / (postdiv + 1);
101 +
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);
106 +
107 +       clk_add_alias("wdt", NULL, "ref", NULL);
108 +       clk_add_alias("uart", NULL, "ref", NULL);
109 +}
110 +
111  static void __init qca955x_clocks_init(void)
112  {
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);
116  }
117  
118 +static void __init qca956x_clocks_init(void)
119 +{
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;
126 +       u32 bootstrap;
127 +
128 +       /*
129 +        * QCA956x timer init workaround has to be applied right before setting
130 +        * up the clock. Else, there will be no jiffies
131 +        */
132 +       u32 misc;
133 +
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);
137 +
138 +       bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
139 +       if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40)
140 +               ref_rate = 40 * 1000 * 1000;
141 +       else
142 +               ref_rate = 25 * 1000 * 1000;
143 +
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;
149 +
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;
157 +
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);
162 +
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;
175 +
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);
180 +
181 +       clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG);
182 +
183 +       postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
184 +                 QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
185 +
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);
190 +       else
191 +               cpu_rate = cpu_pll / (postdiv + 1);
192 +
193 +       postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
194 +                 QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
195 +
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);
200 +       else
201 +               ddr_rate = ddr_pll / (postdiv + 1);
202 +
203 +       postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
204 +                 QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
205 +
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);
210 +       else
211 +               ahb_rate = cpu_pll / (postdiv + 1);
212 +
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);
217 +
218 +       clk_add_alias("wdt", NULL, "ref", NULL);
219 +       clk_add_alias("uart", NULL, "ref", NULL);
220 +}
221 +
222  void __init ath79_clocks_init(void)
223  {
224         if (soc_is_ar71xx())
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();
235         else
236                 BUG();
237  }
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;
250         else
251                 BUG();
252  
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;
263         else
264                 BUG();
265  
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;
279                 break;
280  
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
284         u32 major;
285         u32 minor;
286         u32 rev = 0;
287 +       u32 ver = 1;
288  
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;
293                 break;
294  
295 +       case REV_ID_MAJOR_QCA9533_V2:
296 +               ver = 2;
297 +               ath79_soc_rev = 2;
298 +               /* drop through */
299 +
300 +       case REV_ID_MAJOR_QCA9533:
301 +               ath79_soc = ATH79_SOC_QCA9533;
302 +               chip = "9533";
303 +               rev = id & QCA953X_REV_ID_REVISION_MASK;
304 +               break;
305 +
306         case REV_ID_MAJOR_QCA9556:
307                 ath79_soc = ATH79_SOC_QCA9556;
308                 chip = "9556";
309 @@ -164,14 +176,30 @@ static void __init ath79_detect_sys_type
310                 rev = id & QCA955X_REV_ID_REVISION_MASK;
311                 break;
312  
313 +       case REV_ID_MAJOR_QCA956X:
314 +               ath79_soc = ATH79_SOC_QCA956X;
315 +               chip = "956X";
316 +               rev = id & QCA956X_REV_ID_REVISION_MASK;
317 +               break;
318 +
319 +       case REV_ID_MAJOR_TP9343:
320 +               ath79_soc = ATH79_SOC_TP9343;
321 +               chip = "9343";
322 +               rev = id & QCA956X_REV_ID_REVISION_MASK;
323 +               break;
324 +
325         default:
326                 panic("ath79: unknown SoC, id:0x%08x", id);
327         }
328  
329 -       ath79_soc_rev = rev;
330 +       if (ver == 1)
331 +               ath79_soc_rev = rev;
332  
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",
337 +                       chip, ver, rev);
338 +       else if (soc_is_tp9343())
339 +               sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u",
340                         chip, rev);
341         else
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 {
346         ATH79_SOC_AR9341,
347         ATH79_SOC_AR9342,
348         ATH79_SOC_AR9344,
349 +       ATH79_SOC_QCA9533,
350         ATH79_SOC_QCA9556,
351         ATH79_SOC_QCA9558,
352 +       ATH79_SOC_TP9343,
353 +       ATH79_SOC_QCA956X,
354  };
355  
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();
359  }
360  
361 +static inline int soc_is_qca9533(void)
362 +{
363 +       return ath79_soc == ATH79_SOC_QCA9533;
364 +}
365 +
366 +static inline int soc_is_qca953x(void)
367 +{
368 +       return soc_is_qca9533();
369 +}
370 +
371  static inline int soc_is_qca9556(void)
372  {
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();
376  }
377  
378 +static inline int soc_is_tp9343(void)
379 +{
380 +       return ath79_soc == ATH79_SOC_TP9343;
381 +}
382 +
383 +static inline int soc_is_qca9561(void)
384 +{
385 +       return ath79_soc == ATH79_SOC_QCA956X;
386 +}
387 +
388 +static inline int soc_is_qca9563(void)
389 +{
390 +       return ath79_soc == ATH79_SOC_QCA956X;
391 +}
392 +
393 +static inline int soc_is_qca956x(void)
394 +{
395 +       return soc_is_qca9561() || soc_is_qca9563();
396 +}
397 +
398  void ath79_ddr_wb_flush(unsigned int reg);
399  void ath79_ddr_set_pci_windows(void);
400