clk.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /*
  2. * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
  3. * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <errno.h>
  9. #include <clk.h>
  10. #include <asm/io.h>
  11. #include <asm/arch/hardware.h>
  12. #include <asm/arch/clk.h>
  13. /* Board oscillator frequency */
  14. #ifndef CONFIG_ZYNQ_PS_CLK_FREQ
  15. # define CONFIG_ZYNQ_PS_CLK_FREQ 33333333UL
  16. #endif
  17. /* Register bitfield defines */
  18. #define PLLCTRL_FBDIV_MASK 0x7f000
  19. #define PLLCTRL_FBDIV_SHIFT 12
  20. #define PLLCTRL_BPFORCE_MASK (1 << 4)
  21. #define PLLCTRL_PWRDWN_MASK 2
  22. #define PLLCTRL_PWRDWN_SHIFT 1
  23. #define PLLCTRL_RESET_MASK 1
  24. #define PLLCTRL_RESET_SHIFT 0
  25. #define ZYNQ_CLK_MAXDIV 0x3f
  26. #define CLK_CTRL_DIV1_SHIFT 20
  27. #define CLK_CTRL_DIV1_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
  28. #define CLK_CTRL_DIV0_SHIFT 8
  29. #define CLK_CTRL_DIV0_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
  30. #define CLK_CTRL_SRCSEL_SHIFT 4
  31. #define CLK_CTRL_SRCSEL_MASK (0x3 << CLK_CTRL_SRCSEL_SHIFT)
  32. #define CLK_CTRL_DIV2X_SHIFT 26
  33. #define CLK_CTRL_DIV2X_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
  34. #define CLK_CTRL_DIV3X_SHIFT 20
  35. #define CLK_CTRL_DIV3X_MASK (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
  36. #define ZYNQ_CLKMUX_SEL_0 0
  37. #define ZYNQ_CLKMUX_SEL_1 1
  38. #define ZYNQ_CLKMUX_SEL_2 2
  39. #define ZYNQ_CLKMUX_SEL_3 3
  40. DECLARE_GLOBAL_DATA_PTR;
  41. struct clk;
  42. /**
  43. * struct clk_ops:
  44. * @set_rate: Function pointer to set_rate() implementation
  45. * @get_rate: Function pointer to get_rate() implementation
  46. */
  47. struct clk_ops {
  48. int (*set_rate)(struct clk *clk, unsigned long rate);
  49. unsigned long (*get_rate)(struct clk *clk);
  50. };
  51. /**
  52. * struct clk:
  53. * @name: Clock name
  54. * @frequency: Currenct frequency
  55. * @parent: Parent clock
  56. * @flags: Clock flags
  57. * @reg: Clock control register
  58. * @ops: Clock operations
  59. */
  60. struct clk {
  61. char *name;
  62. unsigned long frequency;
  63. enum zynq_clk parent;
  64. unsigned int flags;
  65. u32 *reg;
  66. struct clk_ops ops;
  67. };
  68. #define ZYNQ_CLK_FLAGS_HAS_2_DIVS 1
  69. static struct clk clks[clk_max];
  70. /**
  71. * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
  72. * @srcsel: Mux select value
  73. * Returns the clock identifier associated with the selected mux input.
  74. */
  75. static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
  76. {
  77. unsigned int ret;
  78. switch (srcsel) {
  79. case ZYNQ_CLKMUX_SEL_0:
  80. case ZYNQ_CLKMUX_SEL_1:
  81. ret = armpll_clk;
  82. break;
  83. case ZYNQ_CLKMUX_SEL_2:
  84. ret = ddrpll_clk;
  85. break;
  86. case ZYNQ_CLKMUX_SEL_3:
  87. ret = iopll_clk;
  88. break;
  89. default:
  90. ret = armpll_clk;
  91. break;
  92. }
  93. return ret;
  94. }
  95. /**
  96. * ddr2x_get_rate() - Get clock rate of DDR2x clock
  97. * @clk: Clock handle
  98. * Returns the current clock rate of @clk.
  99. */
  100. static unsigned long ddr2x_get_rate(struct clk *clk)
  101. {
  102. u32 clk_ctrl = readl(clk->reg);
  103. u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
  104. return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
  105. }
  106. /**
  107. * ddr3x_get_rate() - Get clock rate of DDR3x clock
  108. * @clk: Clock handle
  109. * Returns the current clock rate of @clk.
  110. */
  111. static unsigned long ddr3x_get_rate(struct clk *clk)
  112. {
  113. u32 clk_ctrl = readl(clk->reg);
  114. u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
  115. return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
  116. }
  117. static void init_ddr_clocks(void)
  118. {
  119. u32 div0, div1;
  120. unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
  121. u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
  122. /* DDR2x */
  123. clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
  124. clks[ddr2x_clk].parent = ddrpll_clk;
  125. clks[ddr2x_clk].name = "ddr_2x";
  126. clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
  127. clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
  128. /* DDR3x */
  129. clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
  130. clks[ddr3x_clk].parent = ddrpll_clk;
  131. clks[ddr3x_clk].name = "ddr_3x";
  132. clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
  133. clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
  134. /* DCI */
  135. clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
  136. div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
  137. div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
  138. clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
  139. clks[dci_clk].parent = ddrpll_clk;
  140. clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
  141. DIV_ROUND_CLOSEST(prate, div0), div1);
  142. clks[dci_clk].name = "dci";
  143. gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
  144. }
  145. static void init_cpu_clocks(void)
  146. {
  147. int clk_621;
  148. u32 reg, div, srcsel;
  149. enum zynq_clk parent;
  150. reg = readl(&slcr_base->arm_clk_ctrl);
  151. clk_621 = readl(&slcr_base->clk_621_true) & 1;
  152. div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
  153. srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
  154. parent = __zynq_clk_cpu_get_parent(srcsel);
  155. /* cpu clocks */
  156. clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
  157. clks[cpu_6or4x_clk].parent = parent;
  158. clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
  159. zynq_clk_get_rate(parent), div);
  160. clks[cpu_6or4x_clk].name = "cpu_6or4x";
  161. clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
  162. clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
  163. clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
  164. clks[cpu_3or2x_clk].name = "cpu_3or2x";
  165. clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
  166. clks[cpu_2x_clk].parent = cpu_6or4x_clk;
  167. clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
  168. (2 + clk_621);
  169. clks[cpu_2x_clk].name = "cpu_2x";
  170. clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
  171. clks[cpu_1x_clk].parent = cpu_6or4x_clk;
  172. clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
  173. (4 + 2 * clk_621);
  174. clks[cpu_1x_clk].name = "cpu_1x";
  175. }
  176. /**
  177. * periph_calc_two_divs() - Calculate clock dividers
  178. * @cur_rate: Current clock rate
  179. * @tgt_rate: Target clock rate
  180. * @prate: Parent clock rate
  181. * @div0: First divider (output)
  182. * @div1: Second divider (output)
  183. * Returns the actual clock rate possible.
  184. *
  185. * Calculates clock dividers for clocks with two 6-bit dividers.
  186. */
  187. static unsigned long periph_calc_two_divs(unsigned long cur_rate,
  188. unsigned long tgt_rate, unsigned long prate, u32 *div0,
  189. u32 *div1)
  190. {
  191. long err, best_err = (long)(~0UL >> 1);
  192. unsigned long rate, best_rate = 0;
  193. u32 d0, d1;
  194. for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
  195. for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
  196. rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
  197. d1);
  198. err = abs(rate - tgt_rate);
  199. if (err < best_err) {
  200. *div0 = d0;
  201. *div1 = d1;
  202. best_err = err;
  203. best_rate = rate;
  204. }
  205. }
  206. }
  207. return best_rate;
  208. }
  209. /**
  210. * zynq_clk_periph_set_rate() - Set clock rate
  211. * @clk: Handle of the peripheral clock
  212. * @rate: New clock rate
  213. * Sets the clock frequency of @clk to @rate. Returns zero on success.
  214. */
  215. static int zynq_clk_periph_set_rate(struct clk *clk,
  216. unsigned long rate)
  217. {
  218. u32 ctrl, div0 = 0, div1 = 0;
  219. unsigned long prate, new_rate, cur_rate = clk->frequency;
  220. ctrl = readl(clk->reg);
  221. prate = zynq_clk_get_rate(clk->parent);
  222. ctrl &= ~CLK_CTRL_DIV0_MASK;
  223. if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
  224. ctrl &= ~CLK_CTRL_DIV1_MASK;
  225. new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
  226. &div1);
  227. ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
  228. } else {
  229. div0 = DIV_ROUND_CLOSEST(prate, rate);
  230. div0 &= ZYNQ_CLK_MAXDIV;
  231. new_rate = DIV_ROUND_CLOSEST(rate, div0);
  232. }
  233. /* write new divs to hardware */
  234. ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
  235. writel(ctrl, clk->reg);
  236. /* update frequency in clk framework */
  237. clk->frequency = new_rate;
  238. return 0;
  239. }
  240. /**
  241. * zynq_clk_periph_get_rate() - Get clock rate
  242. * @clk: Handle of the peripheral clock
  243. * Returns the current clock rate of @clk.
  244. */
  245. static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
  246. {
  247. u32 clk_ctrl = readl(clk->reg);
  248. u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
  249. u32 div1 = 1;
  250. if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
  251. div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
  252. /* a register value of zero == division by 1 */
  253. if (!div0)
  254. div0 = 1;
  255. if (!div1)
  256. div1 = 1;
  257. return
  258. DIV_ROUND_CLOSEST(
  259. DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
  260. div1);
  261. }
  262. /**
  263. * __zynq_clk_periph_get_parent() - Decode clock multiplexer
  264. * @srcsel: Mux select value
  265. * Returns the clock identifier associated with the selected mux input.
  266. */
  267. static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
  268. {
  269. switch (srcsel) {
  270. case ZYNQ_CLKMUX_SEL_0:
  271. case ZYNQ_CLKMUX_SEL_1:
  272. return iopll_clk;
  273. case ZYNQ_CLKMUX_SEL_2:
  274. return armpll_clk;
  275. case ZYNQ_CLKMUX_SEL_3:
  276. return ddrpll_clk;
  277. default:
  278. return 0;
  279. }
  280. }
  281. /**
  282. * zynq_clk_periph_get_parent() - Decode clock multiplexer
  283. * @clk: Clock handle
  284. * Returns the clock identifier associated with the selected mux input.
  285. */
  286. static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
  287. {
  288. u32 clk_ctrl = readl(clk->reg);
  289. u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
  290. return __zynq_clk_periph_get_parent(srcsel);
  291. }
  292. /**
  293. * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
  294. * @clk: Pointer to struct clk for the clock
  295. * @ctrl: Clock control register
  296. * @name: PLL name
  297. * @two_divs: Indicates whether the clock features one or two dividers
  298. */
  299. static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
  300. bool two_divs)
  301. {
  302. clk->name = name;
  303. clk->reg = ctrl;
  304. if (two_divs)
  305. clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
  306. clk->parent = zynq_clk_periph_get_parent(clk);
  307. clk->frequency = zynq_clk_periph_get_rate(clk);
  308. clk->ops.get_rate = zynq_clk_periph_get_rate;
  309. clk->ops.set_rate = zynq_clk_periph_set_rate;
  310. return 0;
  311. }
  312. static void init_periph_clocks(void)
  313. {
  314. zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
  315. "gem0", 1);
  316. zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
  317. "gem1", 1);
  318. zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
  319. "smc", 0);
  320. zynq_clk_register_periph_clk(&clks[lqspi_clk],
  321. &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
  322. zynq_clk_register_periph_clk(&clks[sdio0_clk],
  323. &slcr_base->sdio_clk_ctrl, "sdio0", 0);
  324. zynq_clk_register_periph_clk(&clks[sdio1_clk],
  325. &slcr_base->sdio_clk_ctrl, "sdio1", 0);
  326. zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
  327. "spi0", 0);
  328. zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
  329. "spi1", 0);
  330. zynq_clk_register_periph_clk(&clks[uart0_clk],
  331. &slcr_base->uart_clk_ctrl, "uart0", 0);
  332. zynq_clk_register_periph_clk(&clks[uart1_clk],
  333. &slcr_base->uart_clk_ctrl, "uart1", 0);
  334. zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
  335. &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
  336. zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
  337. &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
  338. zynq_clk_register_periph_clk(&clks[pcap_clk],
  339. &slcr_base->pcap_clk_ctrl, "pcap", 0);
  340. zynq_clk_register_periph_clk(&clks[fclk0_clk],
  341. &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
  342. zynq_clk_register_periph_clk(&clks[fclk1_clk],
  343. &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
  344. zynq_clk_register_periph_clk(&clks[fclk2_clk],
  345. &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
  346. zynq_clk_register_periph_clk(&clks[fclk3_clk],
  347. &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
  348. }
  349. /**
  350. * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
  351. * @clk: Pointer to struct clk for the clock
  352. * @ctrl: Clock control register
  353. * @name: PLL name
  354. */
  355. static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
  356. {
  357. clk->name = name;
  358. clk->reg = ctrl;
  359. clk->parent = cpu_1x_clk;
  360. clk->frequency = zynq_clk_get_rate(clk->parent);
  361. }
  362. static void init_aper_clocks(void)
  363. {
  364. zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
  365. &slcr_base->aper_clk_ctrl, "usb0_aper");
  366. zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
  367. &slcr_base->aper_clk_ctrl, "usb1_aper");
  368. zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
  369. &slcr_base->aper_clk_ctrl, "gem0_aper");
  370. zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
  371. &slcr_base->aper_clk_ctrl, "gem1_aper");
  372. zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
  373. &slcr_base->aper_clk_ctrl, "sdio0_aper");
  374. zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
  375. &slcr_base->aper_clk_ctrl, "sdio1_aper");
  376. zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
  377. &slcr_base->aper_clk_ctrl, "spi0_aper");
  378. zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
  379. &slcr_base->aper_clk_ctrl, "spi1_aper");
  380. zynq_clk_register_aper_clk(&clks[can0_aper_clk],
  381. &slcr_base->aper_clk_ctrl, "can0_aper");
  382. zynq_clk_register_aper_clk(&clks[can1_aper_clk],
  383. &slcr_base->aper_clk_ctrl, "can1_aper");
  384. zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
  385. &slcr_base->aper_clk_ctrl, "i2c0_aper");
  386. zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
  387. &slcr_base->aper_clk_ctrl, "i2c1_aper");
  388. zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
  389. &slcr_base->aper_clk_ctrl, "uart0_aper");
  390. zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
  391. &slcr_base->aper_clk_ctrl, "uart1_aper");
  392. zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
  393. &slcr_base->aper_clk_ctrl, "gpio_aper");
  394. zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
  395. &slcr_base->aper_clk_ctrl, "lqspi_aper");
  396. zynq_clk_register_aper_clk(&clks[smc_aper_clk],
  397. &slcr_base->aper_clk_ctrl, "smc_aper");
  398. }
  399. /**
  400. * __zynq_clk_pll_get_rate() - Get PLL rate
  401. * @addr: Address of the PLL's control register
  402. * Returns the current PLL output rate.
  403. */
  404. static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
  405. {
  406. u32 reg, mul, bypass;
  407. reg = readl(addr);
  408. bypass = reg & PLLCTRL_BPFORCE_MASK;
  409. if (bypass)
  410. mul = 1;
  411. else
  412. mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
  413. return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
  414. }
  415. /**
  416. * zynq_clk_pll_get_rate() - Get PLL rate
  417. * @pll: Handle of the PLL
  418. * Returns the current clock rate of @pll.
  419. */
  420. static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
  421. {
  422. return __zynq_clk_pll_get_rate(pll->reg);
  423. }
  424. /**
  425. * zynq_clk_register_pll() - Set up a PLL with the framework
  426. * @clk: Pointer to struct clk for the PLL
  427. * @ctrl: PLL control register
  428. * @name: PLL name
  429. * @prate: PLL input clock rate
  430. */
  431. static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
  432. unsigned long prate)
  433. {
  434. clk->name = name;
  435. clk->reg = ctrl;
  436. clk->frequency = zynq_clk_pll_get_rate(clk);
  437. clk->ops.get_rate = zynq_clk_pll_get_rate;
  438. }
  439. /**
  440. * clkid_2_register() - Get clock control register
  441. * @id: Clock identifier of one of the PLLs
  442. * Returns the address of the requested PLL's control register.
  443. */
  444. static u32 *clkid_2_register(enum zynq_clk id)
  445. {
  446. switch (id) {
  447. case armpll_clk:
  448. return &slcr_base->arm_pll_ctrl;
  449. case ddrpll_clk:
  450. return &slcr_base->ddr_pll_ctrl;
  451. case iopll_clk:
  452. return &slcr_base->io_pll_ctrl;
  453. default:
  454. return &slcr_base->io_pll_ctrl;
  455. }
  456. }
  457. /* API */
  458. /**
  459. * zynq_clk_early_init() - Early init for the clock framework
  460. *
  461. * This function is called from before relocation and sets up the CPU clock
  462. * frequency in the global data struct.
  463. */
  464. void zynq_clk_early_init(void)
  465. {
  466. u32 reg = readl(&slcr_base->arm_clk_ctrl);
  467. u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
  468. u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
  469. enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
  470. u32 *pllreg = clkid_2_register(parent);
  471. unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
  472. if (!div)
  473. div = 1;
  474. gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
  475. }
  476. /**
  477. * get_uart_clk() - Get UART input frequency
  478. * @dev_index: UART ID
  479. * Returns UART input clock frequency in Hz.
  480. *
  481. * Compared to zynq_clk_get_rate() this function is designed to work before
  482. * relocation and can be called when the serial UART is set up.
  483. */
  484. unsigned long get_uart_clk(int dev_index)
  485. {
  486. u32 reg = readl(&slcr_base->uart_clk_ctrl);
  487. u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
  488. u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
  489. enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
  490. u32 *pllreg = clkid_2_register(parent);
  491. unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
  492. if (!div)
  493. div = 1;
  494. return DIV_ROUND_CLOSEST(prate, div);
  495. }
  496. /**
  497. * set_cpu_clk_info() - Initialize clock framework
  498. * Always returns zero.
  499. *
  500. * This function is called from common code after relocation and sets up the
  501. * clock framework. The framework must not be used before this function had been
  502. * called.
  503. */
  504. int set_cpu_clk_info(void)
  505. {
  506. zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
  507. "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
  508. zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
  509. "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
  510. zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
  511. "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
  512. init_ddr_clocks();
  513. init_cpu_clocks();
  514. init_periph_clocks();
  515. init_aper_clocks();
  516. gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
  517. gd->bd->bi_dsp_freq = 0;
  518. return 0;
  519. }
  520. /**
  521. * zynq_clk_get_rate() - Get clock rate
  522. * @clk: Clock identifier
  523. * Returns the current clock rate of @clk on success or zero for an invalid
  524. * clock id.
  525. */
  526. unsigned long zynq_clk_get_rate(enum zynq_clk clk)
  527. {
  528. if (clk < 0 || clk >= clk_max)
  529. return 0;
  530. return clks[clk].frequency;
  531. }
  532. /**
  533. * zynq_clk_set_rate() - Set clock rate
  534. * @clk: Clock identifier
  535. * @rate: Requested clock rate
  536. * Passes on the return value from the clock's set_rate() function or negative
  537. * errno.
  538. */
  539. int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
  540. {
  541. if (clk < 0 || clk >= clk_max)
  542. return -ENODEV;
  543. if (clks[clk].ops.set_rate)
  544. return clks[clk].ops.set_rate(&clks[clk], rate);
  545. return -ENXIO;
  546. }
  547. /**
  548. * zynq_clk_get_name() - Get clock name
  549. * @clk: Clock identifier
  550. * Returns the name of @clk.
  551. */
  552. const char *zynq_clk_get_name(enum zynq_clk clk)
  553. {
  554. return clks[clk].name;
  555. }
  556. /**
  557. * soc_clk_dump() - Print clock frequencies
  558. * Returns zero on success
  559. *
  560. * Implementation for the clk dump command.
  561. */
  562. int soc_clk_dump(void)
  563. {
  564. int i;
  565. printf("clk\t\tfrequency\n");
  566. for (i = 0; i < clk_max; i++) {
  567. const char *name = zynq_clk_get_name(i);
  568. if (name)
  569. printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
  570. }
  571. return 0;
  572. }