dpll.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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.h>
  18. #include <linux/clk-provider.h>
  19. #include <linux/slab.h>
  20. #include <linux/err.h>
  21. #include <linux/of.h>
  22. #include <linux/of_address.h>
  23. #include <linux/clk/ti.h>
  24. #include "clock.h"
  25. #undef pr_fmt
  26. #define pr_fmt(fmt) "%s: " fmt, __func__
  27. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  28. defined(CONFIG_SOC_DRA7XX)
  29. static const struct clk_ops dpll_m4xen_ck_ops = {
  30. .enable = &omap3_noncore_dpll_enable,
  31. .disable = &omap3_noncore_dpll_disable,
  32. .recalc_rate = &omap4_dpll_regm4xen_recalc,
  33. .round_rate = &omap4_dpll_regm4xen_round_rate,
  34. .set_rate = &omap3_noncore_dpll_set_rate,
  35. .set_parent = &omap3_noncore_dpll_set_parent,
  36. .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
  37. .determine_rate = &omap4_dpll_regm4xen_determine_rate,
  38. .get_parent = &omap2_init_dpll_parent,
  39. .save_context = &omap3_core_dpll_save_context,
  40. .restore_context = &omap3_core_dpll_restore_context,
  41. };
  42. #else
  43. static const struct clk_ops dpll_m4xen_ck_ops = {};
  44. #endif
  45. #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
  46. defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
  47. defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
  48. static const struct clk_ops dpll_core_ck_ops = {
  49. .recalc_rate = &omap3_dpll_recalc,
  50. .get_parent = &omap2_init_dpll_parent,
  51. };
  52. static const struct clk_ops dpll_ck_ops = {
  53. .enable = &omap3_noncore_dpll_enable,
  54. .disable = &omap3_noncore_dpll_disable,
  55. .recalc_rate = &omap3_dpll_recalc,
  56. .round_rate = &omap2_dpll_round_rate,
  57. .set_rate = &omap3_noncore_dpll_set_rate,
  58. .set_parent = &omap3_noncore_dpll_set_parent,
  59. .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
  60. .determine_rate = &omap3_noncore_dpll_determine_rate,
  61. .get_parent = &omap2_init_dpll_parent,
  62. .save_context = &omap3_noncore_dpll_save_context,
  63. .restore_context = &omap3_noncore_dpll_restore_context,
  64. };
  65. static const struct clk_ops dpll_no_gate_ck_ops = {
  66. .recalc_rate = &omap3_dpll_recalc,
  67. .get_parent = &omap2_init_dpll_parent,
  68. .round_rate = &omap2_dpll_round_rate,
  69. .set_rate = &omap3_noncore_dpll_set_rate,
  70. .set_parent = &omap3_noncore_dpll_set_parent,
  71. .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
  72. .determine_rate = &omap3_noncore_dpll_determine_rate,
  73. .save_context = &omap3_noncore_dpll_save_context,
  74. .restore_context = &omap3_noncore_dpll_restore_context
  75. };
  76. #else
  77. static const struct clk_ops dpll_core_ck_ops = {};
  78. static const struct clk_ops dpll_ck_ops = {};
  79. static const struct clk_ops dpll_no_gate_ck_ops = {};
  80. const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
  81. #endif
  82. #ifdef CONFIG_ARCH_OMAP2
  83. static const struct clk_ops omap2_dpll_core_ck_ops = {
  84. .get_parent = &omap2_init_dpll_parent,
  85. .recalc_rate = &omap2_dpllcore_recalc,
  86. .round_rate = &omap2_dpll_round_rate,
  87. .set_rate = &omap2_reprogram_dpllcore,
  88. };
  89. #else
  90. static const struct clk_ops omap2_dpll_core_ck_ops = {};
  91. #endif
  92. #ifdef CONFIG_ARCH_OMAP3
  93. static const struct clk_ops omap3_dpll_core_ck_ops = {
  94. .get_parent = &omap2_init_dpll_parent,
  95. .recalc_rate = &omap3_dpll_recalc,
  96. .round_rate = &omap2_dpll_round_rate,
  97. };
  98. #else
  99. static const struct clk_ops omap3_dpll_core_ck_ops = {};
  100. #endif
  101. #ifdef CONFIG_ARCH_OMAP3
  102. static const struct clk_ops omap3_dpll_ck_ops = {
  103. .enable = &omap3_noncore_dpll_enable,
  104. .disable = &omap3_noncore_dpll_disable,
  105. .get_parent = &omap2_init_dpll_parent,
  106. .recalc_rate = &omap3_dpll_recalc,
  107. .set_rate = &omap3_noncore_dpll_set_rate,
  108. .set_parent = &omap3_noncore_dpll_set_parent,
  109. .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
  110. .determine_rate = &omap3_noncore_dpll_determine_rate,
  111. .round_rate = &omap2_dpll_round_rate,
  112. };
  113. static const struct clk_ops omap3_dpll5_ck_ops = {
  114. .enable = &omap3_noncore_dpll_enable,
  115. .disable = &omap3_noncore_dpll_disable,
  116. .get_parent = &omap2_init_dpll_parent,
  117. .recalc_rate = &omap3_dpll_recalc,
  118. .set_rate = &omap3_dpll5_set_rate,
  119. .set_parent = &omap3_noncore_dpll_set_parent,
  120. .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
  121. .determine_rate = &omap3_noncore_dpll_determine_rate,
  122. .round_rate = &omap2_dpll_round_rate,
  123. };
  124. static const struct clk_ops omap3_dpll_per_ck_ops = {
  125. .enable = &omap3_noncore_dpll_enable,
  126. .disable = &omap3_noncore_dpll_disable,
  127. .get_parent = &omap2_init_dpll_parent,
  128. .recalc_rate = &omap3_dpll_recalc,
  129. .set_rate = &omap3_dpll4_set_rate,
  130. .set_parent = &omap3_noncore_dpll_set_parent,
  131. .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
  132. .determine_rate = &omap3_noncore_dpll_determine_rate,
  133. .round_rate = &omap2_dpll_round_rate,
  134. };
  135. #endif
  136. static const struct clk_ops dpll_x2_ck_ops = {
  137. .recalc_rate = &omap3_clkoutx2_recalc,
  138. };
  139. /**
  140. * _register_dpll - low level registration of a DPLL clock
  141. * @hw: hardware clock definition for the clock
  142. * @node: device node for the clock
  143. *
  144. * Finalizes DPLL registration process. In case a failure (clk-ref or
  145. * clk-bypass is missing), the clock is added to retry list and
  146. * the initialization is retried on later stage.
  147. */
  148. static void __init _register_dpll(void *user,
  149. struct device_node *node)
  150. {
  151. struct clk_hw *hw = user;
  152. struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
  153. struct dpll_data *dd = clk_hw->dpll_data;
  154. struct clk *clk;
  155. clk = of_clk_get(node, 0);
  156. if (IS_ERR(clk)) {
  157. pr_debug("clk-ref missing for %pOFn, retry later\n",
  158. node);
  159. if (!ti_clk_retry_init(node, hw, _register_dpll))
  160. return;
  161. goto cleanup;
  162. }
  163. dd->clk_ref = __clk_get_hw(clk);
  164. clk = of_clk_get(node, 1);
  165. if (IS_ERR(clk)) {
  166. pr_debug("clk-bypass missing for %pOFn, retry later\n",
  167. node);
  168. if (!ti_clk_retry_init(node, hw, _register_dpll))
  169. return;
  170. goto cleanup;
  171. }
  172. dd->clk_bypass = __clk_get_hw(clk);
  173. /* register the clock */
  174. clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
  175. if (!IS_ERR(clk)) {
  176. omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
  177. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  178. kfree(clk_hw->hw.init->parent_names);
  179. kfree(clk_hw->hw.init);
  180. return;
  181. }
  182. cleanup:
  183. kfree(clk_hw->dpll_data);
  184. kfree(clk_hw->hw.init->parent_names);
  185. kfree(clk_hw->hw.init);
  186. kfree(clk_hw);
  187. }
  188. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  189. defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
  190. defined(CONFIG_SOC_AM43XX)
  191. /**
  192. * _register_dpll_x2 - Registers a DPLLx2 clock
  193. * @node: device node for this clock
  194. * @ops: clk_ops for this clock
  195. * @hw_ops: clk_hw_ops for this clock
  196. *
  197. * Initializes a DPLL x 2 clock from device tree data.
  198. */
  199. static void _register_dpll_x2(struct device_node *node,
  200. const struct clk_ops *ops,
  201. const struct clk_hw_omap_ops *hw_ops)
  202. {
  203. struct clk *clk;
  204. struct clk_init_data init = { NULL };
  205. struct clk_hw_omap *clk_hw;
  206. const char *name = node->name;
  207. const char *parent_name;
  208. parent_name = of_clk_get_parent_name(node, 0);
  209. if (!parent_name) {
  210. pr_err("%pOFn must have parent\n", node);
  211. return;
  212. }
  213. clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
  214. if (!clk_hw)
  215. return;
  216. clk_hw->ops = hw_ops;
  217. clk_hw->hw.init = &init;
  218. init.name = name;
  219. init.ops = ops;
  220. init.parent_names = &parent_name;
  221. init.num_parents = 1;
  222. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  223. defined(CONFIG_SOC_DRA7XX)
  224. if (hw_ops == &clkhwops_omap4_dpllmx) {
  225. int ret;
  226. /* Check if register defined, if not, drop hw-ops */
  227. ret = of_property_count_elems_of_size(node, "reg", 1);
  228. if (ret <= 0) {
  229. clk_hw->ops = NULL;
  230. } else if (ti_clk_get_reg_addr(node, 0, &clk_hw->clksel_reg)) {
  231. kfree(clk_hw);
  232. return;
  233. }
  234. }
  235. #endif
  236. /* register the clock */
  237. clk = ti_clk_register(NULL, &clk_hw->hw, name);
  238. if (IS_ERR(clk)) {
  239. kfree(clk_hw);
  240. } else {
  241. omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
  242. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  243. }
  244. }
  245. #endif
  246. /**
  247. * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
  248. * @node: device node containing the DPLL info
  249. * @ops: ops for the DPLL
  250. * @ddt: DPLL data template to use
  251. *
  252. * Initializes a DPLL clock from device tree data.
  253. */
  254. static void __init of_ti_dpll_setup(struct device_node *node,
  255. const struct clk_ops *ops,
  256. const struct dpll_data *ddt)
  257. {
  258. struct clk_hw_omap *clk_hw = NULL;
  259. struct clk_init_data *init = NULL;
  260. const char **parent_names = NULL;
  261. struct dpll_data *dd = NULL;
  262. u8 dpll_mode = 0;
  263. dd = kzalloc(sizeof(*dd), GFP_KERNEL);
  264. clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
  265. init = kzalloc(sizeof(*init), GFP_KERNEL);
  266. if (!dd || !clk_hw || !init)
  267. goto cleanup;
  268. memcpy(dd, ddt, sizeof(*dd));
  269. clk_hw->dpll_data = dd;
  270. clk_hw->ops = &clkhwops_omap3_dpll;
  271. clk_hw->hw.init = init;
  272. init->name = node->name;
  273. init->ops = ops;
  274. init->num_parents = of_clk_get_parent_count(node);
  275. if (!init->num_parents) {
  276. pr_err("%pOFn must have parent(s)\n", node);
  277. goto cleanup;
  278. }
  279. parent_names = kcalloc(init->num_parents, sizeof(char *), GFP_KERNEL);
  280. if (!parent_names)
  281. goto cleanup;
  282. of_clk_parent_fill(node, parent_names, init->num_parents);
  283. init->parent_names = parent_names;
  284. if (ti_clk_get_reg_addr(node, 0, &dd->control_reg))
  285. goto cleanup;
  286. /*
  287. * Special case for OMAP2 DPLL, register order is different due to
  288. * missing idlest_reg, also clkhwops is different. Detected from
  289. * missing idlest_mask.
  290. */
  291. if (!dd->idlest_mask) {
  292. if (ti_clk_get_reg_addr(node, 1, &dd->mult_div1_reg))
  293. goto cleanup;
  294. #ifdef CONFIG_ARCH_OMAP2
  295. clk_hw->ops = &clkhwops_omap2xxx_dpll;
  296. omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
  297. #endif
  298. } else {
  299. if (ti_clk_get_reg_addr(node, 1, &dd->idlest_reg))
  300. goto cleanup;
  301. if (ti_clk_get_reg_addr(node, 2, &dd->mult_div1_reg))
  302. goto cleanup;
  303. }
  304. if (dd->autoidle_mask) {
  305. if (ti_clk_get_reg_addr(node, 3, &dd->autoidle_reg))
  306. goto cleanup;
  307. }
  308. if (of_property_read_bool(node, "ti,low-power-stop"))
  309. dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
  310. if (of_property_read_bool(node, "ti,low-power-bypass"))
  311. dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
  312. if (of_property_read_bool(node, "ti,lock"))
  313. dpll_mode |= 1 << DPLL_LOCKED;
  314. if (dpll_mode)
  315. dd->modes = dpll_mode;
  316. _register_dpll(&clk_hw->hw, node);
  317. return;
  318. cleanup:
  319. kfree(dd);
  320. kfree(parent_names);
  321. kfree(init);
  322. kfree(clk_hw);
  323. }
  324. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  325. defined(CONFIG_SOC_DRA7XX)
  326. static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
  327. {
  328. _register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
  329. }
  330. CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
  331. of_ti_omap4_dpll_x2_setup);
  332. #endif
  333. #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
  334. static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
  335. {
  336. _register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
  337. }
  338. CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
  339. of_ti_am3_dpll_x2_setup);
  340. #endif
  341. #ifdef CONFIG_ARCH_OMAP3
  342. static void __init of_ti_omap3_dpll_setup(struct device_node *node)
  343. {
  344. const struct dpll_data dd = {
  345. .idlest_mask = 0x1,
  346. .enable_mask = 0x7,
  347. .autoidle_mask = 0x7,
  348. .mult_mask = 0x7ff << 8,
  349. .div1_mask = 0x7f,
  350. .max_multiplier = 2047,
  351. .max_divider = 128,
  352. .min_divider = 1,
  353. .freqsel_mask = 0xf0,
  354. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  355. };
  356. if ((of_machine_is_compatible("ti,omap3630") ||
  357. of_machine_is_compatible("ti,omap36xx")) &&
  358. !strcmp(node->name, "dpll5_ck"))
  359. of_ti_dpll_setup(node, &omap3_dpll5_ck_ops, &dd);
  360. else
  361. of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
  362. }
  363. CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
  364. of_ti_omap3_dpll_setup);
  365. static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
  366. {
  367. const struct dpll_data dd = {
  368. .idlest_mask = 0x1,
  369. .enable_mask = 0x7,
  370. .autoidle_mask = 0x7,
  371. .mult_mask = 0x7ff << 16,
  372. .div1_mask = 0x7f << 8,
  373. .max_multiplier = 2047,
  374. .max_divider = 128,
  375. .min_divider = 1,
  376. .freqsel_mask = 0xf0,
  377. };
  378. of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
  379. }
  380. CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
  381. of_ti_omap3_core_dpll_setup);
  382. static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
  383. {
  384. const struct dpll_data dd = {
  385. .idlest_mask = 0x1 << 1,
  386. .enable_mask = 0x7 << 16,
  387. .autoidle_mask = 0x7 << 3,
  388. .mult_mask = 0x7ff << 8,
  389. .div1_mask = 0x7f,
  390. .max_multiplier = 2047,
  391. .max_divider = 128,
  392. .min_divider = 1,
  393. .freqsel_mask = 0xf00000,
  394. .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
  395. };
  396. of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
  397. }
  398. CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
  399. of_ti_omap3_per_dpll_setup);
  400. static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
  401. {
  402. const struct dpll_data dd = {
  403. .idlest_mask = 0x1 << 1,
  404. .enable_mask = 0x7 << 16,
  405. .autoidle_mask = 0x7 << 3,
  406. .mult_mask = 0xfff << 8,
  407. .div1_mask = 0x7f,
  408. .max_multiplier = 4095,
  409. .max_divider = 128,
  410. .min_divider = 1,
  411. .sddiv_mask = 0xff << 24,
  412. .dco_mask = 0xe << 20,
  413. .flags = DPLL_J_TYPE,
  414. .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
  415. };
  416. of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
  417. }
  418. CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
  419. of_ti_omap3_per_jtype_dpll_setup);
  420. #endif
  421. static void __init of_ti_omap4_dpll_setup(struct device_node *node)
  422. {
  423. const struct dpll_data dd = {
  424. .idlest_mask = 0x1,
  425. .enable_mask = 0x7,
  426. .autoidle_mask = 0x7,
  427. .mult_mask = 0x7ff << 8,
  428. .div1_mask = 0x7f,
  429. .max_multiplier = 2047,
  430. .max_divider = 128,
  431. .min_divider = 1,
  432. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  433. };
  434. of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
  435. }
  436. CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
  437. of_ti_omap4_dpll_setup);
  438. static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
  439. {
  440. const struct dpll_data dd = {
  441. .idlest_mask = 0x1,
  442. .enable_mask = 0x7,
  443. .autoidle_mask = 0x7,
  444. .mult_mask = 0x7ff << 8,
  445. .div1_mask = 0x7f,
  446. .max_multiplier = 2047,
  447. .max_divider = 128,
  448. .dcc_mask = BIT(22),
  449. .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
  450. .min_divider = 1,
  451. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  452. };
  453. of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
  454. }
  455. CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
  456. of_ti_omap5_mpu_dpll_setup);
  457. static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
  458. {
  459. const struct dpll_data dd = {
  460. .idlest_mask = 0x1,
  461. .enable_mask = 0x7,
  462. .autoidle_mask = 0x7,
  463. .mult_mask = 0x7ff << 8,
  464. .div1_mask = 0x7f,
  465. .max_multiplier = 2047,
  466. .max_divider = 128,
  467. .min_divider = 1,
  468. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  469. };
  470. of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
  471. }
  472. CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
  473. of_ti_omap4_core_dpll_setup);
  474. #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
  475. defined(CONFIG_SOC_DRA7XX)
  476. static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
  477. {
  478. const struct dpll_data dd = {
  479. .idlest_mask = 0x1,
  480. .enable_mask = 0x7,
  481. .autoidle_mask = 0x7,
  482. .mult_mask = 0x7ff << 8,
  483. .div1_mask = 0x7f,
  484. .max_multiplier = 2047,
  485. .max_divider = 128,
  486. .min_divider = 1,
  487. .m4xen_mask = 0x800,
  488. .lpmode_mask = 1 << 10,
  489. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  490. };
  491. of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
  492. }
  493. CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
  494. of_ti_omap4_m4xen_dpll_setup);
  495. static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
  496. {
  497. const struct dpll_data dd = {
  498. .idlest_mask = 0x1,
  499. .enable_mask = 0x7,
  500. .autoidle_mask = 0x7,
  501. .mult_mask = 0xfff << 8,
  502. .div1_mask = 0xff,
  503. .max_multiplier = 4095,
  504. .max_divider = 256,
  505. .min_divider = 1,
  506. .sddiv_mask = 0xff << 24,
  507. .flags = DPLL_J_TYPE,
  508. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  509. };
  510. of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
  511. }
  512. CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
  513. of_ti_omap4_jtype_dpll_setup);
  514. #endif
  515. static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
  516. {
  517. const struct dpll_data dd = {
  518. .idlest_mask = 0x1,
  519. .enable_mask = 0x7,
  520. .mult_mask = 0x7ff << 8,
  521. .div1_mask = 0x7f,
  522. .max_multiplier = 2047,
  523. .max_divider = 128,
  524. .min_divider = 1,
  525. .max_rate = 1000000000,
  526. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  527. };
  528. of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
  529. }
  530. CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
  531. of_ti_am3_no_gate_dpll_setup);
  532. static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
  533. {
  534. const struct dpll_data dd = {
  535. .idlest_mask = 0x1,
  536. .enable_mask = 0x7,
  537. .mult_mask = 0x7ff << 8,
  538. .div1_mask = 0x7f,
  539. .max_multiplier = 4095,
  540. .max_divider = 256,
  541. .min_divider = 2,
  542. .flags = DPLL_J_TYPE,
  543. .max_rate = 2000000000,
  544. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  545. };
  546. of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
  547. }
  548. CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
  549. of_ti_am3_jtype_dpll_setup);
  550. static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
  551. {
  552. const struct dpll_data dd = {
  553. .idlest_mask = 0x1,
  554. .enable_mask = 0x7,
  555. .mult_mask = 0x7ff << 8,
  556. .div1_mask = 0x7f,
  557. .max_multiplier = 2047,
  558. .max_divider = 128,
  559. .min_divider = 1,
  560. .max_rate = 2000000000,
  561. .flags = DPLL_J_TYPE,
  562. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  563. };
  564. of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
  565. }
  566. CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
  567. "ti,am3-dpll-no-gate-j-type-clock",
  568. of_ti_am3_no_gate_jtype_dpll_setup);
  569. static void __init of_ti_am3_dpll_setup(struct device_node *node)
  570. {
  571. const struct dpll_data dd = {
  572. .idlest_mask = 0x1,
  573. .enable_mask = 0x7,
  574. .mult_mask = 0x7ff << 8,
  575. .div1_mask = 0x7f,
  576. .max_multiplier = 2047,
  577. .max_divider = 128,
  578. .min_divider = 1,
  579. .max_rate = 1000000000,
  580. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  581. };
  582. of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
  583. }
  584. CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
  585. static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
  586. {
  587. const struct dpll_data dd = {
  588. .idlest_mask = 0x1,
  589. .enable_mask = 0x7,
  590. .mult_mask = 0x7ff << 8,
  591. .div1_mask = 0x7f,
  592. .max_multiplier = 2047,
  593. .max_divider = 128,
  594. .min_divider = 1,
  595. .max_rate = 1000000000,
  596. .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
  597. };
  598. of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
  599. }
  600. CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
  601. of_ti_am3_core_dpll_setup);
  602. static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
  603. {
  604. const struct dpll_data dd = {
  605. .enable_mask = 0x3,
  606. .mult_mask = 0x3ff << 12,
  607. .div1_mask = 0xf << 8,
  608. .max_divider = 16,
  609. .min_divider = 1,
  610. };
  611. of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
  612. }
  613. CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
  614. of_ti_omap2_core_dpll_setup);