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) 50static 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 66static 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 90static 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 120static 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 176static 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 187static 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 204static 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 266void __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 274void __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 282void __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 289void __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 296void __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 303void __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 */ 320static 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 344static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) 345{ 346 return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); 347} 348 349static void __init omap_common_init_early(void) 350{ 351 omap_init_consistent_dma_size(); 352} 353 354static 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 388void __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 403void __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 422void __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 436void __init omap3430_init_early(void) 437{ 438 omap3_init_early(); 439} 440 441void __init omap35xx_init_early(void) 442{ 443 omap3_init_early(); 444} 445 446void __init omap3630_init_early(void) 447{ 448 omap3_init_early(); 449} 450 451void __init am35xx_init_early(void) 452{ 453 omap3_init_early(); 454} 455 456void __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 472void __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 487void __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