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