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 = L4_PER_44XX_VIRT, 219 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS), 220 .length = L4_PER_44XX_SIZE, 221 .type = MT_DEVICE, 222 }, 223 #ifdef CONFIG_OMAP4_ERRATA_I688 224 { 225 .virtual = OMAP4_SRAM_VA, 226 .pfn = __phys_to_pfn(OMAP4_SRAM_PA), 227 .length = PAGE_SIZE, 228 .type = MT_MEMORY_SO, 229 }, 230 #endif 231 232 }; 233 #endif 234 235 #ifdef CONFIG_SOC_OMAP2420 236 void __init omap242x_map_common_io(void) 237 { 238 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 239 iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); 240 } 241 #endif 242 243 #ifdef CONFIG_SOC_OMAP2430 244 void __init omap243x_map_common_io(void) 245 { 246 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 247 iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); 248 } 249 #endif 250 251 #ifdef CONFIG_ARCH_OMAP3 252 void __init omap34xx_map_common_io(void) 253 { 254 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); 255 } 256 #endif 257 258 #ifdef CONFIG_SOC_OMAPTI81XX 259 void __init omapti81xx_map_common_io(void) 260 { 261 iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); 262 } 263 #endif 264 265 #ifdef CONFIG_SOC_OMAPAM33XX 266 void __init omapam33xx_map_common_io(void) 267 { 268 iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); 269 } 270 #endif 271 272 #ifdef CONFIG_ARCH_OMAP4 273 void __init omap44xx_map_common_io(void) 274 { 275 iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); 276 omap_barriers_init(); 277 } 278 #endif 279 280 /* 281 * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters 282 * 283 * Sets the CORE DPLL3 M2 divider to the same value that it's at 284 * currently. This has the effect of setting the SDRC SDRAM AC timing 285 * registers to the values currently defined by the kernel. Currently 286 * only defined for OMAP3; will return 0 if called on OMAP2. Returns 287 * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2, 288 * or passes along the return value of clk_set_rate(). 289 */ 290 static int __init _omap2_init_reprogram_sdrc(void) 291 { 292 struct clk *dpll3_m2_ck; 293 int v = -EINVAL; 294 long rate; 295 296 if (!cpu_is_omap34xx()) 297 return 0; 298 299 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); 300 if (IS_ERR(dpll3_m2_ck)) 301 return -EINVAL; 302 303 rate = clk_get_rate(dpll3_m2_ck); 304 pr_info("Reprogramming SDRC clock to %ld Hz\n", rate); 305 v = clk_set_rate(dpll3_m2_ck, rate); 306 if (v) 307 pr_err("dpll3_m2_clk rate change failed: %d\n", v); 308 309 clk_put(dpll3_m2_ck); 310 311 return v; 312 } 313 314 static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) 315 { 316 return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); 317 } 318 319 static void __init omap_common_init_early(void) 320 { 321 omap_init_consistent_dma_size(); 322 } 323 324 static void __init omap_hwmod_init_postsetup(void) 325 { 326 u8 postsetup_state; 327 328 /* Set the default postsetup state for all hwmods */ 329 #ifdef CONFIG_PM_RUNTIME 330 postsetup_state = _HWMOD_STATE_IDLE; 331 #else 332 postsetup_state = _HWMOD_STATE_ENABLED; 333 #endif 334 omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state); 335 336 /* 337 * Set the default postsetup state for unusual modules (like 338 * MPU WDT). 339 * 340 * The postsetup_state is not actually used until 341 * omap_hwmod_late_init(), so boards that desire full watchdog 342 * coverage of kernel initialization can reprogram the 343 * postsetup_state between the calls to 344 * omap2_init_common_infra() and omap_sdrc_init(). 345 * 346 * XXX ideally we could detect whether the MPU WDT was currently 347 * enabled here and make this conditional 348 */ 349 postsetup_state = _HWMOD_STATE_DISABLED; 350 omap_hwmod_for_each_by_class("wd_timer", 351 _set_hwmod_postsetup_state, 352 &postsetup_state); 353 354 omap_pm_if_early_init(); 355 } 356 357 #ifdef CONFIG_SOC_OMAP2420 358 void __init omap2420_init_early(void) 359 { 360 omap2_set_globals_242x(); 361 omap2xxx_check_revision(); 362 omap_common_init_early(); 363 omap2xxx_voltagedomains_init(); 364 omap242x_powerdomains_init(); 365 omap242x_clockdomains_init(); 366 omap2420_hwmod_init(); 367 omap_hwmod_init_postsetup(); 368 omap2420_clk_init(); 369 } 370 #endif 371 372 #ifdef CONFIG_SOC_OMAP2430 373 void __init omap2430_init_early(void) 374 { 375 omap2_set_globals_243x(); 376 omap2xxx_check_revision(); 377 omap_common_init_early(); 378 omap2xxx_voltagedomains_init(); 379 omap243x_powerdomains_init(); 380 omap243x_clockdomains_init(); 381 omap2430_hwmod_init(); 382 omap_hwmod_init_postsetup(); 383 omap2430_clk_init(); 384 } 385 #endif 386 387 /* 388 * Currently only board-omap3beagle.c should call this because of the 389 * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT. 390 */ 391 #ifdef CONFIG_ARCH_OMAP3 392 void __init omap3_init_early(void) 393 { 394 omap2_set_globals_3xxx(); 395 omap3xxx_check_revision(); 396 omap3xxx_check_features(); 397 omap_common_init_early(); 398 omap3xxx_voltagedomains_init(); 399 omap3xxx_powerdomains_init(); 400 omap3xxx_clockdomains_init(); 401 omap3xxx_hwmod_init(); 402 omap_hwmod_init_postsetup(); 403 omap3xxx_clk_init(); 404 } 405 406 void __init omap3430_init_early(void) 407 { 408 omap3_init_early(); 409 } 410 411 void __init omap35xx_init_early(void) 412 { 413 omap3_init_early(); 414 } 415 416 void __init omap3630_init_early(void) 417 { 418 omap3_init_early(); 419 } 420 421 void __init am35xx_init_early(void) 422 { 423 omap3_init_early(); 424 } 425 426 void __init ti81xx_init_early(void) 427 { 428 omap2_set_globals_ti81xx(); 429 omap3xxx_check_revision(); 430 ti81xx_check_features(); 431 omap_common_init_early(); 432 omap3xxx_voltagedomains_init(); 433 omap3xxx_powerdomains_init(); 434 omap3xxx_clockdomains_init(); 435 omap3xxx_hwmod_init(); 436 omap_hwmod_init_postsetup(); 437 omap3xxx_clk_init(); 438 } 439 #endif 440 441 #ifdef CONFIG_ARCH_OMAP4 442 void __init omap4430_init_early(void) 443 { 444 omap2_set_globals_443x(); 445 omap4xxx_check_revision(); 446 omap4xxx_check_features(); 447 omap_common_init_early(); 448 omap44xx_voltagedomains_init(); 449 omap44xx_powerdomains_init(); 450 omap44xx_clockdomains_init(); 451 omap44xx_hwmod_init(); 452 omap_hwmod_init_postsetup(); 453 omap4xxx_clk_init(); 454 } 455 #endif 456 457 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 458 struct omap_sdrc_params *sdrc_cs1) 459 { 460 omap_sram_init(); 461 462 if (cpu_is_omap24xx() || omap3_has_sdrc()) { 463 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 464 _omap2_init_reprogram_sdrc(); 465 } 466 } 467