Merge branch 'x86-doc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / arm / plat-omap / common.c
1 /*
2  * linux/arch/arm/plat-omap/common.c
3  *
4  * Code common to all OMAP machines.
5  * The file is created by Tony Lindgren <tony@atomide.com>
6  *
7  * Copyright (C) 2009 Texas Instruments
8  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
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 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/console.h>
19 #include <linux/serial.h>
20 #include <linux/tty.h>
21 #include <linux/serial_8250.h>
22 #include <linux/serial_reg.h>
23 #include <linux/clk.h>
24 #include <linux/io.h>
25
26 #include <mach/hardware.h>
27 #include <asm/system.h>
28 #include <asm/pgtable.h>
29 #include <asm/mach/map.h>
30 #include <asm/setup.h>
31
32 #include <plat/common.h>
33 #include <plat/board.h>
34 #include <plat/control.h>
35 #include <plat/mux.h>
36 #include <plat/fpga.h>
37 #include <plat/serial.h>
38
39 #include <plat/clock.h>
40
41 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
42 # include "../mach-omap2/sdrc.h"
43 #endif
44
45 #define NO_LENGTH_CHECK 0xffffffff
46
47 struct omap_board_config_kernel *omap_board_config;
48 int omap_board_config_size;
49
50 /* used by omap-smp.c and board-4430sdp.c */
51 void __iomem *gic_cpu_base_addr;
52
53 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
54 {
55         struct omap_board_config_kernel *kinfo = NULL;
56         int i;
57
58         /* Try to find the config from the board-specific structures
59          * in the kernel. */
60         for (i = 0; i < omap_board_config_size; i++) {
61                 if (omap_board_config[i].tag == tag) {
62                         if (skip == 0) {
63                                 kinfo = &omap_board_config[i];
64                                 break;
65                         } else {
66                                 skip--;
67                         }
68                 }
69         }
70         if (kinfo == NULL)
71                 return NULL;
72         return kinfo->data;
73 }
74
75 const void *__omap_get_config(u16 tag, size_t len, int nr)
76 {
77         return get_config(tag, len, nr, NULL);
78 }
79 EXPORT_SYMBOL(__omap_get_config);
80
81 const void *omap_get_var_config(u16 tag, size_t *len)
82 {
83         return get_config(tag, NO_LENGTH_CHECK, 0, len);
84 }
85 EXPORT_SYMBOL(omap_get_var_config);
86
87 /*
88  * 32KHz clocksource ... always available, on pretty most chips except
89  * OMAP 730 and 1510.  Other timers could be used as clocksources, with
90  * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
91  * but systems won't necessarily want to spend resources that way.
92  */
93
94 #define OMAP16XX_TIMER_32K_SYNCHRONIZED         0xfffbc410
95
96 #if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
97
98 #include <linux/clocksource.h>
99
100 /*
101  * offset_32k holds the init time counter value. It is then subtracted
102  * from every counter read to achieve a counter that counts time from the
103  * kernel boot (needed for sched_clock()).
104  */
105 static u32 offset_32k __read_mostly;
106
107 #ifdef CONFIG_ARCH_OMAP16XX
108 static cycle_t omap16xx_32k_read(struct clocksource *cs)
109 {
110         return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
111 }
112 #else
113 #define omap16xx_32k_read       NULL
114 #endif
115
116 #ifdef CONFIG_ARCH_OMAP2420
117 static cycle_t omap2420_32k_read(struct clocksource *cs)
118 {
119         return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
120 }
121 #else
122 #define omap2420_32k_read       NULL
123 #endif
124
125 #ifdef CONFIG_ARCH_OMAP2430
126 static cycle_t omap2430_32k_read(struct clocksource *cs)
127 {
128         return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
129 }
130 #else
131 #define omap2430_32k_read       NULL
132 #endif
133
134 #ifdef CONFIG_ARCH_OMAP3
135 static cycle_t omap34xx_32k_read(struct clocksource *cs)
136 {
137         return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
138 }
139 #else
140 #define omap34xx_32k_read       NULL
141 #endif
142
143 #ifdef CONFIG_ARCH_OMAP4
144 static cycle_t omap44xx_32k_read(struct clocksource *cs)
145 {
146         return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
147 }
148 #else
149 #define omap44xx_32k_read       NULL
150 #endif
151
152 /*
153  * Kernel assumes that sched_clock can be called early but may not have
154  * things ready yet.
155  */
156 static cycle_t omap_32k_read_dummy(struct clocksource *cs)
157 {
158         return 0;
159 }
160
161 static struct clocksource clocksource_32k = {
162         .name           = "32k_counter",
163         .rating         = 250,
164         .read           = omap_32k_read_dummy,
165         .mask           = CLOCKSOURCE_MASK(32),
166         .shift          = 10,
167         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
168 };
169
170 /*
171  * Returns current time from boot in nsecs. It's OK for this to wrap
172  * around for now, as it's just a relative time stamp.
173  */
174 unsigned long long sched_clock(void)
175 {
176         return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
177                                   clocksource_32k.mult, clocksource_32k.shift);
178 }
179
180 /**
181  * read_persistent_clock -  Return time from a persistent clock.
182  *
183  * Reads the time from a source which isn't disabled during PM, the
184  * 32k sync timer.  Convert the cycles elapsed since last read into
185  * nsecs and adds to a monotonically increasing timespec.
186  */
187 static struct timespec persistent_ts;
188 static cycles_t cycles, last_cycles;
189 void read_persistent_clock(struct timespec *ts)
190 {
191         unsigned long long nsecs;
192         cycles_t delta;
193         struct timespec *tsp = &persistent_ts;
194
195         last_cycles = cycles;
196         cycles = clocksource_32k.read(&clocksource_32k);
197         delta = cycles - last_cycles;
198
199         nsecs = clocksource_cyc2ns(delta,
200                                    clocksource_32k.mult, clocksource_32k.shift);
201
202         timespec_add_ns(tsp, nsecs);
203         *ts = *tsp;
204 }
205
206 static int __init omap_init_clocksource_32k(void)
207 {
208         static char err[] __initdata = KERN_ERR
209                         "%s: can't register clocksource!\n";
210
211         if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
212                 struct clk *sync_32k_ick;
213
214                 if (cpu_is_omap16xx())
215                         clocksource_32k.read = omap16xx_32k_read;
216                 else if (cpu_is_omap2420())
217                         clocksource_32k.read = omap2420_32k_read;
218                 else if (cpu_is_omap2430())
219                         clocksource_32k.read = omap2430_32k_read;
220                 else if (cpu_is_omap34xx())
221                         clocksource_32k.read = omap34xx_32k_read;
222                 else if (cpu_is_omap44xx())
223                         clocksource_32k.read = omap44xx_32k_read;
224                 else
225                         return -ENODEV;
226
227                 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
228                 if (sync_32k_ick)
229                         clk_enable(sync_32k_ick);
230
231                 clocksource_32k.mult = clocksource_hz2mult(32768,
232                                             clocksource_32k.shift);
233
234                 offset_32k = clocksource_32k.read(&clocksource_32k);
235
236                 if (clocksource_register(&clocksource_32k))
237                         printk(err, clocksource_32k.name);
238         }
239         return 0;
240 }
241 arch_initcall(omap_init_clocksource_32k);
242
243 #endif  /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
244
245 /* Global address base setup code */
246
247 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
248
249 static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
250 {
251         omap2_set_globals_tap(omap2_globals);
252         omap2_set_globals_sdrc(omap2_globals);
253         omap2_set_globals_control(omap2_globals);
254         omap2_set_globals_prcm(omap2_globals);
255         omap2_set_globals_uart(omap2_globals);
256 }
257
258 #endif
259
260 #if defined(CONFIG_ARCH_OMAP2420)
261
262 static struct omap_globals omap242x_globals = {
263         .class  = OMAP242X_CLASS,
264         .tap    = OMAP2_L4_IO_ADDRESS(0x48014000),
265         .sdrc   = OMAP2420_SDRC_BASE,
266         .sms    = OMAP2420_SMS_BASE,
267         .ctrl   = OMAP2420_CTRL_BASE,
268         .prm    = OMAP2420_PRM_BASE,
269         .cm     = OMAP2420_CM_BASE,
270         .uart1_phys     = OMAP2_UART1_BASE,
271         .uart2_phys     = OMAP2_UART2_BASE,
272         .uart3_phys     = OMAP2_UART3_BASE,
273 };
274
275 void __init omap2_set_globals_242x(void)
276 {
277         __omap2_set_globals(&omap242x_globals);
278 }
279 #endif
280
281 #if defined(CONFIG_ARCH_OMAP2430)
282
283 static struct omap_globals omap243x_globals = {
284         .class  = OMAP243X_CLASS,
285         .tap    = OMAP2_L4_IO_ADDRESS(0x4900a000),
286         .sdrc   = OMAP243X_SDRC_BASE,
287         .sms    = OMAP243X_SMS_BASE,
288         .ctrl   = OMAP243X_CTRL_BASE,
289         .prm    = OMAP2430_PRM_BASE,
290         .cm     = OMAP2430_CM_BASE,
291         .uart1_phys     = OMAP2_UART1_BASE,
292         .uart2_phys     = OMAP2_UART2_BASE,
293         .uart3_phys     = OMAP2_UART3_BASE,
294 };
295
296 void __init omap2_set_globals_243x(void)
297 {
298         __omap2_set_globals(&omap243x_globals);
299 }
300 #endif
301
302 #if defined(CONFIG_ARCH_OMAP3)
303
304 static struct omap_globals omap3_globals = {
305         .class  = OMAP343X_CLASS,
306         .tap    = OMAP2_L4_IO_ADDRESS(0x4830A000),
307         .sdrc   = OMAP343X_SDRC_BASE,
308         .sms    = OMAP343X_SMS_BASE,
309         .ctrl   = OMAP343X_CTRL_BASE,
310         .prm    = OMAP3430_PRM_BASE,
311         .cm     = OMAP3430_CM_BASE,
312         .uart1_phys     = OMAP3_UART1_BASE,
313         .uart2_phys     = OMAP3_UART2_BASE,
314         .uart3_phys     = OMAP3_UART3_BASE,
315 };
316
317 void __init omap2_set_globals_343x(void)
318 {
319         __omap2_set_globals(&omap3_globals);
320 }
321
322 void __init omap2_set_globals_36xx(void)
323 {
324         omap3_globals.uart4_phys = OMAP3_UART4_BASE;
325
326         __omap2_set_globals(&omap3_globals);
327 }
328 #endif
329
330 #if defined(CONFIG_ARCH_OMAP4)
331 static struct omap_globals omap4_globals = {
332         .class  = OMAP443X_CLASS,
333         .tap    = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
334         .ctrl   = OMAP443X_CTRL_BASE,
335         .prm    = OMAP4430_PRM_BASE,
336         .cm     = OMAP4430_CM_BASE,
337         .cm2    = OMAP4430_CM2_BASE,
338         .uart1_phys     = OMAP4_UART1_BASE,
339         .uart2_phys     = OMAP4_UART2_BASE,
340         .uart3_phys     = OMAP4_UART3_BASE,
341         .uart4_phys     = OMAP4_UART4_BASE,
342 };
343
344 void __init omap2_set_globals_443x(void)
345 {
346         omap2_set_globals_tap(&omap4_globals);
347         omap2_set_globals_control(&omap4_globals);
348         omap2_set_globals_prcm(&omap4_globals);
349         omap2_set_globals_uart(&omap4_globals);
350 }
351 #endif
352