dpll.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. * OMAP DPLL clock support
  3. *
  4. * Copyright (C) 2013 Texas Instruments, Inc.
  5. *
  6. * Tero Kristo <t-kristo@ti.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13. * kind, whether express or implied; without even the implied warranty
  14. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/clk-provider.h>
  18. #include <linux/slab.h>
  19. #include <linux/err.h>
  20. #include <linux/of.h>
  21. #include <linux/of_address.h>
  22. #include <linux/clk/ti.h>
  23. #undef pr_fmt
  24. #define pr_fmt(fmt) "%s: " fmt, __func__
  25. #define DPLL_HAS_AUTOIDLE 0x1
  26. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  27. defined(CONFIG_SOC_DRA7XX)
  28. static const struct clk_ops dpll_m4xen_ck_ops = {
  29. .enable = &omap3_noncore_dpll_enable,
  30. .disable = &omap3_noncore_dpll_disable,
  31. .recalc_rate = &omap4_dpll_regm4xen_recalc,
  32. .round_rate = &omap4_dpll_regm4xen_round_rate,
  33. .set_rate = &omap3_noncore_dpll_set_rate,
  34. .get_parent = &omap2_init_dpll_parent,
  35. };
  36. #endif
  37. static const struct clk_ops dpll_core_ck_ops = {
  38. .recalc_rate = &omap3_dpll_recalc,
  39. .get_parent = &omap2_init_dpll_parent,
  40. };
  41. #ifdef CONFIG_ARCH_OMAP3
  42. static const struct clk_ops omap3_dpll_core_ck_ops = {
  43. .get_parent = &omap2_init_dpll_parent,
  44. .recalc_rate = &omap3_dpll_recalc,
  45. .round_rate = &omap2_dpll_round_rate,
  46. };
  47. #endif
  48. static const struct clk_ops dpll_ck_ops = {
  49. .enable = &omap3_noncore_dpll_enable,
  50. .disable = &omap3_noncore_dpll_disable,
  51. .recalc_rate = &omap3_dpll_recalc,
  52. .round_rate = &omap2_dpll_round_rate,
  53. .set_rate = &omap3_noncore_dpll_set_rate,
  54. .get_parent = &omap2_init_dpll_parent,
  55. };
  56. static const struct clk_ops dpll_no_gate_ck_ops = {
  57. .recalc_rate = &omap3_dpll_recalc,
  58. .get_parent = &omap2_init_dpll_parent,
  59. .round_rate = &omap2_dpll_round_rate,
  60. .set_rate = &omap3_noncore_dpll_set_rate,
  61. };
  62. #ifdef CONFIG_ARCH_OMAP3
  63. static const struct clk_ops omap3_dpll_ck_ops = {
  64. .enable = &omap3_noncore_dpll_enable,
  65. .disable = &omap3_noncore_dpll_disable,
  66. .get_parent = &omap2_init_dpll_parent,
  67. .recalc_rate = &omap3_dpll_recalc,
  68. .set_rate = &omap3_noncore_dpll_set_rate,
  69. .round_rate = &omap2_dpll_round_rate,
  70. };
  71. static const struct clk_ops omap3_dpll_per_ck_ops = {
  72. .enable = &omap3_noncore_dpll_enable,
  73. .disable = &omap3_noncore_dpll_disable,
  74. .get_parent = &omap2_init_dpll_parent,
  75. .recalc_rate = &omap3_dpll_recalc,
  76. .set_rate = &omap3_dpll4_set_rate,
  77. .round_rate = &omap2_dpll_round_rate,
  78. };
  79. #endif
  80. static const struct clk_ops dpll_x2_ck_ops = {
  81. .recalc_rate = &omap3_clkoutx2_recalc,
  82. };
  83. /**
  84. * ti_clk_register_dpll - low level registration of a DPLL clock
  85. * @hw: hardware clock definition for the clock
  86. * @node: device node for the clock
  87. *
  88. * Finalizes DPLL registration process. In case a failure (clk-ref or
  89. * clk-bypass is missing), the clock is added to retry list and
  90. * the initialization is retried on later stage.
  91. */
  92. static void __init ti_clk_register_dpll(struct clk_hw *hw,
  93. struct device_node *node)
  94. {
  95. struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
  96. struct dpll_data *dd = clk_hw->dpll_data;
  97. struct clk *clk;
  98. dd->clk_ref = of_clk_get(node, 0);
  99. dd->clk_bypass = of_clk_get(node, 1);
  100. if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
  101. pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
  102. node->name);
  103. if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll))
  104. return;
  105. goto cleanup;
  106. }
  107. /* register the clock */
  108. clk = clk_register(NULL, &clk_hw->hw);
  109. if (!IS_ERR(clk)) {
  110. omap2_init_clk_hw_omap_clocks(clk);
  111. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  112. kfree(clk_hw->hw.init->parent_names);
  113. kfree(clk_hw->hw.init);
  114. return;
  115. }
  116. cleanup:
  117. kfree(clk_hw->dpll_data);
  118. kfree(clk_hw->hw.init->parent_names);
  119. kfree(clk_hw->hw.init);
  120. kfree(clk_hw);
  121. }
  122. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  123. defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX)
  124. /**
  125. * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
  126. * @node: device node for this clock
  127. * @ops: clk_ops for this clock
  128. * @hw_ops: clk_hw_ops for this clock
  129. *
  130. * Initializes a DPLL x 2 clock from device tree data.
  131. */
  132. static void ti_clk_register_dpll_x2(struct device_node *node,
  133. const struct clk_ops *ops,
  134. const struct clk_hw_omap_ops *hw_ops)
  135. {
  136. struct clk *clk;
  137. struct clk_init_data init = { NULL };
  138. struct clk_hw_omap *clk_hw;
  139. const char *name = node->name;
  140. const char *parent_name;
  141. parent_name = of_clk_get_parent_name(node, 0);
  142. if (!parent_name) {
  143. pr_err("%s must have parent\n", node->name);
  144. return;
  145. }
  146. clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
  147. if (!clk_hw)
  148. return;
  149. clk_hw->ops = hw_ops;
  150. clk_hw->hw.init = &init;
  151. init.name = name;
  152. init.ops = ops;
  153. init.parent_names = &parent_name;
  154. init.num_parents = 1;
  155. /* register the clock */
  156. clk = clk_register(NULL, &clk_hw->hw);
  157. if (IS_ERR(clk)) {
  158. kfree(clk_hw);
  159. } else {
  160. omap2_init_clk_hw_omap_clocks(clk);
  161. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  162. }
  163. }
  164. #endif
  165. /**
  166. * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
  167. * @node: device node containing the DPLL info
  168. * @ops: ops for the DPLL
  169. * @ddt: DPLL data template to use
  170. * @init_flags: flags for controlling init types
  171. *
  172. * Initializes a DPLL clock from device tree data.
  173. */
  174. static void __init of_ti_dpll_setup(struct device_node *node,
  175. const struct clk_ops *ops,
  176. const struct dpll_data *ddt,
  177. u8 init_flags)
  178. {
  179. struct clk_hw_omap *clk_hw = NULL;
  180. struct clk_init_data *init = NULL;
  181. const char **parent_names = NULL;
  182. struct dpll_data *dd = NULL;
  183. int i;
  184. u8 dpll_mode = 0;
  185. dd = kzalloc(sizeof(*dd), GFP_KERNEL);
  186. clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
  187. init = kzalloc(sizeof(*init), GFP_KERNEL);
  188. if (!dd || !clk_hw || !init)
  189. goto cleanup;
  190. memcpy(dd, ddt, sizeof(*dd));
  191. clk_hw->dpll_data = dd;
  192. clk_hw->ops = &clkhwops_omap3_dpll;
  193. clk_hw->hw.init = init;
  194. clk_hw->flags = MEMMAP_ADDRESSING;
  195. init->name = node->name;
  196. init->ops = ops;
  197. init->num_parents = of_clk_get_parent_count(node);
  198. if (init->num_parents < 1) {
  199. pr_err("%s must have parent(s)\n", node->name);
  200. goto cleanup;
  201. }
  202. parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);
  203. if (!parent_names)
  204. goto cleanup;
  205. for (i = 0; i < init->num_parents; i++)
  206. parent_names[i] = of_clk_get_parent_name(node, i);
  207. init->parent_names = parent_names;
  208. dd->control_reg = ti_clk_get_reg_addr(node, 0);
  209. dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
  210. dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
  211. if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg)
  212. goto cleanup;
  213. if (init_flags & DPLL_HAS_AUTOIDLE) {
  214. dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
  215. if (!dd->autoidle_reg)
  216. goto cleanup;
  217. }
  218. if (of_property_read_bool(node, "ti,low-power-stop"))
  219. dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
  220. if (of_property_read_bool(node, "ti,low-power-bypass"))
  221. dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
  222. if (of_property_read_bool(node, "ti,lock"))
  223. dpll_mode |= 1 << DPLL_LOCKED;
  224. if (dpll_mode)
  225. dd->modes = dpll_mode;
  226. ti_clk_register_dpll(&clk_hw->hw, node);
  227. return;
  228. cleanup:
  229. kfree(dd);
  230. kfree(parent_names);
  231. kfree(init);
  232. kfree(clk_hw);
  233. }
  234. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  235. defined(CONFIG_SOC_DRA7XX)
  236. static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
  237. {
  238. ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
  239. }
  240. CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
  241. of_ti_omap4_dpll_x2_setup);
  242. #endif
  243. #ifdef CONFIG_SOC_AM33XX
  244. static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
  245. {
  246. ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
  247. }
  248. CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
  249. of_ti_am3_dpll_x2_setup);
  250. #endif
  251. #ifdef CONFIG_ARCH_OMAP3
  252. static void __init of_ti_omap3_dpll_setup(struct device_node *node)
  253. {
  254. const struct dpll_data dd = {
  255. .idlest_mask = 0x1,
  256. .enable_mask = 0x7,
  257. .autoidle_mask = 0x7,
  258. .mult_mask = 0x7ff << 8,
  259. .div1_mask = 0x7f,
  260. .max_multiplier = 2047,
  261. .max_divider = 128,
  262. .min_divider = 1,
  263. .freqsel_mask = 0xf0,
  264. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  265. };
  266. of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  267. }
  268. CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
  269. of_ti_omap3_dpll_setup);
  270. static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
  271. {
  272. const struct dpll_data dd = {
  273. .idlest_mask = 0x1,
  274. .enable_mask = 0x7,
  275. .autoidle_mask = 0x7,
  276. .mult_mask = 0x7ff << 16,
  277. .div1_mask = 0x7f << 8,
  278. .max_multiplier = 2047,
  279. .max_divider = 128,
  280. .min_divider = 1,
  281. .freqsel_mask = 0xf0,
  282. };
  283. of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  284. }
  285. CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
  286. of_ti_omap3_core_dpll_setup);
  287. static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
  288. {
  289. const struct dpll_data dd = {
  290. .idlest_mask = 0x1 << 1,
  291. .enable_mask = 0x7 << 16,
  292. .autoidle_mask = 0x7 << 3,
  293. .mult_mask = 0x7ff << 8,
  294. .div1_mask = 0x7f,
  295. .max_multiplier = 2047,
  296. .max_divider = 128,
  297. .min_divider = 1,
  298. .freqsel_mask = 0xf00000,
  299. .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
  300. };
  301. of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  302. }
  303. CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
  304. of_ti_omap3_per_dpll_setup);
  305. static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
  306. {
  307. const struct dpll_data dd = {
  308. .idlest_mask = 0x1 << 1,
  309. .enable_mask = 0x7 << 16,
  310. .autoidle_mask = 0x7 << 3,
  311. .mult_mask = 0xfff << 8,
  312. .div1_mask = 0x7f,
  313. .max_multiplier = 4095,
  314. .max_divider = 128,
  315. .min_divider = 1,
  316. .sddiv_mask = 0xff << 24,
  317. .dco_mask = 0xe << 20,
  318. .flags = DPLL_J_TYPE,
  319. .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
  320. };
  321. of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  322. }
  323. CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
  324. of_ti_omap3_per_jtype_dpll_setup);
  325. #endif
  326. static void __init of_ti_omap4_dpll_setup(struct device_node *node)
  327. {
  328. const struct dpll_data dd = {
  329. .idlest_mask = 0x1,
  330. .enable_mask = 0x7,
  331. .autoidle_mask = 0x7,
  332. .mult_mask = 0x7ff << 8,
  333. .div1_mask = 0x7f,
  334. .max_multiplier = 2047,
  335. .max_divider = 128,
  336. .min_divider = 1,
  337. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  338. };
  339. of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  340. }
  341. CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
  342. of_ti_omap4_dpll_setup);
  343. static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
  344. {
  345. const struct dpll_data dd = {
  346. .idlest_mask = 0x1,
  347. .enable_mask = 0x7,
  348. .autoidle_mask = 0x7,
  349. .mult_mask = 0x7ff << 8,
  350. .div1_mask = 0x7f,
  351. .max_multiplier = 2047,
  352. .max_divider = 128,
  353. .min_divider = 1,
  354. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  355. };
  356. of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  357. }
  358. CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
  359. of_ti_omap4_core_dpll_setup);
  360. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  361. defined(CONFIG_SOC_DRA7XX)
  362. static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
  363. {
  364. const struct dpll_data dd = {
  365. .idlest_mask = 0x1,
  366. .enable_mask = 0x7,
  367. .autoidle_mask = 0x7,
  368. .mult_mask = 0x7ff << 8,
  369. .div1_mask = 0x7f,
  370. .max_multiplier = 2047,
  371. .max_divider = 128,
  372. .min_divider = 1,
  373. .m4xen_mask = 0x800,
  374. .lpmode_mask = 1 << 10,
  375. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  376. };
  377. of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  378. }
  379. CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
  380. of_ti_omap4_m4xen_dpll_setup);
  381. static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
  382. {
  383. const struct dpll_data dd = {
  384. .idlest_mask = 0x1,
  385. .enable_mask = 0x7,
  386. .autoidle_mask = 0x7,
  387. .mult_mask = 0xfff << 8,
  388. .div1_mask = 0xff,
  389. .max_multiplier = 4095,
  390. .max_divider = 256,
  391. .min_divider = 1,
  392. .sddiv_mask = 0xff << 24,
  393. .flags = DPLL_J_TYPE,
  394. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  395. };
  396. of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
  397. }
  398. CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
  399. of_ti_omap4_jtype_dpll_setup);
  400. #endif
  401. static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
  402. {
  403. const struct dpll_data dd = {
  404. .idlest_mask = 0x1,
  405. .enable_mask = 0x7,
  406. .autoidle_mask = 0x7,
  407. .mult_mask = 0x7ff << 8,
  408. .div1_mask = 0x7f,
  409. .max_multiplier = 2047,
  410. .max_divider = 128,
  411. .min_divider = 1,
  412. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  413. };
  414. of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0);
  415. }
  416. CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
  417. of_ti_am3_no_gate_dpll_setup);
  418. static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
  419. {
  420. const struct dpll_data dd = {
  421. .idlest_mask = 0x1,
  422. .enable_mask = 0x7,
  423. .autoidle_mask = 0x7,
  424. .mult_mask = 0x7ff << 8,
  425. .div1_mask = 0x7f,
  426. .max_multiplier = 4095,
  427. .max_divider = 256,
  428. .min_divider = 2,
  429. .flags = DPLL_J_TYPE,
  430. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  431. };
  432. of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0);
  433. }
  434. CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
  435. of_ti_am3_jtype_dpll_setup);
  436. static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
  437. {
  438. const struct dpll_data dd = {
  439. .idlest_mask = 0x1,
  440. .enable_mask = 0x7,
  441. .autoidle_mask = 0x7,
  442. .mult_mask = 0x7ff << 8,
  443. .div1_mask = 0x7f,
  444. .max_multiplier = 2047,
  445. .max_divider = 128,
  446. .min_divider = 1,
  447. .flags = DPLL_J_TYPE,
  448. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  449. };
  450. of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0);
  451. }
  452. CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
  453. "ti,am3-dpll-no-gate-j-type-clock",
  454. of_ti_am3_no_gate_jtype_dpll_setup);
  455. static void __init of_ti_am3_dpll_setup(struct device_node *node)
  456. {
  457. const struct dpll_data dd = {
  458. .idlest_mask = 0x1,
  459. .enable_mask = 0x7,
  460. .autoidle_mask = 0x7,
  461. .mult_mask = 0x7ff << 8,
  462. .div1_mask = 0x7f,
  463. .max_multiplier = 2047,
  464. .max_divider = 128,
  465. .min_divider = 1,
  466. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  467. };
  468. of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0);
  469. }
  470. CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
  471. static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
  472. {
  473. const struct dpll_data dd = {
  474. .idlest_mask = 0x1,
  475. .enable_mask = 0x7,
  476. .autoidle_mask = 0x7,
  477. .mult_mask = 0x7ff << 8,
  478. .div1_mask = 0x7f,
  479. .max_multiplier = 2047,
  480. .max_divider = 128,
  481. .min_divider = 1,
  482. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  483. };
  484. of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0);
  485. }
  486. CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
  487. of_ti_am3_core_dpll_setup);