]> git.enpas.org Git - openwrt.git/blob - target/linux/xburst/files-2.6.32/arch/mips/include/asm/mach-jz4740/clock.h
4869b88f28395177b861d2ab2dcc56c4c3ecfa49
[openwrt.git] / target / linux / xburst / files-2.6.32 / arch / mips / include / asm / mach-jz4740 / clock.h
1 /*
2  *  linux/include/asm-mips/mach-jz4740/clock.h
3  *
4  *  JZ4740 clocks definition.
5  *
6  *  Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc.
7  *
8  *  Author: <lhhuang@ingenic.cn>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #ifndef __ASM_JZ4740_CLOCK_H__
16 #define __ASM_JZ4740_CLOCK_H__
17
18 #include <asm/mach-jz4740/regs.h>
19
20 /***************************************************************************
21  * CPM
22  ***************************************************************************/
23 #define __cpm_get_pllm() \
24         ((REG_CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT)
25 #define __cpm_get_plln() \
26         ((REG_CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT)
27 #define __cpm_get_pllod() \
28         ((REG_CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT)
29
30 #define __cpm_get_cdiv() \
31         ((REG_CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT)
32 #define __cpm_get_hdiv() \
33         ((REG_CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT)
34 #define __cpm_get_pdiv() \
35         ((REG_CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT)
36 #define __cpm_get_mdiv() \
37         ((REG_CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT)
38 #define __cpm_get_ldiv() \
39         ((REG_CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT)
40 #define __cpm_get_udiv() \
41         ((REG_CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT)
42 #define __cpm_get_i2sdiv() \
43         ((REG_CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT)
44 #define __cpm_get_pixdiv() \
45         ((REG_CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT)
46 #define __cpm_get_mscdiv() \
47         ((REG_CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT)
48 #define __cpm_get_uhcdiv() \
49         ((REG_CPM_UHCCDR & CPM_UHCCDR_UHCDIV_MASK) >> CPM_UHCCDR_UHCDIV_BIT)
50 #define __cpm_get_ssidiv() \
51         ((REG_CPM_SSICCDR & CPM_SSICDR_SSICDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT)
52
53 #define __cpm_set_cdiv(v) \
54         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | ((v) << (CPM_CPCCR_CDIV_BIT)))
55 #define __cpm_set_hdiv(v) \
56         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | ((v) << (CPM_CPCCR_HDIV_BIT)))
57 #define __cpm_set_pdiv(v) \
58         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | ((v) << (CPM_CPCCR_PDIV_BIT)))
59 #define __cpm_set_mdiv(v) \
60         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | ((v) << (CPM_CPCCR_MDIV_BIT)))
61 #define __cpm_set_ldiv(v) \
62         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
63 #define __cpm_set_udiv(v) \
64         (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | ((v) << (CPM_CPCCR_UDIV_BIT)))
65 #define __cpm_set_i2sdiv(v) \
66         (REG_CPM_I2SCDR = (REG_CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | ((v) << (CPM_I2SCDR_I2SDIV_BIT)))
67 #define __cpm_set_pixdiv(v) \
68         (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
69 #define __cpm_set_mscdiv(v) \
70         (REG_CPM_MSCCDR = (REG_CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | ((v) << (CPM_MSCCDR_MSCDIV_BIT)))
71 #define __cpm_set_uhcdiv(v) \
72         (REG_CPM_UHCCDR = (REG_CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | ((v) << (CPM_UHCCDR_UHCDIV_BIT)))
73 #define __cpm_ssiclk_select_exclk() \
74         (REG_CPM_SSICDR &= ~CPM_SSICDR_SCS)
75 #define __cpm_ssiclk_select_pllout() \
76         (REG_CPM_SSICDR |= CPM_SSICDR_SCS)
77 #define __cpm_set_ssidiv(v) \
78         (REG_CPM_SSICDR = (REG_CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT)))
79
80 #define __cpm_select_i2sclk_exclk()     (REG_CPM_CPCCR &= ~CPM_CPCCR_I2CS)
81 #define __cpm_select_i2sclk_pll()       (REG_CPM_CPCCR |= CPM_CPCCR_I2CS)
82 #define __cpm_enable_cko()              (REG_CPM_CPCCR |= CPM_CPCCR_CLKOEN)
83 #define __cpm_select_usbclk_exclk()     (REG_CPM_CPCCR &= ~CPM_CPCCR_UCS)
84 #define __cpm_select_usbclk_pll()       (REG_CPM_CPCCR |= CPM_CPCCR_UCS)
85 #define __cpm_enable_pll_change()       (REG_CPM_CPCCR |= CPM_CPCCR_CE)
86 #define __cpm_pllout_direct()           (REG_CPM_CPCCR |= CPM_CPCCR_PCS)
87 #define __cpm_pllout_div2()             (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS)
88
89 #define __cpm_pll_is_on()               (REG_CPM_CPPCR & CPM_CPPCR_PLLS)
90 #define __cpm_pll_bypass()              (REG_CPM_CPPCR |= CPM_CPPCR_PLLBP)
91 #define __cpm_pll_enable()              (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN)
92
93 #define __cpm_get_cclk_doze_duty() \
94         ((REG_CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)
95 #define __cpm_set_cclk_doze_duty(v) \
96         (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT)))
97
98 #define __cpm_doze_mode()               (REG_CPM_LCR |= CPM_LCR_DOZE_ON)
99 #define __cpm_idle_mode() \
100         (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE)
101 #define __cpm_sleep_mode() \
102         (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP)
103
104 #define __cpm_stop_all()        (REG_CPM_CLKGR = 0x7fff)
105 #define __cpm_stop_uart1()      (REG_CPM_CLKGR |= CPM_CLKGR_UART1)
106 #define __cpm_stop_uhc()        (REG_CPM_CLKGR |= CPM_CLKGR_UHC)
107 #define __cpm_stop_ipu()        (REG_CPM_CLKGR |= CPM_CLKGR_IPU)
108 #define __cpm_stop_dmac()       (REG_CPM_CLKGR |= CPM_CLKGR_DMAC)
109 #define __cpm_stop_udc()        (REG_CPM_CLKGR |= CPM_CLKGR_UDC)
110 #define __cpm_stop_lcd()        (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
111 #define __cpm_stop_cim()        (REG_CPM_CLKGR |= CPM_CLKGR_CIM)
112 #define __cpm_stop_sadc()       (REG_CPM_CLKGR |= CPM_CLKGR_SADC)
113 #define __cpm_stop_msc()        (REG_CPM_CLKGR |= CPM_CLKGR_MSC)
114 #define __cpm_stop_aic1()       (REG_CPM_CLKGR |= CPM_CLKGR_AIC1)
115 #define __cpm_stop_aic2()       (REG_CPM_CLKGR |= CPM_CLKGR_AIC2)
116 #define __cpm_stop_ssi()        (REG_CPM_CLKGR |= CPM_CLKGR_SSI)
117 #define __cpm_stop_i2c()        (REG_CPM_CLKGR |= CPM_CLKGR_I2C)
118 #define __cpm_stop_rtc()        (REG_CPM_CLKGR |= CPM_CLKGR_RTC)
119 #define __cpm_stop_tcu()        (REG_CPM_CLKGR |= CPM_CLKGR_TCU)
120 #define __cpm_stop_uart0()      (REG_CPM_CLKGR |= CPM_CLKGR_UART0)
121
122 #define __cpm_start_all()       (REG_CPM_CLKGR = 0x0)
123 #define __cpm_start_uart1()     (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1)
124 #define __cpm_start_uhc()       (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC)
125 #define __cpm_start_ipu()       (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU)
126 #define __cpm_start_dmac()      (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC)
127 #define __cpm_start_udc()       (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC)
128 #define __cpm_start_lcd()       (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
129 #define __cpm_start_cim()       (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM)
130 #define __cpm_start_sadc()      (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC)
131 #define __cpm_start_msc()       (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC)
132 #define __cpm_start_aic1()      (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1)
133 #define __cpm_start_aic2()      (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2)
134 #define __cpm_start_ssi()       (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI)
135 #define __cpm_start_i2c()       (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C)
136 #define __cpm_start_rtc()       (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC)
137 #define __cpm_start_tcu()       (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
138 #define __cpm_start_uart0()     (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0)
139
140 #define __cpm_get_o1st() \
141         ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT)
142 #define __cpm_set_o1st(v) \
143         (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT)))
144 #define __cpm_suspend_usbphy()          (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND)
145 #define __cpm_enable_osc_in_sleep()     (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE)
146
147
148
149 /*
150  * JZ4740 clocks structure
151  */
152 typedef struct {
153         unsigned int cclk;      /* CPU clock */
154         unsigned int hclk;      /* System bus clock */
155         unsigned int pclk;      /* Peripheral bus clock */
156         unsigned int mclk;      /* Flash/SRAM/SDRAM clock */
157         unsigned int lcdclk;    /* LCDC module clock */
158         unsigned int pixclk;    /* LCD pixel clock */
159         unsigned int i2sclk;    /* AIC module clock */
160         unsigned int usbclk;    /* USB module clock */
161         unsigned int mscclk;    /* MSC module clock */
162         unsigned int extalclk;  /* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
163         unsigned int rtcclk;    /* RTC clock for CPM,INTC,RTC,TCU,WDT */
164 } jz_clocks_t;
165
166 extern jz_clocks_t jz_clocks;
167
168
169 /* PLL output frequency */
170 static __inline__ unsigned int __cpm_get_pllout(void)
171 {
172         unsigned long m, n, no, pllout;
173         unsigned long cppcr = REG_CPM_CPPCR;
174         unsigned long od[4] = {1, 2, 2, 4};
175         if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
176                 m = __cpm_get_pllm() + 2;
177                 n = __cpm_get_plln() + 2;
178                 no = od[__cpm_get_pllod()];
179                 pllout = ((JZ_EXTAL) / (n * no)) * m;
180         } else
181                 pllout = JZ_EXTAL;
182         return pllout;
183 }
184
185 /* PLL output frequency for MSC/I2S/LCD/USB */
186 static __inline__ unsigned int __cpm_get_pllout2(void)
187 {
188         if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
189                 return __cpm_get_pllout();
190         else
191                 return __cpm_get_pllout()/2;
192 }
193
194 /* CPU core clock */
195 static __inline__ unsigned int __cpm_get_cclk(void)
196 {
197         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
198
199         return __cpm_get_pllout() / div[__cpm_get_cdiv()];
200 }
201
202 /* AHB system bus clock */
203 static __inline__ unsigned int __cpm_get_hclk(void)
204 {
205         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
206
207         return __cpm_get_pllout() / div[__cpm_get_hdiv()];
208 }
209
210 /* Memory bus clock */
211 static __inline__ unsigned int __cpm_get_mclk(void)
212 {
213         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
214
215         return __cpm_get_pllout() / div[__cpm_get_mdiv()];
216 }
217
218 /* APB peripheral bus clock */
219 static __inline__ unsigned int __cpm_get_pclk(void)
220 {
221         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
222
223         return __cpm_get_pllout() / div[__cpm_get_pdiv()];
224 }
225
226 /* LCDC module clock */
227 static __inline__ unsigned int __cpm_get_lcdclk(void)
228 {
229         return __cpm_get_pllout2() / (__cpm_get_ldiv() + 1);
230 }
231
232 /* LCD pixel clock */
233 static __inline__ unsigned int __cpm_get_pixclk(void)
234 {
235         return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1);
236 }
237
238 /* I2S clock */
239 static __inline__ unsigned int __cpm_get_i2sclk(void)
240 {
241         if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) {
242                 return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
243         }
244         else {
245                 return JZ_EXTAL;
246         }
247 }
248
249 /* USB clock */
250 static __inline__ unsigned int __cpm_get_usbclk(void)
251 {
252         if (REG_CPM_CPCCR & CPM_CPCCR_UCS) {
253                 return __cpm_get_pllout2() / (__cpm_get_udiv() + 1);
254         }
255         else {
256                 return JZ_EXTAL;
257         }
258 }
259
260 /* MSC clock */
261 static __inline__ unsigned int __cpm_get_mscclk(void)
262 {
263         return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1);
264 }
265
266 /* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
267 static __inline__ unsigned int __cpm_get_extalclk(void)
268 {
269         return JZ_EXTAL;
270 }
271
272 /* RTC clock for CPM,INTC,RTC,TCU,WDT */
273 static __inline__ unsigned int __cpm_get_rtcclk(void)
274 {
275         return JZ_EXTAL_RTC;
276 }
277
278 /*
279  * Output 24MHz for SD and 16MHz for MMC.
280  */
281 static inline void __cpm_select_msc_clk(int sd)
282 {
283         unsigned int pllout2 = __cpm_get_pllout2();
284         unsigned int div = 0;
285
286         if (sd) {
287                 div = pllout2 / 24000000;
288         }
289         else {
290                 div = pllout2 / 16000000;
291         }
292
293         REG_CPM_MSCCDR = div - 1;
294 }
295
296 int jz_init_clocks(unsigned long ext_rate);
297
298 #endif /* __ASM_JZ4740_CLOCK_H__ */