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 } 497