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