4869b88f28395177b861d2ab2dcc56c4c3ecfa49
[openwrt/svn-archive/archive.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__ */