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