xref: /openbmc/linux/drivers/clk/mvebu/kirkwood.c (revision e8e8a9b0)
1e89406c9SSebastian Hesselbarth /*
2e89406c9SSebastian Hesselbarth  * Marvell Kirkwood SoC clocks
3e89406c9SSebastian Hesselbarth  *
4e89406c9SSebastian Hesselbarth  * Copyright (C) 2012 Marvell
5e89406c9SSebastian Hesselbarth  *
6e89406c9SSebastian Hesselbarth  * Gregory CLEMENT <gregory.clement@free-electrons.com>
7e89406c9SSebastian Hesselbarth  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
8e89406c9SSebastian Hesselbarth  * Andrew Lunn <andrew@lunn.ch>
9e89406c9SSebastian Hesselbarth  *
10e89406c9SSebastian Hesselbarth  * This file is licensed under the terms of the GNU General Public
11e89406c9SSebastian Hesselbarth  * License version 2.  This program is licensed "as is" without any
12e89406c9SSebastian Hesselbarth  * warranty of any kind, whether express or implied.
13e89406c9SSebastian Hesselbarth  */
14e89406c9SSebastian Hesselbarth 
15e89406c9SSebastian Hesselbarth #include <linux/kernel.h>
16e8e8a9b0SMike Turquette #include <linux/slab.h>
17e89406c9SSebastian Hesselbarth #include <linux/clk-provider.h>
18e89406c9SSebastian Hesselbarth #include <linux/io.h>
19e89406c9SSebastian Hesselbarth #include <linux/of.h>
20e8e8a9b0SMike Turquette #include <linux/of_address.h>
21e89406c9SSebastian Hesselbarth #include "common.h"
22e89406c9SSebastian Hesselbarth 
23e89406c9SSebastian Hesselbarth /*
24e89406c9SSebastian Hesselbarth  * Core Clocks
25e89406c9SSebastian Hesselbarth  *
26e89406c9SSebastian Hesselbarth  * Kirkwood PLL sample-at-reset configuration
27e89406c9SSebastian Hesselbarth  * (6180 has different SAR layout than other Kirkwood SoCs)
28e89406c9SSebastian Hesselbarth  *
29e89406c9SSebastian Hesselbarth  * SAR0[4:3,22,1] : CPU frequency (6281,6292,6282)
30e89406c9SSebastian Hesselbarth  *	4  =  600 MHz
31e89406c9SSebastian Hesselbarth  *	6  =  800 MHz
32e89406c9SSebastian Hesselbarth  *	7  = 1000 MHz
33e89406c9SSebastian Hesselbarth  *	9  = 1200 MHz
34e89406c9SSebastian Hesselbarth  *	12 = 1500 MHz
35e89406c9SSebastian Hesselbarth  *	13 = 1600 MHz
36e89406c9SSebastian Hesselbarth  *	14 = 1800 MHz
37e89406c9SSebastian Hesselbarth  *	15 = 2000 MHz
38e89406c9SSebastian Hesselbarth  *	others reserved.
39e89406c9SSebastian Hesselbarth  *
40e89406c9SSebastian Hesselbarth  * SAR0[19,10:9] : CPU to L2 Clock divider ratio (6281,6292,6282)
41e89406c9SSebastian Hesselbarth  *	1 = (1/2) * CPU
42e89406c9SSebastian Hesselbarth  *	3 = (1/3) * CPU
43e89406c9SSebastian Hesselbarth  *	5 = (1/4) * CPU
44e89406c9SSebastian Hesselbarth  *	others reserved.
45e89406c9SSebastian Hesselbarth  *
46e89406c9SSebastian Hesselbarth  * SAR0[8:5] : CPU to DDR DRAM Clock divider ratio (6281,6292,6282)
47e89406c9SSebastian Hesselbarth  *	2 = (1/2) * CPU
48e89406c9SSebastian Hesselbarth  *	4 = (1/3) * CPU
49e89406c9SSebastian Hesselbarth  *	6 = (1/4) * CPU
50e89406c9SSebastian Hesselbarth  *	7 = (2/9) * CPU
51e89406c9SSebastian Hesselbarth  *	8 = (1/5) * CPU
52e89406c9SSebastian Hesselbarth  *	9 = (1/6) * CPU
53e89406c9SSebastian Hesselbarth  *	others reserved.
54e89406c9SSebastian Hesselbarth  *
55e89406c9SSebastian Hesselbarth  * SAR0[4:2] : Kirkwood 6180 cpu/l2/ddr clock configuration (6180 only)
56e89406c9SSebastian Hesselbarth  *	5 = [CPU =  600 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/3) * CPU]
57e89406c9SSebastian Hesselbarth  *	6 = [CPU =  800 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/4) * CPU]
58e89406c9SSebastian Hesselbarth  *	7 = [CPU = 1000 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/5) * CPU]
59e89406c9SSebastian Hesselbarth  *	others reserved.
60e89406c9SSebastian Hesselbarth  *
61e89406c9SSebastian Hesselbarth  * SAR0[21] : TCLK frequency
62e89406c9SSebastian Hesselbarth  *	0 = 200 MHz
63e89406c9SSebastian Hesselbarth  *	1 = 166 MHz
64e89406c9SSebastian Hesselbarth  *	others reserved.
65e89406c9SSebastian Hesselbarth  */
66e89406c9SSebastian Hesselbarth 
67e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_CPU_FREQ(x)	\
68e89406c9SSebastian Hesselbarth 	(((x & (1 <<  1)) >>  1) |	\
69e89406c9SSebastian Hesselbarth 	 ((x & (1 << 22)) >> 21) |	\
70e89406c9SSebastian Hesselbarth 	 ((x & (3 <<  3)) >>  1))
71e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_L2_RATIO(x)	\
72e89406c9SSebastian Hesselbarth 	(((x & (3 <<  9)) >> 9) |	\
73e89406c9SSebastian Hesselbarth 	 (((x & (1 << 19)) >> 17)))
74e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_DDR_RATIO		5
75e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_DDR_RATIO_MASK	0xf
76e89406c9SSebastian Hesselbarth #define SAR_MV88F6180_CLK		2
77e89406c9SSebastian Hesselbarth #define SAR_MV88F6180_CLK_MASK		0x7
78e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_TCLK_FREQ		21
79e89406c9SSebastian Hesselbarth #define SAR_KIRKWOOD_TCLK_FREQ_MASK	0x1
80e89406c9SSebastian Hesselbarth 
81e89406c9SSebastian Hesselbarth enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
82e89406c9SSebastian Hesselbarth 
83847b1c00SSachin Kamat static const struct coreclk_ratio kirkwood_coreclk_ratios[] __initconst = {
84e89406c9SSebastian Hesselbarth 	{ .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
85e89406c9SSebastian Hesselbarth 	{ .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
86e89406c9SSebastian Hesselbarth };
87e89406c9SSebastian Hesselbarth 
88e89406c9SSebastian Hesselbarth static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
89e89406c9SSebastian Hesselbarth {
90e89406c9SSebastian Hesselbarth 	u32 opt = (readl(sar) >> SAR_KIRKWOOD_TCLK_FREQ) &
91e89406c9SSebastian Hesselbarth 		SAR_KIRKWOOD_TCLK_FREQ_MASK;
92e89406c9SSebastian Hesselbarth 	return (opt) ? 166666667 : 200000000;
93e89406c9SSebastian Hesselbarth }
94e89406c9SSebastian Hesselbarth 
95847b1c00SSachin Kamat static const u32 kirkwood_cpu_freqs[] __initconst = {
96e89406c9SSebastian Hesselbarth 	0, 0, 0, 0,
97e89406c9SSebastian Hesselbarth 	600000000,
98e89406c9SSebastian Hesselbarth 	0,
99e89406c9SSebastian Hesselbarth 	800000000,
100e89406c9SSebastian Hesselbarth 	1000000000,
101e89406c9SSebastian Hesselbarth 	0,
102e89406c9SSebastian Hesselbarth 	1200000000,
103e89406c9SSebastian Hesselbarth 	0, 0,
104e89406c9SSebastian Hesselbarth 	1500000000,
105e89406c9SSebastian Hesselbarth 	1600000000,
106e89406c9SSebastian Hesselbarth 	1800000000,
107e89406c9SSebastian Hesselbarth 	2000000000
108e89406c9SSebastian Hesselbarth };
109e89406c9SSebastian Hesselbarth 
110e89406c9SSebastian Hesselbarth static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
111e89406c9SSebastian Hesselbarth {
112e89406c9SSebastian Hesselbarth 	u32 opt = SAR_KIRKWOOD_CPU_FREQ(readl(sar));
113e89406c9SSebastian Hesselbarth 	return kirkwood_cpu_freqs[opt];
114e89406c9SSebastian Hesselbarth }
115e89406c9SSebastian Hesselbarth 
116847b1c00SSachin Kamat static const int kirkwood_cpu_l2_ratios[8][2] __initconst = {
117e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
118e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
119e89406c9SSebastian Hesselbarth };
120e89406c9SSebastian Hesselbarth 
121847b1c00SSachin Kamat static const int kirkwood_cpu_ddr_ratios[16][2] __initconst = {
122e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
123e89406c9SSebastian Hesselbarth 	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
124e89406c9SSebastian Hesselbarth 	{ 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
125e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }
126e89406c9SSebastian Hesselbarth };
127e89406c9SSebastian Hesselbarth 
128e89406c9SSebastian Hesselbarth static void __init kirkwood_get_clk_ratio(
129e89406c9SSebastian Hesselbarth 	void __iomem *sar, int id, int *mult, int *div)
130e89406c9SSebastian Hesselbarth {
131e89406c9SSebastian Hesselbarth 	switch (id) {
132e89406c9SSebastian Hesselbarth 	case KIRKWOOD_CPU_TO_L2:
133e89406c9SSebastian Hesselbarth 	{
134e89406c9SSebastian Hesselbarth 		u32 opt = SAR_KIRKWOOD_L2_RATIO(readl(sar));
135e89406c9SSebastian Hesselbarth 		*mult = kirkwood_cpu_l2_ratios[opt][0];
136e89406c9SSebastian Hesselbarth 		*div = kirkwood_cpu_l2_ratios[opt][1];
137e89406c9SSebastian Hesselbarth 		break;
138e89406c9SSebastian Hesselbarth 	}
139e89406c9SSebastian Hesselbarth 	case KIRKWOOD_CPU_TO_DDR:
140e89406c9SSebastian Hesselbarth 	{
141e89406c9SSebastian Hesselbarth 		u32 opt = (readl(sar) >> SAR_KIRKWOOD_DDR_RATIO) &
142e89406c9SSebastian Hesselbarth 			SAR_KIRKWOOD_DDR_RATIO_MASK;
143e89406c9SSebastian Hesselbarth 		*mult = kirkwood_cpu_ddr_ratios[opt][0];
144e89406c9SSebastian Hesselbarth 		*div = kirkwood_cpu_ddr_ratios[opt][1];
145e89406c9SSebastian Hesselbarth 		break;
146e89406c9SSebastian Hesselbarth 	}
147e89406c9SSebastian Hesselbarth 	}
148e89406c9SSebastian Hesselbarth }
149e89406c9SSebastian Hesselbarth 
150847b1c00SSachin Kamat static const u32 mv88f6180_cpu_freqs[] __initconst = {
151e89406c9SSebastian Hesselbarth 	0, 0, 0, 0, 0,
152e89406c9SSebastian Hesselbarth 	600000000,
153e89406c9SSebastian Hesselbarth 	800000000,
154e89406c9SSebastian Hesselbarth 	1000000000
155e89406c9SSebastian Hesselbarth };
156e89406c9SSebastian Hesselbarth 
157e89406c9SSebastian Hesselbarth static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
158e89406c9SSebastian Hesselbarth {
159e89406c9SSebastian Hesselbarth 	u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) & SAR_MV88F6180_CLK_MASK;
160e89406c9SSebastian Hesselbarth 	return mv88f6180_cpu_freqs[opt];
161e89406c9SSebastian Hesselbarth }
162e89406c9SSebastian Hesselbarth 
163847b1c00SSachin Kamat static const int mv88f6180_cpu_ddr_ratios[8][2] __initconst = {
164e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
165e89406c9SSebastian Hesselbarth 	{ 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
166e89406c9SSebastian Hesselbarth };
167e89406c9SSebastian Hesselbarth 
168e89406c9SSebastian Hesselbarth static void __init mv88f6180_get_clk_ratio(
169e89406c9SSebastian Hesselbarth 	void __iomem *sar, int id, int *mult, int *div)
170e89406c9SSebastian Hesselbarth {
171e89406c9SSebastian Hesselbarth 	switch (id) {
172e89406c9SSebastian Hesselbarth 	case KIRKWOOD_CPU_TO_L2:
173e89406c9SSebastian Hesselbarth 	{
174e89406c9SSebastian Hesselbarth 		/* mv88f6180 has a fixed 1:2 CPU-to-L2 ratio */
175e89406c9SSebastian Hesselbarth 		*mult = 1;
176e89406c9SSebastian Hesselbarth 		*div = 2;
177e89406c9SSebastian Hesselbarth 		break;
178e89406c9SSebastian Hesselbarth 	}
179e89406c9SSebastian Hesselbarth 	case KIRKWOOD_CPU_TO_DDR:
180e89406c9SSebastian Hesselbarth 	{
181e89406c9SSebastian Hesselbarth 		u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) &
182e89406c9SSebastian Hesselbarth 			SAR_MV88F6180_CLK_MASK;
183e89406c9SSebastian Hesselbarth 		*mult = mv88f6180_cpu_ddr_ratios[opt][0];
184e89406c9SSebastian Hesselbarth 		*div = mv88f6180_cpu_ddr_ratios[opt][1];
185e89406c9SSebastian Hesselbarth 		break;
186e89406c9SSebastian Hesselbarth 	}
187e89406c9SSebastian Hesselbarth 	}
188e89406c9SSebastian Hesselbarth }
189e89406c9SSebastian Hesselbarth 
190e89406c9SSebastian Hesselbarth static const struct coreclk_soc_desc kirkwood_coreclks = {
191e89406c9SSebastian Hesselbarth 	.get_tclk_freq = kirkwood_get_tclk_freq,
192e89406c9SSebastian Hesselbarth 	.get_cpu_freq = kirkwood_get_cpu_freq,
193e89406c9SSebastian Hesselbarth 	.get_clk_ratio = kirkwood_get_clk_ratio,
194e89406c9SSebastian Hesselbarth 	.ratios = kirkwood_coreclk_ratios,
195e89406c9SSebastian Hesselbarth 	.num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
196e89406c9SSebastian Hesselbarth };
197e89406c9SSebastian Hesselbarth 
198e89406c9SSebastian Hesselbarth static const struct coreclk_soc_desc mv88f6180_coreclks = {
199e89406c9SSebastian Hesselbarth 	.get_tclk_freq = kirkwood_get_tclk_freq,
200e89406c9SSebastian Hesselbarth 	.get_cpu_freq = mv88f6180_get_cpu_freq,
201e89406c9SSebastian Hesselbarth 	.get_clk_ratio = mv88f6180_get_clk_ratio,
202e89406c9SSebastian Hesselbarth 	.ratios = kirkwood_coreclk_ratios,
203e89406c9SSebastian Hesselbarth 	.num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
204e89406c9SSebastian Hesselbarth };
205e89406c9SSebastian Hesselbarth 
206e89406c9SSebastian Hesselbarth /*
207e89406c9SSebastian Hesselbarth  * Clock Gating Control
208e89406c9SSebastian Hesselbarth  */
209e89406c9SSebastian Hesselbarth 
210847b1c00SSachin Kamat static const struct clk_gating_soc_desc kirkwood_gating_desc[] __initconst = {
211e89406c9SSebastian Hesselbarth 	{ "ge0", NULL, 0, 0 },
212e89406c9SSebastian Hesselbarth 	{ "pex0", NULL, 2, 0 },
213e89406c9SSebastian Hesselbarth 	{ "usb0", NULL, 3, 0 },
214e89406c9SSebastian Hesselbarth 	{ "sdio", NULL, 4, 0 },
215e89406c9SSebastian Hesselbarth 	{ "tsu", NULL, 5, 0 },
216e89406c9SSebastian Hesselbarth 	{ "runit", NULL, 7, 0 },
217e89406c9SSebastian Hesselbarth 	{ "xor0", NULL, 8, 0 },
218e89406c9SSebastian Hesselbarth 	{ "audio", NULL, 9, 0 },
219e89406c9SSebastian Hesselbarth 	{ "powersave", "cpuclk", 11, 0 },
220e89406c9SSebastian Hesselbarth 	{ "sata0", NULL, 14, 0 },
221e89406c9SSebastian Hesselbarth 	{ "sata1", NULL, 15, 0 },
222e89406c9SSebastian Hesselbarth 	{ "xor1", NULL, 16, 0 },
223e89406c9SSebastian Hesselbarth 	{ "crypto", NULL, 17, 0 },
224e89406c9SSebastian Hesselbarth 	{ "pex1", NULL, 18, 0 },
225e89406c9SSebastian Hesselbarth 	{ "ge1", NULL, 19, 0 },
226e89406c9SSebastian Hesselbarth 	{ "tdm", NULL, 20, 0 },
227e89406c9SSebastian Hesselbarth 	{ }
228e89406c9SSebastian Hesselbarth };
229e89406c9SSebastian Hesselbarth 
230e8e8a9b0SMike Turquette 
231e8e8a9b0SMike Turquette /*
232e8e8a9b0SMike Turquette  * Clock Muxing Control
233e8e8a9b0SMike Turquette  */
234e8e8a9b0SMike Turquette 
235e8e8a9b0SMike Turquette struct clk_muxing_soc_desc {
236e8e8a9b0SMike Turquette 	const char *name;
237e8e8a9b0SMike Turquette 	const char **parents;
238e8e8a9b0SMike Turquette 	int num_parents;
239e8e8a9b0SMike Turquette 	int shift;
240e8e8a9b0SMike Turquette 	int width;
241e8e8a9b0SMike Turquette 	unsigned long flags;
242e8e8a9b0SMike Turquette };
243e8e8a9b0SMike Turquette 
244e8e8a9b0SMike Turquette struct clk_muxing_ctrl {
245e8e8a9b0SMike Turquette 	spinlock_t *lock;
246e8e8a9b0SMike Turquette 	struct clk **muxes;
247e8e8a9b0SMike Turquette 	int num_muxes;
248e8e8a9b0SMike Turquette };
249e8e8a9b0SMike Turquette 
250e8e8a9b0SMike Turquette #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
251e8e8a9b0SMike Turquette 
252e8e8a9b0SMike Turquette static struct clk *clk_muxing_get_src(
253e8e8a9b0SMike Turquette 	struct of_phandle_args *clkspec, void *data)
254e8e8a9b0SMike Turquette {
255e8e8a9b0SMike Turquette 	struct clk_muxing_ctrl *ctrl = (struct clk_muxing_ctrl *)data;
256e8e8a9b0SMike Turquette 	int n;
257e8e8a9b0SMike Turquette 
258e8e8a9b0SMike Turquette 	if (clkspec->args_count < 1)
259e8e8a9b0SMike Turquette 		return ERR_PTR(-EINVAL);
260e8e8a9b0SMike Turquette 
261e8e8a9b0SMike Turquette 	for (n = 0; n < ctrl->num_muxes; n++) {
262e8e8a9b0SMike Turquette 		struct clk_mux *mux =
263e8e8a9b0SMike Turquette 			to_clk_mux(__clk_get_hw(ctrl->muxes[n]));
264e8e8a9b0SMike Turquette 		if (clkspec->args[0] == mux->shift)
265e8e8a9b0SMike Turquette 			return ctrl->muxes[n];
266e8e8a9b0SMike Turquette 	}
267e8e8a9b0SMike Turquette 	return ERR_PTR(-ENODEV);
268e8e8a9b0SMike Turquette }
269e8e8a9b0SMike Turquette 
270e8e8a9b0SMike Turquette static void __init kirkwood_clk_muxing_setup(struct device_node *np,
271e8e8a9b0SMike Turquette 				   const struct clk_muxing_soc_desc *desc)
272e8e8a9b0SMike Turquette {
273e8e8a9b0SMike Turquette 	struct clk_muxing_ctrl *ctrl;
274e8e8a9b0SMike Turquette 	void __iomem *base;
275e8e8a9b0SMike Turquette 	int n;
276e8e8a9b0SMike Turquette 
277e8e8a9b0SMike Turquette 	base = of_iomap(np, 0);
278e8e8a9b0SMike Turquette 	if (WARN_ON(!base))
279e8e8a9b0SMike Turquette 		return;
280e8e8a9b0SMike Turquette 
281e8e8a9b0SMike Turquette 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
282e8e8a9b0SMike Turquette 	if (WARN_ON(!ctrl))
283e8e8a9b0SMike Turquette 		goto ctrl_out;
284e8e8a9b0SMike Turquette 
285e8e8a9b0SMike Turquette 	/* lock must already be initialized */
286e8e8a9b0SMike Turquette 	ctrl->lock = &ctrl_gating_lock;
287e8e8a9b0SMike Turquette 
288e8e8a9b0SMike Turquette 	/* Count, allocate, and register clock muxes */
289e8e8a9b0SMike Turquette 	for (n = 0; desc[n].name;)
290e8e8a9b0SMike Turquette 		n++;
291e8e8a9b0SMike Turquette 
292e8e8a9b0SMike Turquette 	ctrl->num_muxes = n;
293e8e8a9b0SMike Turquette 	ctrl->muxes = kcalloc(ctrl->num_muxes, sizeof(struct clk *),
294e8e8a9b0SMike Turquette 			GFP_KERNEL);
295e8e8a9b0SMike Turquette 	if (WARN_ON(!ctrl->muxes))
296e8e8a9b0SMike Turquette 		goto muxes_out;
297e8e8a9b0SMike Turquette 
298e8e8a9b0SMike Turquette 	for (n = 0; n < ctrl->num_muxes; n++) {
299e8e8a9b0SMike Turquette 		ctrl->muxes[n] = clk_register_mux(NULL, desc[n].name,
300e8e8a9b0SMike Turquette 				desc[n].parents, desc[n].num_parents,
301e8e8a9b0SMike Turquette 				desc[n].flags, base, desc[n].shift,
302e8e8a9b0SMike Turquette 				desc[n].width, desc[n].flags, ctrl->lock);
303e8e8a9b0SMike Turquette 		WARN_ON(IS_ERR(ctrl->muxes[n]));
304e8e8a9b0SMike Turquette 	}
305e8e8a9b0SMike Turquette 
306e8e8a9b0SMike Turquette 	of_clk_add_provider(np, clk_muxing_get_src, ctrl);
307e8e8a9b0SMike Turquette 
308e8e8a9b0SMike Turquette 	return;
309e8e8a9b0SMike Turquette muxes_out:
310e8e8a9b0SMike Turquette 	kfree(ctrl);
311e8e8a9b0SMike Turquette ctrl_out:
312e8e8a9b0SMike Turquette 	iounmap(base);
313e8e8a9b0SMike Turquette }
314e8e8a9b0SMike Turquette 
31558d516aeSSebastian Hesselbarth static void __init kirkwood_clk_init(struct device_node *np)
316e89406c9SSebastian Hesselbarth {
31758d516aeSSebastian Hesselbarth 	struct device_node *cgnp =
31858d516aeSSebastian Hesselbarth 		of_find_compatible_node(NULL, NULL, "marvell,kirkwood-gating-clock");
31958d516aeSSebastian Hesselbarth 
32058d516aeSSebastian Hesselbarth 
32158d516aeSSebastian Hesselbarth 	if (of_device_is_compatible(np, "marvell,mv88f6180-core-clock"))
32258d516aeSSebastian Hesselbarth 		mvebu_coreclk_setup(np, &mv88f6180_coreclks);
32358d516aeSSebastian Hesselbarth 	else
32458d516aeSSebastian Hesselbarth 		mvebu_coreclk_setup(np, &kirkwood_coreclks);
32558d516aeSSebastian Hesselbarth 
32658d516aeSSebastian Hesselbarth 	if (cgnp)
32758d516aeSSebastian Hesselbarth 		mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc);
328e89406c9SSebastian Hesselbarth }
32958d516aeSSebastian Hesselbarth CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock",
33058d516aeSSebastian Hesselbarth 	       kirkwood_clk_init);
33158d516aeSSebastian Hesselbarth CLK_OF_DECLARE(mv88f6180_clk, "marvell,mv88f6180-core-clock",
33258d516aeSSebastian Hesselbarth 	       kirkwood_clk_init);
333