aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2014-11-12 13:08:31 -0500
committerMaxime Ripard <maxime.ripard@free-electrons.com>2014-11-23 11:02:56 -0500
commit95e94c1fadcd1959857db45c2e11810a893badd0 (patch)
tree2c62bbbe6df23b6b1ab8bb5660d06dc3384a58fd
parent13d52f61065dcdbea13aae2f0aea6af43a3abf65 (diff)
clk: sunxi: Implement A31 PLL6 as a divs clock for 2x output
Some clock modules on the A31 use PLL6x2 as one of their inputs. This patch changes the PLL6 implementation for A31 to a divs clock, i.e. clock with multiple outputs that have different dividers. The first output will be the normal PLL6 output, and the second will be PLL6x2. This patch fixes the PLL6 N factor in the clock driver, and removes any /2 dividers in the PLL6 factors clock part. The N factor counts from 1 to 32, mapping to values 0 to 31, as shown in the A31 manual. 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.txt19
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c28
2 files changed, 33 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index d199f9153e04..67b2b99f2b33 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -71,8 +71,9 @@ Required properties for all clocks:
71 multiplexed clocks, the list order must match the hardware 71 multiplexed clocks, the list order must match the hardware
72 programming order. 72 programming order.
73- #clock-cells : from common clock binding; shall be set to 0 except for 73- #clock-cells : from common clock binding; shall be set to 0 except for
74 "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and 74 the following compatibles where it shall be set to 1:
75 "allwinner,sun4i-pll6-clk" where it shall be set to 1 75 "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk",
76 "allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk"
76- clock-output-names : shall be the corresponding names of the outputs. 77- clock-output-names : shall be the corresponding names of the outputs.
77 If the clock module only has one output, the name shall be the 78 If the clock module only has one output, the name shall be the
78 module name. 79 module name.
@@ -87,6 +88,12 @@ Clock consumers should specify the desired clocks they use with a
87"clocks" phandle cell. Consumers that are using a gated clock should 88"clocks" phandle cell. Consumers that are using a gated clock should
88provide an additional ID in their clock property. This ID is the 89provide an additional ID in their clock property. This ID is the
89offset of the bit controlling this particular gate in the register. 90offset of the bit controlling this particular gate in the register.
91For the other clocks with "#clock-cells" = 1, the additional ID shall
92refer to the index of the output.
93
94For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output
95is the normal PLL6 output, or "pll6". The second output is rate doubled
96PLL6, or "pll6x2".
90 97
91For example: 98For example:
92 99
@@ -114,6 +121,14 @@ pll5: clk@01c20020 {
114 clock-output-names = "pll5_ddr", "pll5_other"; 121 clock-output-names = "pll5_ddr", "pll5_other";
115}; 122};
116 123
124pll6: clk@01c20028 {
125 #clock-cells = <1>;
126 compatible = "allwinner,sun6i-a31-pll6-clk";
127 reg = <0x01c20028 0x4>;
128 clocks = <&osc24M>;
129 clock-output-names = "pll6", "pll6x2";
130};
131
117cpu: cpu@01c20054 { 132cpu: cpu@01c20054 {
118 #clock-cells = <0>; 133 #clock-cells = <0>;
119 compatible = "allwinner,sun4i-a10-cpu-clk"; 134 compatible = "allwinner,sun4i-a10-cpu-clk";
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index d46949372762..570202582dcf 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -245,9 +245,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
245} 245}
246 246
247/** 247/**
248 * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 248 * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2
249 * PLL6 rate is calculated as follows 249 * PLL6x2 rate is calculated as follows
250 * rate = parent_rate * n * (k + 1) / 2 250 * rate = parent_rate * (n + 1) * (k + 1)
251 * parent_rate is always 24Mhz 251 * parent_rate is always 24Mhz
252 */ 252 */
253 253
@@ -256,13 +256,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
256{ 256{
257 u8 div; 257 u8 div;
258 258
259 /* 259 /* Normalize value to a parent_rate multiple (24M) */
260 * We always have 24MHz / 2, so we can just say that our
261 * parent clock is 12MHz.
262 */
263 parent_rate = parent_rate / 2;
264
265 /* Normalize value to a parent_rate multiple (24M / 2) */
266 div = *freq / parent_rate; 260 div = *freq / parent_rate;
267 *freq = parent_rate * div; 261 *freq = parent_rate * div;
268 262
@@ -274,7 +268,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
274 if (*k > 3) 268 if (*k > 3)
275 *k = 3; 269 *k = 3;
276 270
277 *n = DIV_ROUND_UP(div, (*k+1)); 271 *n = DIV_ROUND_UP(div, (*k+1)) - 1;
278} 272}
279 273
280/** 274/**
@@ -445,6 +439,7 @@ static struct clk_factors_config sun6i_a31_pll6_config = {
445 .nwidth = 5, 439 .nwidth = 5,
446 .kshift = 4, 440 .kshift = 4,
447 .kwidth = 2, 441 .kwidth = 2,
442 .n_start = 1,
448}; 443};
449 444
450static struct clk_factors_config sun4i_apb1_config = { 445static struct clk_factors_config sun4i_apb1_config = {
@@ -504,6 +499,7 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = {
504 .enable = 31, 499 .enable = 31,
505 .table = &sun6i_a31_pll6_config, 500 .table = &sun6i_a31_pll6_config,
506 .getter = sun6i_a31_get_pll6_factors, 501 .getter = sun6i_a31_get_pll6_factors,
502 .name = "pll6x2",
507}; 503};
508 504
509static const struct factors_data sun4i_apb1_data __initconst = { 505static const struct factors_data sun4i_apb1_data __initconst = {
@@ -942,6 +938,14 @@ static const struct divs_data pll6_divs_data __initconst = {
942 } 938 }
943}; 939};
944 940
941static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
942 .factors = &sun6i_a31_pll6_data,
943 .ndivs = 1,
944 .div = {
945 { .fixed = 2 }, /* normal output */
946 }
947};
948
945/** 949/**
946 * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks 950 * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
947 * 951 *
@@ -1082,7 +1086,6 @@ static const struct of_device_id clk_factors_match[] __initconst = {
1082 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, 1086 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
1083 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, 1087 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
1084 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, 1088 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
1085 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
1086 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, 1089 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
1087 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, 1090 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
1088 {} 1091 {}
@@ -1101,6 +1104,7 @@ static const struct of_device_id clk_div_match[] __initconst = {
1101static const struct of_device_id clk_divs_match[] __initconst = { 1104static const struct of_device_id clk_divs_match[] __initconst = {
1102 {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, 1105 {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,},
1103 {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, 1106 {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,},
1107 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,},
1104 {} 1108 {}
1105}; 1109};
1106 1110