diff options
Diffstat (limited to 'drivers/clk/sunxi/clk-sunxi.c')
-rw-r--r-- | drivers/clk/sunxi/clk-sunxi.c | 305 |
1 files changed, 276 insertions, 29 deletions
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index abb6c5ac8a10..bd7dc733c1ca 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/clkdev.h> | 18 | #include <linux/clkdev.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/reset-controller.h> | ||
21 | 22 | ||
22 | #include "clk-factors.h" | 23 | #include "clk-factors.h" |
23 | 24 | ||
@@ -51,6 +52,8 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) | |||
51 | if (!gate) | 52 | if (!gate) |
52 | goto err_free_fixed; | 53 | goto err_free_fixed; |
53 | 54 | ||
55 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
56 | |||
54 | /* set up gate and fixed rate properties */ | 57 | /* set up gate and fixed rate properties */ |
55 | gate->reg = of_iomap(node, 0); | 58 | gate->reg = of_iomap(node, 0); |
56 | gate->bit_idx = SUNXI_OSC24M_GATE; | 59 | gate->bit_idx = SUNXI_OSC24M_GATE; |
@@ -77,7 +80,7 @@ err_free_gate: | |||
77 | err_free_fixed: | 80 | err_free_fixed: |
78 | kfree(fixed); | 81 | kfree(fixed); |
79 | } | 82 | } |
80 | CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup); | 83 | CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-a10-osc-clk", sun4i_osc_clk_setup); |
81 | 84 | ||
82 | 85 | ||
83 | 86 | ||
@@ -249,7 +252,38 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, | |||
249 | *n = DIV_ROUND_UP(div, (*k+1)); | 252 | *n = DIV_ROUND_UP(div, (*k+1)); |
250 | } | 253 | } |
251 | 254 | ||
255 | /** | ||
256 | * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 | ||
257 | * PLL6 rate is calculated as follows | ||
258 | * rate = parent_rate * n * (k + 1) / 2 | ||
259 | * parent_rate is always 24Mhz | ||
260 | */ | ||
261 | |||
262 | static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, | ||
263 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
264 | { | ||
265 | u8 div; | ||
266 | |||
267 | /* | ||
268 | * We always have 24MHz / 2, so we can just say that our | ||
269 | * parent clock is 12MHz. | ||
270 | */ | ||
271 | parent_rate = parent_rate / 2; | ||
252 | 272 | ||
273 | /* Normalize value to a parent_rate multiple (24M / 2) */ | ||
274 | div = *freq / parent_rate; | ||
275 | *freq = parent_rate * div; | ||
276 | |||
277 | /* we were called to round the frequency, we can now return */ | ||
278 | if (n == NULL) | ||
279 | return; | ||
280 | |||
281 | *k = div / 32; | ||
282 | if (*k > 3) | ||
283 | *k = 3; | ||
284 | |||
285 | *n = DIV_ROUND_UP(div, (*k+1)); | ||
286 | } | ||
253 | 287 | ||
254 | /** | 288 | /** |
255 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 | 289 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 |
@@ -265,7 +299,7 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, | |||
265 | if (parent_rate < *freq) | 299 | if (parent_rate < *freq) |
266 | *freq = parent_rate; | 300 | *freq = parent_rate; |
267 | 301 | ||
268 | parent_rate = (parent_rate + (*freq - 1)) / *freq; | 302 | parent_rate = DIV_ROUND_UP(parent_rate, *freq); |
269 | 303 | ||
270 | /* Invalid rate! */ | 304 | /* Invalid rate! */ |
271 | if (parent_rate > 32) | 305 | if (parent_rate > 32) |
@@ -296,7 +330,7 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, | |||
296 | 330 | ||
297 | /** | 331 | /** |
298 | * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks | 332 | * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks |
299 | * MMC rate is calculated as follows | 333 | * MOD0 rate is calculated as follows |
300 | * rate = (parent_rate >> p) / (m + 1); | 334 | * rate = (parent_rate >> p) / (m + 1); |
301 | */ | 335 | */ |
302 | 336 | ||
@@ -310,7 +344,7 @@ static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate, | |||
310 | if (*freq > parent_rate) | 344 | if (*freq > parent_rate) |
311 | *freq = parent_rate; | 345 | *freq = parent_rate; |
312 | 346 | ||
313 | div = parent_rate / *freq; | 347 | div = DIV_ROUND_UP(parent_rate, *freq); |
314 | 348 | ||
315 | if (div < 16) | 349 | if (div < 16) |
316 | calcp = 0; | 350 | calcp = 0; |
@@ -351,7 +385,7 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, | |||
351 | if (*freq > parent_rate) | 385 | if (*freq > parent_rate) |
352 | *freq = parent_rate; | 386 | *freq = parent_rate; |
353 | 387 | ||
354 | div = parent_rate / *freq; | 388 | div = DIV_ROUND_UP(parent_rate, *freq); |
355 | 389 | ||
356 | if (div < 32) | 390 | if (div < 32) |
357 | calcp = 0; | 391 | calcp = 0; |
@@ -377,6 +411,102 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, | |||
377 | 411 | ||
378 | 412 | ||
379 | /** | 413 | /** |
414 | * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module | ||
415 | * | ||
416 | * This clock looks something like this | ||
417 | * ________________________ | ||
418 | * MII TX clock from PHY >-----|___________ _________|----> to GMAC core | ||
419 | * GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY | ||
420 | * Ext. 125MHz RGMII TX clk >--|__divider__/ | | ||
421 | * |________________________| | ||
422 | * | ||
423 | * The external 125 MHz reference is optional, i.e. GMAC can use its | ||
424 | * internal TX clock just fine. The A31 GMAC clock module does not have | ||
425 | * the divider controls for the external reference. | ||
426 | * | ||
427 | * To keep it simple, let the GMAC use either the MII TX clock for MII mode, | ||
428 | * and its internal TX clock for GMII and RGMII modes. The GMAC driver should | ||
429 | * select the appropriate source and gate/ungate the output to the PHY. | ||
430 | * | ||
431 | * Only the GMAC should use this clock. Altering the clock so that it doesn't | ||
432 | * match the GMAC's operation parameters will result in the GMAC not being | ||
433 | * able to send traffic out. The GMAC driver should set the clock rate and | ||
434 | * enable/disable this clock to configure the required state. The clock | ||
435 | * driver then responds by auto-reparenting the clock. | ||
436 | */ | ||
437 | |||
438 | #define SUN7I_A20_GMAC_GPIT 2 | ||
439 | #define SUN7I_A20_GMAC_MASK 0x3 | ||
440 | #define SUN7I_A20_GMAC_PARENTS 2 | ||
441 | |||
442 | static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) | ||
443 | { | ||
444 | struct clk *clk; | ||
445 | struct clk_mux *mux; | ||
446 | struct clk_gate *gate; | ||
447 | const char *clk_name = node->name; | ||
448 | const char *parents[SUN7I_A20_GMAC_PARENTS]; | ||
449 | void *reg; | ||
450 | |||
451 | if (of_property_read_string(node, "clock-output-names", &clk_name)) | ||
452 | return; | ||
453 | |||
454 | /* allocate mux and gate clock structs */ | ||
455 | mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); | ||
456 | if (!mux) | ||
457 | return; | ||
458 | |||
459 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | ||
460 | if (!gate) | ||
461 | goto free_mux; | ||
462 | |||
463 | /* gmac clock requires exactly 2 parents */ | ||
464 | parents[0] = of_clk_get_parent_name(node, 0); | ||
465 | parents[1] = of_clk_get_parent_name(node, 1); | ||
466 | if (!parents[0] || !parents[1]) | ||
467 | goto free_gate; | ||
468 | |||
469 | reg = of_iomap(node, 0); | ||
470 | if (!reg) | ||
471 | goto free_gate; | ||
472 | |||
473 | /* set up gate and fixed rate properties */ | ||
474 | gate->reg = reg; | ||
475 | gate->bit_idx = SUN7I_A20_GMAC_GPIT; | ||
476 | gate->lock = &clk_lock; | ||
477 | mux->reg = reg; | ||
478 | mux->mask = SUN7I_A20_GMAC_MASK; | ||
479 | mux->flags = CLK_MUX_INDEX_BIT; | ||
480 | mux->lock = &clk_lock; | ||
481 | |||
482 | clk = clk_register_composite(NULL, clk_name, | ||
483 | parents, SUN7I_A20_GMAC_PARENTS, | ||
484 | &mux->hw, &clk_mux_ops, | ||
485 | NULL, NULL, | ||
486 | &gate->hw, &clk_gate_ops, | ||
487 | 0); | ||
488 | |||
489 | if (IS_ERR(clk)) | ||
490 | goto iounmap_reg; | ||
491 | |||
492 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
493 | clk_register_clkdev(clk, clk_name, NULL); | ||
494 | |||
495 | return; | ||
496 | |||
497 | iounmap_reg: | ||
498 | iounmap(reg); | ||
499 | free_gate: | ||
500 | kfree(gate); | ||
501 | free_mux: | ||
502 | kfree(mux); | ||
503 | } | ||
504 | CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk", | ||
505 | sun7i_a20_gmac_clk_setup); | ||
506 | |||
507 | |||
508 | |||
509 | /** | ||
380 | * sunxi_factors_clk_setup() - Setup function for factor clocks | 510 | * sunxi_factors_clk_setup() - Setup function for factor clocks |
381 | */ | 511 | */ |
382 | 512 | ||
@@ -387,6 +517,7 @@ struct factors_data { | |||
387 | int mux; | 517 | int mux; |
388 | struct clk_factors_config *table; | 518 | struct clk_factors_config *table; |
389 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); | 519 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); |
520 | const char *name; | ||
390 | }; | 521 | }; |
391 | 522 | ||
392 | static struct clk_factors_config sun4i_pll1_config = { | 523 | static struct clk_factors_config sun4i_pll1_config = { |
@@ -416,6 +547,13 @@ static struct clk_factors_config sun4i_pll5_config = { | |||
416 | .kwidth = 2, | 547 | .kwidth = 2, |
417 | }; | 548 | }; |
418 | 549 | ||
550 | static struct clk_factors_config sun6i_a31_pll6_config = { | ||
551 | .nshift = 8, | ||
552 | .nwidth = 5, | ||
553 | .kshift = 4, | ||
554 | .kwidth = 2, | ||
555 | }; | ||
556 | |||
419 | static struct clk_factors_config sun4i_apb1_config = { | 557 | static struct clk_factors_config sun4i_apb1_config = { |
420 | .mshift = 0, | 558 | .mshift = 0, |
421 | .mwidth = 5, | 559 | .mwidth = 5, |
@@ -451,10 +589,30 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = { | |||
451 | .getter = sun6i_a31_get_pll1_factors, | 589 | .getter = sun6i_a31_get_pll1_factors, |
452 | }; | 590 | }; |
453 | 591 | ||
592 | static const struct factors_data sun7i_a20_pll4_data __initconst = { | ||
593 | .enable = 31, | ||
594 | .table = &sun4i_pll5_config, | ||
595 | .getter = sun4i_get_pll5_factors, | ||
596 | }; | ||
597 | |||
454 | static const struct factors_data sun4i_pll5_data __initconst = { | 598 | static const struct factors_data sun4i_pll5_data __initconst = { |
455 | .enable = 31, | 599 | .enable = 31, |
456 | .table = &sun4i_pll5_config, | 600 | .table = &sun4i_pll5_config, |
457 | .getter = sun4i_get_pll5_factors, | 601 | .getter = sun4i_get_pll5_factors, |
602 | .name = "pll5", | ||
603 | }; | ||
604 | |||
605 | static const struct factors_data sun4i_pll6_data __initconst = { | ||
606 | .enable = 31, | ||
607 | .table = &sun4i_pll5_config, | ||
608 | .getter = sun4i_get_pll5_factors, | ||
609 | .name = "pll6", | ||
610 | }; | ||
611 | |||
612 | static const struct factors_data sun6i_a31_pll6_data __initconst = { | ||
613 | .enable = 31, | ||
614 | .table = &sun6i_a31_pll6_config, | ||
615 | .getter = sun6i_a31_get_pll6_factors, | ||
458 | }; | 616 | }; |
459 | 617 | ||
460 | static const struct factors_data sun4i_apb1_data __initconst = { | 618 | static const struct factors_data sun4i_apb1_data __initconst = { |
@@ -497,14 +655,14 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, | |||
497 | (parents[i] = of_clk_get_parent_name(node, i)) != NULL) | 655 | (parents[i] = of_clk_get_parent_name(node, i)) != NULL) |
498 | i++; | 656 | i++; |
499 | 657 | ||
500 | /* Nodes should be providing the name via clock-output-names | 658 | /* |
501 | * but originally our dts didn't, and so we used node->name. | 659 | * some factor clocks, such as pll5 and pll6, may have multiple |
502 | * The new, better nodes look like clk@deadbeef, so we pull the | 660 | * outputs, and have their name designated in factors_data |
503 | * name just in this case */ | 661 | */ |
504 | if (!strcmp("clk", clk_name)) { | 662 | if (data->name) |
505 | of_property_read_string_index(node, "clock-output-names", | 663 | clk_name = data->name; |
506 | 0, &clk_name); | 664 | else |
507 | } | 665 | of_property_read_string(node, "clock-output-names", &clk_name); |
508 | 666 | ||
509 | factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); | 667 | factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); |
510 | if (!factors) | 668 | if (!factors) |
@@ -601,6 +759,8 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, | |||
601 | (parents[i] = of_clk_get_parent_name(node, i)) != NULL) | 759 | (parents[i] = of_clk_get_parent_name(node, i)) != NULL) |
602 | i++; | 760 | i++; |
603 | 761 | ||
762 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
763 | |||
604 | clk = clk_register_mux(NULL, clk_name, parents, i, | 764 | clk = clk_register_mux(NULL, clk_name, parents, i, |
605 | CLK_SET_RATE_NO_REPARENT, reg, | 765 | CLK_SET_RATE_NO_REPARENT, reg, |
606 | data->shift, SUNXI_MUX_GATE_WIDTH, | 766 | data->shift, SUNXI_MUX_GATE_WIDTH, |
@@ -660,6 +820,8 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, | |||
660 | 820 | ||
661 | clk_parent = of_clk_get_parent_name(node, 0); | 821 | clk_parent = of_clk_get_parent_name(node, 0); |
662 | 822 | ||
823 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
824 | |||
663 | clk = clk_register_divider(NULL, clk_name, clk_parent, 0, | 825 | clk = clk_register_divider(NULL, clk_name, clk_parent, 0, |
664 | reg, data->shift, data->width, | 826 | reg, data->shift, data->width, |
665 | data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, | 827 | data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, |
@@ -673,6 +835,59 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, | |||
673 | 835 | ||
674 | 836 | ||
675 | /** | 837 | /** |
838 | * sunxi_gates_reset... - reset bits in leaf gate clk registers handling | ||
839 | */ | ||
840 | |||
841 | struct gates_reset_data { | ||
842 | void __iomem *reg; | ||
843 | spinlock_t *lock; | ||
844 | struct reset_controller_dev rcdev; | ||
845 | }; | ||
846 | |||
847 | static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev, | ||
848 | unsigned long id) | ||
849 | { | ||
850 | struct gates_reset_data *data = container_of(rcdev, | ||
851 | struct gates_reset_data, | ||
852 | rcdev); | ||
853 | unsigned long flags; | ||
854 | u32 reg; | ||
855 | |||
856 | spin_lock_irqsave(data->lock, flags); | ||
857 | |||
858 | reg = readl(data->reg); | ||
859 | writel(reg & ~BIT(id), data->reg); | ||
860 | |||
861 | spin_unlock_irqrestore(data->lock, flags); | ||
862 | |||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev, | ||
867 | unsigned long id) | ||
868 | { | ||
869 | struct gates_reset_data *data = container_of(rcdev, | ||
870 | struct gates_reset_data, | ||
871 | rcdev); | ||
872 | unsigned long flags; | ||
873 | u32 reg; | ||
874 | |||
875 | spin_lock_irqsave(data->lock, flags); | ||
876 | |||
877 | reg = readl(data->reg); | ||
878 | writel(reg | BIT(id), data->reg); | ||
879 | |||
880 | spin_unlock_irqrestore(data->lock, flags); | ||
881 | |||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static struct reset_control_ops sunxi_gates_reset_ops = { | ||
886 | .assert = sunxi_gates_reset_assert, | ||
887 | .deassert = sunxi_gates_reset_deassert, | ||
888 | }; | ||
889 | |||
890 | /** | ||
676 | * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks | 891 | * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks |
677 | */ | 892 | */ |
678 | 893 | ||
@@ -680,6 +895,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, | |||
680 | 895 | ||
681 | struct gates_data { | 896 | struct gates_data { |
682 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); | 897 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); |
898 | u32 reset_mask; | ||
683 | }; | 899 | }; |
684 | 900 | ||
685 | static const struct gates_data sun4i_axi_gates_data __initconst = { | 901 | static const struct gates_data sun4i_axi_gates_data __initconst = { |
@@ -746,10 +962,21 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = { | |||
746 | .mask = { 0xff80ff }, | 962 | .mask = { 0xff80ff }, |
747 | }; | 963 | }; |
748 | 964 | ||
965 | static const struct gates_data sun4i_a10_usb_gates_data __initconst = { | ||
966 | .mask = {0x1C0}, | ||
967 | .reset_mask = 0x07, | ||
968 | }; | ||
969 | |||
970 | static const struct gates_data sun5i_a13_usb_gates_data __initconst = { | ||
971 | .mask = {0x140}, | ||
972 | .reset_mask = 0x03, | ||
973 | }; | ||
974 | |||
749 | static void __init sunxi_gates_clk_setup(struct device_node *node, | 975 | static void __init sunxi_gates_clk_setup(struct device_node *node, |
750 | struct gates_data *data) | 976 | struct gates_data *data) |
751 | { | 977 | { |
752 | struct clk_onecell_data *clk_data; | 978 | struct clk_onecell_data *clk_data; |
979 | struct gates_reset_data *reset_data; | ||
753 | const char *clk_parent; | 980 | const char *clk_parent; |
754 | const char *clk_name; | 981 | const char *clk_name; |
755 | void *reg; | 982 | void *reg; |
@@ -793,6 +1020,21 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, | |||
793 | clk_data->clk_num = i; | 1020 | clk_data->clk_num = i; |
794 | 1021 | ||
795 | of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | 1022 | of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); |
1023 | |||
1024 | /* Register a reset controler for gates with reset bits */ | ||
1025 | if (data->reset_mask == 0) | ||
1026 | return; | ||
1027 | |||
1028 | reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); | ||
1029 | if (!reset_data) | ||
1030 | return; | ||
1031 | |||
1032 | reset_data->reg = reg; | ||
1033 | reset_data->lock = &clk_lock; | ||
1034 | reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1; | ||
1035 | reset_data->rcdev.ops = &sunxi_gates_reset_ops; | ||
1036 | reset_data->rcdev.of_node = node; | ||
1037 | reset_controller_register(&reset_data->rcdev); | ||
796 | } | 1038 | } |
797 | 1039 | ||
798 | 1040 | ||
@@ -832,7 +1074,7 @@ static const struct divs_data pll5_divs_data __initconst = { | |||
832 | }; | 1074 | }; |
833 | 1075 | ||
834 | static const struct divs_data pll6_divs_data __initconst = { | 1076 | static const struct divs_data pll6_divs_data __initconst = { |
835 | .factors = &sun4i_pll5_data, | 1077 | .factors = &sun4i_pll6_data, |
836 | .div = { | 1078 | .div = { |
837 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ | 1079 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ |
838 | { .fixed = 2 }, /* P, other */ | 1080 | { .fixed = 2 }, /* P, other */ |
@@ -854,7 +1096,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
854 | struct divs_data *data) | 1096 | struct divs_data *data) |
855 | { | 1097 | { |
856 | struct clk_onecell_data *clk_data; | 1098 | struct clk_onecell_data *clk_data; |
857 | const char *parent = node->name; | 1099 | const char *parent; |
858 | const char *clk_name; | 1100 | const char *clk_name; |
859 | struct clk **clks, *pclk; | 1101 | struct clk **clks, *pclk; |
860 | struct clk_hw *gate_hw, *rate_hw; | 1102 | struct clk_hw *gate_hw, *rate_hw; |
@@ -868,6 +1110,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
868 | 1110 | ||
869 | /* Set up factor clock that we will be dividing */ | 1111 | /* Set up factor clock that we will be dividing */ |
870 | pclk = sunxi_factors_clk_setup(node, data->factors); | 1112 | pclk = sunxi_factors_clk_setup(node, data->factors); |
1113 | parent = __clk_get_name(pclk); | ||
871 | 1114 | ||
872 | reg = of_iomap(node, 0); | 1115 | reg = of_iomap(node, 0); |
873 | 1116 | ||
@@ -970,56 +1213,60 @@ free_clkdata: | |||
970 | 1213 | ||
971 | /* Matches for factors clocks */ | 1214 | /* Matches for factors clocks */ |
972 | static const struct of_device_id clk_factors_match[] __initconst = { | 1215 | static const struct of_device_id clk_factors_match[] __initconst = { |
973 | {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,}, | 1216 | {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, |
974 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, | 1217 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, |
975 | {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, | 1218 | {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, |
976 | {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, | 1219 | {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, |
1220 | {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, | ||
1221 | {.compatible = "allwinner,sun4i-a10-mod0-clk", .data = &sun4i_mod0_data,}, | ||
977 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, | 1222 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, |
978 | {} | 1223 | {} |
979 | }; | 1224 | }; |
980 | 1225 | ||
981 | /* Matches for divider clocks */ | 1226 | /* Matches for divider clocks */ |
982 | static const struct of_device_id clk_div_match[] __initconst = { | 1227 | static const struct of_device_id clk_div_match[] __initconst = { |
983 | {.compatible = "allwinner,sun4i-axi-clk", .data = &sun4i_axi_data,}, | 1228 | {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, |
984 | {.compatible = "allwinner,sun4i-ahb-clk", .data = &sun4i_ahb_data,}, | 1229 | {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, |
985 | {.compatible = "allwinner,sun4i-apb0-clk", .data = &sun4i_apb0_data,}, | 1230 | {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, |
986 | {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, | 1231 | {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, |
987 | {} | 1232 | {} |
988 | }; | 1233 | }; |
989 | 1234 | ||
990 | /* Matches for divided outputs */ | 1235 | /* Matches for divided outputs */ |
991 | static const struct of_device_id clk_divs_match[] __initconst = { | 1236 | static const struct of_device_id clk_divs_match[] __initconst = { |
992 | {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,}, | 1237 | {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, |
993 | {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,}, | 1238 | {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, |
994 | {} | 1239 | {} |
995 | }; | 1240 | }; |
996 | 1241 | ||
997 | /* Matches for mux clocks */ | 1242 | /* Matches for mux clocks */ |
998 | static const struct of_device_id clk_mux_match[] __initconst = { | 1243 | static const struct of_device_id clk_mux_match[] __initconst = { |
999 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,}, | 1244 | {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, |
1000 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, | 1245 | {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, |
1001 | {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, | 1246 | {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, |
1002 | {} | 1247 | {} |
1003 | }; | 1248 | }; |
1004 | 1249 | ||
1005 | /* Matches for gate clocks */ | 1250 | /* Matches for gate clocks */ |
1006 | static const struct of_device_id clk_gates_match[] __initconst = { | 1251 | static const struct of_device_id clk_gates_match[] __initconst = { |
1007 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,}, | 1252 | {.compatible = "allwinner,sun4i-a10-axi-gates-clk", .data = &sun4i_axi_gates_data,}, |
1008 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,}, | 1253 | {.compatible = "allwinner,sun4i-a10-ahb-gates-clk", .data = &sun4i_ahb_gates_data,}, |
1009 | {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,}, | 1254 | {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,}, |
1010 | {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, | 1255 | {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, |
1011 | {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, | 1256 | {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, |
1012 | {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, | 1257 | {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, |
1013 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, | 1258 | {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, |
1014 | {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, | 1259 | {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, |
1015 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, | 1260 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, |
1016 | {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, | 1261 | {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, |
1017 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, | 1262 | {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, |
1018 | {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, | 1263 | {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, |
1019 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, | 1264 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, |
1020 | {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, | 1265 | {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, |
1021 | {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, | 1266 | {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, |
1022 | {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, | 1267 | {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, |
1268 | {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, | ||
1269 | {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,}, | ||
1023 | {} | 1270 | {} |
1024 | }; | 1271 | }; |
1025 | 1272 | ||