xref: /openbmc/linux/arch/arm/mach-ep93xx/clock.c (revision e8e0929d)
1 /*
2  * arch/arm/mach-ep93xx/clock.c
3  * Clock control for Cirrus EP93xx chips.
4  *
5  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/module.h>
17 #include <linux/string.h>
18 #include <linux/io.h>
19 
20 #include <asm/clkdev.h>
21 #include <asm/div64.h>
22 #include <mach/hardware.h>
23 
24 
25 struct clk {
26 	unsigned long	rate;
27 	int		users;
28 	int		sw_locked;
29 	void __iomem	*enable_reg;
30 	u32		enable_mask;
31 
32 	unsigned long	(*get_rate)(struct clk *clk);
33 	int		(*set_rate)(struct clk *clk, unsigned long rate);
34 };
35 
36 
37 static unsigned long get_uart_rate(struct clk *clk);
38 
39 static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
40 static int set_div_rate(struct clk *clk, unsigned long rate);
41 
42 static struct clk clk_uart1 = {
43 	.sw_locked	= 1,
44 	.enable_reg	= EP93XX_SYSCON_DEVCFG,
45 	.enable_mask	= EP93XX_SYSCON_DEVCFG_U1EN,
46 	.get_rate	= get_uart_rate,
47 };
48 static struct clk clk_uart2 = {
49 	.sw_locked	= 1,
50 	.enable_reg	= EP93XX_SYSCON_DEVCFG,
51 	.enable_mask	= EP93XX_SYSCON_DEVCFG_U2EN,
52 	.get_rate	= get_uart_rate,
53 };
54 static struct clk clk_uart3 = {
55 	.sw_locked	= 1,
56 	.enable_reg	= EP93XX_SYSCON_DEVCFG,
57 	.enable_mask	= EP93XX_SYSCON_DEVCFG_U3EN,
58 	.get_rate	= get_uart_rate,
59 };
60 static struct clk clk_pll1;
61 static struct clk clk_f;
62 static struct clk clk_h;
63 static struct clk clk_p;
64 static struct clk clk_pll2;
65 static struct clk clk_usb_host = {
66 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
67 	.enable_mask	= EP93XX_SYSCON_PWRCNT_USH_EN,
68 };
69 static struct clk clk_keypad = {
70 	.sw_locked	= 1,
71 	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
72 	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
73 	.set_rate	= set_keytchclk_rate,
74 };
75 static struct clk clk_pwm = {
76 	.rate		= EP93XX_EXT_CLK_RATE,
77 };
78 
79 static struct clk clk_video = {
80 	.sw_locked	= 1,
81 	.enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
82 	.enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
83 	.set_rate	= set_div_rate,
84 };
85 
86 /* DMA Clocks */
87 static struct clk clk_m2p0 = {
88 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
89 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P0,
90 };
91 static struct clk clk_m2p1 = {
92 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
93 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P1,
94 };
95 static struct clk clk_m2p2 = {
96 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
97 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P2,
98 };
99 static struct clk clk_m2p3 = {
100 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
101 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P3,
102 };
103 static struct clk clk_m2p4 = {
104 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
105 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P4,
106 };
107 static struct clk clk_m2p5 = {
108 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
109 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P5,
110 };
111 static struct clk clk_m2p6 = {
112 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
113 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P6,
114 };
115 static struct clk clk_m2p7 = {
116 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
117 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P7,
118 };
119 static struct clk clk_m2p8 = {
120 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
121 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P8,
122 };
123 static struct clk clk_m2p9 = {
124 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
125 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P9,
126 };
127 static struct clk clk_m2m0 = {
128 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
129 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M0,
130 };
131 static struct clk clk_m2m1 = {
132 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
133 	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M1,
134 };
135 
136 #define INIT_CK(dev,con,ck)					\
137 	{ .dev_id = dev, .con_id = con, .clk = ck }
138 
139 static struct clk_lookup clocks[] = {
140 	INIT_CK("apb:uart1",		NULL,		&clk_uart1),
141 	INIT_CK("apb:uart2",		NULL,		&clk_uart2),
142 	INIT_CK("apb:uart3",		NULL,		&clk_uart3),
143 	INIT_CK(NULL,			"pll1",		&clk_pll1),
144 	INIT_CK(NULL,			"fclk",		&clk_f),
145 	INIT_CK(NULL,			"hclk",		&clk_h),
146 	INIT_CK(NULL,			"pclk",		&clk_p),
147 	INIT_CK(NULL,			"pll2",		&clk_pll2),
148 	INIT_CK("ep93xx-ohci",		NULL,		&clk_usb_host),
149 	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
150 	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
151 	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
152 	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
153 	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
154 	INIT_CK(NULL,			"m2p2",		&clk_m2p2),
155 	INIT_CK(NULL,			"m2p3",		&clk_m2p3),
156 	INIT_CK(NULL,			"m2p4",		&clk_m2p4),
157 	INIT_CK(NULL,			"m2p5",		&clk_m2p5),
158 	INIT_CK(NULL,			"m2p6",		&clk_m2p6),
159 	INIT_CK(NULL,			"m2p7",		&clk_m2p7),
160 	INIT_CK(NULL,			"m2p8",		&clk_m2p8),
161 	INIT_CK(NULL,			"m2p9",		&clk_m2p9),
162 	INIT_CK(NULL,			"m2m0",		&clk_m2m0),
163 	INIT_CK(NULL,			"m2m1",		&clk_m2m1),
164 };
165 
166 
167 int clk_enable(struct clk *clk)
168 {
169 	if (!clk->users++ && clk->enable_reg) {
170 		u32 value;
171 
172 		value = __raw_readl(clk->enable_reg);
173 		value |= clk->enable_mask;
174 		if (clk->sw_locked)
175 			ep93xx_syscon_swlocked_write(value, clk->enable_reg);
176 		else
177 			__raw_writel(value, clk->enable_reg);
178 	}
179 
180 	return 0;
181 }
182 EXPORT_SYMBOL(clk_enable);
183 
184 void clk_disable(struct clk *clk)
185 {
186 	if (!--clk->users && clk->enable_reg) {
187 		u32 value;
188 
189 		value = __raw_readl(clk->enable_reg);
190 		value &= ~clk->enable_mask;
191 		if (clk->sw_locked)
192 			ep93xx_syscon_swlocked_write(value, clk->enable_reg);
193 		else
194 			__raw_writel(value, clk->enable_reg);
195 	}
196 }
197 EXPORT_SYMBOL(clk_disable);
198 
199 static unsigned long get_uart_rate(struct clk *clk)
200 {
201 	u32 value;
202 
203 	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
204 	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
205 		return EP93XX_EXT_CLK_RATE;
206 	else
207 		return EP93XX_EXT_CLK_RATE / 2;
208 }
209 
210 unsigned long clk_get_rate(struct clk *clk)
211 {
212 	if (clk->get_rate)
213 		return clk->get_rate(clk);
214 
215 	return clk->rate;
216 }
217 EXPORT_SYMBOL(clk_get_rate);
218 
219 static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
220 {
221 	u32 val;
222 	u32 div_bit;
223 
224 	val = __raw_readl(clk->enable_reg);
225 
226 	/*
227 	 * The Key Matrix and ADC clocks are configured using the same
228 	 * System Controller register.  The clock used will be either
229 	 * 1/4 or 1/16 the external clock rate depending on the
230 	 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
231 	 * bit being set or cleared.
232 	 */
233 	div_bit = clk->enable_mask >> 15;
234 
235 	if (rate == EP93XX_KEYTCHCLK_DIV4)
236 		val |= div_bit;
237 	else if (rate == EP93XX_KEYTCHCLK_DIV16)
238 		val &= ~div_bit;
239 	else
240 		return -EINVAL;
241 
242 	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
243 	clk->rate = rate;
244 	return 0;
245 }
246 
247 static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
248 				  int *pdiv, int *div)
249 {
250 	unsigned long max_rate, best_rate = 0,
251 		actual_rate = 0, mclk_rate = 0, rate_err = -1;
252 	int i, found = 0, __div = 0, __pdiv = 0;
253 
254 	/* Don't exceed the maximum rate */
255 	max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
256 		       (unsigned long)EP93XX_EXT_CLK_RATE / 4);
257 	rate = min(rate, max_rate);
258 
259 	/*
260 	 * Try the two pll's and the external clock
261 	 * Because the valid predividers are 2, 2.5 and 3, we multiply
262 	 * all the clocks by 2 to avoid floating point math.
263 	 *
264 	 * This is based on the algorithm in the ep93xx raster guide:
265 	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
266 	 *
267 	 */
268 	for (i = 0; i < 3; i++) {
269 		if (i == 0)
270 			mclk_rate = EP93XX_EXT_CLK_RATE * 2;
271 		else if (i == 1)
272 			mclk_rate = clk_pll1.rate * 2;
273 		else if (i == 2)
274 			mclk_rate = clk_pll2.rate * 2;
275 
276 		/* Try each predivider value */
277 		for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
278 			__div = mclk_rate / (rate * __pdiv);
279 			if (__div < 2 || __div > 127)
280 				continue;
281 
282 			actual_rate = mclk_rate / (__pdiv * __div);
283 
284 			if (!found || abs(actual_rate - rate) < rate_err) {
285 				*pdiv = __pdiv - 3;
286 				*div = __div;
287 				*psel = (i == 2);
288 				*esel = (i != 0);
289 				best_rate = actual_rate;
290 				rate_err = abs(actual_rate - rate);
291 				found = 1;
292 			}
293 		}
294 	}
295 
296 	if (!found)
297 		return 0;
298 
299 	return best_rate;
300 }
301 
302 static int set_div_rate(struct clk *clk, unsigned long rate)
303 {
304 	unsigned long actual_rate;
305 	int psel = 0, esel = 0, pdiv = 0, div = 0;
306 	u32 val;
307 
308 	actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
309 	if (actual_rate == 0)
310 		return -EINVAL;
311 	clk->rate = actual_rate;
312 
313 	/* Clear the esel, psel, pdiv and div bits */
314 	val = __raw_readl(clk->enable_reg);
315 	val &= ~0x7fff;
316 
317 	/* Set the new esel, psel, pdiv and div bits for the new clock rate */
318 	val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
319 		(psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
320 		(pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
321 	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
322 	return 0;
323 }
324 
325 int clk_set_rate(struct clk *clk, unsigned long rate)
326 {
327 	if (clk->set_rate)
328 		return clk->set_rate(clk, rate);
329 
330 	return -EINVAL;
331 }
332 EXPORT_SYMBOL(clk_set_rate);
333 
334 
335 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
336 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
337 static char pclk_divisors[] = { 1, 2, 4, 8 };
338 
339 /*
340  * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
341  */
342 static unsigned long calc_pll_rate(u32 config_word)
343 {
344 	unsigned long long rate;
345 	int i;
346 
347 	rate = EP93XX_EXT_CLK_RATE;
348 	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
349 	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
350 	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
351 	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
352 		rate >>= 1;
353 
354 	return (unsigned long)rate;
355 }
356 
357 static void __init ep93xx_dma_clock_init(void)
358 {
359 	clk_m2p0.rate = clk_h.rate;
360 	clk_m2p1.rate = clk_h.rate;
361 	clk_m2p2.rate = clk_h.rate;
362 	clk_m2p3.rate = clk_h.rate;
363 	clk_m2p4.rate = clk_h.rate;
364 	clk_m2p5.rate = clk_h.rate;
365 	clk_m2p6.rate = clk_h.rate;
366 	clk_m2p7.rate = clk_h.rate;
367 	clk_m2p8.rate = clk_h.rate;
368 	clk_m2p9.rate = clk_h.rate;
369 	clk_m2m0.rate = clk_h.rate;
370 	clk_m2m1.rate = clk_h.rate;
371 }
372 
373 static int __init ep93xx_clock_init(void)
374 {
375 	u32 value;
376 	int i;
377 
378 	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
379 	if (!(value & 0x00800000)) {			/* PLL1 bypassed?  */
380 		clk_pll1.rate = EP93XX_EXT_CLK_RATE;
381 	} else {
382 		clk_pll1.rate = calc_pll_rate(value);
383 	}
384 	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
385 	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
386 	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
387 	ep93xx_dma_clock_init();
388 
389 	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
390 	if (!(value & 0x00080000)) {			/* PLL2 bypassed?  */
391 		clk_pll2.rate = EP93XX_EXT_CLK_RATE;
392 	} else if (value & 0x00040000) {		/* PLL2 enabled?  */
393 		clk_pll2.rate = calc_pll_rate(value);
394 	} else {
395 		clk_pll2.rate = 0;
396 	}
397 	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
398 
399 	printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
400 		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
401 	printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
402 		clk_f.rate / 1000000, clk_h.rate / 1000000,
403 		clk_p.rate / 1000000);
404 
405 	for (i = 0; i < ARRAY_SIZE(clocks); i++)
406 		clkdev_add(&clocks[i]);
407 	return 0;
408 }
409 arch_initcall(ep93xx_clock_init);
410