Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
io.c
Go to the documentation of this file.
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 <[email protected]>
11  * Syed Khasim <[email protected]>
12  *
13  * Added OMAP4 support - Santosh Shilimkar <[email protected]>
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 #include <plat/dma.h>
35 
36 #include "soc.h"
37 #include "iomap.h"
38 #include "voltage.h"
39 #include "powerdomain.h"
40 #include "clockdomain.h"
41 #include "common.h"
42 #include "clock.h"
43 #include "clock2xxx.h"
44 #include "clock3xxx.h"
45 #include "clock44xx.h"
46 
47 /*
48  * The machine specific code may provide the extra mapping besides the
49  * default mapping provided here.
50  */
51 
52 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
53 static struct map_desc omap24xx_io_desc[] __initdata = {
54  {
55  .virtual = L3_24XX_VIRT,
57  .length = L3_24XX_SIZE,
58  .type = MT_DEVICE
59  },
60  {
61  .virtual = L4_24XX_VIRT,
63  .length = L4_24XX_SIZE,
64  .type = MT_DEVICE
65  },
66 };
67 
68 #ifdef CONFIG_SOC_OMAP2420
69 static struct map_desc omap242x_io_desc[] __initdata = {
70  {
73  .length = DSP_MEM_2420_SIZE,
74  .type = MT_DEVICE
75  },
76  {
77  .virtual = DSP_IPI_2420_VIRT,
79  .length = DSP_IPI_2420_SIZE,
80  .type = MT_DEVICE
81  },
82  {
83  .virtual = DSP_MMU_2420_VIRT,
85  .length = DSP_MMU_2420_SIZE,
86  .type = MT_DEVICE
87  },
88 };
89 
90 #endif
91 
92 #ifdef CONFIG_SOC_OMAP2430
93 static struct map_desc omap243x_io_desc[] __initdata = {
94  {
97  .length = L4_WK_243X_SIZE,
98  .type = MT_DEVICE
99  },
100  {
101  .virtual = OMAP243X_GPMC_VIRT,
103  .length = OMAP243X_GPMC_SIZE,
104  .type = MT_DEVICE
105  },
106  {
107  .virtual = OMAP243X_SDRC_VIRT,
109  .length = OMAP243X_SDRC_SIZE,
110  .type = MT_DEVICE
111  },
112  {
113  .virtual = OMAP243X_SMS_VIRT,
115  .length = OMAP243X_SMS_SIZE,
116  .type = MT_DEVICE
117  },
118 };
119 #endif
120 #endif
121 
122 #ifdef CONFIG_ARCH_OMAP3
123 static struct map_desc omap34xx_io_desc[] __initdata = {
124  {
126  .pfn = __phys_to_pfn(L3_34XX_PHYS),
127  .length = L3_34XX_SIZE,
128  .type = MT_DEVICE
129  },
130  {
131  .virtual = L4_34XX_VIRT,
132  .pfn = __phys_to_pfn(L4_34XX_PHYS),
133  .length = L4_34XX_SIZE,
134  .type = MT_DEVICE
135  },
136  {
137  .virtual = OMAP34XX_GPMC_VIRT,
139  .length = OMAP34XX_GPMC_SIZE,
140  .type = MT_DEVICE
141  },
142  {
143  .virtual = OMAP343X_SMS_VIRT,
145  .length = OMAP343X_SMS_SIZE,
146  .type = MT_DEVICE
147  },
148  {
149  .virtual = OMAP343X_SDRC_VIRT,
151  .length = OMAP343X_SDRC_SIZE,
152  .type = MT_DEVICE
153  },
154  {
155  .virtual = L4_PER_34XX_VIRT,
157  .length = L4_PER_34XX_SIZE,
158  .type = MT_DEVICE
159  },
160  {
161  .virtual = L4_EMU_34XX_VIRT,
163  .length = L4_EMU_34XX_SIZE,
164  .type = MT_DEVICE
165  },
166 #if defined(CONFIG_DEBUG_LL) && \
167  (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3))
168  {
169  .virtual = ZOOM_UART_VIRT,
171  .length = SZ_1M,
172  .type = MT_DEVICE
173  },
174 #endif
175 };
176 #endif
177 
178 #ifdef CONFIG_SOC_TI81XX
179 static struct map_desc omapti81xx_io_desc[] __initdata = {
180  {
182  .pfn = __phys_to_pfn(L4_34XX_PHYS),
183  .length = L4_34XX_SIZE,
184  .type = MT_DEVICE
185  }
186 };
187 #endif
188 
189 #ifdef CONFIG_SOC_AM33XX
190 static struct map_desc omapam33xx_io_desc[] __initdata = {
191  {
193  .pfn = __phys_to_pfn(L4_34XX_PHYS),
194  .length = L4_34XX_SIZE,
195  .type = MT_DEVICE
196  },
197  {
198  .virtual = L4_WK_AM33XX_VIRT,
200  .length = L4_WK_AM33XX_SIZE,
201  .type = MT_DEVICE
202  }
203 };
204 #endif
205 
206 #ifdef CONFIG_ARCH_OMAP4
207 static struct map_desc omap44xx_io_desc[] __initdata = {
208  {
210  .pfn = __phys_to_pfn(L3_44XX_PHYS),
211  .length = L3_44XX_SIZE,
212  .type = MT_DEVICE,
213  },
214  {
215  .virtual = L4_44XX_VIRT,
216  .pfn = __phys_to_pfn(L4_44XX_PHYS),
217  .length = L4_44XX_SIZE,
218  .type = MT_DEVICE,
219  },
220  {
221  .virtual = L4_PER_44XX_VIRT,
223  .length = L4_PER_44XX_SIZE,
224  .type = MT_DEVICE,
225  },
226 #ifdef CONFIG_OMAP4_ERRATA_I688
227  {
228  .virtual = OMAP4_SRAM_VA,
230  .length = PAGE_SIZE,
231  .type = MT_MEMORY_SO,
232  },
233 #endif
234 
235 };
236 #endif
237 
238 #ifdef CONFIG_SOC_OMAP5
239 static struct map_desc omap54xx_io_desc[] __initdata = {
240  {
242  .pfn = __phys_to_pfn(L3_54XX_PHYS),
243  .length = L3_54XX_SIZE,
244  .type = MT_DEVICE,
245  },
246  {
247  .virtual = L4_54XX_VIRT,
248  .pfn = __phys_to_pfn(L4_54XX_PHYS),
249  .length = L4_54XX_SIZE,
250  .type = MT_DEVICE,
251  },
252  {
253  .virtual = L4_WK_54XX_VIRT,
255  .length = L4_WK_54XX_SIZE,
256  .type = MT_DEVICE,
257  },
258  {
259  .virtual = L4_PER_54XX_VIRT,
261  .length = L4_PER_54XX_SIZE,
262  .type = MT_DEVICE,
263  },
264 };
265 #endif
266 
267 #ifdef CONFIG_SOC_OMAP2420
268 void __init omap242x_map_common_io(void)
269 {
270  iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
271  iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
272 }
273 #endif
274 
275 #ifdef CONFIG_SOC_OMAP2430
276 void __init omap243x_map_common_io(void)
277 {
278  iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
279  iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
280 }
281 #endif
282 
283 #ifdef CONFIG_ARCH_OMAP3
284 void __init omap34xx_map_common_io(void)
285 {
286  iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
287 }
288 #endif
289 
290 #ifdef CONFIG_SOC_TI81XX
291 void __init omapti81xx_map_common_io(void)
292 {
293  iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
294 }
295 #endif
296 
297 #ifdef CONFIG_SOC_AM33XX
298 void __init omapam33xx_map_common_io(void)
299 {
300  iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
301 }
302 #endif
303 
304 #ifdef CONFIG_ARCH_OMAP4
305 void __init omap44xx_map_common_io(void)
306 {
307  iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
309 }
310 #endif
311 
312 #ifdef CONFIG_SOC_OMAP5
313 void __init omap5_map_common_io(void)
314 {
315  iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
316 }
317 #endif
318 /*
319  * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
320  *
321  * Sets the CORE DPLL3 M2 divider to the same value that it's at
322  * currently. This has the effect of setting the SDRC SDRAM AC timing
323  * registers to the values currently defined by the kernel. Currently
324  * only defined for OMAP3; will return 0 if called on OMAP2. Returns
325  * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
326  * or passes along the return value of clk_set_rate().
327  */
328 static int __init _omap2_init_reprogram_sdrc(void)
329 {
330  struct clk *dpll3_m2_ck;
331  int v = -EINVAL;
332  long rate;
333 
334  if (!cpu_is_omap34xx())
335  return 0;
336 
337  dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
338  if (IS_ERR(dpll3_m2_ck))
339  return -EINVAL;
340 
341  rate = clk_get_rate(dpll3_m2_ck);
342  pr_info("Reprogramming SDRC clock to %ld Hz\n", rate);
343  v = clk_set_rate(dpll3_m2_ck, rate);
344  if (v)
345  pr_err("dpll3_m2_clk rate change failed: %d\n", v);
346 
347  clk_put(dpll3_m2_ck);
348 
349  return v;
350 }
351 
352 static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
353 {
354  return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
355 }
356 
357 static void __init omap_common_init_early(void)
358 {
360 }
361 
362 static void __init omap_hwmod_init_postsetup(void)
363 {
364  u8 postsetup_state;
365 
366  /* Set the default postsetup state for all hwmods */
367 #ifdef CONFIG_PM_RUNTIME
368  postsetup_state = _HWMOD_STATE_IDLE;
369 #else
370  postsetup_state = _HWMOD_STATE_ENABLED;
371 #endif
372  omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
373 
375 }
376 
377 #ifdef CONFIG_SOC_OMAP2420
378 void __init omap2420_init_early(void)
379 {
382  omap_common_init_early();
387  omap_hwmod_init_postsetup();
389 }
390 
391 void __init omap2420_init_late(void)
392 {
393  omap_mux_late_init();
395  omap2_pm_init();
396 }
397 #endif
398 
399 #ifdef CONFIG_SOC_OMAP2430
400 void __init omap2430_init_early(void)
401 {
404  omap_common_init_early();
409  omap_hwmod_init_postsetup();
411 }
412 
413 void __init omap2430_init_late(void)
414 {
415  omap_mux_late_init();
417  omap2_pm_init();
418 }
419 #endif
420 
421 /*
422  * Currently only board-omap3beagle.c should call this because of the
423  * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT.
424  */
425 #ifdef CONFIG_ARCH_OMAP3
426 void __init omap3_init_early(void)
427 {
431  omap_common_init_early();
436  omap_hwmod_init_postsetup();
438 }
439 
440 void __init omap3430_init_early(void)
441 {
443 }
444 
445 void __init omap35xx_init_early(void)
446 {
448 }
449 
450 void __init omap3630_init_early(void)
451 {
453 }
454 
455 void __init am35xx_init_early(void)
456 {
458 }
459 
460 void __init ti81xx_init_early(void)
461 {
465  omap_common_init_early();
470  omap_hwmod_init_postsetup();
472 }
473 
474 void __init omap3_init_late(void)
475 {
476  omap_mux_late_init();
478  omap3_pm_init();
479 }
480 
481 void __init omap3430_init_late(void)
482 {
483  omap_mux_late_init();
485  omap3_pm_init();
486 }
487 
488 void __init omap35xx_init_late(void)
489 {
490  omap_mux_late_init();
492  omap3_pm_init();
493 }
494 
495 void __init omap3630_init_late(void)
496 {
497  omap_mux_late_init();
499  omap3_pm_init();
500 }
501 
502 void __init am35xx_init_late(void)
503 {
504  omap_mux_late_init();
506  omap3_pm_init();
507 }
508 
509 void __init ti81xx_init_late(void)
510 {
511  omap_mux_late_init();
513  omap3_pm_init();
514 }
515 #endif
516 
517 #ifdef CONFIG_SOC_AM33XX
518 void __init am33xx_init_early(void)
519 {
523  omap_common_init_early();
528  omap_hwmod_init_postsetup();
529  am33xx_clk_init();
530 }
531 #endif
532 
533 #ifdef CONFIG_ARCH_OMAP4
534 void __init omap4430_init_early(void)
535 {
539  omap_common_init_early();
544  omap_hwmod_init_postsetup();
546 }
547 
548 void __init omap4430_init_late(void)
549 {
550  omap_mux_late_init();
552  omap4_pm_init();
553 }
554 #endif
555 
556 #ifdef CONFIG_SOC_OMAP5
557 void __init omap5_init_early(void)
558 {
561  omap_common_init_early();
562 }
563 #endif
564 
565 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
566  struct omap_sdrc_params *sdrc_cs1)
567 {
568  omap_sram_init();
569 
570  if (cpu_is_omap24xx() || omap3_has_sdrc()) {
571  omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
572  _omap2_init_reprogram_sdrc();
573  }
574 }