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/mux.h> 32 #include <plat/sram.h> 33 #include <plat/sdrc.h> 34 #include <plat/gpmc.h> 35 #include <plat/serial.h> 36 #include <plat/mux.h> 37 #include <plat/vram.h> 38 39 #include "clock.h" 40 41 #include <plat/omap-pm.h> 42 #include <plat/powerdomain.h> 43 #include "powerdomains.h" 44 45 #include <plat/clockdomain.h> 46 #include "clockdomains.h" 47 #include <plat/omap_hwmod.h> 48 #include "omap_hwmod_2420.h" 49 #include "omap_hwmod_2430.h" 50 #include "omap_hwmod_34xx.h" 51 52 /* 53 * The machine specific code may provide the extra mapping besides the 54 * default mapping provided here. 55 */ 56 57 #ifdef CONFIG_ARCH_OMAP24XX 58 static struct map_desc omap24xx_io_desc[] __initdata = { 59 { 60 .virtual = L3_24XX_VIRT, 61 .pfn = __phys_to_pfn(L3_24XX_PHYS), 62 .length = L3_24XX_SIZE, 63 .type = MT_DEVICE 64 }, 65 { 66 .virtual = L4_24XX_VIRT, 67 .pfn = __phys_to_pfn(L4_24XX_PHYS), 68 .length = L4_24XX_SIZE, 69 .type = MT_DEVICE 70 }, 71 }; 72 73 #ifdef CONFIG_ARCH_OMAP2420 74 static struct map_desc omap242x_io_desc[] __initdata = { 75 { 76 .virtual = DSP_MEM_24XX_VIRT, 77 .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), 78 .length = DSP_MEM_24XX_SIZE, 79 .type = MT_DEVICE 80 }, 81 { 82 .virtual = DSP_IPI_24XX_VIRT, 83 .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), 84 .length = DSP_IPI_24XX_SIZE, 85 .type = MT_DEVICE 86 }, 87 { 88 .virtual = DSP_MMU_24XX_VIRT, 89 .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), 90 .length = DSP_MMU_24XX_SIZE, 91 .type = MT_DEVICE 92 }, 93 }; 94 95 #endif 96 97 #ifdef CONFIG_ARCH_OMAP2430 98 static struct map_desc omap243x_io_desc[] __initdata = { 99 { 100 .virtual = L4_WK_243X_VIRT, 101 .pfn = __phys_to_pfn(L4_WK_243X_PHYS), 102 .length = L4_WK_243X_SIZE, 103 .type = MT_DEVICE 104 }, 105 { 106 .virtual = OMAP243X_GPMC_VIRT, 107 .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS), 108 .length = OMAP243X_GPMC_SIZE, 109 .type = MT_DEVICE 110 }, 111 { 112 .virtual = OMAP243X_SDRC_VIRT, 113 .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS), 114 .length = OMAP243X_SDRC_SIZE, 115 .type = MT_DEVICE 116 }, 117 { 118 .virtual = OMAP243X_SMS_VIRT, 119 .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS), 120 .length = OMAP243X_SMS_SIZE, 121 .type = MT_DEVICE 122 }, 123 }; 124 #endif 125 #endif 126 127 #ifdef CONFIG_ARCH_OMAP34XX 128 static struct map_desc omap34xx_io_desc[] __initdata = { 129 { 130 .virtual = L3_34XX_VIRT, 131 .pfn = __phys_to_pfn(L3_34XX_PHYS), 132 .length = L3_34XX_SIZE, 133 .type = MT_DEVICE 134 }, 135 { 136 .virtual = L4_34XX_VIRT, 137 .pfn = __phys_to_pfn(L4_34XX_PHYS), 138 .length = L4_34XX_SIZE, 139 .type = MT_DEVICE 140 }, 141 { 142 .virtual = L4_WK_34XX_VIRT, 143 .pfn = __phys_to_pfn(L4_WK_34XX_PHYS), 144 .length = L4_WK_34XX_SIZE, 145 .type = MT_DEVICE 146 }, 147 { 148 .virtual = OMAP34XX_GPMC_VIRT, 149 .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS), 150 .length = OMAP34XX_GPMC_SIZE, 151 .type = MT_DEVICE 152 }, 153 { 154 .virtual = OMAP343X_SMS_VIRT, 155 .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS), 156 .length = OMAP343X_SMS_SIZE, 157 .type = MT_DEVICE 158 }, 159 { 160 .virtual = OMAP343X_SDRC_VIRT, 161 .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS), 162 .length = OMAP343X_SDRC_SIZE, 163 .type = MT_DEVICE 164 }, 165 { 166 .virtual = L4_PER_34XX_VIRT, 167 .pfn = __phys_to_pfn(L4_PER_34XX_PHYS), 168 .length = L4_PER_34XX_SIZE, 169 .type = MT_DEVICE 170 }, 171 { 172 .virtual = L4_EMU_34XX_VIRT, 173 .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS), 174 .length = L4_EMU_34XX_SIZE, 175 .type = MT_DEVICE 176 }, 177 }; 178 #endif 179 #ifdef CONFIG_ARCH_OMAP4 180 static 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 = L4_WK_44XX_VIRT, 195 .pfn = __phys_to_pfn(L4_WK_44XX_PHYS), 196 .length = L4_WK_44XX_SIZE, 197 .type = MT_DEVICE, 198 }, 199 { 200 .virtual = OMAP44XX_GPMC_VIRT, 201 .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS), 202 .length = OMAP44XX_GPMC_SIZE, 203 .type = MT_DEVICE, 204 }, 205 { 206 .virtual = OMAP44XX_EMIF1_VIRT, 207 .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS), 208 .length = OMAP44XX_EMIF1_SIZE, 209 .type = MT_DEVICE, 210 }, 211 { 212 .virtual = OMAP44XX_EMIF2_VIRT, 213 .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS), 214 .length = OMAP44XX_EMIF2_SIZE, 215 .type = MT_DEVICE, 216 }, 217 { 218 .virtual = OMAP44XX_DMM_VIRT, 219 .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS), 220 .length = OMAP44XX_DMM_SIZE, 221 .type = MT_DEVICE, 222 }, 223 { 224 .virtual = L4_PER_44XX_VIRT, 225 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS), 226 .length = L4_PER_44XX_SIZE, 227 .type = MT_DEVICE, 228 }, 229 { 230 .virtual = L4_EMU_44XX_VIRT, 231 .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS), 232 .length = L4_EMU_44XX_SIZE, 233 .type = MT_DEVICE, 234 }, 235 }; 236 #endif 237 238 void __init omap2_map_common_io(void) 239 { 240 #if defined(CONFIG_ARCH_OMAP2420) 241 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 242 iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); 243 #endif 244 245 #if defined(CONFIG_ARCH_OMAP2430) 246 iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); 247 iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); 248 #endif 249 250 #if defined(CONFIG_ARCH_OMAP34XX) 251 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); 252 #endif 253 254 #if defined(CONFIG_ARCH_OMAP4) 255 iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); 256 #endif 257 /* Normally devicemaps_init() would flush caches and tlb after 258 * mdesc->map_io(), but we must also do it here because of the CPU 259 * revision check below. 260 */ 261 local_flush_tlb_all(); 262 flush_cache_all(); 263 264 omap2_check_revision(); 265 omap_sram_init(); 266 omapfb_reserve_sdram(); 267 omap_vram_reserve_sdram(); 268 } 269 270 /* 271 * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters 272 * 273 * Sets the CORE DPLL3 M2 divider to the same value that it's at 274 * currently. This has the effect of setting the SDRC SDRAM AC timing 275 * registers to the values currently defined by the kernel. Currently 276 * only defined for OMAP3; will return 0 if called on OMAP2. Returns 277 * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2, 278 * or passes along the return value of clk_set_rate(). 279 */ 280 static int __init _omap2_init_reprogram_sdrc(void) 281 { 282 struct clk *dpll3_m2_ck; 283 int v = -EINVAL; 284 long rate; 285 286 if (!cpu_is_omap34xx()) 287 return 0; 288 289 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); 290 if (!dpll3_m2_ck) 291 return -EINVAL; 292 293 rate = clk_get_rate(dpll3_m2_ck); 294 pr_info("Reprogramming SDRC clock to %ld Hz\n", rate); 295 v = clk_set_rate(dpll3_m2_ck, rate); 296 if (v) 297 pr_err("dpll3_m2_clk rate change failed: %d\n", v); 298 299 clk_put(dpll3_m2_ck); 300 301 return v; 302 } 303 304 void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, 305 struct omap_sdrc_params *sdrc_cs1) 306 { 307 struct omap_hwmod **hwmods = NULL; 308 309 if (cpu_is_omap2420()) 310 hwmods = omap2420_hwmods; 311 else if (cpu_is_omap2430()) 312 hwmods = omap2430_hwmods; 313 else if (cpu_is_omap34xx()) 314 hwmods = omap34xx_hwmods; 315 316 #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ 317 /* The OPP tables have to be registered before a clk init */ 318 omap_hwmod_init(hwmods); 319 omap2_mux_init(); 320 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); 321 pwrdm_init(powerdomains_omap); 322 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); 323 #endif 324 omap2_clk_init(); 325 omap_serial_early_init(); 326 #ifndef CONFIG_ARCH_OMAP4 327 omap_hwmod_late_init(); 328 omap_pm_if_init(); 329 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 330 _omap2_init_reprogram_sdrc(); 331 #endif 332 gpmc_init(); 333 } 334