2 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <linux/delay.h>
21 #include <linux/clk.h>
23 #include <linux/jiffies.h>
25 #include <asm/clkdev.h>
26 #include <asm/div64.h>
28 #include <mach/mx23.h>
29 #include <mach/common.h>
30 #include <mach/clock.h>
32 #include "regs-clkctrl-mx23.h"
34 #define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
35 #define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
37 #define PARENT_RATE_SHIFT 8
39 static int _raw_clk_enable(struct clk *clk)
43 if (clk->enable_reg) {
44 reg = __raw_readl(clk->enable_reg);
45 reg &= ~(1 << clk->enable_shift);
46 __raw_writel(reg, clk->enable_reg);
52 static void _raw_clk_disable(struct clk *clk)
56 if (clk->enable_reg) {
57 reg = __raw_readl(clk->enable_reg);
58 reg |= 1 << clk->enable_shift;
59 __raw_writel(reg, clk->enable_reg);
66 static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
71 static struct clk ref_xtal_clk = {
72 .get_rate = ref_xtal_clk_get_rate,
78 static unsigned long pll_clk_get_rate(struct clk *clk)
83 static int pll_clk_enable(struct clk *clk)
85 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
86 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
87 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
89 /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
90 * and is incorrect (excessive). Per definition of the PLLCTRL0
91 * POWER field, waiting at least 10us.
98 static void pll_clk_disable(struct clk *clk)
100 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
101 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
102 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
105 static struct clk pll_clk = {
106 .get_rate = pll_clk_get_rate,
107 .enable = pll_clk_enable,
108 .disable = pll_clk_disable,
109 .parent = &ref_xtal_clk,
115 #define _CLK_GET_RATE_REF(name, sr, ss) \
116 static unsigned long name##_get_rate(struct clk *clk) \
118 unsigned long parent_rate; \
121 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
122 div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
123 parent_rate = clk_get_rate(clk->parent); \
125 return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
126 div, PARENT_RATE_SHIFT); \
129 _CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
130 _CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
131 _CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
132 _CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
134 #define _DEFINE_CLOCK_REF(name, er, es) \
135 static struct clk name = { \
136 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
137 .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
138 .get_rate = name##_get_rate, \
139 .enable = _raw_clk_enable, \
140 .disable = _raw_clk_disable, \
141 .parent = &pll_clk, \
144 _DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
145 _DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
146 _DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
147 _DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
154 static unsigned long rtc_clk_get_rate(struct clk *clk)
156 /* ref_xtal_clk is implemented as the only parent */
157 return clk_get_rate(clk->parent) / 768;
160 static unsigned long clk32k_clk_get_rate(struct clk *clk)
162 return clk->parent->get_rate(clk->parent) / 750;
165 #define _CLK_GET_RATE(name, rs) \
166 static unsigned long name##_get_rate(struct clk *clk) \
170 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
172 if (clk->parent == &ref_xtal_clk) \
173 div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
174 BP_CLKCTRL_##rs##_DIV_XTAL; \
176 div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
177 BP_CLKCTRL_##rs##_DIV_##rs; \
182 return clk_get_rate(clk->parent) / div; \
185 _CLK_GET_RATE(cpu_clk, CPU)
186 _CLK_GET_RATE(emi_clk, EMI)
188 #define _CLK_GET_RATE1(name, rs) \
189 static unsigned long name##_get_rate(struct clk *clk) \
193 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
194 div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
199 return clk_get_rate(clk->parent) / div; \
202 _CLK_GET_RATE1(hbus_clk, HBUS)
203 _CLK_GET_RATE1(xbus_clk, XBUS)
204 _CLK_GET_RATE1(ssp_clk, SSP)
205 _CLK_GET_RATE1(gpmi_clk, GPMI)
206 _CLK_GET_RATE1(lcdif_clk, PIX)
208 #define _CLK_GET_RATE_STUB(name) \
209 static unsigned long name##_get_rate(struct clk *clk) \
211 return clk_get_rate(clk->parent); \
214 _CLK_GET_RATE_STUB(uart_clk)
215 _CLK_GET_RATE_STUB(audio_clk)
216 _CLK_GET_RATE_STUB(pwm_clk)
221 static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
223 u32 reg, bm_busy, div_max, d, f, div, frac;
224 unsigned long diff, parent_rate, calc_rate;
227 parent_rate = clk_get_rate(clk->parent);
229 if (clk->parent == &ref_xtal_clk) {
230 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
231 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
232 div = DIV_ROUND_UP(parent_rate, rate);
233 if (div == 0 || div > div_max)
236 div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
237 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
238 rate >>= PARENT_RATE_SHIFT;
239 parent_rate >>= PARENT_RATE_SHIFT;
242 for (d = 1; d <= div_max; d++) {
243 f = parent_rate * 18 / d / rate;
244 if ((parent_rate * 18 / d) % rate)
246 if (f < 18 || f > 35)
249 calc_rate = parent_rate * 18 / f / d;
250 if (calc_rate > rate)
253 if (rate - calc_rate < diff) {
256 diff = rate - calc_rate;
263 if (diff == parent_rate)
266 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
267 reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
269 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
272 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
273 reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
274 reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
275 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
277 for (i = 10000; i; i--)
278 if (!(__raw_readl(CLKCTRL_BASE_ADDR +
279 HW_CLKCTRL_CPU) & bm_busy))
282 pr_err("%s: divider writing timeout\n", __func__);
289 #define _CLK_SET_RATE(name, dr) \
290 static int name##_set_rate(struct clk *clk, unsigned long rate) \
292 u32 reg, div_max, div; \
293 unsigned long parent_rate; \
296 parent_rate = clk_get_rate(clk->parent); \
297 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
299 div = DIV_ROUND_UP(parent_rate, rate); \
300 if (div == 0 || div > div_max) \
303 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
304 reg &= ~BM_CLKCTRL_##dr##_DIV; \
305 reg |= div << BP_CLKCTRL_##dr##_DIV; \
306 if (reg | (1 << clk->enable_shift)) { \
307 pr_err("%s: clock is gated\n", __func__); \
310 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
312 for (i = 10000; i; i--) \
313 if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
314 HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
317 pr_err("%s: divider writing timeout\n", __func__); \
324 _CLK_SET_RATE(xbus_clk, XBUS)
325 _CLK_SET_RATE(ssp_clk, SSP)
326 _CLK_SET_RATE(gpmi_clk, GPMI)
327 _CLK_SET_RATE(lcdif_clk, PIX)
329 #define _CLK_SET_RATE_STUB(name) \
330 static int name##_set_rate(struct clk *clk, unsigned long rate) \
335 _CLK_SET_RATE_STUB(emi_clk)
336 _CLK_SET_RATE_STUB(uart_clk)
337 _CLK_SET_RATE_STUB(audio_clk)
338 _CLK_SET_RATE_STUB(pwm_clk)
339 _CLK_SET_RATE_STUB(clk32k_clk)
344 #define _CLK_SET_PARENT(name, bit) \
345 static int name##_set_parent(struct clk *clk, struct clk *parent) \
347 if (parent != clk->parent) { \
348 __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
349 HW_CLKCTRL_CLKSEQ_TOG); \
350 clk->parent = parent; \
356 _CLK_SET_PARENT(cpu_clk, CPU)
357 _CLK_SET_PARENT(emi_clk, EMI)
358 _CLK_SET_PARENT(ssp_clk, SSP)
359 _CLK_SET_PARENT(gpmi_clk, GPMI)
360 _CLK_SET_PARENT(lcdif_clk, PIX)
362 #define _CLK_SET_PARENT_STUB(name) \
363 static int name##_set_parent(struct clk *clk, struct clk *parent) \
365 if (parent != clk->parent) \
371 _CLK_SET_PARENT_STUB(uart_clk)
372 _CLK_SET_PARENT_STUB(audio_clk)
373 _CLK_SET_PARENT_STUB(pwm_clk)
374 _CLK_SET_PARENT_STUB(clk32k_clk)
379 static struct clk cpu_clk = {
380 .get_rate = cpu_clk_get_rate,
381 .set_rate = cpu_clk_set_rate,
382 .set_parent = cpu_clk_set_parent,
383 .parent = &ref_cpu_clk,
386 static struct clk hbus_clk = {
387 .get_rate = hbus_clk_get_rate,
391 static struct clk xbus_clk = {
392 .get_rate = xbus_clk_get_rate,
393 .set_rate = xbus_clk_set_rate,
394 .parent = &ref_xtal_clk,
397 static struct clk rtc_clk = {
398 .get_rate = rtc_clk_get_rate,
399 .parent = &ref_xtal_clk,
402 /* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
403 static struct clk usb_clk = {
404 .enable_reg = DIGCTRL_BASE_ADDR,
406 .enable = _raw_clk_enable,
407 .disable = _raw_clk_disable,
411 #define _DEFINE_CLOCK(name, er, es, p) \
412 static struct clk name = { \
413 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
414 .enable_shift = BP_CLKCTRL_##er##_##es, \
415 .get_rate = name##_get_rate, \
416 .set_rate = name##_set_rate, \
417 .set_parent = name##_set_parent, \
418 .enable = _raw_clk_enable, \
419 .disable = _raw_clk_disable, \
423 _DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
424 _DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
425 _DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
426 _DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
427 _DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
428 _DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
429 _DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
430 _DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
432 #define _REGISTER_CLOCK(d, n, c) \
439 static struct clk_lookup lookups[] = {
440 _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
441 _REGISTER_CLOCK("rtc", NULL, rtc_clk)
442 _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
443 _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
444 _REGISTER_CLOCK(NULL, "usb", usb_clk)
445 _REGISTER_CLOCK(NULL, "audio", audio_clk)
446 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
449 static int clk_misc_init(void)
454 /* Fix up parent per register setting */
455 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
456 cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
457 &ref_xtal_clk : &ref_cpu_clk;
458 emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
459 &ref_xtal_clk : &ref_emi_clk;
460 ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
461 &ref_xtal_clk : &ref_io_clk;
462 gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
463 &ref_xtal_clk : &ref_io_clk;
464 lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
465 &ref_xtal_clk : &ref_pix_clk;
467 /* Use int div over frac when both are available */
468 __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
469 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
470 __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
471 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
472 __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
473 CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
475 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
476 reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
477 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
479 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
480 reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
481 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
483 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
484 reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
485 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
487 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
488 reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
489 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
492 * Set safe hbus clock divider. A divider of 3 ensure that
493 * the Vddd voltage required for the cpu clock is sufficiently
494 * high for the hbus clock.
496 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
497 reg &= BM_CLKCTRL_HBUS_DIV;
498 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
499 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
501 for (i = 10000; i; i--)
502 if (!(__raw_readl(CLKCTRL_BASE_ADDR +
503 HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
506 pr_err("%s: divider writing timeout\n", __func__);
510 /* Gate off cpu clock in WFI for power saving */
511 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
512 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
517 int __init mx23_clocks_init(void)
521 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
523 mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);