PageRenderTime 18ms CodeModel.GetById 6ms app.highlight 10ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/arm/mach-omap2/io.c

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