0016-MIPS-ath79-add-support-for-QCA953x-SoC.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. From cff23ba486e3c5d17c4d7e446f5eddead855c101 Mon Sep 17 00:00:00 2001
  2. From: John Crispin <[email protected]>
  3. Date: Tue, 6 Mar 2018 08:45:55 +0100
  4. Subject: [PATCH 16/27] MIPS: ath79: add support for QCA953x SoC
  5. Note that the clock calculation looks very similar to the QCA955x, but the
  6. meaning of the bits CPUCLK_FROM_CPUPLL and DDRCLK_FROM_DDRPLL is reversed.
  7. Signed-off-by: Matthias Schiffer <[email protected]>
  8. ---
  9. arch/mips/ath79/Kconfig | 6 ++-
  10. arch/mips/ath79/clock.c | 87 ++++++++++++++++++++++++++++++++
  11. arch/mips/ath79/common.c | 4 ++
  12. arch/mips/ath79/dev-common.c | 4 ++
  13. arch/mips/ath79/early_printk.c | 2 +
  14. arch/mips/ath79/irq.c | 33 +++++++++++-
  15. arch/mips/ath79/setup.c | 21 ++++++--
  16. arch/mips/include/asm/mach-ath79/ath79.h | 11 ++++
  17. 8 files changed, 162 insertions(+), 6 deletions(-)
  18. diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
  19. index 9547cf1ea38d..b03f5c8b9d1e 100644
  20. --- a/arch/mips/ath79/Kconfig
  21. +++ b/arch/mips/ath79/Kconfig
  22. @@ -94,6 +94,10 @@ config SOC_AR934X
  23. select PCI_AR724X if PCI
  24. def_bool n
  25. +config SOC_QCA953X
  26. + select USB_ARCH_HAS_EHCI
  27. + def_bool n
  28. +
  29. config SOC_QCA955X
  30. select HW_HAS_PCI
  31. select PCI_AR724X if PCI
  32. @@ -115,7 +119,7 @@ config ATH79_DEV_USB
  33. def_bool n
  34. config ATH79_DEV_WMAC
  35. - depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
  36. + depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X)
  37. def_bool n
  38. endif
  39. diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
  40. index 6b1000b6a6a6..b9595b2d1b65 100644
  41. --- a/arch/mips/ath79/clock.c
  42. +++ b/arch/mips/ath79/clock.c
  43. @@ -355,6 +355,91 @@ static void __init ar934x_clocks_init(void)
  44. iounmap(dpll_base);
  45. }
  46. +static void __init qca953x_clocks_init(void)
  47. +{
  48. + unsigned long ref_rate;
  49. + unsigned long cpu_rate;
  50. + unsigned long ddr_rate;
  51. + unsigned long ahb_rate;
  52. + u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
  53. + u32 cpu_pll, ddr_pll;
  54. + u32 bootstrap;
  55. +
  56. + bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
  57. + if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
  58. + ref_rate = 40 * 1000 * 1000;
  59. + else
  60. + ref_rate = 25 * 1000 * 1000;
  61. +
  62. + pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG);
  63. + out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
  64. + QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
  65. + ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
  66. + QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
  67. + nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) &
  68. + QCA953X_PLL_CPU_CONFIG_NINT_MASK;
  69. + frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
  70. + QCA953X_PLL_CPU_CONFIG_NFRAC_MASK;
  71. +
  72. + cpu_pll = nint * ref_rate / ref_div;
  73. + cpu_pll += frac * (ref_rate >> 6) / ref_div;
  74. + cpu_pll /= (1 << out_div);
  75. +
  76. + pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG);
  77. + out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
  78. + QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
  79. + ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
  80. + QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
  81. + nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) &
  82. + QCA953X_PLL_DDR_CONFIG_NINT_MASK;
  83. + frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
  84. + QCA953X_PLL_DDR_CONFIG_NFRAC_MASK;
  85. +
  86. + ddr_pll = nint * ref_rate / ref_div;
  87. + ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
  88. + ddr_pll /= (1 << out_div);
  89. +
  90. + clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG);
  91. +
  92. + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
  93. + QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
  94. +
  95. + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
  96. + cpu_rate = ref_rate;
  97. + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
  98. + cpu_rate = cpu_pll / (postdiv + 1);
  99. + else
  100. + cpu_rate = ddr_pll / (postdiv + 1);
  101. +
  102. + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
  103. + QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
  104. +
  105. + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
  106. + ddr_rate = ref_rate;
  107. + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
  108. + ddr_rate = ddr_pll / (postdiv + 1);
  109. + else
  110. + ddr_rate = cpu_pll / (postdiv + 1);
  111. +
  112. + postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
  113. + QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
  114. +
  115. + if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
  116. + ahb_rate = ref_rate;
  117. + else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
  118. + ahb_rate = ddr_pll / (postdiv + 1);
  119. + else
  120. + ahb_rate = cpu_pll / (postdiv + 1);
  121. +
  122. + ath79_add_sys_clkdev("ref", ref_rate);
  123. + ath79_add_sys_clkdev("cpu", cpu_rate);
  124. + ath79_add_sys_clkdev("ddr", ddr_rate);
  125. + ath79_add_sys_clkdev("ahb", ahb_rate);
  126. +
  127. + clk_add_alias("wdt", NULL, "ref", NULL);
  128. + clk_add_alias("uart", NULL, "ref", NULL);
  129. +}
  130. +
  131. static void __init qca955x_clocks_init(void)
  132. {
  133. unsigned long ref_rate;
  134. @@ -450,6 +535,8 @@ void __init ath79_clocks_init(void)
  135. ar933x_clocks_init();
  136. else if (soc_is_ar934x())
  137. ar934x_clocks_init();
  138. + else if (soc_is_qca953x())
  139. + qca953x_clocks_init();
  140. else if (soc_is_qca955x())
  141. qca955x_clocks_init();
  142. else
  143. diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
  144. index a32a9181a296..a485a7c35b9b 100644
  145. --- a/arch/mips/ath79/common.c
  146. +++ b/arch/mips/ath79/common.c
  147. @@ -103,6 +103,8 @@ void ath79_device_reset_set(u32 mask)
  148. reg = AR933X_RESET_REG_RESET_MODULE;
  149. else if (soc_is_ar934x())
  150. reg = AR934X_RESET_REG_RESET_MODULE;
  151. + else if (soc_is_qca953x())
  152. + reg = QCA953X_RESET_REG_RESET_MODULE;
  153. else if (soc_is_qca955x())
  154. reg = QCA955X_RESET_REG_RESET_MODULE;
  155. else
  156. @@ -131,6 +133,8 @@ void ath79_device_reset_clear(u32 mask)
  157. reg = AR933X_RESET_REG_RESET_MODULE;
  158. else if (soc_is_ar934x())
  159. reg = AR934X_RESET_REG_RESET_MODULE;
  160. + else if (soc_is_qca953x())
  161. + reg = QCA953X_RESET_REG_RESET_MODULE;
  162. else if (soc_is_qca955x())
  163. reg = QCA955X_RESET_REG_RESET_MODULE;
  164. else
  165. diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
  166. index 9d0172a4dc69..99d8b88f1e6d 100644
  167. --- a/arch/mips/ath79/dev-common.c
  168. +++ b/arch/mips/ath79/dev-common.c
  169. @@ -85,6 +85,7 @@ void __init ath79_register_uart(void)
  170. soc_is_ar724x() ||
  171. soc_is_ar913x() ||
  172. soc_is_ar934x() ||
  173. + soc_is_qca953x() ||
  174. soc_is_qca955x()) {
  175. ath79_uart_data[0].uartclk = uart_clk_rate;
  176. platform_device_register(&ath79_uart_device);
  177. @@ -148,6 +149,9 @@ void __init ath79_gpio_init(void)
  178. } else if (soc_is_ar934x()) {
  179. ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT;
  180. ath79_gpio_pdata.oe_inverted = 1;
  181. + } else if (soc_is_qca953x()) {
  182. + ath79_gpio_pdata.ngpios = QCA953X_GPIO_COUNT;
  183. + ath79_gpio_pdata.oe_inverted = 1;
  184. } else if (soc_is_qca955x()) {
  185. ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT;
  186. ath79_gpio_pdata.oe_inverted = 1;
  187. diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
  188. index ec3978678653..cc00839b7181 100644
  189. --- a/arch/mips/ath79/early_printk.c
  190. +++ b/arch/mips/ath79/early_printk.c
  191. @@ -116,6 +116,8 @@ static void prom_putchar_init(void)
  192. case REV_ID_MAJOR_AR9341:
  193. case REV_ID_MAJOR_AR9342:
  194. case REV_ID_MAJOR_AR9344:
  195. + case REV_ID_MAJOR_QCA9533:
  196. + case REV_ID_MAJOR_QCA9533_V2:
  197. case REV_ID_MAJOR_QCA9556:
  198. case REV_ID_MAJOR_QCA9558:
  199. _prom_putchar = prom_putchar_ar71xx;
  200. diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
  201. index 2dfff1f19004..756b5aee3500 100644
  202. --- a/arch/mips/ath79/irq.c
  203. +++ b/arch/mips/ath79/irq.c
  204. @@ -56,6 +56,34 @@ static void ar934x_ip2_irq_init(void)
  205. irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
  206. }
  207. +static void qca953x_ip2_irq_dispatch(struct irq_desc *desc)
  208. +{
  209. + u32 status;
  210. +
  211. + status = ath79_reset_rr(QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS);
  212. +
  213. + if (status & QCA953X_PCIE_WMAC_INT_PCIE_ALL) {
  214. + ath79_ddr_wb_flush(3);
  215. + generic_handle_irq(ATH79_IP2_IRQ(0));
  216. + } else if (status & QCA953X_PCIE_WMAC_INT_WMAC_ALL) {
  217. + ath79_ddr_wb_flush(4);
  218. + generic_handle_irq(ATH79_IP2_IRQ(1));
  219. + } else {
  220. + spurious_interrupt();
  221. + }
  222. +}
  223. +
  224. +static void qca953x_irq_init(void)
  225. +{
  226. + int i;
  227. +
  228. + for (i = ATH79_IP2_IRQ_BASE;
  229. + i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
  230. + irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
  231. +
  232. + irq_set_chained_handler(ATH79_CPU_IRQ(2), qca953x_ip2_irq_dispatch);
  233. +}
  234. +
  235. static void qca955x_ip2_irq_dispatch(struct irq_desc *desc)
  236. {
  237. u32 status;
  238. @@ -143,7 +171,7 @@ void __init arch_init_irq(void)
  239. soc_is_ar913x() || soc_is_ar933x()) {
  240. irq_wb_chan2 = 3;
  241. irq_wb_chan3 = 2;
  242. - } else if (soc_is_ar934x()) {
  243. + } else if (soc_is_ar934x() || soc_is_qca953x()) {
  244. irq_wb_chan3 = 2;
  245. }
  246. @@ -154,6 +182,7 @@ void __init arch_init_irq(void)
  247. else if (soc_is_ar724x() ||
  248. soc_is_ar933x() ||
  249. soc_is_ar934x() ||
  250. + soc_is_qca953x() ||
  251. soc_is_qca955x())
  252. misc_is_ar71xx = false;
  253. else
  254. @@ -164,6 +193,8 @@ void __init arch_init_irq(void)
  255. if (soc_is_ar934x())
  256. ar934x_ip2_irq_init();
  257. + else if (soc_is_qca953x())
  258. + qca953x_irq_init();
  259. else if (soc_is_qca955x())
  260. qca955x_irq_init();
  261. }
  262. diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
  263. index 26a058d58d37..f782ae6c77d6 100644
  264. --- a/arch/mips/ath79/setup.c
  265. +++ b/arch/mips/ath79/setup.c
  266. @@ -60,6 +60,7 @@ static void __init ath79_detect_sys_type(void)
  267. u32 major;
  268. u32 minor;
  269. u32 rev = 0;
  270. + u32 ver = 1;
  271. id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
  272. major = id & REV_ID_MAJOR_MASK;
  273. @@ -152,6 +153,17 @@ static void __init ath79_detect_sys_type(void)
  274. rev = id & AR934X_REV_ID_REVISION_MASK;
  275. break;
  276. + case REV_ID_MAJOR_QCA9533_V2:
  277. + ver = 2;
  278. + ath79_soc_rev = 2;
  279. + /* drop through */
  280. +
  281. + case REV_ID_MAJOR_QCA9533:
  282. + ath79_soc = ATH79_SOC_QCA9533;
  283. + chip = "9533";
  284. + rev = id & QCA953X_REV_ID_REVISION_MASK;
  285. + break;
  286. +
  287. case REV_ID_MAJOR_QCA9556:
  288. ath79_soc = ATH79_SOC_QCA9556;
  289. chip = "9556";
  290. @@ -168,11 +180,12 @@ static void __init ath79_detect_sys_type(void)
  291. panic("ath79: unknown SoC, id:0x%08x", id);
  292. }
  293. - ath79_soc_rev = rev;
  294. + if (ver == 1)
  295. + ath79_soc_rev = rev;
  296. - if (soc_is_qca955x())
  297. - sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
  298. - chip, rev);
  299. + if (soc_is_qca953x() || soc_is_qca955x())
  300. + sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u",
  301. + chip, ver, rev);
  302. else
  303. sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
  304. pr_info("SoC: %s\n", ath79_sys_type);
  305. diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
  306. index 6e6c0fead776..98a7ccf3d358 100644
  307. --- a/arch/mips/include/asm/mach-ath79/ath79.h
  308. +++ b/arch/mips/include/asm/mach-ath79/ath79.h
  309. @@ -32,6 +32,7 @@ enum ath79_soc_type {
  310. ATH79_SOC_AR9341,
  311. ATH79_SOC_AR9342,
  312. ATH79_SOC_AR9344,
  313. + ATH79_SOC_QCA9533,
  314. ATH79_SOC_QCA9556,
  315. ATH79_SOC_QCA9558,
  316. };
  317. @@ -100,6 +101,16 @@ static inline int soc_is_ar934x(void)
  318. return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
  319. }
  320. +static inline int soc_is_qca9533(void)
  321. +{
  322. + return ath79_soc == ATH79_SOC_QCA9533;
  323. +}
  324. +
  325. +static inline int soc_is_qca953x(void)
  326. +{
  327. + return soc_is_qca9533();
  328. +}
  329. +
  330. static inline int soc_is_qca9556(void)
  331. {
  332. return ath79_soc == ATH79_SOC_QCA9556;
  333. --
  334. 2.11.0