diff options
author | Chen-Yu Tsai <wens@csie.org> | 2015-03-19 13:19:03 -0400 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2015-03-21 06:48:40 -0400 |
commit | 9f2430973d6713b73b3d25990d0ceb77a12a13a6 (patch) | |
tree | b6259c8f18e6b5269d527b86bfff84b67134f755 | |
parent | 71f32f56cb54303a1b6ce6811373f57d87de40d3 (diff) |
clk: sunxi: Add muxable ahb factors clock for sun5i and sun7i
The AHB clock on sun5i and sun7i are muxable divider clocks.
Use a factors clock to support them.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-rw-r--r-- | Documentation/devicetree/bindings/clock/sunxi.txt | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-sunxi.c | 52 |
2 files changed, 53 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 3f1dcd879af7..4fa11af3d378 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt | |||
@@ -20,6 +20,7 @@ Required properties: | |||
20 | "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 | 20 | "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 |
21 | "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates | 21 | "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates |
22 | "allwinner,sun4i-a10-ahb-clk" - for the AHB clock | 22 | "allwinner,sun4i-a10-ahb-clk" - for the AHB clock |
23 | "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13 | ||
23 | "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 | 24 | "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 |
24 | "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 | 25 | "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 |
25 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 | 26 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 |
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index b6f28ac4f9d5..ae7b1c4d6aae 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -482,6 +482,45 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, | |||
482 | } | 482 | } |
483 | 483 | ||
484 | /** | 484 | /** |
485 | * sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB | ||
486 | * AHB rate is calculated as follows | ||
487 | * rate = parent_rate >> p | ||
488 | */ | ||
489 | |||
490 | static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, | ||
491 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
492 | { | ||
493 | u32 div; | ||
494 | |||
495 | /* divide only */ | ||
496 | if (parent_rate < *freq) | ||
497 | *freq = parent_rate; | ||
498 | |||
499 | /* | ||
500 | * user manual says valid speed is 8k ~ 276M, but tests show it | ||
501 | * can work at speeds up to 300M, just after reparenting to pll6 | ||
502 | */ | ||
503 | if (*freq < 8000) | ||
504 | *freq = 8000; | ||
505 | if (*freq > 300000000) | ||
506 | *freq = 300000000; | ||
507 | |||
508 | div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); | ||
509 | |||
510 | /* p = 0 ~ 3 */ | ||
511 | if (div > 3) | ||
512 | div = 3; | ||
513 | |||
514 | *freq = parent_rate >> div; | ||
515 | |||
516 | /* we were called to round the frequency, we can now return */ | ||
517 | if (p == NULL) | ||
518 | return; | ||
519 | |||
520 | *p = div; | ||
521 | } | ||
522 | |||
523 | /** | ||
485 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 | 524 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 |
486 | * APB1 rate is calculated as follows | 525 | * APB1 rate is calculated as follows |
487 | * rate = (parent_rate >> p) / (m + 1); | 526 | * rate = (parent_rate >> p) / (m + 1); |
@@ -616,6 +655,11 @@ static struct clk_factors_config sun6i_a31_pll6_config = { | |||
616 | .n_start = 1, | 655 | .n_start = 1, |
617 | }; | 656 | }; |
618 | 657 | ||
658 | static struct clk_factors_config sun5i_a13_ahb_config = { | ||
659 | .pshift = 4, | ||
660 | .pwidth = 2, | ||
661 | }; | ||
662 | |||
619 | static struct clk_factors_config sun4i_apb1_config = { | 663 | static struct clk_factors_config sun4i_apb1_config = { |
620 | .mshift = 0, | 664 | .mshift = 0, |
621 | .mwidth = 5, | 665 | .mwidth = 5, |
@@ -676,6 +720,13 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { | |||
676 | .name = "pll6x2", | 720 | .name = "pll6x2", |
677 | }; | 721 | }; |
678 | 722 | ||
723 | static const struct factors_data sun5i_a13_ahb_data __initconst = { | ||
724 | .mux = 6, | ||
725 | .muxmask = BIT(1) | BIT(0), | ||
726 | .table = &sun5i_a13_ahb_config, | ||
727 | .getter = sun5i_a13_get_ahb_factors, | ||
728 | }; | ||
729 | |||
679 | static const struct factors_data sun4i_apb1_data __initconst = { | 730 | static const struct factors_data sun4i_apb1_data __initconst = { |
680 | .mux = 24, | 731 | .mux = 24, |
681 | .muxmask = BIT(1) | BIT(0), | 732 | .muxmask = BIT(1) | BIT(0), |
@@ -1184,6 +1235,7 @@ static const struct of_device_id clk_factors_match[] __initconst = { | |||
1184 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, | 1235 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, |
1185 | {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, | 1236 | {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, |
1186 | {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, | 1237 | {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, |
1238 | {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,}, | ||
1187 | {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, | 1239 | {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, |
1188 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, | 1240 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, |
1189 | {} | 1241 | {} |