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 20#include <linux/module.h> 21#include <linux/kernel.h> 22#include <linux/init.h> 23#include <linux/io.h> 24#include <linux/clk.h> 25#include <linux/omapfb.h> 26 27#include <asm/tlb.h> 28 29#include <asm/mach/map.h> 30 31#include <plat/sram.h> 32#include <plat/sdrc.h> 33#include <plat/gpmc.h> 34#include <plat/serial.h> 35 36#include "clock2xxx.h" 37#include "clock3xxx.h" 38#include "clock44xx.h" 39 40#include <plat/omap-pm.h> 41#include <plat/powerdomain.h> 42#include "powerdomains.h" 43 44#include <plat/clockdomain.h> 45#include "clockdomains.h" 46 47#include <plat/omap_hwmod.h> 48 49/* 50 * The machine specific code may provide the extra mapping besides the 51 * default mapping provided here. 52 */ 53 54#ifdef CONFIG_ARCH_OMAP2 55static struct map_desc omap24xx_io_desc[] __initdata = { 56 { 57 .virtual = L3_24XX_VIRT, 58 .pfn = __phys_to_pfn(L3_24XX_PHYS), 59 .length = L3_24XX_SIZE, 60 .type = MT_DEVICE 61 }, 62 { 63 .virtual = L4_24XX_VIRT, 64 .pfn = __phys_to_pfn(L4_24XX_PHYS), 65 .length = L4_24XX_SIZE, 66 .type = MT_DEVICE 67 }, 68}; 69 70#ifdef CONFIG_ARCH_OMAP2420 71static struct map_desc omap242x_io_desc[] __initdata = { 72 { 73 .virtual = DSP_MEM_2420_VIRT, 74 .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS), 75 .length = DSP_MEM_2420_SIZE, 76 .type = MT_DEVICE 77 }, 78 { 79 .virtual = DSP_IPI_2420_VIRT, 80 .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS), 81 .length = DSP_IPI_2420_SIZE, 82 .type = MT_DEVICE 83 }, 84 { 85 .virtual = DSP_MMU_2420_VIRT, 86 .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS), 87 .length = DSP_MMU_2420_SIZE, 88 .type = MT_DEVICE 89 }, 90}; 91 92#endif 93 94#ifdef CONFIG_ARCH_OMAP2430 95static struct map_desc omap243x_io_desc[] __initdata = { 96 { 97 .virtual = L4_WK_243X_VIRT, 98 .pfn = __phys_to_pfn(L4_WK_243X_PHYS), 99 .length = L4_WK_243X_SIZE, 100 .type = MT_DEVICE 101 }, 102 { 103 .virtual = OMAP243X_GPMC_VIRT, 104 .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS), 105 .length = OMAP243X_GPMC_SIZE, 106 .type = MT_DEVICE 107 }, 108 { 109 .virtual = OMAP243X_SDRC_VIRT, 110 .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS), 111 .length = OMAP243X_SDRC_SIZE, 112 .type = MT_DEVICE 113 }, 114 { 115 .virtual = OMAP243X_SMS_VIRT, 116 .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS), 117 .length = OMAP243X_SMS_SIZE, 118 .type = MT_DEVICE 119 }, 120}; 121#endif 122#endif 123 124#ifdef CONFIG_ARCH_OMAP3 125static struct map_desc omap34xx_io_desc[] __initdata = { 126 { 127 .virtual = L3_34XX_VIRT, 128 .pfn = __phys_to_pfn(L3_34XX_PHYS), 129 .length = L3_34XX_SIZE, 130 .type = MT_DEVICE 131 }, 132 { 133 .virtual = L4_34XX_VIRT, 134 .pfn = __phys_to_pfn(L4_34XX_PHYS), 135 .length = L4_34XX_SIZE, 136 .type = MT_DEVICE 137 }, 138 { 139 .virtual = OMAP34XX_GPMC_VIRT, 140 .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS), 141 .length = OMAP34XX_GPMC_SIZE, 142 .type = MT_DEVICE 143 }, 144 { 145 .virtual = OMAP343X_SMS_VIRT, 146 .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS), 147 .length = OMAP343X_SMS_SIZE, 148 .type = MT_DEVICE 149 }, 150 { 151 .virtual = OMAP343X_SDRC_VIRT, 152 .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS), 153 .length = OMAP343X_SDRC_SIZE, 154 .type = MT_DEVICE 155 }, 156 { 157 .virtual = L4_PER_34XX_VIRT, 158 .pfn = __phys_to_pfn(L4_PER_34XX_PHYS), 159 .length = L4_PER_34XX_SIZE, 160 .type = MT_DEVICE 161 }, 162 { 163 .virtual = L4_EMU_34XX_VIRT, 164 .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS), 165 .length = L4_EMU_34XX_SIZE, 166 .type = MT_DEVICE 167 }, 168#if defined(CONFIG_DEBUG_LL) && (defined(CONFIG_MACH_OMAP_ZOOM2) || \ 169 defined(CONFIG_MACH_OMAP_ZOOM3)) 170 { 171 .virtual = ZOOM_UART_VIRT, 172 .pfn = __phys_to_pfn(ZOOM_UART_BASE), 173 .length = SZ_1M, 174 .type = MT_DEVICE 175 }, 176#endif 177}; 178#endif 179#ifdef CONFIG_ARCH_OMAP4 180static struct map_desc omap44xx_io_desc[] __initdata = { 181 { 182 .virtual = L3_44XX_VIRT, 183 .pfn = __phys_to_pfn(L3_44XX_PHYS), 184 .length = L3_44XX_SIZE, 185 .type = MT_DEVICE, 186 }, 187 { 188 .virtual = L4_44XX_VIRT, 189 .pfn = __phys_to_pfn(L4_44XX_PHYS), 190 .length = L4_44XX_SIZE, 191 .type = MT_DEVICE, 192 }, 193 { 194 .virtual = OMAP44XX_GPMC_VIRT, 195 .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS), 196 .length = OMAP44XX_GPMC_SIZE, 197 .type = MT_DEVICE, 198 }, 199 { 200 .virtual = OMAP44XX_EMIF1_VIRT, 201 .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS), 202 .length = OMAP44XX_EMIF1_SIZE, 203 .type = MT_DEVICE, 204 }, 205 { 206 .virtual = OMAP44XX_EMIF2_VIRT, 207 .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS), 208 .length = OMAP44XX_EMIF2_SIZE, 209 .type = MT_DEVICE, 210 }, 211 { 212 .virtual = OMAP44XX_DMM_VIRT, 213 .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS), 214 .length = OMAP44XX_DMM_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 { 224 .virtual = L4_EMU_44XX_VIRT, 225 .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS), 226 .length = L4_EMU_44XX_SIZE, 227 .type = MT_DEVICE, 228 }, 229}; 230#endif 231 232static void __init _omap2_map_common_io(void) 233{ 234 /* Normally devicemaps_init() would flush caches and tlb after 235 * mdesc->map_io(), but we must also do it here because of the CPU 236 * revision check below. 237 */ 238 local_flush_tlb_all(); 239 flush_cache_all(); 240 241 omap2_check_revision(); 242 omap_sram_init(); 243} 244 245#ifdef CONFIG_ARCH_OMAP2420 246void __init omap242x_map_common_io(void) 247{ 248 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 249 iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); 250 _omap2_map_common_io(); 251} 252#endif 253 254#ifdef CONFIG_ARCH_OMAP2430 255void __init omap243x_map_common_io(void) 256{ 257 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 258 iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); 259 _omap2_map_common_io(); 260} 261#endif 262 263#ifdef CONFIG_ARCH_OMAP3 264void __init omap34xx_map_common_io(void) 265{ 266 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); 267 _omap2_map_common_io(); 268} 269#endif 270 271#ifdef CONFIG_ARCH_OMAP4 272void __init omap44xx_map_common_io(void) 273{ 274 iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); 275 _omap2_map_common_io(); 276} 277#endif 278 279/* 280 * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters 281 * 282 * Sets the CORE DPLL3 M2 divider to the same value that it's at 283 * currently. This has the effect of setting the SDRC SDRAM AC timing 284 * registers to the values currently defined by the kernel. Currently 285 * only defined for OMAP3; will return 0 if called on OMAP2. Returns 286 * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2, 287 * or passes along the return value of clk_set_rate(). 288 */ 289static int __init _omap2_init_reprogram_sdrc(void) 290{ 291 struct clk *dpll3_m2_ck; 292 int v = -EINVAL; 293 long rate; 294 295 if (!cpu_is_omap34xx()) 296 return 0; 297 298 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); 299 if (!dpll3_m2_ck) 300 return -EINVAL; 301 302 rate = clk_get_rate(dpll3_m2_ck); 303 pr_info("Reprogramming SDRC clock to %ld Hz\n", rate); 304 v = clk_set_rate(dpll3_m2_ck, rate); 305 if (v) 306 pr_err("dpll3_m2_clk rate change failed: %d\n", v); 307 308 clk_put(dpll3_m2_ck); 309 310 return v; 311} 312 313void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, 314 struct omap_sdrc_params *sdrc_cs1) 315{ 316 u8 skip_setup_idle = 0; 317 318 pwrdm_init(powerdomains_omap); 319 clkdm_init(clockdomains_omap, clkdm_autodeps); 320 if (cpu_is_omap242x()) 321 omap2420_hwmod_init(); 322 else if (cpu_is_omap243x()) 323 omap2430_hwmod_init(); 324 else if (cpu_is_omap34xx()) 325 omap3xxx_hwmod_init(); 326 /* The OPP tables have to be registered before a clk init */ 327 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); 328 329 if (cpu_is_omap2420()) 330 omap2420_clk_init(); 331 else if (cpu_is_omap2430()) 332 omap2430_clk_init(); 333 else if (cpu_is_omap34xx()) 334 omap3xxx_clk_init(); 335 else if (cpu_is_omap44xx()) 336 omap4xxx_clk_init(); 337 else 338 pr_err("Could not init clock framework - unknown CPU\n"); 339 340 omap_serial_early_init(); 341 342#ifndef CONFIG_PM_RUNTIME 343 skip_setup_idle = 1; 344#endif 345 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 346 omap_hwmod_late_init(skip_setup_idle); 347 348 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 349 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 350 _omap2_init_reprogram_sdrc(); 351 } 352 gpmc_init(); 353} 354