dpll.c 20 KB

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