ARM: omap: Setup consistent dma size at boot time
[linux-2.6-block.git] / arch / arm / mach-omap2 / io.c
CommitLineData
1dbae815
TL
1/*
2 * linux/arch/arm/mach-omap2/io.c
3 *
4 * OMAP2 I/O mapping code
5 *
6 * Copyright (C) 2005 Nokia Corporation
44169075 7 * Copyright (C) 2007-2009 Texas Instruments
646e3ed1
TL
8 *
9 * Author:
10 * Juha Yrjola <juha.yrjola@nokia.com>
11 * Syed Khasim <x0khasim@ti.com>
1dbae815 12 *
44169075
SS
13 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
14 *
1dbae815
TL
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
1dbae815
TL
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
fced80c7 22#include <linux/io.h>
2f135eaf 23#include <linux/clk.h>
91773a00 24#include <linux/omapfb.h>
1dbae815 25
120db2cb 26#include <asm/tlb.h>
120db2cb
TL
27
28#include <asm/mach/map.h>
29
ce491cf8
TL
30#include <plat/sram.h>
31#include <plat/sdrc.h>
ce491cf8 32#include <plat/serial.h>
646e3ed1 33
e80a9729 34#include "clock2xxx.h"
657ebfad 35#include "clock3xxx.h"
e80a9729 36#include "clock44xx.h"
b0a330dc 37#include "io.h"
1dbae815 38
ce491cf8 39#include <plat/omap-pm.h>
72e06d08 40#include "powerdomain.h"
1dbae815 41
1540f214 42#include "clockdomain.h"
ce491cf8 43#include <plat/omap_hwmod.h>
5d190c40 44#include <plat/multi.h>
02bfc030 45
1dbae815
TL
46/*
47 * The machine specific code may provide the extra mapping besides the
48 * default mapping provided here.
49 */
cc26b3b0 50
088ef950 51#ifdef CONFIG_ARCH_OMAP2
cc26b3b0 52static struct map_desc omap24xx_io_desc[] __initdata = {
1dbae815
TL
53 {
54 .virtual = L3_24XX_VIRT,
55 .pfn = __phys_to_pfn(L3_24XX_PHYS),
56 .length = L3_24XX_SIZE,
57 .type = MT_DEVICE
58 },
09f21ed4 59 {
cc26b3b0
SMK
60 .virtual = L4_24XX_VIRT,
61 .pfn = __phys_to_pfn(L4_24XX_PHYS),
62 .length = L4_24XX_SIZE,
63 .type = MT_DEVICE
09f21ed4 64 },
cc26b3b0
SMK
65};
66
59b479e0 67#ifdef CONFIG_SOC_OMAP2420
cc26b3b0
SMK
68static struct map_desc omap242x_io_desc[] __initdata = {
69 {
7adb9987
PW
70 .virtual = DSP_MEM_2420_VIRT,
71 .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS),
72 .length = DSP_MEM_2420_SIZE,
cc26b3b0
SMK
73 .type = MT_DEVICE
74 },
75 {
7adb9987
PW
76 .virtual = DSP_IPI_2420_VIRT,
77 .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS),
78 .length = DSP_IPI_2420_SIZE,
cc26b3b0 79 .type = MT_DEVICE
09f21ed4 80 },
cc26b3b0 81 {
7adb9987
PW
82 .virtual = DSP_MMU_2420_VIRT,
83 .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS),
84 .length = DSP_MMU_2420_SIZE,
cc26b3b0
SMK
85 .type = MT_DEVICE
86 },
87};
88
89#endif
90
59b479e0 91#ifdef CONFIG_SOC_OMAP2430
cc26b3b0 92static struct map_desc omap243x_io_desc[] __initdata = {
72d0f1c3
SMK
93 {
94 .virtual = L4_WK_243X_VIRT,
95 .pfn = __phys_to_pfn(L4_WK_243X_PHYS),
96 .length = L4_WK_243X_SIZE,
97 .type = MT_DEVICE
98 },
99 {
100 .virtual = OMAP243X_GPMC_VIRT,
101 .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS),
102 .length = OMAP243X_GPMC_SIZE,
103 .type = MT_DEVICE
104 },
cc26b3b0
SMK
105 {
106 .virtual = OMAP243X_SDRC_VIRT,
107 .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS),
108 .length = OMAP243X_SDRC_SIZE,
109 .type = MT_DEVICE
110 },
111 {
112 .virtual = OMAP243X_SMS_VIRT,
113 .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS),
114 .length = OMAP243X_SMS_SIZE,
115 .type = MT_DEVICE
116 },
117};
72d0f1c3 118#endif
72d0f1c3 119#endif
cc26b3b0 120
a8eb7ca0 121#ifdef CONFIG_ARCH_OMAP3
cc26b3b0 122static struct map_desc omap34xx_io_desc[] __initdata = {
1dbae815 123 {
cc26b3b0
SMK
124 .virtual = L3_34XX_VIRT,
125 .pfn = __phys_to_pfn(L3_34XX_PHYS),
126 .length = L3_34XX_SIZE,
c40fae95
TL
127 .type = MT_DEVICE
128 },
129 {
cc26b3b0
SMK
130 .virtual = L4_34XX_VIRT,
131 .pfn = __phys_to_pfn(L4_34XX_PHYS),
132 .length = L4_34XX_SIZE,
c40fae95
TL
133 .type = MT_DEVICE
134 },
cc26b3b0
SMK
135 {
136 .virtual = OMAP34XX_GPMC_VIRT,
137 .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS),
138 .length = OMAP34XX_GPMC_SIZE,
1dbae815 139 .type = MT_DEVICE
cc26b3b0
SMK
140 },
141 {
142 .virtual = OMAP343X_SMS_VIRT,
143 .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS),
144 .length = OMAP343X_SMS_SIZE,
145 .type = MT_DEVICE
146 },
147 {
148 .virtual = OMAP343X_SDRC_VIRT,
149 .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS),
150 .length = OMAP343X_SDRC_SIZE,
1dbae815 151 .type = MT_DEVICE
cc26b3b0
SMK
152 },
153 {
154 .virtual = L4_PER_34XX_VIRT,
155 .pfn = __phys_to_pfn(L4_PER_34XX_PHYS),
156 .length = L4_PER_34XX_SIZE,
157 .type = MT_DEVICE
158 },
159 {
160 .virtual = L4_EMU_34XX_VIRT,
161 .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS),
162 .length = L4_EMU_34XX_SIZE,
163 .type = MT_DEVICE
164 },
a4f57b81
TL
165#if defined(CONFIG_DEBUG_LL) && \
166 (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3))
167 {
168 .virtual = ZOOM_UART_VIRT,
169 .pfn = __phys_to_pfn(ZOOM_UART_BASE),
170 .length = SZ_1M,
171 .type = MT_DEVICE
172 },
173#endif
1dbae815 174};
cc26b3b0 175#endif
01001712
HP
176
177#ifdef CONFIG_SOC_OMAPTI816X
178static struct map_desc omapti816x_io_desc[] __initdata = {
179 {
180 .virtual = L4_34XX_VIRT,
181 .pfn = __phys_to_pfn(L4_34XX_PHYS),
182 .length = L4_34XX_SIZE,
183 .type = MT_DEVICE
184 },
185};
186#endif
187
44169075
SS
188#ifdef CONFIG_ARCH_OMAP4
189static struct map_desc omap44xx_io_desc[] __initdata = {
190 {
191 .virtual = L3_44XX_VIRT,
192 .pfn = __phys_to_pfn(L3_44XX_PHYS),
193 .length = L3_44XX_SIZE,
194 .type = MT_DEVICE,
195 },
196 {
197 .virtual = L4_44XX_VIRT,
198 .pfn = __phys_to_pfn(L4_44XX_PHYS),
199 .length = L4_44XX_SIZE,
200 .type = MT_DEVICE,
201 },
44169075
SS
202 {
203 .virtual = OMAP44XX_GPMC_VIRT,
204 .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
205 .length = OMAP44XX_GPMC_SIZE,
206 .type = MT_DEVICE,
207 },
f5d2d659
SS
208 {
209 .virtual = OMAP44XX_EMIF1_VIRT,
210 .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
211 .length = OMAP44XX_EMIF1_SIZE,
212 .type = MT_DEVICE,
213 },
214 {
215 .virtual = OMAP44XX_EMIF2_VIRT,
216 .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
217 .length = OMAP44XX_EMIF2_SIZE,
218 .type = MT_DEVICE,
219 },
220 {
221 .virtual = OMAP44XX_DMM_VIRT,
222 .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS),
223 .length = OMAP44XX_DMM_SIZE,
224 .type = MT_DEVICE,
225 },
44169075
SS
226 {
227 .virtual = L4_PER_44XX_VIRT,
228 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
229 .length = L4_PER_44XX_SIZE,
230 .type = MT_DEVICE,
231 },
232 {
233 .virtual = L4_EMU_44XX_VIRT,
234 .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS),
235 .length = L4_EMU_44XX_SIZE,
236 .type = MT_DEVICE,
237 },
238};
239#endif
1dbae815 240
6fbd55d0
TL
241static void __init _omap2_map_common_io(void)
242{
243 /* Normally devicemaps_init() would flush caches and tlb after
244 * mdesc->map_io(), but we must also do it here because of the CPU
245 * revision check below.
246 */
247 local_flush_tlb_all();
248 flush_cache_all();
249
250 omap2_check_revision();
251 omap_sram_init();
009426a0 252 omap_init_consistent_dma_size();
6fbd55d0
TL
253}
254
59b479e0 255#ifdef CONFIG_SOC_OMAP2420
8185e468 256void __init omap242x_map_common_io(void)
1dbae815 257{
cc26b3b0
SMK
258 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
259 iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
6fbd55d0
TL
260 _omap2_map_common_io();
261}
cc26b3b0
SMK
262#endif
263
59b479e0 264#ifdef CONFIG_SOC_OMAP2430
8185e468 265void __init omap243x_map_common_io(void)
6fbd55d0 266{
cc26b3b0
SMK
267 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
268 iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
6fbd55d0
TL
269 _omap2_map_common_io();
270}
cc26b3b0
SMK
271#endif
272
a8eb7ca0 273#ifdef CONFIG_ARCH_OMAP3
8185e468 274void __init omap34xx_map_common_io(void)
6fbd55d0 275{
cc26b3b0 276 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
6fbd55d0
TL
277 _omap2_map_common_io();
278}
cc26b3b0 279#endif
120db2cb 280
01001712
HP
281#ifdef CONFIG_SOC_OMAPTI816X
282void __init omapti816x_map_common_io(void)
283{
284 iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc));
285 _omap2_map_common_io();
286}
287#endif
288
6fbd55d0 289#ifdef CONFIG_ARCH_OMAP4
8185e468 290void __init omap44xx_map_common_io(void)
6fbd55d0 291{
44169075 292 iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
6fbd55d0 293 _omap2_map_common_io();
120db2cb 294}
6fbd55d0 295#endif
120db2cb 296
2f135eaf
PW
297/*
298 * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
299 *
300 * Sets the CORE DPLL3 M2 divider to the same value that it's at
301 * currently. This has the effect of setting the SDRC SDRAM AC timing
302 * registers to the values currently defined by the kernel. Currently
303 * only defined for OMAP3; will return 0 if called on OMAP2. Returns
304 * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
305 * or passes along the return value of clk_set_rate().
306 */
307static int __init _omap2_init_reprogram_sdrc(void)
308{
309 struct clk *dpll3_m2_ck;
310 int v = -EINVAL;
311 long rate;
312
313 if (!cpu_is_omap34xx())
314 return 0;
315
316 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
e281f7ec 317 if (IS_ERR(dpll3_m2_ck))
2f135eaf
PW
318 return -EINVAL;
319
320 rate = clk_get_rate(dpll3_m2_ck);
321 pr_info("Reprogramming SDRC clock to %ld Hz\n", rate);
322 v = clk_set_rate(dpll3_m2_ck, rate);
323 if (v)
324 pr_err("dpll3_m2_clk rate change failed: %d\n", v);
325
326 clk_put(dpll3_m2_ck);
327
328 return v;
329}
330
2092e5cc
PW
331static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
332{
333 return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
334}
335
741e3a89 336/* See irq.c, omap4-common.c and entry-macro.S */
9f9605c2
RK
337void __iomem *omap_irq_base;
338
4805734b 339void __init omap2_init_common_infrastructure(void)
120db2cb 340{
2092e5cc
PW
341 u8 postsetup_state;
342
6e01478a
PW
343 if (cpu_is_omap242x()) {
344 omap2xxx_powerdomains_init();
4aef7a2a 345 omap2xxx_clockdomains_init();
7359154e 346 omap2420_hwmod_init();
6e01478a
PW
347 } else if (cpu_is_omap243x()) {
348 omap2xxx_powerdomains_init();
4aef7a2a 349 omap2xxx_clockdomains_init();
7359154e 350 omap2430_hwmod_init();
6e01478a
PW
351 } else if (cpu_is_omap34xx()) {
352 omap3xxx_powerdomains_init();
4aef7a2a 353 omap3xxx_clockdomains_init();
7359154e 354 omap3xxx_hwmod_init();
6e01478a
PW
355 } else if (cpu_is_omap44xx()) {
356 omap44xx_powerdomains_init();
dc0b3a70 357 omap44xx_clockdomains_init();
55d2cb08 358 omap44xx_hwmod_init();
6e01478a 359 } else {
2092e5cc 360 pr_err("Could not init hwmod data - unknown SoC\n");
6e01478a 361 }
2092e5cc
PW
362
363 /* Set the default postsetup state for all hwmods */
364#ifdef CONFIG_PM_RUNTIME
365 postsetup_state = _HWMOD_STATE_IDLE;
366#else
367 postsetup_state = _HWMOD_STATE_ENABLED;
368#endif
369 omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
55d2cb08 370
ff2516fb
PW
371 /*
372 * Set the default postsetup state for unusual modules (like
373 * MPU WDT).
374 *
375 * The postsetup_state is not actually used until
376 * omap_hwmod_late_init(), so boards that desire full watchdog
377 * coverage of kernel initialization can reprogram the
378 * postsetup_state between the calls to
379 * omap2_init_common_infra() and omap2_init_common_devices().
380 *
381 * XXX ideally we could detect whether the MPU WDT was currently
382 * enabled here and make this conditional
383 */
384 postsetup_state = _HWMOD_STATE_DISABLED;
385 omap_hwmod_for_each_by_class("wd_timer",
386 _set_hwmod_postsetup_state,
387 &postsetup_state);
388
53da4ce2 389 omap_pm_if_early_init();
e80a9729 390
81b34fbe
PW
391 if (cpu_is_omap2420())
392 omap2420_clk_init();
393 else if (cpu_is_omap2430())
394 omap2430_clk_init();
e80a9729
PW
395 else if (cpu_is_omap34xx())
396 omap3xxx_clk_init();
397 else if (cpu_is_omap44xx())
398 omap4xxx_clk_init();
399 else
2092e5cc 400 pr_err("Could not init clock framework - unknown SoC\n");
4805734b
PW
401}
402
4805734b
PW
403void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
404 struct omap_sdrc_params *sdrc_cs1)
405{
01001712 406 if (cpu_is_omap24xx() || omap3_has_sdrc()) {
aa4b1f6e
KH
407 omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
408 _omap2_init_reprogram_sdrc();
409 }
5d190c40 410
1dbae815 411}
df1e9d1c
TL
412
413/*
414 * NOTE: Please use ioremap + __raw_read/write where possible instead of these
415 */
416
417u8 omap_readb(u32 pa)
418{
419 return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
420}
421EXPORT_SYMBOL(omap_readb);
422
423u16 omap_readw(u32 pa)
424{
425 return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
426}
427EXPORT_SYMBOL(omap_readw);
428
429u32 omap_readl(u32 pa)
430{
431 return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
432}
433EXPORT_SYMBOL(omap_readl);
434
435void omap_writeb(u8 v, u32 pa)
436{
437 __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
438}
439EXPORT_SYMBOL(omap_writeb);
440
441void omap_writew(u16 v, u32 pa)
442{
443 __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
444}
445EXPORT_SYMBOL(omap_writew);
446
447void omap_writel(u32 v, u32 pa)
448{
449 __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
450}
451EXPORT_SYMBOL(omap_writel);