aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/sunxi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/sunxi')
-rw-r--r--drivers/clk/sunxi/Makefile4
-rw-r--r--drivers/clk/sunxi/clk-a20-gmac.c2
-rw-r--r--drivers/clk/sunxi/clk-factors.c2
-rw-r--r--drivers/clk/sunxi/clk-factors.h1
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0-gates.c76
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0.c2
-rw-r--r--drivers/clk/sunxi/clk-sun6i-ar100.c4
-rw-r--r--drivers/clk/sunxi/clk-sun8i-apb0.c68
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c129
9 files changed, 236 insertions, 52 deletions
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 762fd64dbd1f..6850cba35871 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -6,4 +6,6 @@ obj-y += clk-sunxi.o clk-factors.o
6obj-y += clk-a10-hosc.o 6obj-y += clk-a10-hosc.o
7obj-y += clk-a20-gmac.o 7obj-y += clk-a20-gmac.o
8 8
9obj-$(CONFIG_MFD_SUN6I_PRCM) += clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o 9obj-$(CONFIG_MFD_SUN6I_PRCM) += \
10 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
11 clk-sun8i-apb0.o
diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c
index 633ddc4389ef..5296fd6dd7b3 100644
--- a/drivers/clk/sunxi/clk-a20-gmac.c
+++ b/drivers/clk/sunxi/clk-a20-gmac.c
@@ -60,7 +60,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
60 struct clk_gate *gate; 60 struct clk_gate *gate;
61 const char *clk_name = node->name; 61 const char *clk_name = node->name;
62 const char *parents[SUN7I_A20_GMAC_PARENTS]; 62 const char *parents[SUN7I_A20_GMAC_PARENTS];
63 void *reg; 63 void __iomem *reg;
64 64
65 if (of_property_read_string(node, "clock-output-names", &clk_name)) 65 if (of_property_read_string(node, "clock-output-names", &clk_name))
66 return; 66 return;
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 3806d97e529b..2057c8ac648f 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -62,7 +62,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
62 p = FACTOR_GET(config->pshift, config->pwidth, reg); 62 p = FACTOR_GET(config->pshift, config->pwidth, reg);
63 63
64 /* Calculate the rate */ 64 /* Calculate the rate */
65 rate = (parent_rate * n * (k + 1) >> p) / (m + 1); 65 rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1);
66 66
67 return rate; 67 return rate;
68} 68}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 02e1a43ebac7..d2d0efa39379 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -15,6 +15,7 @@ struct clk_factors_config {
15 u8 mwidth; 15 u8 mwidth;
16 u8 pshift; 16 u8 pshift;
17 u8 pwidth; 17 u8 pwidth;
18 u8 n_start;
18}; 19};
19 20
20struct clk_factors { 21struct clk_factors {
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
index 670f90d629d7..e10d0521ec76 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
@@ -9,23 +9,53 @@
9 */ 9 */
10 10
11#include <linux/clk-provider.h> 11#include <linux/clk-provider.h>
12#include <linux/clkdev.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/of_device.h>
14#include <linux/platform_device.h> 16#include <linux/platform_device.h>
15 17
16#define SUN6I_APB0_GATES_MAX_SIZE 32 18#define SUN6I_APB0_GATES_MAX_SIZE 32
17 19
20struct gates_data {
21 DECLARE_BITMAP(mask, SUN6I_APB0_GATES_MAX_SIZE);
22};
23
24static const struct gates_data sun6i_a31_apb0_gates __initconst = {
25 .mask = {0x7F},
26};
27
28static const struct gates_data sun8i_a23_apb0_gates __initconst = {
29 .mask = {0x5D},
30};
31
32static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
33 { .compatible = "allwinner,sun6i-a31-apb0-gates-clk", .data = &sun6i_a31_apb0_gates },
34 { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
35 { /* sentinel */ }
36};
37
18static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) 38static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
19{ 39{
20 struct device_node *np = pdev->dev.of_node; 40 struct device_node *np = pdev->dev.of_node;
21 struct clk_onecell_data *clk_data; 41 struct clk_onecell_data *clk_data;
42 const struct of_device_id *device;
43 const struct gates_data *data;
22 const char *clk_parent; 44 const char *clk_parent;
23 const char *clk_name; 45 const char *clk_name;
24 struct resource *r; 46 struct resource *r;
25 void __iomem *reg; 47 void __iomem *reg;
26 int gate_id;
27 int ngates; 48 int ngates;
28 int i; 49 int i;
50 int j = 0;
51
52 if (!np)
53 return -ENODEV;
54
55 device = of_match_device(sun6i_a31_apb0_gates_clk_dt_ids, &pdev->dev);
56 if (!device)
57 return -ENODEV;
58 data = device->data;
29 59
30 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 60 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
31 reg = devm_ioremap_resource(&pdev->dev, r); 61 reg = devm_ioremap_resource(&pdev->dev, r);
@@ -36,54 +66,36 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
36 if (!clk_parent) 66 if (!clk_parent)
37 return -EINVAL; 67 return -EINVAL;
38 68
39 ngates = of_property_count_strings(np, "clock-output-names");
40 if (ngates < 0)
41 return ngates;
42
43 if (!ngates || ngates > SUN6I_APB0_GATES_MAX_SIZE)
44 return -EINVAL;
45
46 clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data), 69 clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
47 GFP_KERNEL); 70 GFP_KERNEL);
48 if (!clk_data) 71 if (!clk_data)
49 return -ENOMEM; 72 return -ENOMEM;
50 73
51 clk_data->clks = devm_kzalloc(&pdev->dev, 74 /* Worst-case size approximation and memory allocation */
52 SUN6I_APB0_GATES_MAX_SIZE * 75 ngates = find_last_bit(data->mask, SUN6I_APB0_GATES_MAX_SIZE);
53 sizeof(struct clk *), 76 clk_data->clks = devm_kcalloc(&pdev->dev, (ngates + 1),
54 GFP_KERNEL); 77 sizeof(struct clk *), GFP_KERNEL);
55 if (!clk_data->clks) 78 if (!clk_data->clks)
56 return -ENOMEM; 79 return -ENOMEM;
57 80
58 for (i = 0; i < ngates; i++) { 81 for_each_set_bit(i, data->mask, SUN6I_APB0_GATES_MAX_SIZE) {
59 of_property_read_string_index(np, "clock-output-names", 82 of_property_read_string_index(np, "clock-output-names",
60 i, &clk_name); 83 j, &clk_name);
61 84
62 gate_id = i; 85 clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
63 of_property_read_u32_index(np, "clock-indices", i, &gate_id); 86 clk_parent, 0, reg, i,
87 0, NULL);
88 WARN_ON(IS_ERR(clk_data->clks[i]));
89 clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
64 90
65 WARN_ON(gate_id >= SUN6I_APB0_GATES_MAX_SIZE); 91 j++;
66 if (gate_id >= SUN6I_APB0_GATES_MAX_SIZE)
67 continue;
68
69 clk_data->clks[gate_id] = clk_register_gate(&pdev->dev,
70 clk_name,
71 clk_parent, 0,
72 reg, gate_id,
73 0, NULL);
74 WARN_ON(IS_ERR(clk_data->clks[gate_id]));
75 } 92 }
76 93
77 clk_data->clk_num = ngates; 94 clk_data->clk_num = ngates + 1;
78 95
79 return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 96 return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
80} 97}
81 98
82const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
83 { .compatible = "allwinner,sun6i-a31-apb0-gates-clk" },
84 { /* sentinel */ }
85};
86
87static struct platform_driver sun6i_a31_apb0_gates_clk_driver = { 99static struct platform_driver sun6i_a31_apb0_gates_clk_driver = {
88 .driver = { 100 .driver = {
89 .name = "sun6i-a31-apb0-gates-clk", 101 .name = "sun6i-a31-apb0-gates-clk",
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c
index 11f17c34c2ae..1fa23371c8c6 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0.c
@@ -57,7 +57,7 @@ static int sun6i_a31_apb0_clk_probe(struct platform_device *pdev)
57 return of_clk_add_provider(np, of_clk_src_simple_get, clk); 57 return of_clk_add_provider(np, of_clk_src_simple_get, clk);
58} 58}
59 59
60const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = { 60static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
61 { .compatible = "allwinner,sun6i-a31-apb0-clk" }, 61 { .compatible = "allwinner,sun6i-a31-apb0-clk" },
62 { /* sentinel */ } 62 { /* sentinel */ }
63}; 63};
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index f73cc051f0dd..eca8ca025b6a 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -160,7 +160,7 @@ static int ar100_set_rate(struct clk_hw *hw, unsigned long rate,
160 return 0; 160 return 0;
161} 161}
162 162
163struct clk_ops ar100_ops = { 163static struct clk_ops ar100_ops = {
164 .recalc_rate = ar100_recalc_rate, 164 .recalc_rate = ar100_recalc_rate,
165 .determine_rate = ar100_determine_rate, 165 .determine_rate = ar100_determine_rate,
166 .set_parent = ar100_set_parent, 166 .set_parent = ar100_set_parent,
@@ -213,7 +213,7 @@ static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev)
213 return of_clk_add_provider(np, of_clk_src_simple_get, clk); 213 return of_clk_add_provider(np, of_clk_src_simple_get, clk);
214} 214}
215 215
216const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { 216static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
217 { .compatible = "allwinner,sun6i-a31-ar100-clk" }, 217 { .compatible = "allwinner,sun6i-a31-ar100-clk" },
218 { /* sentinel */ } 218 { /* sentinel */ }
219}; 219};
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
new file mode 100644
index 000000000000..1f5ba9b4b8cd
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014 Chen-Yu Tsai
3 * Author: Chen-Yu Tsai <wens@csie.org>
4 *
5 * Allwinner A23 APB0 clock driver
6 *
7 * License Terms: GNU General Public License v2
8 *
9 * Based on clk-sun6i-apb0.c
10 * Allwinner A31 APB0 clock driver
11 *
12 * Copyright (C) 2014 Free Electrons
13 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
14 *
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/platform_device.h>
21
22static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
23{
24 struct device_node *np = pdev->dev.of_node;
25 const char *clk_name = np->name;
26 const char *clk_parent;
27 struct resource *r;
28 void __iomem *reg;
29 struct clk *clk;
30
31 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
32 reg = devm_ioremap_resource(&pdev->dev, r);
33 if (IS_ERR(reg))
34 return PTR_ERR(reg);
35
36 clk_parent = of_clk_get_parent_name(np, 0);
37 if (!clk_parent)
38 return -EINVAL;
39
40 of_property_read_string(np, "clock-output-names", &clk_name);
41
42 /* The A23 APB0 clock is a standard 2 bit wide divider clock */
43 clk = clk_register_divider(&pdev->dev, clk_name, clk_parent, 0, reg,
44 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
45 if (IS_ERR(clk))
46 return PTR_ERR(clk);
47
48 return of_clk_add_provider(np, of_clk_src_simple_get, clk);
49}
50
51static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
52 { .compatible = "allwinner,sun8i-a23-apb0-clk" },
53 { /* sentinel */ }
54};
55
56static struct platform_driver sun8i_a23_apb0_clk_driver = {
57 .driver = {
58 .name = "sun8i-a23-apb0-clk",
59 .owner = THIS_MODULE,
60 .of_match_table = sun8i_a23_apb0_clk_dt_ids,
61 },
62 .probe = sun8i_a23_apb0_clk_probe,
63};
64module_platform_driver(sun8i_a23_apb0_clk_driver);
65
66MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
67MODULE_DESCRIPTION("Allwinner A23 APB0 clock Driver");
68MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index fb2ce8440f0e..b654b7b1d137 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -164,6 +164,54 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
164} 164}
165 165
166/** 166/**
167 * sun8i_a23_get_pll1_factors() - calculates n, k, m, p factors for PLL1
168 * PLL1 rate is calculated as follows
169 * rate = (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
170 * parent_rate is always 24Mhz
171 */
172
173static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate,
174 u8 *n, u8 *k, u8 *m, u8 *p)
175{
176 u8 div;
177
178 /* Normalize value to a 6M multiple */
179 div = *freq / 6000000;
180 *freq = 6000000 * div;
181
182 /* we were called to round the frequency, we can now return */
183 if (n == NULL)
184 return;
185
186 /* m is always zero for pll1 */
187 *m = 0;
188
189 /* k is 1 only on these cases */
190 if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
191 *k = 1;
192 else
193 *k = 0;
194
195 /* p will be 2 for divs under 20 and odd divs under 32 */
196 if (div < 20 || (div < 32 && (div & 1)))
197 *p = 2;
198
199 /* p will be 1 for even divs under 32, divs under 40 and odd pairs
200 * of divs between 40-62 */
201 else if (div < 40 || (div < 64 && (div & 2)))
202 *p = 1;
203
204 /* any other entries have p = 0 */
205 else
206 *p = 0;
207
208 /* calculate a suitable n based on k and p */
209 div <<= *p;
210 div /= (*k + 1);
211 *n = div / 4 - 1;
212}
213
214/**
167 * sun4i_get_pll5_factors() - calculates n, k factors for PLL5 215 * sun4i_get_pll5_factors() - calculates n, k factors for PLL5
168 * PLL5 rate is calculated as follows 216 * PLL5 rate is calculated as follows
169 * rate = parent_rate * n * (k + 1) 217 * rate = parent_rate * n * (k + 1)
@@ -422,6 +470,18 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
422 .mwidth = 2, 470 .mwidth = 2,
423}; 471};
424 472
473static struct clk_factors_config sun8i_a23_pll1_config = {
474 .nshift = 8,
475 .nwidth = 5,
476 .kshift = 4,
477 .kwidth = 2,
478 .mshift = 0,
479 .mwidth = 2,
480 .pshift = 16,
481 .pwidth = 2,
482 .n_start = 1,
483};
484
425static struct clk_factors_config sun4i_pll5_config = { 485static struct clk_factors_config sun4i_pll5_config = {
426 .nshift = 8, 486 .nshift = 8,
427 .nwidth = 5, 487 .nwidth = 5,
@@ -471,6 +531,12 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = {
471 .getter = sun6i_a31_get_pll1_factors, 531 .getter = sun6i_a31_get_pll1_factors,
472}; 532};
473 533
534static const struct factors_data sun8i_a23_pll1_data __initconst = {
535 .enable = 31,
536 .table = &sun8i_a23_pll1_config,
537 .getter = sun8i_a23_get_pll1_factors,
538};
539
474static const struct factors_data sun7i_a20_pll4_data __initconst = { 540static const struct factors_data sun7i_a20_pll4_data __initconst = {
475 .enable = 31, 541 .enable = 31,
476 .table = &sun4i_pll5_config, 542 .table = &sun4i_pll5_config,
@@ -527,7 +593,7 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
527 struct clk_hw *mux_hw = NULL; 593 struct clk_hw *mux_hw = NULL;
528 const char *clk_name = node->name; 594 const char *clk_name = node->name;
529 const char *parents[SUNXI_MAX_PARENTS]; 595 const char *parents[SUNXI_MAX_PARENTS];
530 void *reg; 596 void __iomem *reg;
531 int i = 0; 597 int i = 0;
532 598
533 reg = of_iomap(node, 0); 599 reg = of_iomap(node, 0);
@@ -632,7 +698,7 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
632 struct clk *clk; 698 struct clk *clk;
633 const char *clk_name = node->name; 699 const char *clk_name = node->name;
634 const char *parents[SUNXI_MAX_PARENTS]; 700 const char *parents[SUNXI_MAX_PARENTS];
635 void *reg; 701 void __iomem *reg;
636 int i = 0; 702 int i = 0;
637 703
638 reg = of_iomap(node, 0); 704 reg = of_iomap(node, 0);
@@ -664,6 +730,7 @@ struct div_data {
664 u8 shift; 730 u8 shift;
665 u8 pow; 731 u8 pow;
666 u8 width; 732 u8 width;
733 const struct clk_div_table *table;
667}; 734};
668 735
669static const struct div_data sun4i_axi_data __initconst = { 736static const struct div_data sun4i_axi_data __initconst = {
@@ -672,6 +739,23 @@ static const struct div_data sun4i_axi_data __initconst = {
672 .width = 2, 739 .width = 2,
673}; 740};
674 741
742static const struct clk_div_table sun8i_a23_axi_table[] __initconst = {
743 { .val = 0, .div = 1 },
744 { .val = 1, .div = 2 },
745 { .val = 2, .div = 3 },
746 { .val = 3, .div = 4 },
747 { .val = 4, .div = 4 },
748 { .val = 5, .div = 4 },
749 { .val = 6, .div = 4 },
750 { .val = 7, .div = 4 },
751 { } /* sentinel */
752};
753
754static const struct div_data sun8i_a23_axi_data __initconst = {
755 .width = 3,
756 .table = sun8i_a23_axi_table,
757};
758
675static const struct div_data sun4i_ahb_data __initconst = { 759static const struct div_data sun4i_ahb_data __initconst = {
676 .shift = 4, 760 .shift = 4,
677 .pow = 1, 761 .pow = 1,
@@ -696,7 +780,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
696 struct clk *clk; 780 struct clk *clk;
697 const char *clk_name = node->name; 781 const char *clk_name = node->name;
698 const char *clk_parent; 782 const char *clk_parent;
699 void *reg; 783 void __iomem *reg;
700 784
701 reg = of_iomap(node, 0); 785 reg = of_iomap(node, 0);
702 786
@@ -704,10 +788,10 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
704 788
705 of_property_read_string(node, "clock-output-names", &clk_name); 789 of_property_read_string(node, "clock-output-names", &clk_name);
706 790
707 clk = clk_register_divider(NULL, clk_name, clk_parent, 0, 791 clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0,
708 reg, data->shift, data->width, 792 reg, data->shift, data->width,
709 data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, 793 data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
710 &clk_lock); 794 data->table, &clk_lock);
711 if (clk) { 795 if (clk) {
712 of_clk_add_provider(node, of_clk_src_simple_get, clk); 796 of_clk_add_provider(node, of_clk_src_simple_get, clk);
713 clk_register_clkdev(clk, clk_name, NULL); 797 clk_register_clkdev(clk, clk_name, NULL);
@@ -804,6 +888,10 @@ static const struct gates_data sun7i_a20_ahb_gates_data __initconst = {
804 .mask = { 0x12f77fff, 0x16ff3f }, 888 .mask = { 0x12f77fff, 0x16ff3f },
805}; 889};
806 890
891static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = {
892 .mask = {0x25386742, 0x2505111},
893};
894
807static const struct gates_data sun4i_apb0_gates_data __initconst = { 895static const struct gates_data sun4i_apb0_gates_data __initconst = {
808 .mask = {0x4EF}, 896 .mask = {0x4EF},
809}; 897};
@@ -836,6 +924,10 @@ static const struct gates_data sun6i_a31_apb1_gates_data __initconst = {
836 .mask = {0x3031}, 924 .mask = {0x3031},
837}; 925};
838 926
927static const struct gates_data sun8i_a23_apb1_gates_data __initconst = {
928 .mask = {0x3021},
929};
930
839static const struct gates_data sun6i_a31_apb2_gates_data __initconst = { 931static const struct gates_data sun6i_a31_apb2_gates_data __initconst = {
840 .mask = {0x3F000F}, 932 .mask = {0x3F000F},
841}; 933};
@@ -844,6 +936,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
844 .mask = { 0xff80ff }, 936 .mask = { 0xff80ff },
845}; 937};
846 938
939static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
940 .mask = {0x1F0007},
941};
942
847static const struct gates_data sun4i_a10_usb_gates_data __initconst = { 943static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
848 .mask = {0x1C0}, 944 .mask = {0x1C0},
849 .reset_mask = 0x07, 945 .reset_mask = 0x07,
@@ -866,11 +962,10 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
866 struct gates_reset_data *reset_data; 962 struct gates_reset_data *reset_data;
867 const char *clk_parent; 963 const char *clk_parent;
868 const char *clk_name; 964 const char *clk_name;
869 void *reg; 965 void __iomem *reg;
870 int qty; 966 int qty;
871 int i = 0; 967 int i = 0;
872 int j = 0; 968 int j = 0;
873 int ignore;
874 969
875 reg = of_iomap(node, 0); 970 reg = of_iomap(node, 0);
876 971
@@ -891,14 +986,12 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
891 of_property_read_string_index(node, "clock-output-names", 986 of_property_read_string_index(node, "clock-output-names",
892 j, &clk_name); 987 j, &clk_name);
893 988
894 /* No driver claims this clock, but it should remain gated */
895 ignore = !strcmp("ahb_sdram", clk_name) ? CLK_IGNORE_UNUSED : 0;
896
897 clk_data->clks[i] = clk_register_gate(NULL, clk_name, 989 clk_data->clks[i] = clk_register_gate(NULL, clk_name,
898 clk_parent, ignore, 990 clk_parent, 0,
899 reg + 4 * (i/32), i % 32, 991 reg + 4 * (i/32), i % 32,
900 0, &clk_lock); 992 0, &clk_lock);
901 WARN_ON(IS_ERR(clk_data->clks[i])); 993 WARN_ON(IS_ERR(clk_data->clks[i]));
994 clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
902 995
903 j++; 996 j++;
904 } 997 }
@@ -991,7 +1084,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
991 struct clk_gate *gate = NULL; 1084 struct clk_gate *gate = NULL;
992 struct clk_fixed_factor *fix_factor; 1085 struct clk_fixed_factor *fix_factor;
993 struct clk_divider *divider; 1086 struct clk_divider *divider;
994 void *reg; 1087 void __iomem *reg;
995 int i = 0; 1088 int i = 0;
996 int flags, clkflags; 1089 int flags, clkflags;
997 1090
@@ -1102,6 +1195,7 @@ free_clkdata:
1102static const struct of_device_id clk_factors_match[] __initconst = { 1195static const struct of_device_id clk_factors_match[] __initconst = {
1103 {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, 1196 {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,},
1104 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, 1197 {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
1198 {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
1105 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, 1199 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
1106 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, 1200 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
1107 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, 1201 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
@@ -1113,6 +1207,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
1113/* Matches for divider clocks */ 1207/* Matches for divider clocks */
1114static const struct of_device_id clk_div_match[] __initconst = { 1208static const struct of_device_id clk_div_match[] __initconst = {
1115 {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, 1209 {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,},
1210 {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,},
1116 {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, 1211 {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,},
1117 {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, 1212 {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,},
1118 {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, 1213 {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
@@ -1142,6 +1237,7 @@ static const struct of_device_id clk_gates_match[] __initconst = {
1142 {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, 1237 {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
1143 {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, 1238 {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
1144 {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, 1239 {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
1240 {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,},
1145 {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, 1241 {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
1146 {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, 1242 {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
1147 {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, 1243 {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
@@ -1151,7 +1247,9 @@ static const struct of_device_id clk_gates_match[] __initconst = {
1151 {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, 1247 {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
1152 {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, 1248 {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
1153 {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, 1249 {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
1250 {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,},
1154 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, 1251 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
1252 {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
1155 {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, 1253 {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
1156 {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,}, 1254 {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
1157 {.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,}, 1255 {.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,},
@@ -1202,6 +1300,7 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
1202 1300
1203static const char *sun4i_a10_critical_clocks[] __initdata = { 1301static const char *sun4i_a10_critical_clocks[] __initdata = {
1204 "pll5_ddr", 1302 "pll5_ddr",
1303 "ahb_sdram",
1205}; 1304};
1206 1305
1207static void __init sun4i_a10_init_clocks(struct device_node *node) 1306static void __init sun4i_a10_init_clocks(struct device_node *node)
@@ -1214,6 +1313,7 @@ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks)
1214static const char *sun5i_critical_clocks[] __initdata = { 1313static const char *sun5i_critical_clocks[] __initdata = {
1215 "mbus", 1314 "mbus",
1216 "pll5_ddr", 1315 "pll5_ddr",
1316 "ahb_sdram",
1217}; 1317};
1218 1318
1219static void __init sun5i_init_clocks(struct device_node *node) 1319static void __init sun5i_init_clocks(struct device_node *node)
@@ -1236,3 +1336,4 @@ static void __init sun6i_init_clocks(struct device_node *node)
1236 ARRAY_SIZE(sun6i_critical_clocks)); 1336 ARRAY_SIZE(sun6i_critical_clocks));
1237} 1337}
1238CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); 1338CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
1339CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);