ARM: 7630/1: mmc: mmci: Fixup and cleanup code for DMA handling
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / clk / mvebu / clk-gating-ctrl.c
1 /*
2 * Marvell MVEBU clock gating control.
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 * Andrew Lunn <andrew@lunn.ch>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11 #include <linux/kernel.h>
12 #include <linux/bitops.h>
13 #include <linux/io.h>
14 #include <linux/clk.h>
15 #include <linux/clkdev.h>
16 #include <linux/clk-provider.h>
17 #include <linux/clk/mvebu.h>
18 #include <linux/of.h>
19 #include <linux/of_address.h>
20
21 struct mvebu_gating_ctrl {
22 spinlock_t lock;
23 struct clk **gates;
24 int num_gates;
25 };
26
27 struct mvebu_soc_descr {
28 const char *name;
29 const char *parent;
30 int bit_idx;
31 };
32
33 #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
34
35 static struct clk __init *mvebu_clk_gating_get_src(
36 struct of_phandle_args *clkspec, void *data)
37 {
38 struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data;
39 int n;
40
41 if (clkspec->args_count < 1)
42 return ERR_PTR(-EINVAL);
43
44 for (n = 0; n < ctrl->num_gates; n++) {
45 struct clk_gate *gate =
46 to_clk_gate(__clk_get_hw(ctrl->gates[n]));
47 if (clkspec->args[0] == gate->bit_idx)
48 return ctrl->gates[n];
49 }
50 return ERR_PTR(-ENODEV);
51 }
52
53 static void __init mvebu_clk_gating_setup(
54 struct device_node *np, const struct mvebu_soc_descr *descr)
55 {
56 struct mvebu_gating_ctrl *ctrl;
57 struct clk *clk;
58 void __iomem *base;
59 const char *default_parent = NULL;
60 int n;
61
62 base = of_iomap(np, 0);
63
64 clk = of_clk_get(np, 0);
65 if (!IS_ERR(clk)) {
66 default_parent = __clk_get_name(clk);
67 clk_put(clk);
68 }
69
70 ctrl = kzalloc(sizeof(struct mvebu_gating_ctrl), GFP_KERNEL);
71 if (WARN_ON(!ctrl))
72 return;
73
74 spin_lock_init(&ctrl->lock);
75
76 /*
77 * Count, allocate, and register clock gates
78 */
79 for (n = 0; descr[n].name;)
80 n++;
81
82 ctrl->num_gates = n;
83 ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
84 GFP_KERNEL);
85 if (WARN_ON(!ctrl->gates)) {
86 kfree(ctrl);
87 return;
88 }
89
90 for (n = 0; n < ctrl->num_gates; n++) {
91 u8 flags = 0;
92 const char *parent =
93 (descr[n].parent) ? descr[n].parent : default_parent;
94
95 /*
96 * On Armada 370, the DDR clock is a special case: it
97 * isn't taken by any driver, but should anyway be
98 * kept enabled, so we mark it as IGNORE_UNUSED for
99 * now.
100 */
101 if (!strcmp(descr[n].name, "ddr"))
102 flags |= CLK_IGNORE_UNUSED;
103
104 ctrl->gates[n] = clk_register_gate(NULL, descr[n].name, parent,
105 flags, base, descr[n].bit_idx, 0, &ctrl->lock);
106 WARN_ON(IS_ERR(ctrl->gates[n]));
107 }
108 of_clk_add_provider(np, mvebu_clk_gating_get_src, ctrl);
109 }
110
111 /*
112 * SoC specific clock gating control
113 */
114
115 #ifdef CONFIG_MACH_ARMADA_370
116 static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
117 { "audio", NULL, 0 },
118 { "pex0_en", NULL, 1 },
119 { "pex1_en", NULL, 2 },
120 { "ge1", NULL, 3 },
121 { "ge0", NULL, 4 },
122 { "pex0", NULL, 5 },
123 { "pex1", NULL, 9 },
124 { "sata0", NULL, 15 },
125 { "sdio", NULL, 17 },
126 { "tdm", NULL, 25 },
127 { "ddr", NULL, 28 },
128 { "sata1", NULL, 30 },
129 { }
130 };
131 #endif
132
133 #ifdef CONFIG_MACH_ARMADA_XP
134 static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
135 { "audio", NULL, 0 },
136 { "ge3", NULL, 1 },
137 { "ge2", NULL, 2 },
138 { "ge1", NULL, 3 },
139 { "ge0", NULL, 4 },
140 { "pex0", NULL, 5 },
141 { "pex1", NULL, 6 },
142 { "pex2", NULL, 7 },
143 { "pex3", NULL, 8 },
144 { "bp", NULL, 13 },
145 { "sata0lnk", NULL, 14 },
146 { "sata0", "sata0lnk", 15 },
147 { "lcd", NULL, 16 },
148 { "sdio", NULL, 17 },
149 { "usb0", NULL, 18 },
150 { "usb1", NULL, 19 },
151 { "usb2", NULL, 20 },
152 { "xor0", NULL, 22 },
153 { "crypto", NULL, 23 },
154 { "tdm", NULL, 25 },
155 { "xor1", NULL, 28 },
156 { "sata1lnk", NULL, 29 },
157 { "sata1", "sata1lnk", 30 },
158 { }
159 };
160 #endif
161
162 #ifdef CONFIG_ARCH_DOVE
163 static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
164 { "usb0", NULL, 0 },
165 { "usb1", NULL, 1 },
166 { "ge", "gephy", 2 },
167 { "sata", NULL, 3 },
168 { "pex0", NULL, 4 },
169 { "pex1", NULL, 5 },
170 { "sdio0", NULL, 8 },
171 { "sdio1", NULL, 9 },
172 { "nand", NULL, 10 },
173 { "camera", NULL, 11 },
174 { "i2s0", NULL, 12 },
175 { "i2s1", NULL, 13 },
176 { "crypto", NULL, 15 },
177 { "ac97", NULL, 21 },
178 { "pdma", NULL, 22 },
179 { "xor0", NULL, 23 },
180 { "xor1", NULL, 24 },
181 { "gephy", NULL, 30 },
182 { }
183 };
184 #endif
185
186 #ifdef CONFIG_ARCH_KIRKWOOD
187 static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
188 { "ge0", NULL, 0 },
189 { "pex0", NULL, 2 },
190 { "usb0", NULL, 3 },
191 { "sdio", NULL, 4 },
192 { "tsu", NULL, 5 },
193 { "runit", NULL, 7 },
194 { "xor0", NULL, 8 },
195 { "audio", NULL, 9 },
196 { "sata0", NULL, 14 },
197 { "sata1", NULL, 15 },
198 { "xor1", NULL, 16 },
199 { "crypto", NULL, 17 },
200 { "pex1", NULL, 18 },
201 { "ge1", NULL, 19 },
202 { "tdm", NULL, 20 },
203 { }
204 };
205 #endif
206
207 static const __initdata struct of_device_id clk_gating_match[] = {
208 #ifdef CONFIG_MACH_ARMADA_370
209 {
210 .compatible = "marvell,armada-370-gating-clock",
211 .data = armada_370_gating_descr,
212 },
213 #endif
214
215 #ifdef CONFIG_MACH_ARMADA_XP
216 {
217 .compatible = "marvell,armada-xp-gating-clock",
218 .data = armada_xp_gating_descr,
219 },
220 #endif
221
222 #ifdef CONFIG_ARCH_DOVE
223 {
224 .compatible = "marvell,dove-gating-clock",
225 .data = dove_gating_descr,
226 },
227 #endif
228
229 #ifdef CONFIG_ARCH_KIRKWOOD
230 {
231 .compatible = "marvell,kirkwood-gating-clock",
232 .data = kirkwood_gating_descr,
233 },
234 #endif
235
236 { }
237 };
238
239 void __init mvebu_gating_clk_init(void)
240 {
241 struct device_node *np;
242
243 for_each_matching_node(np, clk_gating_match) {
244 const struct of_device_id *match =
245 of_match_node(clk_gating_match, np);
246 mvebu_clk_gating_setup(np,
247 (const struct mvebu_soc_descr *)match->data);
248 }
249 }