clk-arria10.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Marek Vasut <marex@denx.de>
  4. */
  5. #include <common.h>
  6. #include <asm/io.h>
  7. #include <clk-uclass.h>
  8. #include <dm.h>
  9. #include <dm/devres.h>
  10. #include <dm/lists.h>
  11. #include <dm/util.h>
  12. #include <asm/arch/clock_manager.h>
  13. enum socfpga_a10_clk_type {
  14. SOCFPGA_A10_CLK_MAIN_PLL,
  15. SOCFPGA_A10_CLK_PER_PLL,
  16. SOCFPGA_A10_CLK_PERIP_CLK,
  17. SOCFPGA_A10_CLK_GATE_CLK,
  18. SOCFPGA_A10_CLK_UNKNOWN_CLK,
  19. };
  20. struct socfpga_a10_clk_platdata {
  21. enum socfpga_a10_clk_type type;
  22. struct clk_bulk clks;
  23. u32 regs;
  24. /* Fixed divider */
  25. u16 fix_div;
  26. /* Control register */
  27. u16 ctl_reg;
  28. /* Divider register */
  29. u16 div_reg;
  30. u8 div_len;
  31. u8 div_off;
  32. /* Clock gating register */
  33. u16 gate_reg;
  34. u8 gate_bit;
  35. };
  36. static int socfpga_a10_clk_get_upstream(struct clk *clk, struct clk **upclk)
  37. {
  38. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
  39. u32 reg, maxval;
  40. if (plat->clks.count == 0)
  41. return 0;
  42. if (plat->clks.count == 1) {
  43. *upclk = &plat->clks.clks[0];
  44. return 0;
  45. }
  46. if (!plat->ctl_reg) {
  47. dev_err(clk->dev, "Invalid control register\n");
  48. return -EINVAL;
  49. }
  50. reg = readl(plat->regs + plat->ctl_reg);
  51. /* Assume PLLs are ON for now */
  52. if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
  53. reg = (reg >> 8) & 0x3;
  54. maxval = 2;
  55. } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
  56. reg = (reg >> 8) & 0x3;
  57. maxval = 3;
  58. } else {
  59. reg = (reg >> 16) & 0x7;
  60. maxval = 4;
  61. }
  62. if (reg > maxval) {
  63. dev_err(clk->dev, "Invalid clock source\n");
  64. return -EINVAL;
  65. }
  66. *upclk = &plat->clks.clks[reg];
  67. return 0;
  68. }
  69. static int socfpga_a10_clk_endisable(struct clk *clk, bool enable)
  70. {
  71. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
  72. struct clk *upclk = NULL;
  73. int ret;
  74. if (!enable && plat->gate_reg)
  75. clrbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
  76. ret = socfpga_a10_clk_get_upstream(clk, &upclk);
  77. if (ret)
  78. return ret;
  79. if (upclk) {
  80. if (enable)
  81. clk_enable(upclk);
  82. else
  83. clk_disable(upclk);
  84. }
  85. if (enable && plat->gate_reg)
  86. setbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
  87. return 0;
  88. }
  89. static int socfpga_a10_clk_enable(struct clk *clk)
  90. {
  91. return socfpga_a10_clk_endisable(clk, true);
  92. }
  93. static int socfpga_a10_clk_disable(struct clk *clk)
  94. {
  95. return socfpga_a10_clk_endisable(clk, false);
  96. }
  97. static ulong socfpga_a10_clk_get_rate(struct clk *clk)
  98. {
  99. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
  100. struct clk *upclk = NULL;
  101. ulong rate = 0, reg, numer, denom;
  102. int ret;
  103. ret = socfpga_a10_clk_get_upstream(clk, &upclk);
  104. if (ret || !upclk)
  105. return 0;
  106. rate = clk_get_rate(upclk);
  107. if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
  108. reg = readl(plat->regs + plat->ctl_reg + 4); /* VCO1 */
  109. numer = reg & CLKMGR_MAINPLL_VCO1_NUMER_MSK;
  110. denom = (reg >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) &
  111. CLKMGR_MAINPLL_VCO1_DENOM_MSK;
  112. rate /= denom + 1;
  113. rate *= numer + 1;
  114. } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
  115. reg = readl(plat->regs + plat->ctl_reg + 4); /* VCO1 */
  116. numer = reg & CLKMGR_PERPLL_VCO1_NUMER_MSK;
  117. denom = (reg >> CLKMGR_PERPLL_VCO1_DENOM_LSB) &
  118. CLKMGR_PERPLL_VCO1_DENOM_MSK;
  119. rate /= denom + 1;
  120. rate *= numer + 1;
  121. } else {
  122. rate /= plat->fix_div;
  123. if (plat->fix_div == 1 && plat->ctl_reg) {
  124. reg = readl(plat->regs + plat->ctl_reg);
  125. reg &= 0x7ff;
  126. rate /= reg + 1;
  127. }
  128. if (plat->div_reg) {
  129. reg = readl(plat->regs + plat->div_reg);
  130. reg >>= plat->div_off;
  131. reg &= (1 << plat->div_len) - 1;
  132. if (plat->type == SOCFPGA_A10_CLK_PERIP_CLK)
  133. rate /= reg + 1;
  134. if (plat->type == SOCFPGA_A10_CLK_GATE_CLK)
  135. rate /= 1 << reg;
  136. }
  137. }
  138. return rate;
  139. }
  140. static struct clk_ops socfpga_a10_clk_ops = {
  141. .enable = socfpga_a10_clk_enable,
  142. .disable = socfpga_a10_clk_disable,
  143. .get_rate = socfpga_a10_clk_get_rate,
  144. };
  145. /*
  146. * This workaround tries to fix the massively broken generated "handoff" DT,
  147. * which contains duplicate clock nodes without any connection to the clock
  148. * manager DT node. Yet, those "handoff" DT nodes contain configuration of
  149. * the fixed input clock of the Arria10 which are missing from the base DT
  150. * for Arria10.
  151. *
  152. * This workaround sets up upstream clock for the fixed input clocks of the
  153. * A10 described in the base DT such that they map to the fixed clock from
  154. * the "handoff" DT. This does not fully match how the clock look on the
  155. * A10, but it is the least intrusive way to fix this mess.
  156. */
  157. static void socfpga_a10_handoff_workaround(struct udevice *dev)
  158. {
  159. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
  160. const void *fdt = gd->fdt_blob;
  161. struct clk_bulk *bulk = &plat->clks;
  162. int i, ret, offset = dev_of_offset(dev);
  163. static const char * const socfpga_a10_fixedclk_map[] = {
  164. "osc1", "altera_arria10_hps_eosc1",
  165. "cb_intosc_ls_clk", "altera_arria10_hps_cb_intosc_ls",
  166. "f2s_free_clk", "altera_arria10_hps_f2h_free",
  167. };
  168. if (fdt_node_check_compatible(fdt, offset, "fixed-clock"))
  169. return;
  170. for (i = 0; i < ARRAY_SIZE(socfpga_a10_fixedclk_map); i += 2)
  171. if (!strcmp(dev->name, socfpga_a10_fixedclk_map[i]))
  172. break;
  173. if (i == ARRAY_SIZE(socfpga_a10_fixedclk_map))
  174. return;
  175. ret = uclass_get_device_by_name(UCLASS_CLK,
  176. socfpga_a10_fixedclk_map[i + 1], &dev);
  177. if (ret)
  178. return;
  179. bulk->count = 1;
  180. bulk->clks = devm_kcalloc(dev, bulk->count,
  181. sizeof(struct clk), GFP_KERNEL);
  182. if (!bulk->clks)
  183. return;
  184. ret = clk_request(dev, &bulk->clks[0]);
  185. if (ret)
  186. free(bulk->clks);
  187. }
  188. static int socfpga_a10_clk_bind(struct udevice *dev)
  189. {
  190. const void *fdt = gd->fdt_blob;
  191. int offset = dev_of_offset(dev);
  192. bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
  193. const char *name;
  194. int ret;
  195. for (offset = fdt_first_subnode(fdt, offset);
  196. offset > 0;
  197. offset = fdt_next_subnode(fdt, offset)) {
  198. name = fdt_get_name(fdt, offset, NULL);
  199. if (!name)
  200. return -EINVAL;
  201. if (!strcmp(name, "clocks")) {
  202. offset = fdt_first_subnode(fdt, offset);
  203. name = fdt_get_name(fdt, offset, NULL);
  204. if (!name)
  205. return -EINVAL;
  206. }
  207. /* Filter out supported sub-clock */
  208. if (fdt_node_check_compatible(fdt, offset,
  209. "altr,socfpga-a10-pll-clock") &&
  210. fdt_node_check_compatible(fdt, offset,
  211. "altr,socfpga-a10-perip-clk") &&
  212. fdt_node_check_compatible(fdt, offset,
  213. "altr,socfpga-a10-gate-clk") &&
  214. fdt_node_check_compatible(fdt, offset, "fixed-clock"))
  215. continue;
  216. if (pre_reloc_only &&
  217. !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
  218. continue;
  219. ret = device_bind_driver_to_node(dev, "clk-a10", name,
  220. offset_to_ofnode(offset),
  221. NULL);
  222. if (ret)
  223. return ret;
  224. }
  225. return 0;
  226. }
  227. static int socfpga_a10_clk_probe(struct udevice *dev)
  228. {
  229. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
  230. const void *fdt = gd->fdt_blob;
  231. int offset = dev_of_offset(dev);
  232. clk_get_bulk(dev, &plat->clks);
  233. socfpga_a10_handoff_workaround(dev);
  234. if (!fdt_node_check_compatible(fdt, offset,
  235. "altr,socfpga-a10-pll-clock")) {
  236. /* Main PLL has 3 upstream clock */
  237. if (plat->clks.count == 3)
  238. plat->type = SOCFPGA_A10_CLK_MAIN_PLL;
  239. else
  240. plat->type = SOCFPGA_A10_CLK_PER_PLL;
  241. } else if (!fdt_node_check_compatible(fdt, offset,
  242. "altr,socfpga-a10-perip-clk")) {
  243. plat->type = SOCFPGA_A10_CLK_PERIP_CLK;
  244. } else if (!fdt_node_check_compatible(fdt, offset,
  245. "altr,socfpga-a10-gate-clk")) {
  246. plat->type = SOCFPGA_A10_CLK_GATE_CLK;
  247. } else {
  248. plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
  249. }
  250. return 0;
  251. }
  252. static int socfpga_a10_ofdata_to_platdata(struct udevice *dev)
  253. {
  254. struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
  255. struct socfpga_a10_clk_platdata *pplat;
  256. struct udevice *pdev;
  257. const void *fdt = gd->fdt_blob;
  258. unsigned int divreg[3], gatereg[2];
  259. int ret, offset = dev_of_offset(dev);
  260. u32 regs;
  261. regs = dev_read_u32_default(dev, "reg", 0x0);
  262. if (!fdt_node_check_compatible(fdt, offset, "altr,clk-mgr")) {
  263. plat->regs = devfdt_get_addr(dev);
  264. } else {
  265. pdev = dev_get_parent(dev);
  266. if (!pdev)
  267. return -ENODEV;
  268. pplat = dev_get_platdata(pdev);
  269. if (!pplat)
  270. return -EINVAL;
  271. plat->ctl_reg = regs;
  272. plat->regs = pplat->regs;
  273. }
  274. plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
  275. plat->fix_div = dev_read_u32_default(dev, "fixed-divider", 1);
  276. ret = dev_read_u32_array(dev, "div-reg", divreg, ARRAY_SIZE(divreg));
  277. if (!ret) {
  278. plat->div_reg = divreg[0];
  279. plat->div_len = divreg[2];
  280. plat->div_off = divreg[1];
  281. }
  282. ret = dev_read_u32_array(dev, "clk-gate", gatereg, ARRAY_SIZE(gatereg));
  283. if (!ret) {
  284. plat->gate_reg = gatereg[0];
  285. plat->gate_bit = gatereg[1];
  286. }
  287. return 0;
  288. }
  289. static const struct udevice_id socfpga_a10_clk_match[] = {
  290. { .compatible = "altr,clk-mgr" },
  291. {}
  292. };
  293. U_BOOT_DRIVER(socfpga_a10_clk) = {
  294. .name = "clk-a10",
  295. .id = UCLASS_CLK,
  296. .of_match = socfpga_a10_clk_match,
  297. .ops = &socfpga_a10_clk_ops,
  298. .bind = socfpga_a10_clk_bind,
  299. .probe = socfpga_a10_clk_probe,
  300. .ofdata_to_platdata = socfpga_a10_ofdata_to_platdata,
  301. .platdata_auto_alloc_size = sizeof(struct socfpga_a10_clk_platdata),
  302. };