.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2013 Freescale Semiconductor, Inc. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | * |
---|
8 | 5 | * clock driver for Freescale QorIQ SoCs. |
---|
9 | 6 | */ |
---|
.. | .. |
---|
34 | 31 | #define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */ |
---|
35 | 32 | #define CGB_PLL1 4 |
---|
36 | 33 | #define CGB_PLL2 5 |
---|
| 34 | +#define MAX_PLL_DIV 32 |
---|
37 | 35 | |
---|
38 | 36 | struct clockgen_pll_div { |
---|
39 | 37 | struct clk *clk; |
---|
.. | .. |
---|
41 | 39 | }; |
---|
42 | 40 | |
---|
43 | 41 | struct clockgen_pll { |
---|
44 | | - struct clockgen_pll_div div[8]; |
---|
| 42 | + struct clockgen_pll_div div[MAX_PLL_DIV]; |
---|
45 | 43 | }; |
---|
46 | 44 | |
---|
47 | 45 | #define CLKSEL_VALID 1 |
---|
.. | .. |
---|
79 | 77 | const struct clockgen_muxinfo *cmux_groups[2]; |
---|
80 | 78 | const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL]; |
---|
81 | 79 | void (*init_periph)(struct clockgen *cg); |
---|
82 | | - int cmux_to_group[NUM_CMUX]; /* -1 terminates if fewer than NUM_CMUX */ |
---|
| 80 | + int cmux_to_group[NUM_CMUX + 1]; /* array should be -1 terminated */ |
---|
83 | 81 | u32 pll_mask; /* 1 << n bit set if PLL n is valid */ |
---|
84 | 82 | u32 flags; /* CG_xxx */ |
---|
85 | 83 | }; |
---|
.. | .. |
---|
97 | 95 | }; |
---|
98 | 96 | |
---|
99 | 97 | static struct clockgen clockgen; |
---|
| 98 | +static bool add_cpufreq_dev __initdata; |
---|
100 | 99 | |
---|
101 | 100 | static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg) |
---|
102 | 101 | { |
---|
.. | .. |
---|
245 | 244 | }, |
---|
246 | 245 | }; |
---|
247 | 246 | |
---|
| 247 | +static const struct clockgen_muxinfo ls1021a_cmux = { |
---|
| 248 | + { |
---|
| 249 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
---|
| 250 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 251 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
---|
| 252 | + } |
---|
| 253 | +}; |
---|
| 254 | + |
---|
| 255 | +static const struct clockgen_muxinfo ls1028a_hwa1 = { |
---|
| 256 | + { |
---|
| 257 | + { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
---|
| 258 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
---|
| 259 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 260 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
| 261 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
---|
| 262 | + {}, |
---|
| 263 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 264 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 265 | + }, |
---|
| 266 | +}; |
---|
| 267 | + |
---|
| 268 | +static const struct clockgen_muxinfo ls1028a_hwa2 = { |
---|
| 269 | + { |
---|
| 270 | + { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
---|
| 271 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
---|
| 272 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 273 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 274 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
---|
| 275 | + {}, |
---|
| 276 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 277 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
| 278 | + }, |
---|
| 279 | +}; |
---|
| 280 | + |
---|
| 281 | +static const struct clockgen_muxinfo ls1028a_hwa3 = { |
---|
| 282 | + { |
---|
| 283 | + { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
---|
| 284 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
---|
| 285 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 286 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
| 287 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
---|
| 288 | + {}, |
---|
| 289 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 290 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 291 | + }, |
---|
| 292 | +}; |
---|
| 293 | + |
---|
| 294 | +static const struct clockgen_muxinfo ls1028a_hwa4 = { |
---|
| 295 | + { |
---|
| 296 | + { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, |
---|
| 297 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
---|
| 298 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 299 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 300 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
---|
| 301 | + {}, |
---|
| 302 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 303 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
| 304 | + }, |
---|
| 305 | +}; |
---|
| 306 | + |
---|
248 | 307 | static const struct clockgen_muxinfo ls1043a_hwa1 = { |
---|
249 | 308 | { |
---|
250 | 309 | {}, |
---|
.. | .. |
---|
289 | 348 | {}, |
---|
290 | 349 | {}, |
---|
291 | 350 | { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 351 | + }, |
---|
| 352 | +}; |
---|
| 353 | + |
---|
| 354 | +static const struct clockgen_muxinfo ls1088a_hwa1 = { |
---|
| 355 | + { |
---|
| 356 | + {}, |
---|
| 357 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, |
---|
| 358 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 359 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
| 360 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, |
---|
| 361 | + {}, |
---|
| 362 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 363 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 364 | + }, |
---|
| 365 | +}; |
---|
| 366 | + |
---|
| 367 | +static const struct clockgen_muxinfo ls1088a_hwa2 = { |
---|
| 368 | + { |
---|
| 369 | + {}, |
---|
| 370 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, |
---|
| 371 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, |
---|
| 372 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, |
---|
| 373 | + { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, |
---|
| 374 | + {}, |
---|
| 375 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, |
---|
| 376 | + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, |
---|
292 | 377 | }, |
---|
293 | 378 | }; |
---|
294 | 379 | |
---|
.. | .. |
---|
500 | 585 | { |
---|
501 | 586 | .compat = "fsl,ls1021a-clockgen", |
---|
502 | 587 | .cmux_groups = { |
---|
503 | | - &t1023_cmux |
---|
| 588 | + &ls1021a_cmux |
---|
504 | 589 | }, |
---|
505 | 590 | .cmux_to_group = { |
---|
506 | 591 | 0, -1 |
---|
507 | 592 | }, |
---|
508 | 593 | .pll_mask = 0x03, |
---|
| 594 | + }, |
---|
| 595 | + { |
---|
| 596 | + .compat = "fsl,ls1028a-clockgen", |
---|
| 597 | + .cmux_groups = { |
---|
| 598 | + &clockgen2_cmux_cga12 |
---|
| 599 | + }, |
---|
| 600 | + .hwaccel = { |
---|
| 601 | + &ls1028a_hwa1, &ls1028a_hwa2, |
---|
| 602 | + &ls1028a_hwa3, &ls1028a_hwa4 |
---|
| 603 | + }, |
---|
| 604 | + .cmux_to_group = { |
---|
| 605 | + 0, 0, 0, 0, -1 |
---|
| 606 | + }, |
---|
| 607 | + .pll_mask = 0x07, |
---|
| 608 | + .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
---|
509 | 609 | }, |
---|
510 | 610 | { |
---|
511 | 611 | .compat = "fsl,ls1043a-clockgen", |
---|
.. | .. |
---|
542 | 642 | .cmux_groups = { |
---|
543 | 643 | &clockgen2_cmux_cga12 |
---|
544 | 644 | }, |
---|
| 645 | + .hwaccel = { |
---|
| 646 | + &ls1088a_hwa1, &ls1088a_hwa2 |
---|
| 647 | + }, |
---|
545 | 648 | .cmux_to_group = { |
---|
546 | 649 | 0, 0, -1 |
---|
547 | 650 | }, |
---|
.. | .. |
---|
565 | 668 | }, |
---|
566 | 669 | .cmux_to_group = { |
---|
567 | 670 | 0, 0, 1, 1, -1 |
---|
| 671 | + }, |
---|
| 672 | + .pll_mask = 0x37, |
---|
| 673 | + .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
---|
| 674 | + }, |
---|
| 675 | + { |
---|
| 676 | + .compat = "fsl,lx2160a-clockgen", |
---|
| 677 | + .cmux_groups = { |
---|
| 678 | + &clockgen2_cmux_cga12, &clockgen2_cmux_cgb |
---|
| 679 | + }, |
---|
| 680 | + .cmux_to_group = { |
---|
| 681 | + 0, 0, 0, 0, 1, 1, 1, 1, -1 |
---|
568 | 682 | }, |
---|
569 | 683 | .pll_mask = 0x37, |
---|
570 | 684 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
---|
.. | .. |
---|
601 | 715 | &p4080_cmux_grp1, &p4080_cmux_grp2 |
---|
602 | 716 | }, |
---|
603 | 717 | .cmux_to_group = { |
---|
604 | | - 0, 0, 0, 0, 1, 1, 1, 1 |
---|
| 718 | + 0, 0, 0, 0, 1, 1, 1, 1, -1 |
---|
605 | 719 | }, |
---|
606 | 720 | .pll_mask = 0x1f, |
---|
607 | 721 | }, |
---|
.. | .. |
---|
914 | 1028 | } |
---|
915 | 1029 | } |
---|
916 | 1030 | |
---|
917 | | -static void __init clockgen_init(struct device_node *np); |
---|
| 1031 | +static void __init _clockgen_init(struct device_node *np, bool legacy); |
---|
918 | 1032 | |
---|
919 | 1033 | /* |
---|
920 | 1034 | * Legacy nodes may get probed before the parent clockgen node. |
---|
.. | .. |
---|
924 | 1038 | */ |
---|
925 | 1039 | static void __init legacy_init_clockgen(struct device_node *np) |
---|
926 | 1040 | { |
---|
927 | | - if (!clockgen.node) |
---|
928 | | - clockgen_init(of_get_parent(np)); |
---|
| 1041 | + if (!clockgen.node) { |
---|
| 1042 | + struct device_node *parent_np; |
---|
| 1043 | + |
---|
| 1044 | + parent_np = of_get_parent(np); |
---|
| 1045 | + _clockgen_init(parent_np, true); |
---|
| 1046 | + of_node_put(parent_np); |
---|
| 1047 | + } |
---|
929 | 1048 | } |
---|
930 | 1049 | |
---|
931 | 1050 | /* Legacy node */ |
---|
.. | .. |
---|
945 | 1064 | |
---|
946 | 1065 | rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); |
---|
947 | 1066 | if (rc) { |
---|
948 | | - pr_err("%s: Couldn't register clk provider for node %s: %d\n", |
---|
949 | | - __func__, np->name, rc); |
---|
| 1067 | + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", |
---|
| 1068 | + __func__, np, rc); |
---|
950 | 1069 | return; |
---|
951 | 1070 | } |
---|
952 | 1071 | } |
---|
.. | .. |
---|
1020 | 1139 | sysclk = of_get_child_by_name(clockgen.node, "sysclk"); |
---|
1021 | 1140 | if (sysclk) { |
---|
1022 | 1141 | clk = sysclk_from_fixed(sysclk, name); |
---|
| 1142 | + of_node_put(sysclk); |
---|
1023 | 1143 | if (!IS_ERR(clk)) |
---|
1024 | 1144 | return clk; |
---|
1025 | 1145 | } |
---|
.. | .. |
---|
1128 | 1248 | int ret; |
---|
1129 | 1249 | |
---|
1130 | 1250 | /* |
---|
1131 | | - * For platform PLL, there are 8 divider clocks. |
---|
| 1251 | + * For platform PLL, there are MAX_PLL_DIV divider clocks. |
---|
1132 | 1252 | * For core PLL, there are 4 divider clocks at most. |
---|
1133 | 1253 | */ |
---|
1134 | 1254 | if (idx != PLATFORM_PLL && i >= 4) |
---|
.. | .. |
---|
1148 | 1268 | pll->div[i].clk = clk; |
---|
1149 | 1269 | ret = clk_register_clkdev(clk, pll->div[i].name, NULL); |
---|
1150 | 1270 | if (ret != 0) |
---|
1151 | | - pr_err("%s: %s: register to lookup table failed %ld\n", |
---|
1152 | | - __func__, pll->div[i].name, PTR_ERR(clk)); |
---|
| 1271 | + pr_err("%s: %s: register to lookup table failed %d\n", |
---|
| 1272 | + __func__, pll->div[i].name, ret); |
---|
1153 | 1273 | |
---|
1154 | 1274 | } |
---|
1155 | 1275 | } |
---|
.. | .. |
---|
1199 | 1319 | |
---|
1200 | 1320 | rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data); |
---|
1201 | 1321 | if (rc) { |
---|
1202 | | - pr_err("%s: Couldn't register clk provider for node %s: %d\n", |
---|
1203 | | - __func__, np->name, rc); |
---|
| 1322 | + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", |
---|
| 1323 | + __func__, np, rc); |
---|
1204 | 1324 | goto err_cell; |
---|
1205 | 1325 | } |
---|
1206 | 1326 | |
---|
.. | .. |
---|
1342 | 1462 | } |
---|
1343 | 1463 | #endif |
---|
1344 | 1464 | |
---|
1345 | | -static void __init clockgen_init(struct device_node *np) |
---|
| 1465 | +static void __init _clockgen_init(struct device_node *np, bool legacy) |
---|
1346 | 1466 | { |
---|
1347 | 1467 | int i, ret; |
---|
1348 | 1468 | bool is_old_ls1021a = false; |
---|
.. | .. |
---|
1360 | 1480 | is_old_ls1021a = true; |
---|
1361 | 1481 | } |
---|
1362 | 1482 | if (!clockgen.regs) { |
---|
1363 | | - pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name); |
---|
| 1483 | + pr_err("%s(): %pOFn: of_iomap() failed\n", __func__, np); |
---|
1364 | 1484 | return; |
---|
1365 | 1485 | } |
---|
1366 | 1486 | |
---|
.. | .. |
---|
1407 | 1527 | |
---|
1408 | 1528 | ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen); |
---|
1409 | 1529 | if (ret) { |
---|
1410 | | - pr_err("%s: Couldn't register clk provider for node %s: %d\n", |
---|
1411 | | - __func__, np->name, ret); |
---|
| 1530 | + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", |
---|
| 1531 | + __func__, np, ret); |
---|
1412 | 1532 | } |
---|
| 1533 | + |
---|
| 1534 | + /* Don't create cpufreq device for legacy clockgen blocks */ |
---|
| 1535 | + add_cpufreq_dev = !legacy; |
---|
1413 | 1536 | |
---|
1414 | 1537 | return; |
---|
1415 | 1538 | err: |
---|
.. | .. |
---|
1417 | 1540 | clockgen.regs = NULL; |
---|
1418 | 1541 | } |
---|
1419 | 1542 | |
---|
| 1543 | +static void __init clockgen_init(struct device_node *np) |
---|
| 1544 | +{ |
---|
| 1545 | + _clockgen_init(np, false); |
---|
| 1546 | +} |
---|
| 1547 | + |
---|
| 1548 | +static int __init clockgen_cpufreq_init(void) |
---|
| 1549 | +{ |
---|
| 1550 | + struct platform_device *pdev; |
---|
| 1551 | + |
---|
| 1552 | + if (add_cpufreq_dev) { |
---|
| 1553 | + pdev = platform_device_register_simple("qoriq-cpufreq", -1, |
---|
| 1554 | + NULL, 0); |
---|
| 1555 | + if (IS_ERR(pdev)) |
---|
| 1556 | + pr_err("Couldn't register qoriq-cpufreq err=%ld\n", |
---|
| 1557 | + PTR_ERR(pdev)); |
---|
| 1558 | + } |
---|
| 1559 | + return 0; |
---|
| 1560 | +} |
---|
| 1561 | +device_initcall(clockgen_cpufreq_init); |
---|
| 1562 | + |
---|
1420 | 1563 | CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init); |
---|
1421 | 1564 | CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init); |
---|
| 1565 | +CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init); |
---|
| 1566 | +CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init); |
---|
1422 | 1567 | CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); |
---|
1423 | 1568 | CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); |
---|
| 1569 | +CLK_OF_DECLARE(qoriq_clockgen_ls1028a, "fsl,ls1028a-clockgen", clockgen_init); |
---|
1424 | 1570 | CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); |
---|
1425 | 1571 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); |
---|
1426 | 1572 | CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); |
---|
1427 | 1573 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); |
---|
| 1574 | +CLK_OF_DECLARE(qoriq_clockgen_lx2160a, "fsl,lx2160a-clockgen", clockgen_init); |
---|
| 1575 | +CLK_OF_DECLARE(qoriq_clockgen_p2041, "fsl,p2041-clockgen", clockgen_init); |
---|
| 1576 | +CLK_OF_DECLARE(qoriq_clockgen_p3041, "fsl,p3041-clockgen", clockgen_init); |
---|
| 1577 | +CLK_OF_DECLARE(qoriq_clockgen_p4080, "fsl,p4080-clockgen", clockgen_init); |
---|
| 1578 | +CLK_OF_DECLARE(qoriq_clockgen_p5020, "fsl,p5020-clockgen", clockgen_init); |
---|
| 1579 | +CLK_OF_DECLARE(qoriq_clockgen_p5040, "fsl,p5040-clockgen", clockgen_init); |
---|
| 1580 | +CLK_OF_DECLARE(qoriq_clockgen_t1023, "fsl,t1023-clockgen", clockgen_init); |
---|
| 1581 | +CLK_OF_DECLARE(qoriq_clockgen_t1040, "fsl,t1040-clockgen", clockgen_init); |
---|
| 1582 | +CLK_OF_DECLARE(qoriq_clockgen_t2080, "fsl,t2080-clockgen", clockgen_init); |
---|
| 1583 | +CLK_OF_DECLARE(qoriq_clockgen_t4240, "fsl,t4240-clockgen", clockgen_init); |
---|
1428 | 1584 | |
---|
1429 | 1585 | /* Legacy nodes */ |
---|
1430 | 1586 | CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init); |
---|