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