aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-02-05 08:05:03 -0500
committerEmilio López <emilio@elopez.com.ar>2014-02-18 07:45:13 -0500
commit92ef67c53ad92487c3c8de75e7940384c2edd793 (patch)
treeca846e52a7c9183ef4038399e5c8d098bbba8827
parent5abdbf2f497c1769aa9df284ad125d40641207c7 (diff)
clk: sunxi: Add support for PLL6 on the A31
The A31 has a slightly different PLL6 clock. Add support for this new clock in our driver. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Emilio López <emilio@elopez.com.ar>
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi.txt1
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c45
2 files changed, 46 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index ca2b6920fca4..c37c764cbbc5 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -11,6 +11,7 @@ Required properties:
11 "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 11 "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
12 "allwinner,sun4i-pll5-clk" - for the PLL5 clock 12 "allwinner,sun4i-pll5-clk" - for the PLL5 clock
13 "allwinner,sun4i-pll6-clk" - for the PLL6 clock 13 "allwinner,sun4i-pll6-clk" - for the PLL6 clock
14 "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
14 "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock 15 "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
15 "allwinner,sun4i-axi-clk" - for the AXI clock 16 "allwinner,sun4i-axi-clk" - for the AXI clock
16 "allwinner,sun4i-axi-gates-clk" - for the AXI gates 17 "allwinner,sun4i-axi-gates-clk" - for the AXI gates
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index a779c31b0de9..d4cf297e8fac 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -252,7 +252,38 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
252 *n = DIV_ROUND_UP(div, (*k+1)); 252 *n = DIV_ROUND_UP(div, (*k+1));
253} 253}
254 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
262static 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;
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;
255 284
285 *n = DIV_ROUND_UP(div, (*k+1));
286}
256 287
257/** 288/**
258 * sun4i_get_apb1_factors() - calculates m, p factors for APB1 289 * sun4i_get_apb1_factors() - calculates m, p factors for APB1
@@ -420,6 +451,13 @@ static struct clk_factors_config sun4i_pll5_config = {
420 .kwidth = 2, 451 .kwidth = 2,
421}; 452};
422 453
454static struct clk_factors_config sun6i_a31_pll6_config = {
455 .nshift = 8,
456 .nwidth = 5,
457 .kshift = 4,
458 .kwidth = 2,
459};
460
423static struct clk_factors_config sun4i_apb1_config = { 461static struct clk_factors_config sun4i_apb1_config = {
424 .mshift = 0, 462 .mshift = 0,
425 .mwidth = 5, 463 .mwidth = 5,
@@ -469,6 +507,12 @@ static const struct factors_data sun4i_pll6_data __initconst = {
469 .name = "pll6", 507 .name = "pll6",
470}; 508};
471 509
510static const struct factors_data sun6i_a31_pll6_data __initconst = {
511 .enable = 31,
512 .table = &sun6i_a31_pll6_config,
513 .getter = sun6i_a31_get_pll6_factors,
514};
515
472static const struct factors_data sun4i_apb1_data __initconst = { 516static const struct factors_data sun4i_apb1_data __initconst = {
473 .table = &sun4i_apb1_config, 517 .table = &sun4i_apb1_config,
474 .getter = sun4i_get_apb1_factors, 518 .getter = sun4i_get_apb1_factors,
@@ -1069,6 +1113,7 @@ free_clkdata:
1069static const struct of_device_id clk_factors_match[] __initconst = { 1113static const struct of_device_id clk_factors_match[] __initconst = {
1070 {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,}, 1114 {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
1071 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, 1115 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
1116 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
1072 {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, 1117 {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
1073 {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, 1118 {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
1074 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, 1119 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},