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