clk-arria10.c 8.9 KB

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