001-mtk-0008-clk-mtmips-add-clock-driver-for-MediaTek-MT7621-SoC.patch 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. From c2e579662748cb5d3bf3e31f58d99c4db4d102c1 Mon Sep 17 00:00:00 2001
  2. From: Weijie Gao <[email protected]>
  3. Date: Fri, 20 May 2022 11:22:36 +0800
  4. Subject: [PATCH 08/25] clk: mtmips: add clock driver for MediaTek MT7621 SoC
  5. This patch adds a clock driver for MediaTek MT7621 SoC.
  6. This driver provides clock gate control as well as getting clock frequency
  7. for CPU/SYS/XTAL and some peripherals.
  8. Reviewed-by: Sean Anderson <[email protected]>
  9. Signed-off-by: Weijie Gao <[email protected]>
  10. ---
  11. drivers/clk/mtmips/Makefile | 1 +
  12. drivers/clk/mtmips/clk-mt7621.c | 288 +++++++++++++++++++++++++
  13. include/dt-bindings/clock/mt7621-clk.h | 46 ++++
  14. 3 files changed, 335 insertions(+)
  15. create mode 100644 drivers/clk/mtmips/clk-mt7621.c
  16. create mode 100644 include/dt-bindings/clock/mt7621-clk.h
  17. --- a/drivers/clk/mtmips/Makefile
  18. +++ b/drivers/clk/mtmips/Makefile
  19. @@ -1,4 +1,5 @@
  20. # SPDX-License-Identifier: GPL-2.0
  21. obj-$(CONFIG_SOC_MT7620) += clk-mt7620.o
  22. +obj-$(CONFIG_SOC_MT7621) += clk-mt7621.o
  23. obj-$(CONFIG_SOC_MT7628) += clk-mt7628.o
  24. --- /dev/null
  25. +++ b/drivers/clk/mtmips/clk-mt7621.c
  26. @@ -0,0 +1,288 @@
  27. +// SPDX-License-Identifier: GPL-2.0
  28. +/*
  29. + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
  30. + *
  31. + * Author: Weijie Gao <[email protected]>
  32. + */
  33. +
  34. +#include <clk-uclass.h>
  35. +#include <dm.h>
  36. +#include <dm/device_compat.h>
  37. +#include <regmap.h>
  38. +#include <syscon.h>
  39. +#include <dt-bindings/clock/mt7621-clk.h>
  40. +#include <linux/io.h>
  41. +#include <linux/bitops.h>
  42. +#include <linux/bitfield.h>
  43. +
  44. +#define SYSC_MAP_SIZE 0x100
  45. +#define MEMC_MAP_SIZE 0x1000
  46. +
  47. +/* SYSC */
  48. +#define SYSCFG0_REG 0x10
  49. +#define XTAL_MODE_SEL GENMASK(8, 6)
  50. +
  51. +#define CLKCFG0_REG 0x2c
  52. +#define CPU_CLK_SEL GENMASK(31, 30)
  53. +#define PERI_CLK_SEL BIT(4)
  54. +
  55. +#define CLKCFG1_REG 0x30
  56. +
  57. +#define CUR_CLK_STS_REG 0x44
  58. +#define CUR_CPU_FDIV GENMASK(12, 8)
  59. +#define CUR_CPU_FFRAC GENMASK(4, 0)
  60. +
  61. +/* MEMC */
  62. +#define MEMPLL1_REG 0x0604
  63. +#define RG_MEPL_DIV2_SEL GENMASK(2, 1)
  64. +
  65. +#define MEMPLL6_REG 0x0618
  66. +#define MEMPLL18_REG 0x0648
  67. +#define RG_MEPL_PREDIV GENMASK(13, 12)
  68. +#define RG_MEPL_FBDIV GENMASK(10, 4)
  69. +
  70. +/* Fixed 500M clock */
  71. +#define GMPLL_CLK 500000000
  72. +
  73. +struct mt7621_clk_priv {
  74. + void __iomem *sysc_base;
  75. + int cpu_clk;
  76. + int ddr_clk;
  77. + int sys_clk;
  78. + int xtal_clk;
  79. +};
  80. +
  81. +enum mt7621_clk_src {
  82. + CLK_SRC_CPU,
  83. + CLK_SRC_DDR,
  84. + CLK_SRC_SYS,
  85. + CLK_SRC_XTAL,
  86. + CLK_SRC_PERI,
  87. + CLK_SRC_125M,
  88. + CLK_SRC_150M,
  89. + CLK_SRC_250M,
  90. + CLK_SRC_270M,
  91. +
  92. + __CLK_SRC_MAX
  93. +};
  94. +
  95. +struct mt7621_clk_map {
  96. + u32 cgbit;
  97. + enum mt7621_clk_src clksrc;
  98. +};
  99. +
  100. +#define CLK_MAP(_id, _cg, _src) \
  101. + [_id] = { .cgbit = (_cg), .clksrc = (_src) }
  102. +
  103. +#define CLK_MAP_SRC(_id, _src) \
  104. + [_id] = { .cgbit = UINT32_MAX, .clksrc = (_src) }
  105. +
  106. +static const struct mt7621_clk_map mt7621_clk_mappings[] = {
  107. + CLK_MAP_SRC(MT7621_CLK_XTAL, CLK_SRC_XTAL),
  108. + CLK_MAP_SRC(MT7621_CLK_CPU, CLK_SRC_CPU),
  109. + CLK_MAP_SRC(MT7621_CLK_BUS, CLK_SRC_SYS),
  110. + CLK_MAP_SRC(MT7621_CLK_50M, CLK_SRC_PERI),
  111. + CLK_MAP_SRC(MT7621_CLK_125M, CLK_SRC_125M),
  112. + CLK_MAP_SRC(MT7621_CLK_150M, CLK_SRC_150M),
  113. + CLK_MAP_SRC(MT7621_CLK_250M, CLK_SRC_250M),
  114. + CLK_MAP_SRC(MT7621_CLK_270M, CLK_SRC_270M),
  115. +
  116. + CLK_MAP(MT7621_CLK_HSDMA, 5, CLK_SRC_150M),
  117. + CLK_MAP(MT7621_CLK_FE, 6, CLK_SRC_250M),
  118. + CLK_MAP(MT7621_CLK_SP_DIVTX, 7, CLK_SRC_270M),
  119. + CLK_MAP(MT7621_CLK_TIMER, 8, CLK_SRC_PERI),
  120. + CLK_MAP(MT7621_CLK_PCM, 11, CLK_SRC_270M),
  121. + CLK_MAP(MT7621_CLK_PIO, 13, CLK_SRC_PERI),
  122. + CLK_MAP(MT7621_CLK_GDMA, 14, CLK_SRC_SYS),
  123. + CLK_MAP(MT7621_CLK_NAND, 15, CLK_SRC_125M),
  124. + CLK_MAP(MT7621_CLK_I2C, 16, CLK_SRC_PERI),
  125. + CLK_MAP(MT7621_CLK_I2S, 17, CLK_SRC_270M),
  126. + CLK_MAP(MT7621_CLK_SPI, 18, CLK_SRC_SYS),
  127. + CLK_MAP(MT7621_CLK_UART1, 19, CLK_SRC_PERI),
  128. + CLK_MAP(MT7621_CLK_UART2, 20, CLK_SRC_PERI),
  129. + CLK_MAP(MT7621_CLK_UART3, 21, CLK_SRC_PERI),
  130. + CLK_MAP(MT7621_CLK_ETH, 23, CLK_SRC_PERI),
  131. + CLK_MAP(MT7621_CLK_PCIE0, 24, CLK_SRC_125M),
  132. + CLK_MAP(MT7621_CLK_PCIE1, 25, CLK_SRC_125M),
  133. + CLK_MAP(MT7621_CLK_PCIE2, 26, CLK_SRC_125M),
  134. + CLK_MAP(MT7621_CLK_CRYPTO, 29, CLK_SRC_250M),
  135. + CLK_MAP(MT7621_CLK_SHXC, 30, CLK_SRC_PERI),
  136. +
  137. + CLK_MAP_SRC(MT7621_CLK_MAX, __CLK_SRC_MAX),
  138. +
  139. + CLK_MAP_SRC(MT7621_CLK_DDR, CLK_SRC_DDR),
  140. +};
  141. +
  142. +static ulong mt7621_clk_get_rate(struct clk *clk)
  143. +{
  144. + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
  145. + u32 val;
  146. +
  147. + switch (mt7621_clk_mappings[clk->id].clksrc) {
  148. + case CLK_SRC_CPU:
  149. + return priv->cpu_clk;
  150. + case CLK_SRC_DDR:
  151. + return priv->ddr_clk;
  152. + case CLK_SRC_SYS:
  153. + return priv->sys_clk;
  154. + case CLK_SRC_XTAL:
  155. + return priv->xtal_clk;
  156. + case CLK_SRC_PERI:
  157. + val = readl(priv->sysc_base + CLKCFG0_REG);
  158. + if (val & PERI_CLK_SEL)
  159. + return priv->xtal_clk;
  160. + else
  161. + return GMPLL_CLK / 10;
  162. + case CLK_SRC_125M:
  163. + return 125000000;
  164. + case CLK_SRC_150M:
  165. + return 150000000;
  166. + case CLK_SRC_250M:
  167. + return 250000000;
  168. + case CLK_SRC_270M:
  169. + return 270000000;
  170. + default:
  171. + return 0;
  172. + }
  173. +}
  174. +
  175. +static int mt7621_clk_enable(struct clk *clk)
  176. +{
  177. + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
  178. + u32 cgbit;
  179. +
  180. + cgbit = mt7621_clk_mappings[clk->id].cgbit;
  181. + if (cgbit == UINT32_MAX)
  182. + return -ENOSYS;
  183. +
  184. + setbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit));
  185. +
  186. + return 0;
  187. +}
  188. +
  189. +static int mt7621_clk_disable(struct clk *clk)
  190. +{
  191. + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
  192. + u32 cgbit;
  193. +
  194. + cgbit = mt7621_clk_mappings[clk->id].cgbit;
  195. + if (cgbit == UINT32_MAX)
  196. + return -ENOSYS;
  197. +
  198. + clrbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit));
  199. +
  200. + return 0;
  201. +}
  202. +
  203. +static int mt7621_clk_request(struct clk *clk)
  204. +{
  205. + if (clk->id >= ARRAY_SIZE(mt7621_clk_mappings))
  206. + return -EINVAL;
  207. + return 0;
  208. +}
  209. +
  210. +const struct clk_ops mt7621_clk_ops = {
  211. + .request = mt7621_clk_request,
  212. + .enable = mt7621_clk_enable,
  213. + .disable = mt7621_clk_disable,
  214. + .get_rate = mt7621_clk_get_rate,
  215. +};
  216. +
  217. +static void mt7621_get_clocks(struct mt7621_clk_priv *priv, struct regmap *memc)
  218. +{
  219. + u32 bs, xtal_sel, clkcfg0, cur_clk, mempll, dividx, fb;
  220. + u32 xtal_clk, xtal_div, ffiv, ffrac, cpu_clk, ddr_clk;
  221. + static const u32 xtal_div_tbl[] = {0, 1, 2, 2};
  222. +
  223. + bs = readl(priv->sysc_base + SYSCFG0_REG);
  224. + clkcfg0 = readl(priv->sysc_base + CLKCFG0_REG);
  225. + cur_clk = readl(priv->sysc_base + CUR_CLK_STS_REG);
  226. +
  227. + xtal_sel = FIELD_GET(XTAL_MODE_SEL, bs);
  228. +
  229. + if (xtal_sel <= 2)
  230. + xtal_clk = 20 * 1000 * 1000;
  231. + else if (xtal_sel <= 5)
  232. + xtal_clk = 40 * 1000 * 1000;
  233. + else
  234. + xtal_clk = 25 * 1000 * 1000;
  235. +
  236. + switch (FIELD_GET(CPU_CLK_SEL, clkcfg0)) {
  237. + case 0:
  238. + cpu_clk = GMPLL_CLK;
  239. + break;
  240. + case 1:
  241. + regmap_read(memc, MEMPLL18_REG, &mempll);
  242. + dividx = FIELD_GET(RG_MEPL_PREDIV, mempll);
  243. + fb = FIELD_GET(RG_MEPL_FBDIV, mempll);
  244. + xtal_div = 1 << xtal_div_tbl[dividx];
  245. + cpu_clk = (fb + 1) * xtal_clk / xtal_div;
  246. + break;
  247. + default:
  248. + cpu_clk = xtal_clk;
  249. + }
  250. +
  251. + ffiv = FIELD_GET(CUR_CPU_FDIV, cur_clk);
  252. + ffrac = FIELD_GET(CUR_CPU_FFRAC, cur_clk);
  253. + cpu_clk = cpu_clk / ffiv * ffrac;
  254. +
  255. + regmap_read(memc, MEMPLL6_REG, &mempll);
  256. + dividx = FIELD_GET(RG_MEPL_PREDIV, mempll);
  257. + fb = FIELD_GET(RG_MEPL_FBDIV, mempll);
  258. + xtal_div = 1 << xtal_div_tbl[dividx];
  259. + ddr_clk = fb * xtal_clk / xtal_div;
  260. +
  261. + regmap_read(memc, MEMPLL1_REG, &bs);
  262. + if (!FIELD_GET(RG_MEPL_DIV2_SEL, bs))
  263. + ddr_clk *= 2;
  264. +
  265. + priv->cpu_clk = cpu_clk;
  266. + priv->sys_clk = cpu_clk / 4;
  267. + priv->ddr_clk = ddr_clk;
  268. + priv->xtal_clk = xtal_clk;
  269. +}
  270. +
  271. +static int mt7621_clk_probe(struct udevice *dev)
  272. +{
  273. + struct mt7621_clk_priv *priv = dev_get_priv(dev);
  274. + struct ofnode_phandle_args args;
  275. + struct udevice *pdev;
  276. + struct regmap *memc;
  277. + int ret;
  278. +
  279. + pdev = dev_get_parent(dev);
  280. + if (!pdev)
  281. + return -ENODEV;
  282. +
  283. + priv->sysc_base = dev_remap_addr(pdev);
  284. + if (!priv->sysc_base)
  285. + return -EINVAL;
  286. +
  287. + /* get corresponding memc phandle */
  288. + ret = dev_read_phandle_with_args(dev, "mediatek,memc", NULL, 0, 0,
  289. + &args);
  290. + if (ret)
  291. + return ret;
  292. +
  293. + memc = syscon_node_to_regmap(args.node);
  294. + if (IS_ERR(memc))
  295. + return PTR_ERR(memc);
  296. +
  297. + mt7621_get_clocks(priv, memc);
  298. +
  299. + return 0;
  300. +}
  301. +
  302. +static const struct udevice_id mt7621_clk_ids[] = {
  303. + { .compatible = "mediatek,mt7621-clk" },
  304. + { }
  305. +};
  306. +
  307. +U_BOOT_DRIVER(mt7621_clk) = {
  308. + .name = "mt7621-clk",
  309. + .id = UCLASS_CLK,
  310. + .of_match = mt7621_clk_ids,
  311. + .probe = mt7621_clk_probe,
  312. + .priv_auto = sizeof(struct mt7621_clk_priv),
  313. + .ops = &mt7621_clk_ops,
  314. +};
  315. --- /dev/null
  316. +++ b/include/dt-bindings/clock/mt7621-clk.h
  317. @@ -0,0 +1,46 @@
  318. +/* SPDX-License-Identifier: GPL-2.0 */
  319. +/*
  320. + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
  321. + *
  322. + * Author: Weijie Gao <[email protected]>
  323. + */
  324. +
  325. +#ifndef _DT_BINDINGS_MT7621_CLK_H_
  326. +#define _DT_BINDINGS_MT7621_CLK_H_
  327. +
  328. +#define MT7621_CLK_XTAL 0
  329. +#define MT7621_CLK_CPU 1
  330. +#define MT7621_CLK_BUS 2
  331. +#define MT7621_CLK_50M 3
  332. +#define MT7621_CLK_125M 4
  333. +#define MT7621_CLK_150M 5
  334. +#define MT7621_CLK_250M 6
  335. +#define MT7621_CLK_270M 7
  336. +
  337. +#define MT7621_CLK_HSDMA 8
  338. +#define MT7621_CLK_FE 9
  339. +#define MT7621_CLK_SP_DIVTX 10
  340. +#define MT7621_CLK_TIMER 11
  341. +#define MT7621_CLK_PCM 12
  342. +#define MT7621_CLK_PIO 13
  343. +#define MT7621_CLK_GDMA 14
  344. +#define MT7621_CLK_NAND 15
  345. +#define MT7621_CLK_I2C 16
  346. +#define MT7621_CLK_I2S 17
  347. +#define MT7621_CLK_SPI 18
  348. +#define MT7621_CLK_UART1 19
  349. +#define MT7621_CLK_UART2 20
  350. +#define MT7621_CLK_UART3 21
  351. +#define MT7621_CLK_ETH 22
  352. +#define MT7621_CLK_PCIE0 23
  353. +#define MT7621_CLK_PCIE1 24
  354. +#define MT7621_CLK_PCIE2 25
  355. +#define MT7621_CLK_CRYPTO 26
  356. +#define MT7621_CLK_SHXC 27
  357. +
  358. +#define MT7621_CLK_MAX 28
  359. +
  360. +/* for u-boot only */
  361. +#define MT7621_CLK_DDR 29
  362. +
  363. +#endif /* _DT_BINDINGS_MT7621_CLK_H_ */