]> Pileus Git - ~andy/linux/blob - arch/arm/mach-omap2/io.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[~andy/linux] / arch / arm / mach-omap2 / io.c
1 /*
2  * linux/arch/arm/mach-omap2/io.c
3  *
4  * OMAP2 I/O mapping code
5  *
6  * Copyright (C) 2005 Nokia Corporation
7  * Copyright (C) 2007-2009 Texas Instruments
8  *
9  * Author:
10  *      Juha Yrjola <juha.yrjola@nokia.com>
11  *      Syed Khasim <x0khasim@ti.com>
12  *
13  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
14  *
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  */
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/io.h>
23 #include <linux/clk.h>
24
25 #include <asm/tlb.h>
26 #include <asm/mach/map.h>
27
28 #include <plat/sram.h>
29 #include <plat/sdrc.h>
30 #include <plat/serial.h>
31 #include <plat/omap-pm.h>
32 #include <plat/omap_hwmod.h>
33 #include <plat/multi.h>
34
35 #include "iomap.h"
36 #include "voltage.h"
37 #include "powerdomain.h"
38 #include "clockdomain.h"
39 #include "common.h"
40 #include "clock2xxx.h"
41 #include "clock3xxx.h"
42 #include "clock44xx.h"
43
44 /*
45  * The machine specific code may provide the extra mapping besides the
46  * default mapping provided here.
47  */
48
49 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
50 static struct map_desc omap24xx_io_desc[] __initdata = {
51         {
52                 .virtual        = L3_24XX_VIRT,
53                 .pfn            = __phys_to_pfn(L3_24XX_PHYS),
54                 .length         = L3_24XX_SIZE,
55                 .type           = MT_DEVICE
56         },
57         {
58                 .virtual        = L4_24XX_VIRT,
59                 .pfn            = __phys_to_pfn(L4_24XX_PHYS),
60                 .length         = L4_24XX_SIZE,
61                 .type           = MT_DEVICE
62         },
63 };
64
65 #ifdef CONFIG_SOC_OMAP2420
66 static struct map_desc omap242x_io_desc[] __initdata = {
67         {
68                 .virtual        = DSP_MEM_2420_VIRT,
69                 .pfn            = __phys_to_pfn(DSP_MEM_2420_PHYS),
70                 .length         = DSP_MEM_2420_SIZE,
71                 .type           = MT_DEVICE
72         },
73         {
74                 .virtual        = DSP_IPI_2420_VIRT,
75                 .pfn            = __phys_to_pfn(DSP_IPI_2420_PHYS),
76                 .length         = DSP_IPI_2420_SIZE,
77                 .type           = MT_DEVICE
78         },
79         {
80                 .virtual        = DSP_MMU_2420_VIRT,
81                 .pfn            = __phys_to_pfn(DSP_MMU_2420_PHYS),
82                 .length         = DSP_MMU_2420_SIZE,
83                 .type           = MT_DEVICE
84         },
85 };
86
87 #endif
88
89 #ifdef CONFIG_SOC_OMAP2430
90 static struct map_desc omap243x_io_desc[] __initdata = {
91         {
92                 .virtual        = L4_WK_243X_VIRT,
93                 .pfn            = __phys_to_pfn(L4_WK_243X_PHYS),
94                 .length         = L4_WK_243X_SIZE,
95                 .type           = MT_DEVICE
96         },
97         {
98                 .virtual        = OMAP243X_GPMC_VIRT,
99                 .pfn            = __phys_to_pfn(OMAP243X_GPMC_PHYS),
100                 .length         = OMAP243X_GPMC_SIZE,
101                 .type           = MT_DEVICE
102         },
103         {
104                 .virtual        = OMAP243X_SDRC_VIRT,
105                 .pfn            = __phys_to_pfn(OMAP243X_SDRC_PHYS),
106                 .length         = OMAP243X_SDRC_SIZE,
107                 .type           = MT_DEVICE
108         },
109         {
110                 .virtual        = OMAP243X_SMS_VIRT,
111                 .pfn            = __phys_to_pfn(OMAP243X_SMS_PHYS),
112                 .length         = OMAP243X_SMS_SIZE,
113                 .type           = MT_DEVICE
114         },
115 };
116 #endif
117 #endif
118
119 #ifdef  CONFIG_ARCH_OMAP3
120 static struct map_desc omap34xx_io_desc[] __initdata = {
121         {
122                 .virtual        = L3_34XX_VIRT,
123                 .pfn            = __phys_to_pfn(L3_34XX_PHYS),
124                 .length         = L3_34XX_SIZE,
125                 .type           = MT_DEVICE
126         },
127         {
128                 .virtual        = L4_34XX_VIRT,
129                 .pfn            = __phys_to_pfn(L4_34XX_PHYS),
130                 .length         = L4_34XX_SIZE,
131                 .type           = MT_DEVICE
132         },
133         {
134                 .virtual        = OMAP34XX_GPMC_VIRT,
135                 .pfn            = __phys_to_pfn(OMAP34XX_GPMC_PHYS),
136                 .length         = OMAP34XX_GPMC_SIZE,
137                 .type           = MT_DEVICE
138         },
139         {
140                 .virtual        = OMAP343X_SMS_VIRT,
141                 .pfn            = __phys_to_pfn(OMAP343X_SMS_PHYS),
142                 .length         = OMAP343X_SMS_SIZE,
143                 .type           = MT_DEVICE
144         },
145         {
146                 .virtual        = OMAP343X_SDRC_VIRT,
147                 .pfn            = __phys_to_pfn(OMAP343X_SDRC_PHYS),
148                 .length         = OMAP343X_SDRC_SIZE,
149                 .type           = MT_DEVICE
150         },
151         {
152                 .virtual        = L4_PER_34XX_VIRT,
153                 .pfn            = __phys_to_pfn(L4_PER_34XX_PHYS),
154                 .length         = L4_PER_34XX_SIZE,
155                 .type           = MT_DEVICE
156         },
157         {
158                 .virtual        = L4_EMU_34XX_VIRT,
159                 .pfn            = __phys_to_pfn(L4_EMU_34XX_PHYS),
160                 .length         = L4_EMU_34XX_SIZE,
161                 .type           = MT_DEVICE
162         },
163 #if defined(CONFIG_DEBUG_LL) &&                                                 \
164         (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3))
165         {
166                 .virtual        = ZOOM_UART_VIRT,
167                 .pfn            = __phys_to_pfn(ZOOM_UART_BASE),
168                 .length         = SZ_1M,
169                 .type           = MT_DEVICE
170         },
171 #endif
172 };
173 #endif
174
175 #ifdef CONFIG_SOC_OMAPTI81XX
176 static struct map_desc omapti81xx_io_desc[] __initdata = {
177         {
178                 .virtual        = L4_34XX_VIRT,
179                 .pfn            = __phys_to_pfn(L4_34XX_PHYS),
180                 .length         = L4_34XX_SIZE,
181                 .type           = MT_DEVICE
182         }
183 };
184 #endif
185
186 #ifdef CONFIG_SOC_OMAPAM33XX
187 static struct map_desc omapam33xx_io_desc[] __initdata = {
188         {
189                 .virtual        = L4_34XX_VIRT,
190                 .pfn            = __phys_to_pfn(L4_34XX_PHYS),
191                 .length         = L4_34XX_SIZE,
192                 .type           = MT_DEVICE
193         },
194         {
195                 .virtual        = L4_WK_AM33XX_VIRT,
196                 .pfn            = __phys_to_pfn(L4_WK_AM33XX_PHYS),
197                 .length         = L4_WK_AM33XX_SIZE,
198                 .type           = MT_DEVICE
199         }
200 };
201 #endif
202
203 #ifdef  CONFIG_ARCH_OMAP4
204 static struct map_desc omap44xx_io_desc[] __initdata = {
205         {
206                 .virtual        = L3_44XX_VIRT,
207                 .pfn            = __phys_to_pfn(L3_44XX_PHYS),
208                 .length         = L3_44XX_SIZE,
209                 .type           = MT_DEVICE,
210         },
211         {
212                 .virtual        = L4_44XX_VIRT,
213                 .pfn            = __phys_to_pfn(L4_44XX_PHYS),
214                 .length         = L4_44XX_SIZE,
215                 .type           = MT_DEVICE,
216         },
217         {
218                 .virtual        = OMAP44XX_GPMC_VIRT,
219                 .pfn            = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
220                 .length         = OMAP44XX_GPMC_SIZE,
221                 .type           = MT_DEVICE,
222         },
223         {
224                 .virtual        = OMAP44XX_EMIF1_VIRT,
225                 .pfn            = __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
226                 .length         = OMAP44XX_EMIF1_SIZE,
227                 .type           = MT_DEVICE,
228         },
229         {
230                 .virtual        = OMAP44XX_EMIF2_VIRT,
231                 .pfn            = __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
232                 .length         = OMAP44XX_EMIF2_SIZE,
233                 .type           = MT_DEVICE,
234         },
235         {
236                 .virtual        = OMAP44XX_DMM_VIRT,
237                 .pfn            = __phys_to_pfn(OMAP44XX_DMM_PHYS),
238                 .length         = OMAP44XX_DMM_SIZE,
239                 .type           = MT_DEVICE,
240         },
241         {
242                 .virtual        = L4_PER_44XX_VIRT,
243                 .pfn            = __phys_to_pfn(L4_PER_44XX_PHYS),
244                 .length         = L4_PER_44XX_SIZE,
245                 .type           = MT_DEVICE,
246         },
247         {
248                 .virtual        = L4_EMU_44XX_VIRT,
249                 .pfn            = __phys_to_pfn(L4_EMU_44XX_PHYS),
250                 .length         = L4_EMU_44XX_SIZE,
251                 .type           = MT_DEVICE,
252         },
253 #ifdef CONFIG_OMAP4_ERRATA_I688
254         {
255                 .virtual        = OMAP4_SRAM_VA,
256                 .pfn            = __phys_to_pfn(OMAP4_SRAM_PA),
257                 .length         = PAGE_SIZE,
258                 .type           = MT_MEMORY_SO,
259         },
260 #endif
261
262 };
263 #endif
264
265 #ifdef CONFIG_SOC_OMAP2420
266 void __init omap242x_map_common_io(void)
267 {
268         iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
269         iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
270 }
271 #endif
272
273 #ifdef CONFIG_SOC_OMAP2430
274 void __init omap243x_map_common_io(void)
275 {
276         iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
277         iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
278 }
279 #endif
280
281 #ifdef CONFIG_ARCH_OMAP3
282 void __init omap34xx_map_common_io(void)
283 {
284         iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
285 }
286 #endif
287
288 #ifdef CONFIG_SOC_OMAPTI81XX
289 void __init omapti81xx_map_common_io(void)
290 {
291         iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
292 }
293 #endif
294
295 #ifdef CONFIG_SOC_OMAPAM33XX
296 void __init omapam33xx_map_common_io(void)
297 {
298         iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
299 }
300 #endif
301
302 #ifdef CONFIG_ARCH_OMAP4
303 void __init omap44xx_map_common_io(void)
304 {
305         iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
306         omap_barriers_init();
307 }
308 #endif
309
310 /*
311  * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
312  *
313  * Sets the CORE DPLL3 M2 divider to the same value that it's at
314  * currently.  This has the effect of setting the SDRC SDRAM AC timing
315  * registers to the values currently defined by the kernel.  Currently
316  * only defined for OMAP3; will return 0 if called on OMAP2.  Returns
317  * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
318  * or passes along the return value of clk_set_rate().
319  */
320 static int __init _omap2_init_reprogram_sdrc(void)
321 {
322         struct clk *dpll3_m2_ck;
323         int v = -EINVAL;
324         long rate;
325
326         if (!cpu_is_omap34xx())
327                 return 0;
328
329         dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
330         if (IS_ERR(dpll3_m2_ck))
331                 return -EINVAL;
332
333         rate = clk_get_rate(dpll3_m2_ck);
334         pr_info("Reprogramming SDRC clock to %ld Hz\n", rate);
335         v = clk_set_rate(dpll3_m2_ck, rate);
336         if (v)
337                 pr_err("dpll3_m2_clk rate change failed: %d\n", v);
338
339         clk_put(dpll3_m2_ck);
340
341         return v;
342 }
343
344 static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
345 {
346         return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
347 }
348
349 static void __init omap_common_init_early(void)
350 {
351         omap_init_consistent_dma_size();
352 }
353
354 static void __init omap_hwmod_init_postsetup(void)
355 {
356         u8 postsetup_state;
357
358         /* Set the default postsetup state for all hwmods */
359 #ifdef CONFIG_PM_RUNTIME
360         postsetup_state = _HWMOD_STATE_IDLE;
361 #else
362         postsetup_state = _HWMOD_STATE_ENABLED;
363 #endif
364         omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
365
366         /*
367          * Set the default postsetup state for unusual modules (like
368          * MPU WDT).
369          *
370          * The postsetup_state is not actually used until
371          * omap_hwmod_late_init(), so boards that desire full watchdog
372          * coverage of kernel initialization can reprogram the
373          * postsetup_state between the calls to
374          * omap2_init_common_infra() and omap_sdrc_init().
375          *
376          * XXX ideally we could detect whether the MPU WDT was currently
377          * enabled here and make this conditional
378          */
379         postsetup_state = _HWMOD_STATE_DISABLED;
380         omap_hwmod_for_each_by_class("wd_timer",
381                                      _set_hwmod_postsetup_state,
382                                      &postsetup_state);
383
384         omap_pm_if_early_init();
385 }
386
387 #ifdef CONFIG_SOC_OMAP2420
388 void __init omap2420_init_early(void)
389 {
390         omap2_set_globals_242x();
391         omap2xxx_check_revision();
392         omap_common_init_early();
393         omap2xxx_voltagedomains_init();
394         omap242x_powerdomains_init();
395         omap242x_clockdomains_init();
396         omap2420_hwmod_init();
397         omap_hwmod_init_postsetup();
398         omap2420_clk_init();
399 }
400 #endif
401
402 #ifdef CONFIG_SOC_OMAP2430
403 void __init omap2430_init_early(void)
404 {
405         omap2_set_globals_243x();
406         omap2xxx_check_revision();
407         omap_common_init_early();
408         omap2xxx_voltagedomains_init();
409         omap243x_powerdomains_init();
410         omap243x_clockdomains_init();
411         omap2430_hwmod_init();
412         omap_hwmod_init_postsetup();
413         omap2430_clk_init();
414 }
415 #endif
416
417 /*
418  * Currently only board-omap3beagle.c should call this because of the
419  * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT.
420  */
421 #ifdef CONFIG_ARCH_OMAP3
422 void __init omap3_init_early(void)
423 {
424         omap2_set_globals_3xxx();
425         omap3xxx_check_revision();
426         omap3xxx_check_features();
427         omap_common_init_early();
428         omap3xxx_voltagedomains_init();
429         omap3xxx_powerdomains_init();
430         omap3xxx_clockdomains_init();
431         omap3xxx_hwmod_init();
432         omap_hwmod_init_postsetup();
433         omap3xxx_clk_init();
434 }
435
436 void __init omap3430_init_early(void)
437 {
438         omap3_init_early();
439 }
440
441 void __init omap35xx_init_early(void)
442 {
443         omap3_init_early();
444 }
445
446 void __init omap3630_init_early(void)
447 {
448         omap3_init_early();
449 }
450
451 void __init am35xx_init_early(void)
452 {
453         omap3_init_early();
454 }
455
456 void __init ti81xx_init_early(void)
457 {
458         omap2_set_globals_ti81xx();
459         omap3xxx_check_revision();
460         ti81xx_check_features();
461         omap_common_init_early();
462         omap3xxx_voltagedomains_init();
463         omap3xxx_powerdomains_init();
464         omap3xxx_clockdomains_init();
465         omap3xxx_hwmod_init();
466         omap_hwmod_init_postsetup();
467         omap3xxx_clk_init();
468 }
469 #endif
470
471 #ifdef CONFIG_ARCH_OMAP4
472 void __init omap4430_init_early(void)
473 {
474         omap2_set_globals_443x();
475         omap4xxx_check_revision();
476         omap4xxx_check_features();
477         omap_common_init_early();
478         omap44xx_voltagedomains_init();
479         omap44xx_powerdomains_init();
480         omap44xx_clockdomains_init();
481         omap44xx_hwmod_init();
482         omap_hwmod_init_postsetup();
483         omap4xxx_clk_init();
484 }
485 #endif
486
487 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
488                                       struct omap_sdrc_params *sdrc_cs1)
489 {
490         omap_sram_init();
491
492         if (cpu_is_omap24xx() || omap3_has_sdrc()) {
493                 omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
494                 _omap2_init_reprogram_sdrc();
495         }
496 }