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) || \ 164*4332ec1aSRoger Quadros defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \ 165*4332ec1aSRoger Quadros defined(CONFIG_SOC_AM43XX) 166f38b0dd6STero Kristo /** 167f38b0dd6STero Kristo * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock 168f38b0dd6STero Kristo * @node: device node for this clock 169f38b0dd6STero Kristo * @ops: clk_ops for this clock 170f38b0dd6STero Kristo * @hw_ops: clk_hw_ops for this clock 171f38b0dd6STero Kristo * 172f38b0dd6STero Kristo * Initializes a DPLL x 2 clock from device tree data. 173f38b0dd6STero Kristo */ 174f38b0dd6STero Kristo static void ti_clk_register_dpll_x2(struct device_node *node, 175f38b0dd6STero Kristo const struct clk_ops *ops, 176f38b0dd6STero Kristo const struct clk_hw_omap_ops *hw_ops) 177f38b0dd6STero Kristo { 178f38b0dd6STero Kristo struct clk *clk; 179f38b0dd6STero Kristo struct clk_init_data init = { NULL }; 180f38b0dd6STero Kristo struct clk_hw_omap *clk_hw; 181f38b0dd6STero Kristo const char *name = node->name; 182f38b0dd6STero Kristo const char *parent_name; 183f38b0dd6STero Kristo 184f38b0dd6STero Kristo parent_name = of_clk_get_parent_name(node, 0); 185f38b0dd6STero Kristo if (!parent_name) { 186f38b0dd6STero Kristo pr_err("%s must have parent\n", node->name); 187f38b0dd6STero Kristo return; 188f38b0dd6STero Kristo } 189f38b0dd6STero Kristo 190f38b0dd6STero Kristo clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 191f38b0dd6STero Kristo if (!clk_hw) 192f38b0dd6STero Kristo return; 193f38b0dd6STero Kristo 194f38b0dd6STero Kristo clk_hw->ops = hw_ops; 195f38b0dd6STero Kristo clk_hw->hw.init = &init; 196f38b0dd6STero Kristo 197f38b0dd6STero Kristo init.name = name; 198f38b0dd6STero Kristo init.ops = ops; 199f38b0dd6STero Kristo init.parent_names = &parent_name; 200f38b0dd6STero Kristo init.num_parents = 1; 201f38b0dd6STero Kristo 202f38b0dd6STero Kristo /* register the clock */ 203f38b0dd6STero Kristo clk = clk_register(NULL, &clk_hw->hw); 204f38b0dd6STero Kristo 205f38b0dd6STero Kristo if (IS_ERR(clk)) { 206f38b0dd6STero Kristo kfree(clk_hw); 207f38b0dd6STero Kristo } else { 208f38b0dd6STero Kristo omap2_init_clk_hw_omap_clocks(clk); 209f38b0dd6STero Kristo of_clk_add_provider(node, of_clk_src_simple_get, clk); 210f38b0dd6STero Kristo } 211f38b0dd6STero Kristo } 212f38b0dd6STero Kristo #endif 213f38b0dd6STero Kristo 214f38b0dd6STero Kristo /** 215f38b0dd6STero Kristo * of_ti_dpll_setup - Setup function for OMAP DPLL clocks 216f38b0dd6STero Kristo * @node: device node containing the DPLL info 217f38b0dd6STero Kristo * @ops: ops for the DPLL 218f38b0dd6STero Kristo * @ddt: DPLL data template to use 219f38b0dd6STero Kristo * 220f38b0dd6STero Kristo * Initializes a DPLL clock from device tree data. 221f38b0dd6STero Kristo */ 222f38b0dd6STero Kristo static void __init of_ti_dpll_setup(struct device_node *node, 223f38b0dd6STero Kristo const struct clk_ops *ops, 224a6fe3771STero Kristo const struct dpll_data *ddt) 225f38b0dd6STero Kristo { 226f38b0dd6STero Kristo struct clk_hw_omap *clk_hw = NULL; 227f38b0dd6STero Kristo struct clk_init_data *init = NULL; 228f38b0dd6STero Kristo const char **parent_names = NULL; 229f38b0dd6STero Kristo struct dpll_data *dd = NULL; 230f38b0dd6STero Kristo int i; 231f38b0dd6STero Kristo u8 dpll_mode = 0; 232f38b0dd6STero Kristo 233f38b0dd6STero Kristo dd = kzalloc(sizeof(*dd), GFP_KERNEL); 234f38b0dd6STero Kristo clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 235f38b0dd6STero Kristo init = kzalloc(sizeof(*init), GFP_KERNEL); 236f38b0dd6STero Kristo if (!dd || !clk_hw || !init) 237f38b0dd6STero Kristo goto cleanup; 238f38b0dd6STero Kristo 239f38b0dd6STero Kristo memcpy(dd, ddt, sizeof(*dd)); 240f38b0dd6STero Kristo 241f38b0dd6STero Kristo clk_hw->dpll_data = dd; 242f38b0dd6STero Kristo clk_hw->ops = &clkhwops_omap3_dpll; 243f38b0dd6STero Kristo clk_hw->hw.init = init; 244f38b0dd6STero Kristo clk_hw->flags = MEMMAP_ADDRESSING; 245f38b0dd6STero Kristo 246f38b0dd6STero Kristo init->name = node->name; 247f38b0dd6STero Kristo init->ops = ops; 248f38b0dd6STero Kristo 249f38b0dd6STero Kristo init->num_parents = of_clk_get_parent_count(node); 250f38b0dd6STero Kristo if (init->num_parents < 1) { 251f38b0dd6STero Kristo pr_err("%s must have parent(s)\n", node->name); 252f38b0dd6STero Kristo goto cleanup; 253f38b0dd6STero Kristo } 254f38b0dd6STero Kristo 255f38b0dd6STero Kristo parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL); 256f38b0dd6STero Kristo if (!parent_names) 257f38b0dd6STero Kristo goto cleanup; 258f38b0dd6STero Kristo 259f38b0dd6STero Kristo for (i = 0; i < init->num_parents; i++) 260f38b0dd6STero Kristo parent_names[i] = of_clk_get_parent_name(node, i); 261f38b0dd6STero Kristo 262f38b0dd6STero Kristo init->parent_names = parent_names; 263f38b0dd6STero Kristo 264f38b0dd6STero Kristo dd->control_reg = ti_clk_get_reg_addr(node, 0); 265f38b0dd6STero Kristo 266aa76fcf4STero Kristo /* 267aa76fcf4STero Kristo * Special case for OMAP2 DPLL, register order is different due to 268aa76fcf4STero Kristo * missing idlest_reg, also clkhwops is different. Detected from 269aa76fcf4STero Kristo * missing idlest_mask. 270aa76fcf4STero Kristo */ 271aa76fcf4STero Kristo if (!dd->idlest_mask) { 272aa76fcf4STero Kristo dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1); 273aa76fcf4STero Kristo #ifdef CONFIG_ARCH_OMAP2 274aa76fcf4STero Kristo clk_hw->ops = &clkhwops_omap2xxx_dpll; 275aa76fcf4STero Kristo omap2xxx_clkt_dpllcore_init(&clk_hw->hw); 276aa76fcf4STero Kristo #endif 277aa76fcf4STero Kristo } else { 278aa76fcf4STero Kristo dd->idlest_reg = ti_clk_get_reg_addr(node, 1); 279aa76fcf4STero Kristo if (!dd->idlest_reg) 280aa76fcf4STero Kristo goto cleanup; 281aa76fcf4STero Kristo 282aa76fcf4STero Kristo dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); 283aa76fcf4STero Kristo } 284aa76fcf4STero Kristo 285aa76fcf4STero Kristo if (!dd->control_reg || !dd->mult_div1_reg) 286f38b0dd6STero Kristo goto cleanup; 287f38b0dd6STero Kristo 288a6fe3771STero Kristo if (dd->autoidle_mask) { 289f38b0dd6STero Kristo dd->autoidle_reg = ti_clk_get_reg_addr(node, 3); 290f38b0dd6STero Kristo if (!dd->autoidle_reg) 291f38b0dd6STero Kristo goto cleanup; 292f38b0dd6STero Kristo } 293f38b0dd6STero Kristo 294f38b0dd6STero Kristo if (of_property_read_bool(node, "ti,low-power-stop")) 295f38b0dd6STero Kristo dpll_mode |= 1 << DPLL_LOW_POWER_STOP; 296f38b0dd6STero Kristo 297f38b0dd6STero Kristo if (of_property_read_bool(node, "ti,low-power-bypass")) 298f38b0dd6STero Kristo dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS; 299f38b0dd6STero Kristo 300f38b0dd6STero Kristo if (of_property_read_bool(node, "ti,lock")) 301f38b0dd6STero Kristo dpll_mode |= 1 << DPLL_LOCKED; 302f38b0dd6STero Kristo 303f38b0dd6STero Kristo if (dpll_mode) 304f38b0dd6STero Kristo dd->modes = dpll_mode; 305f38b0dd6STero Kristo 306f38b0dd6STero Kristo ti_clk_register_dpll(&clk_hw->hw, node); 307f38b0dd6STero Kristo return; 308f38b0dd6STero Kristo 309f38b0dd6STero Kristo cleanup: 310f38b0dd6STero Kristo kfree(dd); 311f38b0dd6STero Kristo kfree(parent_names); 312f38b0dd6STero Kristo kfree(init); 313f38b0dd6STero Kristo kfree(clk_hw); 314f38b0dd6STero Kristo } 315f38b0dd6STero Kristo 316f38b0dd6STero Kristo #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ 317f38b0dd6STero Kristo defined(CONFIG_SOC_DRA7XX) 318f38b0dd6STero Kristo static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node) 319f38b0dd6STero Kristo { 320f38b0dd6STero Kristo ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx); 321f38b0dd6STero Kristo } 322f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock", 323f38b0dd6STero Kristo of_ti_omap4_dpll_x2_setup); 324f38b0dd6STero Kristo #endif 325f38b0dd6STero Kristo 326*4332ec1aSRoger Quadros #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) 327f38b0dd6STero Kristo static void __init of_ti_am3_dpll_x2_setup(struct device_node *node) 328f38b0dd6STero Kristo { 329f38b0dd6STero Kristo ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL); 330f38b0dd6STero Kristo } 331f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock", 332f38b0dd6STero Kristo of_ti_am3_dpll_x2_setup); 333f38b0dd6STero Kristo #endif 334f38b0dd6STero Kristo 335f38b0dd6STero Kristo #ifdef CONFIG_ARCH_OMAP3 336f38b0dd6STero Kristo static void __init of_ti_omap3_dpll_setup(struct device_node *node) 337f38b0dd6STero Kristo { 338f38b0dd6STero Kristo const struct dpll_data dd = { 339f38b0dd6STero Kristo .idlest_mask = 0x1, 340f38b0dd6STero Kristo .enable_mask = 0x7, 341f38b0dd6STero Kristo .autoidle_mask = 0x7, 342f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 343f38b0dd6STero Kristo .div1_mask = 0x7f, 344f38b0dd6STero Kristo .max_multiplier = 2047, 345f38b0dd6STero Kristo .max_divider = 128, 346f38b0dd6STero Kristo .min_divider = 1, 347f38b0dd6STero Kristo .freqsel_mask = 0xf0, 348f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 349f38b0dd6STero Kristo }; 350f38b0dd6STero Kristo 351a6fe3771STero Kristo of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd); 352f38b0dd6STero Kristo } 353f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", 354f38b0dd6STero Kristo of_ti_omap3_dpll_setup); 355f38b0dd6STero Kristo 356f38b0dd6STero Kristo static void __init of_ti_omap3_core_dpll_setup(struct device_node *node) 357f38b0dd6STero Kristo { 358f38b0dd6STero Kristo const struct dpll_data dd = { 359f38b0dd6STero Kristo .idlest_mask = 0x1, 360f38b0dd6STero Kristo .enable_mask = 0x7, 361f38b0dd6STero Kristo .autoidle_mask = 0x7, 362f38b0dd6STero Kristo .mult_mask = 0x7ff << 16, 363f38b0dd6STero Kristo .div1_mask = 0x7f << 8, 364f38b0dd6STero Kristo .max_multiplier = 2047, 365f38b0dd6STero Kristo .max_divider = 128, 366f38b0dd6STero Kristo .min_divider = 1, 367f38b0dd6STero Kristo .freqsel_mask = 0xf0, 368f38b0dd6STero Kristo }; 369f38b0dd6STero Kristo 370a6fe3771STero Kristo of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd); 371f38b0dd6STero Kristo } 372f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", 373f38b0dd6STero Kristo of_ti_omap3_core_dpll_setup); 374f38b0dd6STero Kristo 375f38b0dd6STero Kristo static void __init of_ti_omap3_per_dpll_setup(struct device_node *node) 376f38b0dd6STero Kristo { 377f38b0dd6STero Kristo const struct dpll_data dd = { 378f38b0dd6STero Kristo .idlest_mask = 0x1 << 1, 379f38b0dd6STero Kristo .enable_mask = 0x7 << 16, 380f38b0dd6STero Kristo .autoidle_mask = 0x7 << 3, 381f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 382f38b0dd6STero Kristo .div1_mask = 0x7f, 383f38b0dd6STero Kristo .max_multiplier = 2047, 384f38b0dd6STero Kristo .max_divider = 128, 385f38b0dd6STero Kristo .min_divider = 1, 386f38b0dd6STero Kristo .freqsel_mask = 0xf00000, 387f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 388f38b0dd6STero Kristo }; 389f38b0dd6STero Kristo 390a6fe3771STero Kristo of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); 391f38b0dd6STero Kristo } 392f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", 393f38b0dd6STero Kristo of_ti_omap3_per_dpll_setup); 394f38b0dd6STero Kristo 395f38b0dd6STero Kristo static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node) 396f38b0dd6STero Kristo { 397f38b0dd6STero Kristo const struct dpll_data dd = { 398f38b0dd6STero Kristo .idlest_mask = 0x1 << 1, 399f38b0dd6STero Kristo .enable_mask = 0x7 << 16, 400f38b0dd6STero Kristo .autoidle_mask = 0x7 << 3, 401f38b0dd6STero Kristo .mult_mask = 0xfff << 8, 402f38b0dd6STero Kristo .div1_mask = 0x7f, 403f38b0dd6STero Kristo .max_multiplier = 4095, 404f38b0dd6STero Kristo .max_divider = 128, 405f38b0dd6STero Kristo .min_divider = 1, 406f38b0dd6STero Kristo .sddiv_mask = 0xff << 24, 407f38b0dd6STero Kristo .dco_mask = 0xe << 20, 408f38b0dd6STero Kristo .flags = DPLL_J_TYPE, 409f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 410f38b0dd6STero Kristo }; 411f38b0dd6STero Kristo 412a6fe3771STero Kristo of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); 413f38b0dd6STero Kristo } 414f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock", 415f38b0dd6STero Kristo of_ti_omap3_per_jtype_dpll_setup); 416f38b0dd6STero Kristo #endif 417f38b0dd6STero Kristo 418f38b0dd6STero Kristo static void __init of_ti_omap4_dpll_setup(struct device_node *node) 419f38b0dd6STero Kristo { 420f38b0dd6STero Kristo const struct dpll_data dd = { 421f38b0dd6STero Kristo .idlest_mask = 0x1, 422f38b0dd6STero Kristo .enable_mask = 0x7, 423f38b0dd6STero Kristo .autoidle_mask = 0x7, 424f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 425f38b0dd6STero Kristo .div1_mask = 0x7f, 426f38b0dd6STero Kristo .max_multiplier = 2047, 427f38b0dd6STero Kristo .max_divider = 128, 428f38b0dd6STero Kristo .min_divider = 1, 429f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 430f38b0dd6STero Kristo }; 431f38b0dd6STero Kristo 432a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 433f38b0dd6STero Kristo } 434f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock", 435f38b0dd6STero Kristo of_ti_omap4_dpll_setup); 436f38b0dd6STero Kristo 437b4be0189SNishanth Menon static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node) 438b4be0189SNishanth Menon { 439b4be0189SNishanth Menon const struct dpll_data dd = { 440b4be0189SNishanth Menon .idlest_mask = 0x1, 441b4be0189SNishanth Menon .enable_mask = 0x7, 442b4be0189SNishanth Menon .autoidle_mask = 0x7, 443b4be0189SNishanth Menon .mult_mask = 0x7ff << 8, 444b4be0189SNishanth Menon .div1_mask = 0x7f, 445b4be0189SNishanth Menon .max_multiplier = 2047, 446b4be0189SNishanth Menon .max_divider = 128, 447b4be0189SNishanth Menon .dcc_mask = BIT(22), 448b4be0189SNishanth Menon .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */ 449b4be0189SNishanth Menon .min_divider = 1, 450b4be0189SNishanth Menon .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 451b4be0189SNishanth Menon }; 452b4be0189SNishanth Menon 453b4be0189SNishanth Menon of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 454b4be0189SNishanth Menon } 455b4be0189SNishanth Menon CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock", 456b4be0189SNishanth Menon of_ti_omap5_mpu_dpll_setup); 457b4be0189SNishanth Menon 458f38b0dd6STero Kristo static void __init of_ti_omap4_core_dpll_setup(struct device_node *node) 459f38b0dd6STero Kristo { 460f38b0dd6STero Kristo const struct dpll_data dd = { 461f38b0dd6STero Kristo .idlest_mask = 0x1, 462f38b0dd6STero Kristo .enable_mask = 0x7, 463f38b0dd6STero Kristo .autoidle_mask = 0x7, 464f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 465f38b0dd6STero Kristo .div1_mask = 0x7f, 466f38b0dd6STero Kristo .max_multiplier = 2047, 467f38b0dd6STero Kristo .max_divider = 128, 468f38b0dd6STero Kristo .min_divider = 1, 469f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 470f38b0dd6STero Kristo }; 471f38b0dd6STero Kristo 472a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd); 473f38b0dd6STero Kristo } 474f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock", 475f38b0dd6STero Kristo of_ti_omap4_core_dpll_setup); 476f38b0dd6STero Kristo 477f38b0dd6STero Kristo #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ 478f38b0dd6STero Kristo defined(CONFIG_SOC_DRA7XX) 479f38b0dd6STero Kristo static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node) 480f38b0dd6STero Kristo { 481f38b0dd6STero Kristo const struct dpll_data dd = { 482f38b0dd6STero Kristo .idlest_mask = 0x1, 483f38b0dd6STero Kristo .enable_mask = 0x7, 484f38b0dd6STero Kristo .autoidle_mask = 0x7, 485f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 486f38b0dd6STero Kristo .div1_mask = 0x7f, 487f38b0dd6STero Kristo .max_multiplier = 2047, 488f38b0dd6STero Kristo .max_divider = 128, 489f38b0dd6STero Kristo .min_divider = 1, 490f38b0dd6STero Kristo .m4xen_mask = 0x800, 491f38b0dd6STero Kristo .lpmode_mask = 1 << 10, 492f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 493f38b0dd6STero Kristo }; 494f38b0dd6STero Kristo 495a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); 496f38b0dd6STero Kristo } 497f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", 498f38b0dd6STero Kristo of_ti_omap4_m4xen_dpll_setup); 499f38b0dd6STero Kristo 500f38b0dd6STero Kristo static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node) 501f38b0dd6STero Kristo { 502f38b0dd6STero Kristo const struct dpll_data dd = { 503f38b0dd6STero Kristo .idlest_mask = 0x1, 504f38b0dd6STero Kristo .enable_mask = 0x7, 505f38b0dd6STero Kristo .autoidle_mask = 0x7, 506f38b0dd6STero Kristo .mult_mask = 0xfff << 8, 507f38b0dd6STero Kristo .div1_mask = 0xff, 508f38b0dd6STero Kristo .max_multiplier = 4095, 509f38b0dd6STero Kristo .max_divider = 256, 510f38b0dd6STero Kristo .min_divider = 1, 511f38b0dd6STero Kristo .sddiv_mask = 0xff << 24, 512f38b0dd6STero Kristo .flags = DPLL_J_TYPE, 513f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 514f38b0dd6STero Kristo }; 515f38b0dd6STero Kristo 516a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); 517f38b0dd6STero Kristo } 518f38b0dd6STero Kristo CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", 519f38b0dd6STero Kristo of_ti_omap4_jtype_dpll_setup); 520f38b0dd6STero Kristo #endif 521f38b0dd6STero Kristo 522f38b0dd6STero Kristo static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node) 523f38b0dd6STero Kristo { 524f38b0dd6STero Kristo const struct dpll_data dd = { 525f38b0dd6STero Kristo .idlest_mask = 0x1, 526f38b0dd6STero Kristo .enable_mask = 0x7, 527f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 528f38b0dd6STero Kristo .div1_mask = 0x7f, 529f38b0dd6STero Kristo .max_multiplier = 2047, 530f38b0dd6STero Kristo .max_divider = 128, 531f38b0dd6STero Kristo .min_divider = 1, 532f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 533f38b0dd6STero Kristo }; 534f38b0dd6STero Kristo 535a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); 536f38b0dd6STero Kristo } 537f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock", 538f38b0dd6STero Kristo of_ti_am3_no_gate_dpll_setup); 539f38b0dd6STero Kristo 540f38b0dd6STero Kristo static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node) 541f38b0dd6STero Kristo { 542f38b0dd6STero Kristo const struct dpll_data dd = { 543f38b0dd6STero Kristo .idlest_mask = 0x1, 544f38b0dd6STero Kristo .enable_mask = 0x7, 545f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 546f38b0dd6STero Kristo .div1_mask = 0x7f, 547f38b0dd6STero Kristo .max_multiplier = 4095, 548f38b0dd6STero Kristo .max_divider = 256, 549f38b0dd6STero Kristo .min_divider = 2, 550f38b0dd6STero Kristo .flags = DPLL_J_TYPE, 551f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 552f38b0dd6STero Kristo }; 553f38b0dd6STero Kristo 554a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 555f38b0dd6STero Kristo } 556f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock", 557f38b0dd6STero Kristo of_ti_am3_jtype_dpll_setup); 558f38b0dd6STero Kristo 559f38b0dd6STero Kristo static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node) 560f38b0dd6STero Kristo { 561f38b0dd6STero Kristo const struct dpll_data dd = { 562f38b0dd6STero Kristo .idlest_mask = 0x1, 563f38b0dd6STero Kristo .enable_mask = 0x7, 564f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 565f38b0dd6STero Kristo .div1_mask = 0x7f, 566f38b0dd6STero Kristo .max_multiplier = 2047, 567f38b0dd6STero Kristo .max_divider = 128, 568f38b0dd6STero Kristo .min_divider = 1, 569f38b0dd6STero Kristo .flags = DPLL_J_TYPE, 570f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 571f38b0dd6STero Kristo }; 572f38b0dd6STero Kristo 573a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); 574f38b0dd6STero Kristo } 575f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock, 576f38b0dd6STero Kristo "ti,am3-dpll-no-gate-j-type-clock", 577f38b0dd6STero Kristo of_ti_am3_no_gate_jtype_dpll_setup); 578f38b0dd6STero Kristo 579f38b0dd6STero Kristo static void __init of_ti_am3_dpll_setup(struct device_node *node) 580f38b0dd6STero Kristo { 581f38b0dd6STero Kristo const struct dpll_data dd = { 582f38b0dd6STero Kristo .idlest_mask = 0x1, 583f38b0dd6STero Kristo .enable_mask = 0x7, 584f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 585f38b0dd6STero Kristo .div1_mask = 0x7f, 586f38b0dd6STero Kristo .max_multiplier = 2047, 587f38b0dd6STero Kristo .max_divider = 128, 588f38b0dd6STero Kristo .min_divider = 1, 589f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 590f38b0dd6STero Kristo }; 591f38b0dd6STero Kristo 592a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 593f38b0dd6STero Kristo } 594f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); 595f38b0dd6STero Kristo 596f38b0dd6STero Kristo static void __init of_ti_am3_core_dpll_setup(struct device_node *node) 597f38b0dd6STero Kristo { 598f38b0dd6STero Kristo const struct dpll_data dd = { 599f38b0dd6STero Kristo .idlest_mask = 0x1, 600f38b0dd6STero Kristo .enable_mask = 0x7, 601f38b0dd6STero Kristo .mult_mask = 0x7ff << 8, 602f38b0dd6STero Kristo .div1_mask = 0x7f, 603f38b0dd6STero Kristo .max_multiplier = 2047, 604f38b0dd6STero Kristo .max_divider = 128, 605f38b0dd6STero Kristo .min_divider = 1, 606f38b0dd6STero Kristo .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 607f38b0dd6STero Kristo }; 608f38b0dd6STero Kristo 609a6fe3771STero Kristo of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd); 610f38b0dd6STero Kristo } 611f38b0dd6STero Kristo CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 612f38b0dd6STero Kristo of_ti_am3_core_dpll_setup); 613aa76fcf4STero Kristo 614aa76fcf4STero Kristo static void __init of_ti_omap2_core_dpll_setup(struct device_node *node) 615aa76fcf4STero Kristo { 616aa76fcf4STero Kristo const struct dpll_data dd = { 617aa76fcf4STero Kristo .enable_mask = 0x3, 618aa76fcf4STero Kristo .mult_mask = 0x3ff << 12, 619aa76fcf4STero Kristo .div1_mask = 0xf << 8, 620aa76fcf4STero Kristo .max_divider = 16, 621aa76fcf4STero Kristo .min_divider = 1, 622aa76fcf4STero Kristo }; 623aa76fcf4STero Kristo 624aa76fcf4STero Kristo of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd); 625aa76fcf4STero Kristo } 626aa76fcf4STero Kristo CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock", 627aa76fcf4STero Kristo of_ti_omap2_core_dpll_setup); 628