diff options
author | Mike Turquette <mturquette@linaro.org> | 2013-08-27 21:07:46 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-08-27 21:07:46 -0400 |
commit | c045ddeb3893c4614e6ab694b8d297e3badc23af (patch) | |
tree | 6e13aa83c08809b9d082511b43270da8d11551e5 | |
parent | aa514ce34b65e3dc01f95a0b470b39bbb7e09998 (diff) | |
parent | 1fb2e4aab8b31b15e6be5debacb4203333360fd2 (diff) |
Merge tag 'sunxi-clk-for-3.12' of https://github.com/mripard/linux into clk-next-sunxi
Allwinner clock changes for 3.12
These patches mostly do some cleanup to introduce the basic gated clocks for
the Allwinner A10s, A20 and A31 SoCs.
Conflicts:
drivers/clk/sunxi/clk-sunxi.c
5 files changed, 462 insertions, 38 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index d495521a79d2..00a5c26454eb 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt | |||
@@ -8,19 +8,31 @@ Required properties: | |||
8 | - compatible : shall be one of the following: | 8 | - compatible : shall be one of the following: |
9 | "allwinner,sun4i-osc-clk" - for a gatable oscillator | 9 | "allwinner,sun4i-osc-clk" - for a gatable oscillator |
10 | "allwinner,sun4i-pll1-clk" - for the main PLL clock | 10 | "allwinner,sun4i-pll1-clk" - for the main PLL clock |
11 | "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 | ||
11 | "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock | 12 | "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock |
12 | "allwinner,sun4i-axi-clk" - for the AXI clock | 13 | "allwinner,sun4i-axi-clk" - for the AXI clock |
13 | "allwinner,sun4i-axi-gates-clk" - for the AXI gates | 14 | "allwinner,sun4i-axi-gates-clk" - for the AXI gates |
14 | "allwinner,sun4i-ahb-clk" - for the AHB clock | 15 | "allwinner,sun4i-ahb-clk" - for the AHB clock |
15 | "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10 | 16 | "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10 |
16 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 | 17 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 |
18 | "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s | ||
19 | "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20 | ||
20 | "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 | ||
21 | "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 | ||
17 | "allwinner,sun4i-apb0-clk" - for the APB0 clock | 22 | "allwinner,sun4i-apb0-clk" - for the APB0 clock |
18 | "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10 | 23 | "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10 |
19 | "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 | 24 | "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 |
25 | "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s | ||
26 | "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 | ||
20 | "allwinner,sun4i-apb1-clk" - for the APB1 clock | 27 | "allwinner,sun4i-apb1-clk" - for the APB1 clock |
21 | "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing | 28 | "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing |
22 | "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10 | 29 | "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10 |
23 | "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 | 30 | "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 |
31 | "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s | ||
32 | "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31 | ||
33 | "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 | ||
34 | "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 | ||
35 | "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 | ||
24 | 36 | ||
25 | Required properties for all clocks: | 37 | Required properties for all clocks: |
26 | - reg : shall be the control register address for the clock. | 38 | - reg : shall be the control register address for the clock. |
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt new file mode 100644 index 000000000000..d24279fe1429 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sunxi/sun5i-a10s-gates.txt | |||
@@ -0,0 +1,75 @@ | |||
1 | Gate clock outputs | ||
2 | ------------------ | ||
3 | |||
4 | * AXI gates ("allwinner,sun4i-axi-gates-clk") | ||
5 | |||
6 | DRAM 0 | ||
7 | |||
8 | * AHB gates ("allwinner,sun5i-a10s-ahb-gates-clk") | ||
9 | |||
10 | USB0 0 | ||
11 | EHCI0 1 | ||
12 | OHCI0 2 | ||
13 | |||
14 | SS 5 | ||
15 | DMA 6 | ||
16 | BIST 7 | ||
17 | MMC0 8 | ||
18 | MMC1 9 | ||
19 | MMC2 10 | ||
20 | |||
21 | NAND 13 | ||
22 | SDRAM 14 | ||
23 | |||
24 | EMAC 17 | ||
25 | TS 18 | ||
26 | |||
27 | SPI0 20 | ||
28 | SPI1 21 | ||
29 | SPI2 22 | ||
30 | |||
31 | GPS 26 | ||
32 | |||
33 | HSTIMER 28 | ||
34 | |||
35 | VE 32 | ||
36 | |||
37 | TVE 34 | ||
38 | |||
39 | LCD 36 | ||
40 | |||
41 | CSI 40 | ||
42 | |||
43 | HDMI 43 | ||
44 | DE_BE 44 | ||
45 | |||
46 | DE_FE 46 | ||
47 | |||
48 | IEP 51 | ||
49 | MALI400 52 | ||
50 | |||
51 | * APB0 gates ("allwinner,sun5i-a10s-apb0-gates-clk") | ||
52 | |||
53 | CODEC 0 | ||
54 | |||
55 | IIS 3 | ||
56 | |||
57 | PIO 5 | ||
58 | IR 6 | ||
59 | |||
60 | KEYPAD 10 | ||
61 | |||
62 | * APB1 gates ("allwinner,sun5i-a10s-apb1-gates-clk") | ||
63 | |||
64 | I2C0 0 | ||
65 | I2C1 1 | ||
66 | I2C2 2 | ||
67 | |||
68 | UART0 16 | ||
69 | UART1 17 | ||
70 | UART2 18 | ||
71 | UART3 19 | ||
72 | |||
73 | Notation: | ||
74 | [*]: The datasheet didn't mention these, but they are present on AW code | ||
75 | [**]: The datasheet had this marked as "NC" but they are used on AW code | ||
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt new file mode 100644 index 000000000000..fe44932b5c6b --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sunxi/sun6i-a31-gates.txt | |||
@@ -0,0 +1,83 @@ | |||
1 | Gate clock outputs | ||
2 | ------------------ | ||
3 | |||
4 | * AHB1 gates ("allwinner,sun6i-a31-ahb1-gates-clk") | ||
5 | |||
6 | MIPI DSI 1 | ||
7 | |||
8 | SS 5 | ||
9 | DMA 6 | ||
10 | |||
11 | MMC0 8 | ||
12 | MMC1 9 | ||
13 | MMC2 10 | ||
14 | MMC3 11 | ||
15 | |||
16 | NAND1 12 | ||
17 | NAND0 13 | ||
18 | SDRAM 14 | ||
19 | |||
20 | GMAC 17 | ||
21 | TS 18 | ||
22 | HSTIMER 19 | ||
23 | SPI0 20 | ||
24 | SPI1 21 | ||
25 | SPI2 22 | ||
26 | SPI3 23 | ||
27 | USB_OTG 24 | ||
28 | |||
29 | EHCI0 26 | ||
30 | EHCI1 27 | ||
31 | |||
32 | OHCI0 29 | ||
33 | OHCI1 30 | ||
34 | OHCI2 31 | ||
35 | VE 32 | ||
36 | |||
37 | LCD0 36 | ||
38 | LCD1 37 | ||
39 | |||
40 | CSI 40 | ||
41 | |||
42 | HDMI 43 | ||
43 | DE_BE0 44 | ||
44 | DE_BE1 45 | ||
45 | DE_FE1 46 | ||
46 | DE_FE1 47 | ||
47 | |||
48 | MP 50 | ||
49 | |||
50 | GPU 52 | ||
51 | |||
52 | DEU0 55 | ||
53 | DEU1 56 | ||
54 | DRC0 57 | ||
55 | DRC1 58 | ||
56 | |||
57 | * APB1 gates ("allwinner,sun6i-a31-apb1-gates-clk") | ||
58 | |||
59 | CODEC 0 | ||
60 | |||
61 | DIGITAL MIC 4 | ||
62 | PIO 5 | ||
63 | |||
64 | DAUDIO0 12 | ||
65 | DAUDIO1 13 | ||
66 | |||
67 | * APB2 gates ("allwinner,sun6i-a31-apb2-gates-clk") | ||
68 | |||
69 | I2C0 0 | ||
70 | I2C1 1 | ||
71 | I2C2 2 | ||
72 | I2C3 3 | ||
73 | |||
74 | UART0 16 | ||
75 | UART1 17 | ||
76 | UART2 18 | ||
77 | UART3 19 | ||
78 | UART4 20 | ||
79 | UART5 21 | ||
80 | |||
81 | Notation: | ||
82 | [*]: The datasheet didn't mention these, but they are present on AW code | ||
83 | [**]: The datasheet had this marked as "NC" but they are used on AW code | ||
diff --git a/Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt b/Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt new file mode 100644 index 000000000000..357f4fdc02ef --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sunxi/sun7i-a20-gates.txt | |||
@@ -0,0 +1,98 @@ | |||
1 | Gate clock outputs | ||
2 | ------------------ | ||
3 | |||
4 | * AXI gates ("allwinner,sun4i-axi-gates-clk") | ||
5 | |||
6 | DRAM 0 | ||
7 | |||
8 | * AHB gates ("allwinner,sun7i-a20-ahb-gates-clk") | ||
9 | |||
10 | USB0 0 | ||
11 | EHCI0 1 | ||
12 | OHCI0 2 | ||
13 | EHCI1 3 | ||
14 | OHCI1 4 | ||
15 | SS 5 | ||
16 | DMA 6 | ||
17 | BIST 7 | ||
18 | MMC0 8 | ||
19 | MMC1 9 | ||
20 | MMC2 10 | ||
21 | MMC3 11 | ||
22 | MS 12 | ||
23 | NAND 13 | ||
24 | SDRAM 14 | ||
25 | |||
26 | ACE 16 | ||
27 | EMAC 17 | ||
28 | TS 18 | ||
29 | |||
30 | SPI0 20 | ||
31 | SPI1 21 | ||
32 | SPI2 22 | ||
33 | SPI3 23 | ||
34 | |||
35 | SATA 25 | ||
36 | |||
37 | HSTIMER 28 | ||
38 | |||
39 | VE 32 | ||
40 | TVD 33 | ||
41 | TVE0 34 | ||
42 | TVE1 35 | ||
43 | LCD0 36 | ||
44 | LCD1 37 | ||
45 | |||
46 | CSI0 40 | ||
47 | CSI1 41 | ||
48 | |||
49 | HDMI1 42 | ||
50 | HDMI0 43 | ||
51 | DE_BE0 44 | ||
52 | DE_BE1 45 | ||
53 | DE_FE1 46 | ||
54 | DE_FE1 47 | ||
55 | |||
56 | GMAC 49 | ||
57 | MP 50 | ||
58 | |||
59 | MALI400 52 | ||
60 | |||
61 | * APB0 gates ("allwinner,sun7i-a20-apb0-gates-clk") | ||
62 | |||
63 | CODEC 0 | ||
64 | SPDIF 1 | ||
65 | AC97 2 | ||
66 | IIS0 3 | ||
67 | IIS1 4 | ||
68 | PIO 5 | ||
69 | IR0 6 | ||
70 | IR1 7 | ||
71 | IIS2 8 | ||
72 | |||
73 | KEYPAD 10 | ||
74 | |||
75 | * APB1 gates ("allwinner,sun7i-a20-apb1-gates-clk") | ||
76 | |||
77 | I2C0 0 | ||
78 | I2C1 1 | ||
79 | I2C2 2 | ||
80 | I2C3 3 | ||
81 | CAN 4 | ||
82 | SCR 5 | ||
83 | PS20 6 | ||
84 | PS21 7 | ||
85 | |||
86 | I2C4 15 | ||
87 | UART0 16 | ||
88 | UART1 17 | ||
89 | UART2 18 | ||
90 | UART3 19 | ||
91 | UART4 20 | ||
92 | UART5 21 | ||
93 | UART6 22 | ||
94 | UART7 23 | ||
95 | |||
96 | Notation: | ||
97 | [*]: The datasheet didn't mention these, but they are present on AW code | ||
98 | [**]: The datasheet had this marked as "NC" but they are used on AW code | ||
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 3bbfca5850fd..d39f213f0fbe 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -25,12 +25,12 @@ | |||
25 | static DEFINE_SPINLOCK(clk_lock); | 25 | static DEFINE_SPINLOCK(clk_lock); |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * sunxi_osc_clk_setup() - Setup function for gatable oscillator | 28 | * sun4i_osc_clk_setup() - Setup function for gatable oscillator |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #define SUNXI_OSC24M_GATE 0 | 31 | #define SUNXI_OSC24M_GATE 0 |
32 | 32 | ||
33 | static void __init sunxi_osc_clk_setup(struct device_node *node) | 33 | static void __init sun4i_osc_clk_setup(struct device_node *node) |
34 | { | 34 | { |
35 | struct clk *clk; | 35 | struct clk *clk; |
36 | struct clk_fixed_rate *fixed; | 36 | struct clk_fixed_rate *fixed; |
@@ -69,18 +69,18 @@ static void __init sunxi_osc_clk_setup(struct device_node *node) | |||
69 | clk_register_clkdev(clk, clk_name, NULL); | 69 | clk_register_clkdev(clk, clk_name, NULL); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | CLK_OF_DECLARE(sunxi_osc, "allwinner,sun4i-osc-clk", sunxi_osc_clk_setup); | 72 | CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup); |
73 | 73 | ||
74 | 74 | ||
75 | 75 | ||
76 | /** | 76 | /** |
77 | * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1 | 77 | * sun4i_get_pll1_factors() - calculates n, k, m, p factors for PLL1 |
78 | * PLL1 rate is calculated as follows | 78 | * PLL1 rate is calculated as follows |
79 | * rate = (parent_rate * n * (k + 1) >> p) / (m + 1); | 79 | * rate = (parent_rate * n * (k + 1) >> p) / (m + 1); |
80 | * parent_rate is always 24Mhz | 80 | * parent_rate is always 24Mhz |
81 | */ | 81 | */ |
82 | 82 | ||
83 | static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate, | 83 | static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, |
84 | u8 *n, u8 *k, u8 *m, u8 *p) | 84 | u8 *n, u8 *k, u8 *m, u8 *p) |
85 | { | 85 | { |
86 | u8 div; | 86 | u8 div; |
@@ -125,15 +125,97 @@ static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate, | |||
125 | *n = div / 4; | 125 | *n = div / 4; |
126 | } | 126 | } |
127 | 127 | ||
128 | /** | ||
129 | * sun6i_a31_get_pll1_factors() - calculates n, k and m factors for PLL1 | ||
130 | * PLL1 rate is calculated as follows | ||
131 | * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); | ||
132 | * parent_rate should always be 24MHz | ||
133 | */ | ||
134 | static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, | ||
135 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
136 | { | ||
137 | /* | ||
138 | * We can operate only on MHz, this will make our life easier | ||
139 | * later. | ||
140 | */ | ||
141 | u32 freq_mhz = *freq / 1000000; | ||
142 | u32 parent_freq_mhz = parent_rate / 1000000; | ||
143 | |||
144 | /* | ||
145 | * Round down the frequency to the closest multiple of either | ||
146 | * 6 or 16 | ||
147 | */ | ||
148 | u32 round_freq_6 = round_down(freq_mhz, 6); | ||
149 | u32 round_freq_16 = round_down(freq_mhz, 16); | ||
150 | |||
151 | if (round_freq_6 > round_freq_16) | ||
152 | freq_mhz = round_freq_6; | ||
153 | else | ||
154 | freq_mhz = round_freq_16; | ||
128 | 155 | ||
156 | *freq = freq_mhz * 1000000; | ||
157 | |||
158 | /* | ||
159 | * If the factors pointer are null, we were just called to | ||
160 | * round down the frequency. | ||
161 | * Exit. | ||
162 | */ | ||
163 | if (n == NULL) | ||
164 | return; | ||
165 | |||
166 | /* If the frequency is a multiple of 32 MHz, k is always 3 */ | ||
167 | if (!(freq_mhz % 32)) | ||
168 | *k = 3; | ||
169 | /* If the frequency is a multiple of 9 MHz, k is always 2 */ | ||
170 | else if (!(freq_mhz % 9)) | ||
171 | *k = 2; | ||
172 | /* If the frequency is a multiple of 8 MHz, k is always 1 */ | ||
173 | else if (!(freq_mhz % 8)) | ||
174 | *k = 1; | ||
175 | /* Otherwise, we don't use the k factor */ | ||
176 | else | ||
177 | *k = 0; | ||
178 | |||
179 | /* | ||
180 | * If the frequency is a multiple of 2 but not a multiple of | ||
181 | * 3, m is 3. This is the first time we use 6 here, yet we | ||
182 | * will use it on several other places. | ||
183 | * We use this number because it's the lowest frequency we can | ||
184 | * generate (with n = 0, k = 0, m = 3), so every other frequency | ||
185 | * somehow relates to this frequency. | ||
186 | */ | ||
187 | if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) | ||
188 | *m = 2; | ||
189 | /* | ||
190 | * If the frequency is a multiple of 6MHz, but the factor is | ||
191 | * odd, m will be 3 | ||
192 | */ | ||
193 | else if ((freq_mhz / 6) & 1) | ||
194 | *m = 3; | ||
195 | /* Otherwise, we end up with m = 1 */ | ||
196 | else | ||
197 | *m = 1; | ||
198 | |||
199 | /* Calculate n thanks to the above factors we already got */ | ||
200 | *n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1; | ||
201 | |||
202 | /* | ||
203 | * If n end up being outbound, and that we can still decrease | ||
204 | * m, do it. | ||
205 | */ | ||
206 | if ((*n + 1) > 31 && (*m + 1) > 1) { | ||
207 | *n = (*n + 1) / 2 - 1; | ||
208 | *m = (*m + 1) / 2 - 1; | ||
209 | } | ||
210 | } | ||
129 | 211 | ||
130 | /** | 212 | /** |
131 | * sunxi_get_apb1_factors() - calculates m, p factors for APB1 | 213 | * sun4i_get_apb1_factors() - calculates m, p factors for APB1 |
132 | * APB1 rate is calculated as follows | 214 | * APB1 rate is calculated as follows |
133 | * rate = (parent_rate >> p) / (m + 1); | 215 | * rate = (parent_rate >> p) / (m + 1); |
134 | */ | 216 | */ |
135 | 217 | ||
136 | static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate, | 218 | static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, |
137 | u8 *n, u8 *k, u8 *m, u8 *p) | 219 | u8 *n, u8 *k, u8 *m, u8 *p) |
138 | { | 220 | { |
139 | u8 calcm, calcp; | 221 | u8 calcm, calcp; |
@@ -179,7 +261,7 @@ struct factors_data { | |||
179 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); | 261 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); |
180 | }; | 262 | }; |
181 | 263 | ||
182 | static struct clk_factors_config pll1_config = { | 264 | static struct clk_factors_config sun4i_pll1_config = { |
183 | .nshift = 8, | 265 | .nshift = 8, |
184 | .nwidth = 5, | 266 | .nwidth = 5, |
185 | .kshift = 4, | 267 | .kshift = 4, |
@@ -190,21 +272,35 @@ static struct clk_factors_config pll1_config = { | |||
190 | .pwidth = 2, | 272 | .pwidth = 2, |
191 | }; | 273 | }; |
192 | 274 | ||
193 | static struct clk_factors_config apb1_config = { | 275 | static struct clk_factors_config sun6i_a31_pll1_config = { |
276 | .nshift = 8, | ||
277 | .nwidth = 5, | ||
278 | .kshift = 4, | ||
279 | .kwidth = 2, | ||
280 | .mshift = 0, | ||
281 | .mwidth = 2, | ||
282 | }; | ||
283 | |||
284 | static struct clk_factors_config sun4i_apb1_config = { | ||
194 | .mshift = 0, | 285 | .mshift = 0, |
195 | .mwidth = 5, | 286 | .mwidth = 5, |
196 | .pshift = 16, | 287 | .pshift = 16, |
197 | .pwidth = 2, | 288 | .pwidth = 2, |
198 | }; | 289 | }; |
199 | 290 | ||
200 | static const __initconst struct factors_data pll1_data = { | 291 | static const __initconst struct factors_data sun4i_pll1_data = { |
201 | .table = &pll1_config, | 292 | .table = &sun4i_pll1_config, |
202 | .getter = sunxi_get_pll1_factors, | 293 | .getter = sun4i_get_pll1_factors, |
294 | }; | ||
295 | |||
296 | static const __initconst struct factors_data sun6i_a31_pll1_data = { | ||
297 | .table = &sun6i_a31_pll1_config, | ||
298 | .getter = sun6i_a31_get_pll1_factors, | ||
203 | }; | 299 | }; |
204 | 300 | ||
205 | static const __initconst struct factors_data apb1_data = { | 301 | static const __initconst struct factors_data sun4i_apb1_data = { |
206 | .table = &apb1_config, | 302 | .table = &sun4i_apb1_config, |
207 | .getter = sunxi_get_apb1_factors, | 303 | .getter = sun4i_get_apb1_factors, |
208 | }; | 304 | }; |
209 | 305 | ||
210 | static void __init sunxi_factors_clk_setup(struct device_node *node, | 306 | static void __init sunxi_factors_clk_setup(struct device_node *node, |
@@ -240,11 +336,15 @@ struct mux_data { | |||
240 | u8 shift; | 336 | u8 shift; |
241 | }; | 337 | }; |
242 | 338 | ||
243 | static const __initconst struct mux_data cpu_mux_data = { | 339 | static const __initconst struct mux_data sun4i_cpu_mux_data = { |
244 | .shift = 16, | 340 | .shift = 16, |
245 | }; | 341 | }; |
246 | 342 | ||
247 | static const __initconst struct mux_data apb1_mux_data = { | 343 | static const __initconst struct mux_data sun6i_a31_ahb1_mux_data = { |
344 | .shift = 12, | ||
345 | }; | ||
346 | |||
347 | static const __initconst struct mux_data sun4i_apb1_mux_data = { | ||
248 | .shift = 24, | 348 | .shift = 24, |
249 | }; | 349 | }; |
250 | 350 | ||
@@ -279,26 +379,34 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, | |||
279 | * sunxi_divider_clk_setup() - Setup function for simple divider clocks | 379 | * sunxi_divider_clk_setup() - Setup function for simple divider clocks |
280 | */ | 380 | */ |
281 | 381 | ||
282 | #define SUNXI_DIVISOR_WIDTH 2 | ||
283 | |||
284 | struct div_data { | 382 | struct div_data { |
285 | u8 shift; | 383 | u8 shift; |
286 | u8 pow; | 384 | u8 pow; |
385 | u8 width; | ||
386 | }; | ||
387 | |||
388 | static const __initconst struct div_data sun4i_axi_data = { | ||
389 | .shift = 0, | ||
390 | .pow = 0, | ||
391 | .width = 2, | ||
287 | }; | 392 | }; |
288 | 393 | ||
289 | static const __initconst struct div_data axi_data = { | 394 | static const __initconst struct div_data sun4i_ahb_data = { |
290 | .shift = 0, | 395 | .shift = 4, |
291 | .pow = 0, | 396 | .pow = 1, |
397 | .width = 2, | ||
292 | }; | 398 | }; |
293 | 399 | ||
294 | static const __initconst struct div_data ahb_data = { | 400 | static const __initconst struct div_data sun4i_apb0_data = { |
295 | .shift = 4, | 401 | .shift = 8, |
296 | .pow = 1, | 402 | .pow = 1, |
403 | .width = 2, | ||
297 | }; | 404 | }; |
298 | 405 | ||
299 | static const __initconst struct div_data apb0_data = { | 406 | static const __initconst struct div_data sun6i_a31_apb2_div_data = { |
300 | .shift = 8, | 407 | .shift = 0, |
301 | .pow = 1, | 408 | .pow = 0, |
409 | .width = 4, | ||
302 | }; | 410 | }; |
303 | 411 | ||
304 | static void __init sunxi_divider_clk_setup(struct device_node *node, | 412 | static void __init sunxi_divider_clk_setup(struct device_node *node, |
@@ -314,7 +422,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, | |||
314 | clk_parent = of_clk_get_parent_name(node, 0); | 422 | clk_parent = of_clk_get_parent_name(node, 0); |
315 | 423 | ||
316 | clk = clk_register_divider(NULL, clk_name, clk_parent, 0, | 424 | clk = clk_register_divider(NULL, clk_name, clk_parent, 0, |
317 | reg, data->shift, SUNXI_DIVISOR_WIDTH, | 425 | reg, data->shift, data->width, |
318 | data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, | 426 | data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, |
319 | &clk_lock); | 427 | &clk_lock); |
320 | if (clk) { | 428 | if (clk) { |
@@ -343,26 +451,62 @@ static const __initconst struct gates_data sun4i_ahb_gates_data = { | |||
343 | .mask = {0x7F77FFF, 0x14FB3F}, | 451 | .mask = {0x7F77FFF, 0x14FB3F}, |
344 | }; | 452 | }; |
345 | 453 | ||
454 | static const __initconst struct gates_data sun5i_a10s_ahb_gates_data = { | ||
455 | .mask = {0x147667e7, 0x185915}, | ||
456 | }; | ||
457 | |||
346 | static const __initconst struct gates_data sun5i_a13_ahb_gates_data = { | 458 | static const __initconst struct gates_data sun5i_a13_ahb_gates_data = { |
347 | .mask = {0x107067e7, 0x185111}, | 459 | .mask = {0x107067e7, 0x185111}, |
348 | }; | 460 | }; |
349 | 461 | ||
462 | static const __initconst struct gates_data sun6i_a31_ahb1_gates_data = { | ||
463 | .mask = {0xEDFE7F62, 0x794F931}, | ||
464 | }; | ||
465 | |||
466 | static const __initconst struct gates_data sun7i_a20_ahb_gates_data = { | ||
467 | .mask = { 0x12f77fff, 0x16ff3f }, | ||
468 | }; | ||
469 | |||
350 | static const __initconst struct gates_data sun4i_apb0_gates_data = { | 470 | static const __initconst struct gates_data sun4i_apb0_gates_data = { |
351 | .mask = {0x4EF}, | 471 | .mask = {0x4EF}, |
352 | }; | 472 | }; |
353 | 473 | ||
474 | static const __initconst struct gates_data sun5i_a10s_apb0_gates_data = { | ||
475 | .mask = {0x469}, | ||
476 | }; | ||
477 | |||
354 | static const __initconst struct gates_data sun5i_a13_apb0_gates_data = { | 478 | static const __initconst struct gates_data sun5i_a13_apb0_gates_data = { |
355 | .mask = {0x61}, | 479 | .mask = {0x61}, |
356 | }; | 480 | }; |
357 | 481 | ||
482 | static const __initconst struct gates_data sun7i_a20_apb0_gates_data = { | ||
483 | .mask = { 0x4ff }, | ||
484 | }; | ||
485 | |||
358 | static const __initconst struct gates_data sun4i_apb1_gates_data = { | 486 | static const __initconst struct gates_data sun4i_apb1_gates_data = { |
359 | .mask = {0xFF00F7}, | 487 | .mask = {0xFF00F7}, |
360 | }; | 488 | }; |
361 | 489 | ||
490 | static const __initconst struct gates_data sun5i_a10s_apb1_gates_data = { | ||
491 | .mask = {0xf0007}, | ||
492 | }; | ||
493 | |||
362 | static const __initconst struct gates_data sun5i_a13_apb1_gates_data = { | 494 | static const __initconst struct gates_data sun5i_a13_apb1_gates_data = { |
363 | .mask = {0xa0007}, | 495 | .mask = {0xa0007}, |
364 | }; | 496 | }; |
365 | 497 | ||
498 | static const __initconst struct gates_data sun6i_a31_apb1_gates_data = { | ||
499 | .mask = {0x3031}, | ||
500 | }; | ||
501 | |||
502 | static const __initconst struct gates_data sun6i_a31_apb2_gates_data = { | ||
503 | .mask = {0x3F000F}, | ||
504 | }; | ||
505 | |||
506 | static const __initconst struct gates_data sun7i_a20_apb1_gates_data = { | ||
507 | .mask = { 0xff80ff }, | ||
508 | }; | ||
509 | |||
366 | static void __init sunxi_gates_clk_setup(struct device_node *node, | 510 | static void __init sunxi_gates_clk_setup(struct device_node *node, |
367 | struct gates_data *data) | 511 | struct gates_data *data) |
368 | { | 512 | { |
@@ -414,23 +558,26 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, | |||
414 | 558 | ||
415 | /* Matches for factors clocks */ | 559 | /* Matches for factors clocks */ |
416 | static const __initconst struct of_device_id clk_factors_match[] = { | 560 | static const __initconst struct of_device_id clk_factors_match[] = { |
417 | {.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,}, | 561 | {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,}, |
418 | {.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,}, | 562 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, |
563 | {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, | ||
419 | {} | 564 | {} |
420 | }; | 565 | }; |
421 | 566 | ||
422 | /* Matches for divider clocks */ | 567 | /* Matches for divider clocks */ |
423 | static const __initconst struct of_device_id clk_div_match[] = { | 568 | static const __initconst struct of_device_id clk_div_match[] = { |
424 | {.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,}, | 569 | {.compatible = "allwinner,sun4i-axi-clk", .data = &sun4i_axi_data,}, |
425 | {.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,}, | 570 | {.compatible = "allwinner,sun4i-ahb-clk", .data = &sun4i_ahb_data,}, |
426 | {.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,}, | 571 | {.compatible = "allwinner,sun4i-apb0-clk", .data = &sun4i_apb0_data,}, |
572 | {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, | ||
427 | {} | 573 | {} |
428 | }; | 574 | }; |
429 | 575 | ||
430 | /* Matches for mux clocks */ | 576 | /* Matches for mux clocks */ |
431 | static const __initconst struct of_device_id clk_mux_match[] = { | 577 | static const __initconst struct of_device_id clk_mux_match[] = { |
432 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_mux_data,}, | 578 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,}, |
433 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,}, | 579 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, |
580 | {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, | ||
434 | {} | 581 | {} |
435 | }; | 582 | }; |
436 | 583 | ||
@@ -438,11 +585,20 @@ static const __initconst struct of_device_id clk_mux_match[] = { | |||
438 | static const __initconst struct of_device_id clk_gates_match[] = { | 585 | static const __initconst struct of_device_id clk_gates_match[] = { |
439 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,}, | 586 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,}, |
440 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,}, | 587 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,}, |
588 | {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,}, | ||
441 | {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, | 589 | {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, |
590 | {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, | ||
591 | {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, | ||
442 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, | 592 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, |
593 | {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, | ||
443 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, | 594 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, |
595 | {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, | ||
444 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, | 596 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, |
597 | {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, | ||
445 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, | 598 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, |
599 | {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, | ||
600 | {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, | ||
601 | {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, | ||
446 | {} | 602 | {} |
447 | }; | 603 | }; |
448 | 604 | ||