aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:42:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:42:43 -0400
commit2cf4d4514d5b43c1f3b64bd0ec8b9853bde8f1dc (patch)
treee35a625496acc6ac852846d40b8851186b9d1ac4 /arch/arm/plat-omap
parent44b7532b8b464f606053562400719c9c21276037 (diff)
parentce53895a5d24e0ee19fb92f56c17323fb4c9ab27 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (417 commits) MAINTAINERS: EB110ATX is not ebsa110 MAINTAINERS: update Eric Miao's email address and status fb: add support of LCD display controller on pxa168/910 (base layer) [ARM] 5552/1: ep93xx get_uart_rate(): use EP93XX_SYSCON_PWRCNT and EP93XX_SYSCON_PWRCN [ARM] pxa/sharpsl_pm: zaurus needs generic pxa suspend/resume routines [ARM] 5544/1: Trust PrimeCell resource sizes [ARM] pxa/sharpsl_pm: cleanup of gpio-related code. [ARM] pxa/sharpsl_pm: drop set_irq_type calls [ARM] pxa/sharpsl_pm: merge pxa-specific code into generic one [ARM] pxa/sharpsl_pm: merge the two sharpsl_pm.c since it's now pxa specific [ARM] sa1100: remove unused collie_pm.c [ARM] pxa: fix the conflicting non-static declarations of global_gpios[] [ARM] 5550/1: Add default configure file for w90p910 platform [ARM] 5549/1: Add clock api for w90p910 platform. [ARM] 5548/1: Add gpio api for w90p910 platform [ARM] 5551/1: Add multi-function pin api for w90p910 platform. [ARM] Make ARM_VIC_NR depend on ARM_VIC [ARM] 5546/1: ARM PL022 SSP/SPI driver v3 ARM: OMAP4: SMP: Update defconfig for OMAP4430 ARM: OMAP4: SMP: Enable SMP support for OMAP4430 ...
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig19
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/clock.c37
-rw-r--r--arch/arm/plat-omap/common.c114
-rw-r--r--arch/arm/plat-omap/devices.c2
-rw-r--r--arch/arm/plat-omap/dma.c102
-rw-r--r--arch/arm/plat-omap/dmtimer.c73
-rw-r--r--arch/arm/plat-omap/gpio.c134
-rw-r--r--arch/arm/plat-omap/i2c.c2
-rw-r--r--arch/arm/plat-omap/include/mach/clock.h10
-rw-r--r--arch/arm/plat-omap/include/mach/common.h3
-rw-r--r--arch/arm/plat-omap/include/mach/control.h20
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h21
-rw-r--r--arch/arm/plat-omap/include/mach/debug-macro.S2
-rw-r--r--arch/arm/plat-omap/include/mach/dma.h4
-rw-r--r--arch/arm/plat-omap/include/mach/entry-macro.S83
-rw-r--r--arch/arm/plat-omap/include/mach/gpmc-smc91x.h42
-rw-r--r--arch/arm/plat-omap/include/mach/hardware.h1
-rw-r--r--arch/arm/plat-omap/include/mach/hwa742.h4
-rw-r--r--arch/arm/plat-omap/include/mach/io.h37
-rw-r--r--arch/arm/plat-omap/include/mach/iommu.h168
-rw-r--r--arch/arm/plat-omap/include/mach/iommu2.h96
-rw-r--r--arch/arm/plat-omap/include/mach/iovmm.h94
-rw-r--r--arch/arm/plat-omap/include/mach/irqs.h92
-rw-r--r--arch/arm/plat-omap/include/mach/keypad.h4
-rw-r--r--arch/arm/plat-omap/include/mach/memory.h3
-rw-r--r--arch/arm/plat-omap/include/mach/omap24xx.h18
-rw-r--r--arch/arm/plat-omap/include/mach/omap34xx.h13
-rw-r--r--arch/arm/plat-omap/include/mach/omap44xx.h46
-rw-r--r--arch/arm/plat-omap/include/mach/onenand.h22
-rw-r--r--arch/arm/plat-omap/include/mach/pm.h345
-rw-r--r--arch/arm/plat-omap/include/mach/serial.h25
-rw-r--r--arch/arm/plat-omap/include/mach/smp.h51
-rw-r--r--arch/arm/plat-omap/include/mach/sram.h6
-rw-r--r--arch/arm/plat-omap/include/mach/usb.h6
-rw-r--r--arch/arm/plat-omap/include/mach/vmalloc.h2
-rw-r--r--arch/arm/plat-omap/io.c29
-rw-r--r--arch/arm/plat-omap/iommu.c996
-rw-r--r--arch/arm/plat-omap/iopgtable.h72
-rw-r--r--arch/arm/plat-omap/iovmm.c896
-rw-r--r--arch/arm/plat-omap/mcbsp.c30
-rw-r--r--arch/arm/plat-omap/mux.c3
-rw-r--r--arch/arm/plat-omap/sram.c66
43 files changed, 3241 insertions, 553 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 9dd68fafb374..efe85d095190 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -23,6 +23,11 @@ config ARCH_OMAP3
23 select CPU_V7 23 select CPU_V7
24 select COMMON_CLKDEV 24 select COMMON_CLKDEV
25 25
26config ARCH_OMAP4
27 bool "TI OMAP4"
28 select CPU_V7
29 select ARM_GIC
30
26endchoice 31endchoice
27 32
28comment "OMAP Feature Selections" 33comment "OMAP Feature Selections"
@@ -40,7 +45,6 @@ config OMAP_DEBUG_LEDS
40config OMAP_DEBUG_POWERDOMAIN 45config OMAP_DEBUG_POWERDOMAIN
41 bool "Emit debug messages from powerdomain layer" 46 bool "Emit debug messages from powerdomain layer"
42 depends on ARCH_OMAP2 || ARCH_OMAP3 47 depends on ARCH_OMAP2 || ARCH_OMAP3
43 default n
44 help 48 help
45 Say Y here if you want to compile in powerdomain layer 49 Say Y here if you want to compile in powerdomain layer
46 debugging messages for OMAP2/3. These messages can 50 debugging messages for OMAP2/3. These messages can
@@ -52,7 +56,6 @@ config OMAP_DEBUG_POWERDOMAIN
52config OMAP_DEBUG_CLOCKDOMAIN 56config OMAP_DEBUG_CLOCKDOMAIN
53 bool "Emit debug messages from clockdomain layer" 57 bool "Emit debug messages from clockdomain layer"
54 depends on ARCH_OMAP2 || ARCH_OMAP3 58 depends on ARCH_OMAP2 || ARCH_OMAP3
55 default n
56 help 59 help
57 Say Y here if you want to compile in clockdomain layer 60 Say Y here if you want to compile in clockdomain layer
58 debugging messages for OMAP2/3. These messages can 61 debugging messages for OMAP2/3. These messages can
@@ -110,11 +113,13 @@ config OMAP_MCBSP
110config OMAP_MBOX_FWK 113config OMAP_MBOX_FWK
111 tristate "Mailbox framework support" 114 tristate "Mailbox framework support"
112 depends on ARCH_OMAP 115 depends on ARCH_OMAP
113 default n
114 help 116 help
115 Say Y here if you want to use OMAP Mailbox framework support for 117 Say Y here if you want to use OMAP Mailbox framework support for
116 DSP, IVA1.0 and IVA2 in OMAP1/2/3. 118 DSP, IVA1.0 and IVA2 in OMAP1/2/3.
117 119
120config OMAP_IOMMU
121 tristate
122
118choice 123choice
119 prompt "System timer" 124 prompt "System timer"
120 default OMAP_MPU_TIMER 125 default OMAP_MPU_TIMER
@@ -128,13 +133,13 @@ config OMAP_MPU_TIMER
128 133
129config OMAP_32K_TIMER 134config OMAP_32K_TIMER
130 bool "Use 32KHz timer" 135 bool "Use 32KHz timer"
131 depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX 136 depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4
132 help 137 help
133 Select this option if you want to enable the OMAP 32KHz timer. 138 Select this option if you want to enable the OMAP 32KHz timer.
134 This timer saves power compared to the OMAP_MPU_TIMER, and has 139 This timer saves power compared to the OMAP_MPU_TIMER, and has
135 support for no tick during idle. The 32KHz timer provides less 140 support for no tick during idle. The 32KHz timer provides less
136 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is 141 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
137 currently only available for OMAP16XX, 24XX and 34XX. 142 currently only available for OMAP16XX, 24XX, 34XX and OMAP4.
138 143
139endchoice 144endchoice
140 145
@@ -149,7 +154,7 @@ config OMAP_32K_TIMER_HZ
149 154
150config OMAP_DM_TIMER 155config OMAP_DM_TIMER
151 bool "Use dual-mode timer" 156 bool "Use dual-mode timer"
152 depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX 157 depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4
153 help 158 help
154 Select this option if you want to use OMAP Dual-Mode timers. 159 Select this option if you want to use OMAP Dual-Mode timers.
155 160
@@ -171,7 +176,7 @@ endchoice
171 176
172config OMAP_SERIAL_WAKE 177config OMAP_SERIAL_WAKE
173 bool "Enable wake-up events for serial ports" 178 bool "Enable wake-up events for serial ports"
174 depends on OMAP_MUX 179 depends on ARCH_OMAP1 && OMAP_MUX
175 default y 180 default y
176 help 181 help
177 Select this option if you want to have your system wake up 182 Select this option if you want to have your system wake up
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 04a100cfb8e5..a83279523958 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -13,6 +13,7 @@ obj- :=
13obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o 13obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
14 14
15obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 15obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
16obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
16 17
17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o 18obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
18obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 19obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 29efc279287a..e8c327a45a55 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -36,10 +36,40 @@ static struct clk_functions *arch_clock;
36 * Standard clock functions defined in include/linux/clk.h 36 * Standard clock functions defined in include/linux/clk.h
37 *-------------------------------------------------------------------------*/ 37 *-------------------------------------------------------------------------*/
38 38
39/* This functions is moved to arch/arm/common/clkdev.c. For OMAP4 since
40 * clock framework is not up , it is defined here to avoid rework in
41 * every driver. Also dummy prcm reset function is added */
42
43/* Dummy hooks only for OMAP4.For rest OMAPs, common clkdev is used */
44#if defined(CONFIG_ARCH_OMAP4)
45struct clk *clk_get(struct device *dev, const char *id)
46{
47 return NULL;
48}
49EXPORT_SYMBOL(clk_get);
50
51void clk_put(struct clk *clk)
52{
53}
54EXPORT_SYMBOL(clk_put);
55
56void omap2_clk_prepare_for_reboot(void)
57{
58}
59EXPORT_SYMBOL(omap2_clk_prepare_for_reboot);
60
61void omap_prcm_arch_reset(char mode)
62{
63}
64EXPORT_SYMBOL(omap_prcm_arch_reset);
65#endif
39int clk_enable(struct clk *clk) 66int clk_enable(struct clk *clk)
40{ 67{
41 unsigned long flags; 68 unsigned long flags;
42 int ret = 0; 69 int ret = 0;
70 if (cpu_is_omap44xx())
71 /* OMAP4 clk framework not supported yet */
72 return 0;
43 73
44 if (clk == NULL || IS_ERR(clk)) 74 if (clk == NULL || IS_ERR(clk))
45 return -EINVAL; 75 return -EINVAL;
@@ -140,6 +170,9 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
140 unsigned long flags; 170 unsigned long flags;
141 int ret = -EINVAL; 171 int ret = -EINVAL;
142 172
173 if (cpu_is_omap44xx())
174 /* OMAP4 clk framework not supported yet */
175 return 0;
143 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) 176 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
144 return ret; 177 return ret;
145 178
@@ -240,13 +273,13 @@ void recalculate_root_clocks(void)
240} 273}
241 274
242/** 275/**
243 * clk_init_one - initialize any fields in the struct clk before clk init 276 * clk_preinit - initialize any fields in the struct clk before clk init
244 * @clk: struct clk * to initialize 277 * @clk: struct clk * to initialize
245 * 278 *
246 * Initialize any struct clk fields needed before normal clk initialization 279 * Initialize any struct clk fields needed before normal clk initialization
247 * can run. No return value. 280 * can run. No return value.
248 */ 281 */
249void clk_init_one(struct clk *clk) 282void clk_preinit(struct clk *clk)
250{ 283{
251 INIT_LIST_HEAD(&clk->children); 284 INIT_LIST_HEAD(&clk->children);
252} 285}
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 433021f3d7cc..ebcf006406f9 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -2,6 +2,10 @@
2 * linux/arch/arm/plat-omap/common.c 2 * linux/arch/arm/plat-omap/common.c
3 * 3 *
4 * Code common to all OMAP machines. 4 * Code common to all OMAP machines.
5 * The file is created by Tony Lindgren <tony@atomide.com>
6 *
7 * Copyright (C) 2009 Texas Instruments
8 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
5 * 9 *
6 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -11,7 +15,6 @@
11#include <linux/kernel.h> 15#include <linux/kernel.h>
12#include <linux/init.h> 16#include <linux/init.h>
13#include <linux/delay.h> 17#include <linux/delay.h>
14#include <linux/pm.h>
15#include <linux/console.h> 18#include <linux/console.h>
16#include <linux/serial.h> 19#include <linux/serial.h>
17#include <linux/tty.h> 20#include <linux/tty.h>
@@ -175,25 +178,70 @@ console_initcall(omap_add_serial_console);
175 * but systems won't necessarily want to spend resources that way. 178 * but systems won't necessarily want to spend resources that way.
176 */ 179 */
177 180
178#if defined(CONFIG_ARCH_OMAP16XX) 181#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
179#define TIMER_32K_SYNCHRONIZED 0xfffbc410
180#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
181#define TIMER_32K_SYNCHRONIZED (OMAP2_32KSYNCT_BASE + 0x10)
182#endif
183 182
184#ifdef TIMER_32K_SYNCHRONIZED 183#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
185 184
186#include <linux/clocksource.h> 185#include <linux/clocksource.h>
187 186
188static cycle_t omap_32k_read(struct clocksource *cs) 187#ifdef CONFIG_ARCH_OMAP16XX
188static cycle_t omap16xx_32k_read(struct clocksource *cs)
189{
190 return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
191}
192#else
193#define omap16xx_32k_read NULL
194#endif
195
196#ifdef CONFIG_ARCH_OMAP2420
197static cycle_t omap2420_32k_read(struct clocksource *cs)
198{
199 return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
200}
201#else
202#define omap2420_32k_read NULL
203#endif
204
205#ifdef CONFIG_ARCH_OMAP2430
206static cycle_t omap2430_32k_read(struct clocksource *cs)
207{
208 return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
209}
210#else
211#define omap2430_32k_read NULL
212#endif
213
214#ifdef CONFIG_ARCH_OMAP34XX
215static cycle_t omap34xx_32k_read(struct clocksource *cs)
216{
217 return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
218}
219#else
220#define omap34xx_32k_read NULL
221#endif
222
223#ifdef CONFIG_ARCH_OMAP4
224static cycle_t omap44xx_32k_read(struct clocksource *cs)
189{ 225{
190 return omap_readl(TIMER_32K_SYNCHRONIZED); 226 return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
227}
228#else
229#define omap44xx_32k_read NULL
230#endif
231
232/*
233 * Kernel assumes that sched_clock can be called early but may not have
234 * things ready yet.
235 */
236static cycle_t omap_32k_read_dummy(struct clocksource *cs)
237{
238 return 0;
191} 239}
192 240
193static struct clocksource clocksource_32k = { 241static struct clocksource clocksource_32k = {
194 .name = "32k_counter", 242 .name = "32k_counter",
195 .rating = 250, 243 .rating = 250,
196 .read = omap_32k_read, 244 .read = omap_32k_read_dummy,
197 .mask = CLOCKSOURCE_MASK(32), 245 .mask = CLOCKSOURCE_MASK(32),
198 .shift = 10, 246 .shift = 10,
199 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 247 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -207,7 +255,7 @@ unsigned long long sched_clock(void)
207{ 255{
208 unsigned long long ret; 256 unsigned long long ret;
209 257
210 ret = (unsigned long long)omap_32k_read(&clocksource_32k); 258 ret = (unsigned long long)clocksource_32k.read(&clocksource_32k);
211 ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift; 259 ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
212 return ret; 260 return ret;
213} 261}
@@ -220,6 +268,19 @@ static int __init omap_init_clocksource_32k(void)
220 if (cpu_is_omap16xx() || cpu_class_is_omap2()) { 268 if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
221 struct clk *sync_32k_ick; 269 struct clk *sync_32k_ick;
222 270
271 if (cpu_is_omap16xx())
272 clocksource_32k.read = omap16xx_32k_read;
273 else if (cpu_is_omap2420())
274 clocksource_32k.read = omap2420_32k_read;
275 else if (cpu_is_omap2430())
276 clocksource_32k.read = omap2430_32k_read;
277 else if (cpu_is_omap34xx())
278 clocksource_32k.read = omap34xx_32k_read;
279 else if (cpu_is_omap44xx())
280 clocksource_32k.read = omap44xx_32k_read;
281 else
282 return -ENODEV;
283
223 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); 284 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
224 if (sync_32k_ick) 285 if (sync_32k_ick)
225 clk_enable(sync_32k_ick); 286 clk_enable(sync_32k_ick);
@@ -234,15 +295,13 @@ static int __init omap_init_clocksource_32k(void)
234} 295}
235arch_initcall(omap_init_clocksource_32k); 296arch_initcall(omap_init_clocksource_32k);
236 297
237#endif /* TIMER_32K_SYNCHRONIZED */ 298#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
238 299
239/* Global address base setup code */ 300/* Global address base setup code */
240 301
241#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 302#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
242 303
243static struct omap_globals *omap2_globals; 304static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
244
245static void __init __omap2_set_globals(void)
246{ 305{
247 omap2_set_globals_tap(omap2_globals); 306 omap2_set_globals_tap(omap2_globals);
248 omap2_set_globals_sdrc(omap2_globals); 307 omap2_set_globals_sdrc(omap2_globals);
@@ -266,8 +325,7 @@ static struct omap_globals omap242x_globals = {
266 325
267void __init omap2_set_globals_242x(void) 326void __init omap2_set_globals_242x(void)
268{ 327{
269 omap2_globals = &omap242x_globals; 328 __omap2_set_globals(&omap242x_globals);
270 __omap2_set_globals();
271} 329}
272#endif 330#endif
273 331
@@ -285,8 +343,7 @@ static struct omap_globals omap243x_globals = {
285 343
286void __init omap2_set_globals_243x(void) 344void __init omap2_set_globals_243x(void)
287{ 345{
288 omap2_globals = &omap243x_globals; 346 __omap2_set_globals(&omap243x_globals);
289 __omap2_set_globals();
290} 347}
291#endif 348#endif
292 349
@@ -304,8 +361,23 @@ static struct omap_globals omap343x_globals = {
304 361
305void __init omap2_set_globals_343x(void) 362void __init omap2_set_globals_343x(void)
306{ 363{
307 omap2_globals = &omap343x_globals; 364 __omap2_set_globals(&omap343x_globals);
308 __omap2_set_globals(); 365}
366#endif
367
368#if defined(CONFIG_ARCH_OMAP4)
369static struct omap_globals omap4_globals = {
370 .class = OMAP443X_CLASS,
371 .tap = OMAP2_IO_ADDRESS(0x4830a000),
372 .ctrl = OMAP2_IO_ADDRESS(OMAP443X_CTRL_BASE),
373 .prm = OMAP2_IO_ADDRESS(OMAP4430_PRM_BASE),
374 .cm = OMAP2_IO_ADDRESS(OMAP4430_CM_BASE),
375};
376
377void __init omap2_set_globals_443x(void)
378{
379 omap2_set_globals_tap(&omap4_globals);
380 omap2_set_globals_control(&omap4_globals);
309} 381}
310#endif 382#endif
311 383
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 87fb7ff41794..a64b692a1bfe 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -311,6 +311,8 @@ static void omap_init_wdt(void)
311 wdt_resources[0].start = 0x49016000; /* WDT2 */ 311 wdt_resources[0].start = 0x49016000; /* WDT2 */
312 else if (cpu_is_omap343x()) 312 else if (cpu_is_omap343x())
313 wdt_resources[0].start = 0x48314000; /* WDT2 */ 313 wdt_resources[0].start = 0x48314000; /* WDT2 */
314 else if (cpu_is_omap44xx())
315 wdt_resources[0].start = 0x4a314000;
314 else 316 else
315 return; 317 return;
316 318
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 7fc8c045ad5d..def14ec265b3 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -10,6 +10,9 @@
10 * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com> 10 * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
11 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 11 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
12 * 12 *
13 * Copyright (C) 2009 Texas Instruments
14 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
15 *
13 * Support functions for the OMAP internal DMA channels. 16 * Support functions for the OMAP internal DMA channels.
14 * 17 *
15 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
@@ -310,41 +313,62 @@ EXPORT_SYMBOL(omap_set_dma_transfer_params);
310 313
311void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) 314void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
312{ 315{
313 u16 w;
314
315 BUG_ON(omap_dma_in_1510_mode()); 316 BUG_ON(omap_dma_in_1510_mode());
316 317
317 if (cpu_class_is_omap2()) { 318 if (cpu_class_is_omap1()) {
318 REVISIT_24XX(); 319 u16 w;
319 return;
320 }
321 320
322 w = dma_read(CCR2(lch)); 321 w = dma_read(CCR2(lch));
323 w &= ~0x03; 322 w &= ~0x03;
324 323
325 switch (mode) { 324 switch (mode) {
326 case OMAP_DMA_CONSTANT_FILL: 325 case OMAP_DMA_CONSTANT_FILL:
327 w |= 0x01; 326 w |= 0x01;
328 break; 327 break;
329 case OMAP_DMA_TRANSPARENT_COPY: 328 case OMAP_DMA_TRANSPARENT_COPY:
330 w |= 0x02; 329 w |= 0x02;
331 break; 330 break;
332 case OMAP_DMA_COLOR_DIS: 331 case OMAP_DMA_COLOR_DIS:
333 break; 332 break;
334 default: 333 default:
335 BUG(); 334 BUG();
335 }
336 dma_write(w, CCR2(lch));
337
338 w = dma_read(LCH_CTRL(lch));
339 w &= ~0x0f;
340 /* Default is channel type 2D */
341 if (mode) {
342 dma_write((u16)color, COLOR_L(lch));
343 dma_write((u16)(color >> 16), COLOR_U(lch));
344 w |= 1; /* Channel type G */
345 }
346 dma_write(w, LCH_CTRL(lch));
336 } 347 }
337 dma_write(w, CCR2(lch));
338 348
339 w = dma_read(LCH_CTRL(lch)); 349 if (cpu_class_is_omap2()) {
340 w &= ~0x0f; 350 u32 val;
341 /* Default is channel type 2D */ 351
342 if (mode) { 352 val = dma_read(CCR(lch));
343 dma_write((u16)color, COLOR_L(lch)); 353 val &= ~((1 << 17) | (1 << 16));
344 dma_write((u16)(color >> 16), COLOR_U(lch)); 354
345 w |= 1; /* Channel type G */ 355 switch (mode) {
356 case OMAP_DMA_CONSTANT_FILL:
357 val |= 1 << 16;
358 break;
359 case OMAP_DMA_TRANSPARENT_COPY:
360 val |= 1 << 17;
361 break;
362 case OMAP_DMA_COLOR_DIS:
363 break;
364 default:
365 BUG();
366 }
367 dma_write(val, CCR(lch));
368
369 color &= 0xffffff;
370 dma_write(color, COLOR(lch));
346 } 371 }
347 dma_write(w, LCH_CTRL(lch));
348} 372}
349EXPORT_SYMBOL(omap_set_dma_color_mode); 373EXPORT_SYMBOL(omap_set_dma_color_mode);
350 374
@@ -851,7 +875,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
851 } 875 }
852 l = dma_read(CCR(lch)); 876 l = dma_read(CCR(lch));
853 l &= ~((1 << 6) | (1 << 26)); 877 l &= ~((1 << 6) | (1 << 26));
854 if (cpu_is_omap2430() || cpu_is_omap34xx()) 878 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
855 l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); 879 l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
856 else 880 else
857 l |= ((read_prio & 0x1) << 6); 881 l |= ((read_prio & 0x1) << 6);
@@ -1199,7 +1223,7 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
1199 * Failure: -EINVAL/-ENOMEM 1223 * Failure: -EINVAL/-ENOMEM
1200 */ 1224 */
1201int omap_request_dma_chain(int dev_id, const char *dev_name, 1225int omap_request_dma_chain(int dev_id, const char *dev_name,
1202 void (*callback) (int chain_id, u16 ch_status, 1226 void (*callback) (int lch, u16 ch_status,
1203 void *data), 1227 void *data),
1204 int *chain_id, int no_of_chans, int chain_mode, 1228 int *chain_id, int no_of_chans, int chain_mode,
1205 struct omap_dma_channel_params params) 1229 struct omap_dma_channel_params params)
@@ -1823,7 +1847,8 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
1823#define omap1_dma_irq_handler NULL 1847#define omap1_dma_irq_handler NULL
1824#endif 1848#endif
1825 1849
1826#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 1850#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
1851 defined(CONFIG_ARCH_OMAP4)
1827 1852
1828static int omap2_dma_handle_ch(int ch) 1853static int omap2_dma_handle_ch(int ch)
1829{ 1854{
@@ -2318,6 +2343,9 @@ static int __init omap_init_dma(void)
2318 } else if (cpu_is_omap34xx()) { 2343 } else if (cpu_is_omap34xx()) {
2319 omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE); 2344 omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE);
2320 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; 2345 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2346 } else if (cpu_is_omap44xx()) {
2347 omap_dma_base = IO_ADDRESS(OMAP44XX_DMA4_BASE);
2348 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2321 } else { 2349 } else {
2322 pr_err("DMA init failed for unsupported omap\n"); 2350 pr_err("DMA init failed for unsupported omap\n");
2323 return -ENODEV; 2351 return -ENODEV;
@@ -2416,12 +2444,18 @@ static int __init omap_init_dma(void)
2416 } 2444 }
2417 } 2445 }
2418 2446
2419 if (cpu_is_omap2430() || cpu_is_omap34xx()) 2447 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
2420 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 2448 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
2421 DMA_DEFAULT_FIFO_DEPTH, 0); 2449 DMA_DEFAULT_FIFO_DEPTH, 0);
2422 2450
2423 if (cpu_class_is_omap2()) 2451 if (cpu_class_is_omap2()) {
2424 setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq); 2452 int irq;
2453 if (cpu_is_omap44xx())
2454 irq = INT_44XX_SDMA_IRQ0;
2455 else
2456 irq = INT_24XX_SDMA_IRQ0;
2457 setup_irq(irq, &omap24xx_dma_irq);
2458 }
2425 2459
2426 /* FIXME: Update LCD DMA to work on 24xx */ 2460 /* FIXME: Update LCD DMA to work on 24xx */
2427 if (cpu_class_is_omap1()) { 2461 if (cpu_class_is_omap1()) {
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 55bb99631292..7f50b6103dee 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -7,6 +7,9 @@
7 * OMAP2 support by Juha Yrjola 7 * OMAP2 support by Juha Yrjola
8 * API improvements and OMAP2 clock framework support by Timo Teras 8 * API improvements and OMAP2 clock framework support by Timo Teras
9 * 9 *
10 * Copyright (C) 2009 Texas Instruments
11 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
12 *
10 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 14 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 15 * Free Software Foundation; either version 2 of the License, or (at your
@@ -150,7 +153,8 @@
150struct omap_dm_timer { 153struct omap_dm_timer {
151 unsigned long phys_base; 154 unsigned long phys_base;
152 int irq; 155 int irq;
153#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 156#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
157 defined(CONFIG_ARCH_OMAP4)
154 struct clk *iclk, *fclk; 158 struct clk *iclk, *fclk;
155#endif 159#endif
156 void __iomem *io_base; 160 void __iomem *io_base;
@@ -169,6 +173,9 @@ struct omap_dm_timer {
169#define omap3_dm_timers NULL 173#define omap3_dm_timers NULL
170#define omap3_dm_source_names NULL 174#define omap3_dm_source_names NULL
171#define omap3_dm_source_clocks NULL 175#define omap3_dm_source_clocks NULL
176#define omap4_dm_timers NULL
177#define omap4_dm_source_names NULL
178#define omap4_dm_source_clocks NULL
172 179
173static struct omap_dm_timer omap1_dm_timers[] = { 180static struct omap_dm_timer omap1_dm_timers[] = {
174 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, 181 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
@@ -191,6 +198,9 @@ static const int dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
191#define omap3_dm_timers NULL 198#define omap3_dm_timers NULL
192#define omap3_dm_source_names NULL 199#define omap3_dm_source_names NULL
193#define omap3_dm_source_clocks NULL 200#define omap3_dm_source_clocks NULL
201#define omap4_dm_timers NULL
202#define omap4_dm_source_names NULL
203#define omap4_dm_source_clocks NULL
194 204
195static struct omap_dm_timer omap2_dm_timers[] = { 205static struct omap_dm_timer omap2_dm_timers[] = {
196 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, 206 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
@@ -214,7 +224,7 @@ static const char *omap2_dm_source_names[] __initdata = {
214 NULL 224 NULL
215}; 225};
216 226
217static struct clk **omap2_dm_source_clocks[3]; 227static struct clk *omap2_dm_source_clocks[3];
218static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers); 228static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
219 229
220#elif defined(CONFIG_ARCH_OMAP3) 230#elif defined(CONFIG_ARCH_OMAP3)
@@ -225,6 +235,9 @@ static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
225#define omap2_dm_timers NULL 235#define omap2_dm_timers NULL
226#define omap2_dm_source_names NULL 236#define omap2_dm_source_names NULL
227#define omap2_dm_source_clocks NULL 237#define omap2_dm_source_clocks NULL
238#define omap4_dm_timers NULL
239#define omap4_dm_source_names NULL
240#define omap4_dm_source_clocks NULL
228 241
229static struct omap_dm_timer omap3_dm_timers[] = { 242static struct omap_dm_timer omap3_dm_timers[] = {
230 { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 }, 243 { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
@@ -247,9 +260,43 @@ static const char *omap3_dm_source_names[] __initdata = {
247 NULL 260 NULL
248}; 261};
249 262
250static struct clk **omap3_dm_source_clocks[2]; 263static struct clk *omap3_dm_source_clocks[2];
251static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers); 264static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
252 265
266#elif defined(CONFIG_ARCH_OMAP4)
267
268#define omap_dm_clk_enable(x) clk_enable(x)
269#define omap_dm_clk_disable(x) clk_disable(x)
270#define omap1_dm_timers NULL
271#define omap2_dm_timers NULL
272#define omap2_dm_source_names NULL
273#define omap2_dm_source_clocks NULL
274#define omap3_dm_timers NULL
275#define omap3_dm_source_names NULL
276#define omap3_dm_source_clocks NULL
277
278static struct omap_dm_timer omap4_dm_timers[] = {
279 { .phys_base = 0x4a318000, .irq = INT_44XX_GPTIMER1 },
280 { .phys_base = 0x48032000, .irq = INT_44XX_GPTIMER2 },
281 { .phys_base = 0x48034000, .irq = INT_44XX_GPTIMER3 },
282 { .phys_base = 0x48036000, .irq = INT_44XX_GPTIMER4 },
283 { .phys_base = 0x40138000, .irq = INT_44XX_GPTIMER5 },
284 { .phys_base = 0x4013a000, .irq = INT_44XX_GPTIMER6 },
285 { .phys_base = 0x4013a000, .irq = INT_44XX_GPTIMER7 },
286 { .phys_base = 0x4013e000, .irq = INT_44XX_GPTIMER8 },
287 { .phys_base = 0x4803e000, .irq = INT_44XX_GPTIMER9 },
288 { .phys_base = 0x48086000, .irq = INT_44XX_GPTIMER10 },
289 { .phys_base = 0x48088000, .irq = INT_44XX_GPTIMER11 },
290 { .phys_base = 0x4a320000, .irq = INT_44XX_GPTIMER12 },
291};
292static const char *omap4_dm_source_names[] __initdata = {
293 "sys_ck",
294 "omap_32k_fck",
295 NULL
296};
297static struct clk *omap4_dm_source_clocks[2];
298static const int dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
299
253#else 300#else
254 301
255#error OMAP architecture not supported! 302#error OMAP architecture not supported!
@@ -257,7 +304,7 @@ static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
257#endif 304#endif
258 305
259static struct omap_dm_timer *dm_timers; 306static struct omap_dm_timer *dm_timers;
260static char **dm_source_names; 307static const char **dm_source_names;
261static struct clk **dm_source_clocks; 308static struct clk **dm_source_clocks;
262 309
263static spinlock_t dm_timer_lock; 310static spinlock_t dm_timer_lock;
@@ -459,7 +506,8 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
459} 506}
460EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask); 507EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
461 508
462#elif defined(CONFIG_ARCH_OMAP2) || defined (CONFIG_ARCH_OMAP3) 509#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
510 defined(CONFIG_ARCH_OMAP4)
463 511
464struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 512struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
465{ 513{
@@ -705,12 +753,16 @@ int __init omap_dm_timer_init(void)
705 dm_timers = omap1_dm_timers; 753 dm_timers = omap1_dm_timers;
706 else if (cpu_is_omap24xx()) { 754 else if (cpu_is_omap24xx()) {
707 dm_timers = omap2_dm_timers; 755 dm_timers = omap2_dm_timers;
708 dm_source_names = (char **)omap2_dm_source_names; 756 dm_source_names = omap2_dm_source_names;
709 dm_source_clocks = (struct clk **)omap2_dm_source_clocks; 757 dm_source_clocks = omap2_dm_source_clocks;
710 } else if (cpu_is_omap34xx()) { 758 } else if (cpu_is_omap34xx()) {
711 dm_timers = omap3_dm_timers; 759 dm_timers = omap3_dm_timers;
712 dm_source_names = (char **)omap3_dm_source_names; 760 dm_source_names = omap3_dm_source_names;
713 dm_source_clocks = (struct clk **)omap3_dm_source_clocks; 761 dm_source_clocks = omap3_dm_source_clocks;
762 } else if (cpu_is_omap44xx()) {
763 dm_timers = omap4_dm_timers;
764 dm_source_names = omap4_dm_source_names;
765 dm_source_clocks = omap4_dm_source_clocks;
714 } 766 }
715 767
716 if (cpu_class_is_omap2()) 768 if (cpu_class_is_omap2())
@@ -723,7 +775,8 @@ int __init omap_dm_timer_init(void)
723 for (i = 0; i < dm_timer_count; i++) { 775 for (i = 0; i < dm_timer_count; i++) {
724 timer = &dm_timers[i]; 776 timer = &dm_timers[i];
725 timer->io_base = IO_ADDRESS(timer->phys_base); 777 timer->io_base = IO_ADDRESS(timer->phys_base);
726#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 778#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
779 defined(CONFIG_ARCH_OMAP4)
727 if (cpu_class_is_omap2()) { 780 if (cpu_class_is_omap2()) {
728 char clk_name[16]; 781 char clk_name[16];
729 sprintf(clk_name, "gpt%d_ick", i + 1); 782 sprintf(clk_name, "gpt%d_ick", i + 1);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index ee0b21f5b094..7fd89ba8d3b5 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -6,6 +6,9 @@
6 * Copyright (C) 2003-2005 Nokia Corporation 6 * Copyright (C) 2003-2005 Nokia Corporation
7 * Written by Juha Yrjölä <juha.yrjola@nokia.com> 7 * Written by Juha Yrjölä <juha.yrjola@nokia.com>
8 * 8 *
9 * Copyright (C) 2009 Texas Instruments
10 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
11 *
9 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
@@ -146,6 +149,16 @@
146#define OMAP34XX_GPIO5_BASE IO_ADDRESS(0x49056000) 149#define OMAP34XX_GPIO5_BASE IO_ADDRESS(0x49056000)
147#define OMAP34XX_GPIO6_BASE IO_ADDRESS(0x49058000) 150#define OMAP34XX_GPIO6_BASE IO_ADDRESS(0x49058000)
148 151
152/*
153 * OMAP44XX specific GPIO registers
154 */
155#define OMAP44XX_GPIO1_BASE IO_ADDRESS(0x4a310000)
156#define OMAP44XX_GPIO2_BASE IO_ADDRESS(0x48055000)
157#define OMAP44XX_GPIO3_BASE IO_ADDRESS(0x48057000)
158#define OMAP44XX_GPIO4_BASE IO_ADDRESS(0x48059000)
159#define OMAP44XX_GPIO5_BASE IO_ADDRESS(0x4805B000)
160#define OMAP44XX_GPIO6_BASE IO_ADDRESS(0x4805D000)
161
149#define OMAP_MPUIO_VBASE IO_ADDRESS(OMAP_MPUIO_BASE) 162#define OMAP_MPUIO_VBASE IO_ADDRESS(OMAP_MPUIO_BASE)
150 163
151struct gpio_bank { 164struct gpio_bank {
@@ -153,11 +166,13 @@ struct gpio_bank {
153 u16 irq; 166 u16 irq;
154 u16 virtual_irq_start; 167 u16 virtual_irq_start;
155 int method; 168 int method;
156#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 169#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
170 defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
157 u32 suspend_wakeup; 171 u32 suspend_wakeup;
158 u32 saved_wakeup; 172 u32 saved_wakeup;
159#endif 173#endif
160#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 174#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
175 defined(CONFIG_ARCH_OMAP4)
161 u32 non_wakeup_gpios; 176 u32 non_wakeup_gpios;
162 u32 enabled_non_wakeup_gpios; 177 u32 enabled_non_wakeup_gpios;
163 178
@@ -251,6 +266,24 @@ static struct gpio_bank gpio_bank_34xx[6] = {
251 266
252#endif 267#endif
253 268
269#ifdef CONFIG_ARCH_OMAP4
270static struct gpio_bank gpio_bank_44xx[6] = {
271 { OMAP44XX_GPIO1_BASE, INT_44XX_GPIO_BANK1, IH_GPIO_BASE, \
272 METHOD_GPIO_24XX },
273 { OMAP44XX_GPIO2_BASE, INT_44XX_GPIO_BANK2, IH_GPIO_BASE + 32, \
274 METHOD_GPIO_24XX },
275 { OMAP44XX_GPIO3_BASE, INT_44XX_GPIO_BANK3, IH_GPIO_BASE + 64, \
276 METHOD_GPIO_24XX },
277 { OMAP44XX_GPIO4_BASE, INT_44XX_GPIO_BANK4, IH_GPIO_BASE + 96, \
278 METHOD_GPIO_24XX },
279 { OMAP44XX_GPIO5_BASE, INT_44XX_GPIO_BANK5, IH_GPIO_BASE + 128, \
280 METHOD_GPIO_24XX },
281 { OMAP44XX_GPIO6_BASE, INT_44XX_GPIO_BANK6, IH_GPIO_BASE + 160, \
282 METHOD_GPIO_24XX },
283};
284
285#endif
286
254static struct gpio_bank *gpio_bank; 287static struct gpio_bank *gpio_bank;
255static int gpio_bank_count; 288static int gpio_bank_count;
256 289
@@ -273,7 +306,7 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
273 } 306 }
274 if (cpu_is_omap24xx()) 307 if (cpu_is_omap24xx())
275 return &gpio_bank[gpio >> 5]; 308 return &gpio_bank[gpio >> 5];
276 if (cpu_is_omap34xx()) 309 if (cpu_is_omap34xx() || cpu_is_omap44xx())
277 return &gpio_bank[gpio >> 5]; 310 return &gpio_bank[gpio >> 5];
278 BUG(); 311 BUG();
279 return NULL; 312 return NULL;
@@ -285,7 +318,7 @@ static inline int get_gpio_index(int gpio)
285 return gpio & 0x1f; 318 return gpio & 0x1f;
286 if (cpu_is_omap24xx()) 319 if (cpu_is_omap24xx())
287 return gpio & 0x1f; 320 return gpio & 0x1f;
288 if (cpu_is_omap34xx()) 321 if (cpu_is_omap34xx() || cpu_is_omap44xx())
289 return gpio & 0x1f; 322 return gpio & 0x1f;
290 return gpio & 0x0f; 323 return gpio & 0x0f;
291} 324}
@@ -307,7 +340,7 @@ static inline int gpio_valid(int gpio)
307 return 0; 340 return 0;
308 if (cpu_is_omap24xx() && gpio < 128) 341 if (cpu_is_omap24xx() && gpio < 128)
309 return 0; 342 return 0;
310 if (cpu_is_omap34xx() && gpio < 192) 343 if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
311 return 0; 344 return 0;
312 return -1; 345 return -1;
313} 346}
@@ -353,7 +386,8 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
353 reg += OMAP850_GPIO_DIR_CONTROL; 386 reg += OMAP850_GPIO_DIR_CONTROL;
354 break; 387 break;
355#endif 388#endif
356#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 389#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
390 defined(CONFIG_ARCH_OMAP4)
357 case METHOD_GPIO_24XX: 391 case METHOD_GPIO_24XX:
358 reg += OMAP24XX_GPIO_OE; 392 reg += OMAP24XX_GPIO_OE;
359 break; 393 break;
@@ -425,7 +459,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
425 l &= ~(1 << gpio); 459 l &= ~(1 << gpio);
426 break; 460 break;
427#endif 461#endif
428#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 462#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
463 defined(CONFIG_ARCH_OMAP4)
429 case METHOD_GPIO_24XX: 464 case METHOD_GPIO_24XX:
430 if (enable) 465 if (enable)
431 reg += OMAP24XX_GPIO_SETDATAOUT; 466 reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -476,7 +511,8 @@ static int __omap_get_gpio_datain(int gpio)
476 reg += OMAP850_GPIO_DATA_INPUT; 511 reg += OMAP850_GPIO_DATA_INPUT;
477 break; 512 break;
478#endif 513#endif
479#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 514#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
515 defined(CONFIG_ARCH_OMAP4)
480 case METHOD_GPIO_24XX: 516 case METHOD_GPIO_24XX:
481 reg += OMAP24XX_GPIO_DATAIN; 517 reg += OMAP24XX_GPIO_DATAIN;
482 break; 518 break;
@@ -520,7 +556,7 @@ void omap_set_gpio_debounce(int gpio, int enable)
520 else 556 else
521 goto done; 557 goto done;
522 558
523 if (cpu_is_omap34xx()) { 559 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
524 if (enable) 560 if (enable)
525 clk_enable(bank->dbck); 561 clk_enable(bank->dbck);
526 else 562 else
@@ -550,7 +586,8 @@ void omap_set_gpio_debounce_time(int gpio, int enc_time)
550} 586}
551EXPORT_SYMBOL(omap_set_gpio_debounce_time); 587EXPORT_SYMBOL(omap_set_gpio_debounce_time);
552 588
553#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 589#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
590 defined(CONFIG_ARCH_OMAP4)
554static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, 591static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
555 int trigger) 592 int trigger)
556{ 593{
@@ -660,7 +697,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
660 goto bad; 697 goto bad;
661 break; 698 break;
662#endif 699#endif
663#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 700#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
701 defined(CONFIG_ARCH_OMAP4)
664 case METHOD_GPIO_24XX: 702 case METHOD_GPIO_24XX:
665 set_24xx_gpio_triggering(bank, gpio, trigger); 703 set_24xx_gpio_triggering(bank, gpio, trigger);
666 break; 704 break;
@@ -745,7 +783,8 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
745 reg += OMAP850_GPIO_INT_STATUS; 783 reg += OMAP850_GPIO_INT_STATUS;
746 break; 784 break;
747#endif 785#endif
748#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 786#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
787 defined(CONFIG_ARCH_OMAP4)
749 case METHOD_GPIO_24XX: 788 case METHOD_GPIO_24XX:
750 reg += OMAP24XX_GPIO_IRQSTATUS1; 789 reg += OMAP24XX_GPIO_IRQSTATUS1;
751 break; 790 break;
@@ -814,7 +853,8 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
814 inv = 1; 853 inv = 1;
815 break; 854 break;
816#endif 855#endif
817#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 856#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
857 defined(CONFIG_ARCH_OMAP4)
818 case METHOD_GPIO_24XX: 858 case METHOD_GPIO_24XX:
819 reg += OMAP24XX_GPIO_IRQENABLE1; 859 reg += OMAP24XX_GPIO_IRQENABLE1;
820 mask = 0xffffffff; 860 mask = 0xffffffff;
@@ -887,7 +927,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
887 l |= gpio_mask; 927 l |= gpio_mask;
888 break; 928 break;
889#endif 929#endif
890#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 930#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
931 defined(CONFIG_ARCH_OMAP4)
891 case METHOD_GPIO_24XX: 932 case METHOD_GPIO_24XX:
892 if (enable) 933 if (enable)
893 reg += OMAP24XX_GPIO_SETIRQENABLE1; 934 reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -932,7 +973,8 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
932 spin_unlock_irqrestore(&bank->lock, flags); 973 spin_unlock_irqrestore(&bank->lock, flags);
933 return 0; 974 return 0;
934#endif 975#endif
935#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 976#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
977 defined(CONFIG_ARCH_OMAP4)
936 case METHOD_GPIO_24XX: 978 case METHOD_GPIO_24XX:
937 if (bank->non_wakeup_gpios & (1 << gpio)) { 979 if (bank->non_wakeup_gpios & (1 << gpio)) {
938 printk(KERN_ERR "Unable to modify wakeup on " 980 printk(KERN_ERR "Unable to modify wakeup on "
@@ -1017,7 +1059,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
1017 __raw_writel(1 << offset, reg); 1059 __raw_writel(1 << offset, reg);
1018 } 1060 }
1019#endif 1061#endif
1020#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1062#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1063 defined(CONFIG_ARCH_OMAP4)
1021 if (bank->method == METHOD_GPIO_24XX) { 1064 if (bank->method == METHOD_GPIO_24XX) {
1022 /* Disable wake-up during idle for dynamic tick */ 1065 /* Disable wake-up during idle for dynamic tick */
1023 void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; 1066 void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
@@ -1069,7 +1112,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
1069 if (bank->method == METHOD_GPIO_850) 1112 if (bank->method == METHOD_GPIO_850)
1070 isr_reg = bank->base + OMAP850_GPIO_INT_STATUS; 1113 isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
1071#endif 1114#endif
1072#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1115#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1116 defined(CONFIG_ARCH_OMAP4)
1073 if (bank->method == METHOD_GPIO_24XX) 1117 if (bank->method == METHOD_GPIO_24XX)
1074 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; 1118 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
1075#endif 1119#endif
@@ -1346,7 +1390,7 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
1346/*---------------------------------------------------------------------*/ 1390/*---------------------------------------------------------------------*/
1347 1391
1348static int initialized; 1392static int initialized;
1349#if !defined(CONFIG_ARCH_OMAP3) 1393#if !(defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4))
1350static struct clk * gpio_ick; 1394static struct clk * gpio_ick;
1351#endif 1395#endif
1352 1396
@@ -1359,7 +1403,7 @@ static struct clk * gpio5_ick;
1359static struct clk * gpio5_fck; 1403static struct clk * gpio5_fck;
1360#endif 1404#endif
1361 1405
1362#if defined(CONFIG_ARCH_OMAP3) 1406#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
1363static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; 1407static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
1364#endif 1408#endif
1365 1409
@@ -1419,8 +1463,8 @@ static int __init _omap_gpio_init(void)
1419 } 1463 }
1420#endif 1464#endif
1421 1465
1422#if defined(CONFIG_ARCH_OMAP3) 1466#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
1423 if (cpu_is_omap34xx()) { 1467 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
1424 for (i = 0; i < OMAP34XX_NR_GPIOS; i++) { 1468 for (i = 0; i < OMAP34XX_NR_GPIOS; i++) {
1425 sprintf(clk_name, "gpio%d_ick", i + 1); 1469 sprintf(clk_name, "gpio%d_ick", i + 1);
1426 gpio_iclks[i] = clk_get(NULL, clk_name); 1470 gpio_iclks[i] = clk_get(NULL, clk_name);
@@ -1497,6 +1541,17 @@ static int __init _omap_gpio_init(void)
1497 (rev >> 4) & 0x0f, rev & 0x0f); 1541 (rev >> 4) & 0x0f, rev & 0x0f);
1498 } 1542 }
1499#endif 1543#endif
1544#ifdef CONFIG_ARCH_OMAP4
1545 if (cpu_is_omap44xx()) {
1546 int rev;
1547
1548 gpio_bank_count = OMAP34XX_NR_GPIOS;
1549 gpio_bank = gpio_bank_44xx;
1550 rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
1551 printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n",
1552 (rev >> 4) & 0x0f, rev & 0x0f);
1553 }
1554#endif
1500 for (i = 0; i < gpio_bank_count; i++) { 1555 for (i = 0; i < gpio_bank_count; i++) {
1501 int j, gpio_count = 16; 1556 int j, gpio_count = 16;
1502 1557
@@ -1520,7 +1575,8 @@ static int __init _omap_gpio_init(void)
1520 gpio_count = 32; /* 730 has 32-bit GPIOs */ 1575 gpio_count = 32; /* 730 has 32-bit GPIOs */
1521 } 1576 }
1522 1577
1523#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1578#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1579 defined(CONFIG_ARCH_OMAP4)
1524 if (bank->method == METHOD_GPIO_24XX) { 1580 if (bank->method == METHOD_GPIO_24XX) {
1525 static const u32 non_wakeup_gpios[] = { 1581 static const u32 non_wakeup_gpios[] = {
1526 0xe203ffc0, 0x08700040 1582 0xe203ffc0, 0x08700040
@@ -1577,7 +1633,7 @@ static int __init _omap_gpio_init(void)
1577 set_irq_chained_handler(bank->irq, gpio_irq_handler); 1633 set_irq_chained_handler(bank->irq, gpio_irq_handler);
1578 set_irq_data(bank->irq, bank); 1634 set_irq_data(bank->irq, bank);
1579 1635
1580 if (cpu_is_omap34xx()) { 1636 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
1581 sprintf(clk_name, "gpio%d_dbck", i + 1); 1637 sprintf(clk_name, "gpio%d_dbck", i + 1);
1582 bank->dbck = clk_get(NULL, clk_name); 1638 bank->dbck = clk_get(NULL, clk_name);
1583 if (IS_ERR(bank->dbck)) 1639 if (IS_ERR(bank->dbck))
@@ -1599,7 +1655,8 @@ static int __init _omap_gpio_init(void)
1599 return 0; 1655 return 0;
1600} 1656}
1601 1657
1602#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1658#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
1659 defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
1603static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) 1660static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
1604{ 1661{
1605 int i; 1662 int i;
@@ -1622,7 +1679,8 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
1622 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1679 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
1623 break; 1680 break;
1624#endif 1681#endif
1625#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1682#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1683 defined(CONFIG_ARCH_OMAP4)
1626 case METHOD_GPIO_24XX: 1684 case METHOD_GPIO_24XX:
1627 wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; 1685 wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
1628 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; 1686 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
@@ -1663,7 +1721,8 @@ static int omap_gpio_resume(struct sys_device *dev)
1663 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1721 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
1664 break; 1722 break;
1665#endif 1723#endif
1666#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1724#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1725 defined(CONFIG_ARCH_OMAP4)
1667 case METHOD_GPIO_24XX: 1726 case METHOD_GPIO_24XX:
1668 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; 1727 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
1669 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; 1728 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
@@ -1695,7 +1754,8 @@ static struct sys_device omap_gpio_device = {
1695 1754
1696#endif 1755#endif
1697 1756
1698#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1757#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1758 defined(CONFIG_ARCH_OMAP4)
1699 1759
1700static int workaround_enabled; 1760static int workaround_enabled;
1701 1761
@@ -1711,7 +1771,8 @@ void omap2_gpio_prepare_for_retention(void)
1711 1771
1712 if (!(bank->enabled_non_wakeup_gpios)) 1772 if (!(bank->enabled_non_wakeup_gpios))
1713 continue; 1773 continue;
1714#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1774#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1775 defined(CONFIG_ARCH_OMAP4)
1715 bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); 1776 bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
1716 l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); 1777 l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1717 l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); 1778 l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
@@ -1720,7 +1781,8 @@ void omap2_gpio_prepare_for_retention(void)
1720 bank->saved_risingdetect = l2; 1781 bank->saved_risingdetect = l2;
1721 l1 &= ~bank->enabled_non_wakeup_gpios; 1782 l1 &= ~bank->enabled_non_wakeup_gpios;
1722 l2 &= ~bank->enabled_non_wakeup_gpios; 1783 l2 &= ~bank->enabled_non_wakeup_gpios;
1723#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1784#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1785 defined(CONFIG_ARCH_OMAP4)
1724 __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); 1786 __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1725 __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); 1787 __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
1726#endif 1788#endif
@@ -1745,7 +1807,8 @@ void omap2_gpio_resume_after_retention(void)
1745 1807
1746 if (!(bank->enabled_non_wakeup_gpios)) 1808 if (!(bank->enabled_non_wakeup_gpios))
1747 continue; 1809 continue;
1748#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1810#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1811 defined(CONFIG_ARCH_OMAP4)
1749 __raw_writel(bank->saved_fallingdetect, 1812 __raw_writel(bank->saved_fallingdetect,
1750 bank->base + OMAP24XX_GPIO_FALLINGDETECT); 1813 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1751 __raw_writel(bank->saved_risingdetect, 1814 __raw_writel(bank->saved_risingdetect,
@@ -1755,14 +1818,16 @@ void omap2_gpio_resume_after_retention(void)
1755 * state. If so, generate an IRQ by software. This is 1818 * state. If so, generate an IRQ by software. This is
1756 * horribly racy, but it's the best we can do to work around 1819 * horribly racy, but it's the best we can do to work around
1757 * this silicon bug. */ 1820 * this silicon bug. */
1758#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1821#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1822 defined(CONFIG_ARCH_OMAP4)
1759 l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); 1823 l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
1760#endif 1824#endif
1761 l ^= bank->saved_datain; 1825 l ^= bank->saved_datain;
1762 l &= bank->non_wakeup_gpios; 1826 l &= bank->non_wakeup_gpios;
1763 if (l) { 1827 if (l) {
1764 u32 old0, old1; 1828 u32 old0, old1;
1765#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1829#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1830 defined(CONFIG_ARCH_OMAP4)
1766 old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); 1831 old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
1767 old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); 1832 old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
1768 __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); 1833 __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
@@ -1798,7 +1863,8 @@ static int __init omap_gpio_sysinit(void)
1798 1863
1799 mpuio_init(); 1864 mpuio_init();
1800 1865
1801#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 1866#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
1867 defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
1802 if (cpu_is_omap16xx() || cpu_class_is_omap2()) { 1868 if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
1803 if (ret == 0) { 1869 if (ret == 0) {
1804 ret = sysdev_class_register(&omap_gpio_sysclass); 1870 ret = sysdev_class_register(&omap_gpio_sysclass);
@@ -1887,7 +1953,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
1887 1953
1888 irqstat = irq_desc[irq].status; 1954 irqstat = irq_desc[irq].status;
1889#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \ 1955#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
1890 defined(CONFIG_ARCH_OMAP34XX) 1956 defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
1891 if (is_in && ((bank->suspend_wakeup & mask) 1957 if (is_in && ((bank->suspend_wakeup & mask)
1892 || irqstat & IRQ_TYPE_SENSE_MASK)) { 1958 || irqstat & IRQ_TYPE_SENSE_MASK)) {
1893 char *trigger = NULL; 1959 char *trigger = NULL;
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a303071d5e36..8b848391f0c8 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (C) 2007 Nokia Corporation. 6 * Copyright (C) 2007 Nokia Corporation.
7 * 7 *
8 * Contact: Jarkko Nikula <jarkko.nikula@nokia.com> 8 * Contact: Jarkko Nikula <jhnikula@gmail.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index 073a2c5569f0..f9f65e1ba3f1 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -22,7 +22,8 @@ struct clkops {
22 void (*disable)(struct clk *); 22 void (*disable)(struct clk *);
23}; 23};
24 24
25#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 25#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
26 defined(CONFIG_ARCH_OMAP4)
26 27
27struct clksel_rate { 28struct clksel_rate {
28 u32 val; 29 u32 val;
@@ -51,7 +52,7 @@ struct dpll_data {
51 u8 max_divider; 52 u8 max_divider;
52 u32 max_tolerance; 53 u32 max_tolerance;
53 u16 max_multiplier; 54 u16 max_multiplier;
54# if defined(CONFIG_ARCH_OMAP3) 55#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
55 u8 modes; 56 u8 modes;
56 void __iomem *autoidle_reg; 57 void __iomem *autoidle_reg;
57 void __iomem *idlest_reg; 58 void __iomem *idlest_reg;
@@ -83,7 +84,8 @@ struct clk {
83 void (*init)(struct clk *); 84 void (*init)(struct clk *);
84 __u8 enable_bit; 85 __u8 enable_bit;
85 __s8 usecount; 86 __s8 usecount;
86#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 87#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
88 defined(CONFIG_ARCH_OMAP4)
87 u8 fixed_div; 89 u8 fixed_div;
88 void __iomem *clksel_reg; 90 void __iomem *clksel_reg;
89 u32 clksel_mask; 91 u32 clksel_mask;
@@ -119,7 +121,7 @@ struct clk_functions {
119extern unsigned int mpurate; 121extern unsigned int mpurate;
120 122
121extern int clk_init(struct clk_functions *custom_clocks); 123extern int clk_init(struct clk_functions *custom_clocks);
122extern void clk_init_one(struct clk *clk); 124extern void clk_preinit(struct clk *clk);
123extern int clk_register(struct clk *clk); 125extern int clk_register(struct clk *clk);
124extern void clk_reparent(struct clk *child, struct clk *parent); 126extern void clk_reparent(struct clk *child, struct clk *parent);
125extern void clk_unregister(struct clk *clk); 127extern void clk_unregister(struct clk *clk);
diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h
index 0ecf36deb17b..fdeab421b4dc 100644
--- a/arch/arm/plat-omap/include/mach/common.h
+++ b/arch/arm/plat-omap/include/mach/common.h
@@ -33,8 +33,6 @@ struct sys_timer;
33 33
34extern void omap_map_common_io(void); 34extern void omap_map_common_io(void);
35extern struct sys_timer omap_timer; 35extern struct sys_timer omap_timer;
36extern void omap_serial_init(void);
37extern void omap_serial_enable_clocks(int enable);
38#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) 36#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
39extern int omap_register_i2c_bus(int bus_id, u32 clkrate, 37extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
40 struct i2c_board_info const *info, 38 struct i2c_board_info const *info,
@@ -62,6 +60,7 @@ struct omap_globals {
62void omap2_set_globals_242x(void); 60void omap2_set_globals_242x(void);
63void omap2_set_globals_243x(void); 61void omap2_set_globals_243x(void);
64void omap2_set_globals_343x(void); 62void omap2_set_globals_343x(void);
63void omap2_set_globals_443x(void);
65 64
66/* These get called from omap2_set_globals_xxxx(), do not call these */ 65/* These get called from omap2_set_globals_xxxx(), do not call these */
67void omap2_set_globals_tap(struct omap_globals *); 66void omap2_set_globals_tap(struct omap_globals *);
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
index 269147f3836f..8140dbccb7bc 100644
--- a/arch/arm/plat-omap/include/mach/control.h
+++ b/arch/arm/plat-omap/include/mach/control.h
@@ -1,9 +1,9 @@
1/* 1/*
2 * arch/arm/plat-omap/include/mach/control.h 2 * arch/arm/plat-omap/include/mach/control.h
3 * 3 *
4 * OMAP2/3 System Control Module definitions 4 * OMAP2/3/4 System Control Module definitions
5 * 5 *
6 * Copyright (C) 2007-2008 Texas Instruments, Inc. 6 * Copyright (C) 2007-2009 Texas Instruments, Inc.
7 * Copyright (C) 2007-2008 Nokia Corporation 7 * Copyright (C) 2007-2008 Nokia Corporation
8 * 8 *
9 * Written by Paul Walmsley 9 * Written by Paul Walmsley
@@ -144,6 +144,10 @@
144#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0) 144#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0)
145#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) 145#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
146 146
147/* 34xx D2D idle-related pins, handled by PM core */
148#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
149#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
150
147/* 151/*
148 * REVISIT: This list of registers is not comprehensive - there are more 152 * REVISIT: This list of registers is not comprehensive - there are more
149 * that should be added. 153 * that should be added.
@@ -189,8 +193,18 @@
189#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) 193#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
190#define OMAP2_PBIASLITEVMODE0 (1 << 0) 194#define OMAP2_PBIASLITEVMODE0 (1 << 0)
191 195
196/* CONTROL_IVA2_BOOTMOD bits */
197#define OMAP3_IVA2_BOOTMOD_SHIFT 0
198#define OMAP3_IVA2_BOOTMOD_MASK (0xf << 0)
199#define OMAP3_IVA2_BOOTMOD_IDLE (0x1 << 0)
200
201/* CONTROL_PADCONF_X bits */
202#define OMAP3_PADCONF_WAKEUPEVENT0 (1 << 15)
203#define OMAP3_PADCONF_WAKEUPENABLE0 (1 << 14)
204
192#ifndef __ASSEMBLY__ 205#ifndef __ASSEMBLY__
193#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 206#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
207 defined(CONFIG_ARCH_OMAP4)
194extern void __iomem *omap_ctrl_base_get(void); 208extern void __iomem *omap_ctrl_base_get(void);
195extern u8 omap_ctrl_readb(u16 offset); 209extern u8 omap_ctrl_readb(u16 offset);
196extern u16 omap_ctrl_readw(u16 offset); 210extern u16 omap_ctrl_readw(u16 offset);
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index 98b144252364..fc60c4ebcc28 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -5,8 +5,12 @@
5 * 5 *
6 * Copyright (C) 2004, 2008 Nokia Corporation 6 * Copyright (C) 2004, 2008 Nokia Corporation
7 * 7 *
8 * Copyright (C) 2009 Texas Instruments.
9 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com> 10 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 * 11 *
12 * Added OMAP4 specific defines - Santosh Shilimkar<santosh.shilimkar@ti.com>
13 *
10 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -155,6 +159,8 @@ IS_OMAP_SUBCLASS(343x, 0x343)
155#define cpu_is_omap243x() 0 159#define cpu_is_omap243x() 0
156#define cpu_is_omap34xx() 0 160#define cpu_is_omap34xx() 0
157#define cpu_is_omap343x() 0 161#define cpu_is_omap343x() 0
162#define cpu_is_omap44xx() 0
163#define cpu_is_omap443x() 0
158 164
159#if defined(MULTI_OMAP1) 165#if defined(MULTI_OMAP1)
160# if defined(CONFIG_ARCH_OMAP730) 166# if defined(CONFIG_ARCH_OMAP730)
@@ -348,12 +354,21 @@ IS_OMAP_TYPE(3430, 0x3430)
348# define cpu_is_omap3430() is_omap3430() 354# define cpu_is_omap3430() is_omap3430()
349#endif 355#endif
350 356
357# if defined(CONFIG_ARCH_OMAP4)
358# undef cpu_is_omap44xx
359# undef cpu_is_omap443x
360# define cpu_is_omap44xx() 1
361# define cpu_is_omap443x() 1
362# endif
363
351/* Macros to detect if we have OMAP1 or OMAP2 */ 364/* Macros to detect if we have OMAP1 or OMAP2 */
352#define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \ 365#define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \
353 cpu_is_omap16xx()) 366 cpu_is_omap16xx())
354#define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx()) 367#define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \
368 cpu_is_omap44xx())
355 369
356#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 370#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
371 defined(CONFIG_ARCH_OMAP4)
357 372
358/* Various silicon revisions for omap2 */ 373/* Various silicon revisions for omap2 */
359#define OMAP242X_CLASS 0x24200024 374#define OMAP242X_CLASS 0x24200024
@@ -370,6 +385,8 @@ IS_OMAP_TYPE(3430, 0x3430)
370#define OMAP3430_REV_ES3_0 0x34303034 385#define OMAP3430_REV_ES3_0 0x34303034
371#define OMAP3430_REV_ES3_1 0x34304034 386#define OMAP3430_REV_ES3_1 0x34304034
372 387
388#define OMAP443X_CLASS 0x44300034
389
373/* 390/*
374 * omap_chip bits 391 * omap_chip bits
375 * 392 *
diff --git a/arch/arm/plat-omap/include/mach/debug-macro.S b/arch/arm/plat-omap/include/mach/debug-macro.S
index 1b11f5c6a2d9..ac24050e3416 100644
--- a/arch/arm/plat-omap/include/mach/debug-macro.S
+++ b/arch/arm/plat-omap/include/mach/debug-macro.S
@@ -36,7 +36,7 @@
36 add \rx, \rx, #0x00004000 @ UART 3 36 add \rx, \rx, #0x00004000 @ UART 3
37#endif 37#endif
38 38
39#elif CONFIG_ARCH_OMAP3 39#elif defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
40 moveq \rx, #0x48000000 @ physical base address 40 moveq \rx, #0x48000000 @ physical base address
41 movne \rx, #0xd8000000 @ virtual base 41 movne \rx, #0xd8000000 @ virtual base
42 orr \rx, \rx, #0x0006a000 42 orr \rx, \rx, #0x0006a000
diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h
index 54fe9665b182..8c1eae88737e 100644
--- a/arch/arm/plat-omap/include/mach/dma.h
+++ b/arch/arm/plat-omap/include/mach/dma.h
@@ -48,6 +48,7 @@
48/* Hardware registers for omap2 and omap3 */ 48/* Hardware registers for omap2 and omap3 */
49#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000) 49#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
50#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000) 50#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
51#define OMAP44XX_DMA4_BASE (L4_44XX_BASE + 0x56000)
51 52
52#define OMAP_DMA4_REVISION 0x00 53#define OMAP_DMA4_REVISION 0x00
53#define OMAP_DMA4_GCR 0x78 54#define OMAP_DMA4_GCR 0x78
@@ -144,6 +145,7 @@
144#define OMAP_DMA4_CSSA_U(n) 0 145#define OMAP_DMA4_CSSA_U(n) 0
145#define OMAP_DMA4_CDSA_L(n) 0 146#define OMAP_DMA4_CDSA_L(n) 0
146#define OMAP_DMA4_CDSA_U(n) 0 147#define OMAP_DMA4_CDSA_U(n) 0
148#define OMAP1_DMA_COLOR(n) 0
147 149
148/*----------------------------------------------------------------------------*/ 150/*----------------------------------------------------------------------------*/
149 151
@@ -531,7 +533,7 @@ extern int omap_get_dma_index(int lch, int *ei, int *fi);
531/* Chaining APIs */ 533/* Chaining APIs */
532#ifndef CONFIG_ARCH_OMAP1 534#ifndef CONFIG_ARCH_OMAP1
533extern int omap_request_dma_chain(int dev_id, const char *dev_name, 535extern int omap_request_dma_chain(int dev_id, const char *dev_name,
534 void (*callback) (int chain_id, u16 ch_status, 536 void (*callback) (int lch, u16 ch_status,
535 void *data), 537 void *data),
536 int *chain_id, int no_of_chans, 538 int *chain_id, int no_of_chans,
537 int chain_mode, 539 int chain_mode,
diff --git a/arch/arm/plat-omap/include/mach/entry-macro.S b/arch/arm/plat-omap/include/mach/entry-macro.S
index 2276f89671d8..56426ed45ef4 100644
--- a/arch/arm/plat-omap/include/mach/entry-macro.S
+++ b/arch/arm/plat-omap/include/mach/entry-macro.S
@@ -3,6 +3,9 @@
3 * 3 *
4 * Low-level IRQ helper macros for OMAP-based platforms 4 * Low-level IRQ helper macros for OMAP-based platforms
5 * 5 *
6 * Copyright (C) 2009 Texas Instruments
7 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
6 * This file is licensed under the terms of the GNU General Public 9 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any 10 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied. 11 * warranty of any kind, whether express or implied.
@@ -10,6 +13,7 @@
10#include <mach/hardware.h> 13#include <mach/hardware.h>
11#include <mach/io.h> 14#include <mach/io.h>
12#include <mach/irqs.h> 15#include <mach/irqs.h>
16#include <asm/hardware/gic.h>
13 17
14#if defined(CONFIG_ARCH_OMAP1) 18#if defined(CONFIG_ARCH_OMAP1)
15 19
@@ -56,15 +60,21 @@
56 .endm 60 .endm
57 61
58#endif 62#endif
59#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 63#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
64 defined(CONFIG_ARCH_OMAP4)
60 65
61#if defined(CONFIG_ARCH_OMAP24XX)
62#include <mach/omap24xx.h> 66#include <mach/omap24xx.h>
63#endif
64#if defined(CONFIG_ARCH_OMAP34XX)
65#include <mach/omap34xx.h> 67#include <mach/omap34xx.h>
66#endif
67 68
69/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
70#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
71#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
72#elif defined(CONFIG_ARCH_OMAP34XX)
73#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE)
74#endif
75#if defined(CONFIG_ARCH_OMAP4)
76#include <mach/omap44xx.h>
77#endif
68#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* Active interrupt offset */ 78#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* Active interrupt offset */
69#define ACTIVEIRQ_MASK 0x7f /* Active interrupt bits */ 79#define ACTIVEIRQ_MASK 0x7f /* Active interrupt bits */
70 80
@@ -77,6 +87,7 @@
77 .macro arch_ret_to_user, tmp1, tmp2 87 .macro arch_ret_to_user, tmp1, tmp2
78 .endm 88 .endm
79 89
90#ifndef CONFIG_ARCH_OMAP4
80 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 91 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
81 ldr \base, =OMAP2_VA_IC_BASE 92 ldr \base, =OMAP2_VA_IC_BASE
82 ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */ 93 ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */
@@ -92,6 +103,68 @@
92 and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */ 103 and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
93 104
94 .endm 105 .endm
106#else
107 /*
108 * The interrupt numbering scheme is defined in the
109 * interrupt controller spec. To wit:
110 *
111 * Interrupts 0-15 are IPI
112 * 16-28 are reserved
113 * 29-31 are local. We allow 30 to be used for the watchdog.
114 * 32-1020 are global
115 * 1021-1022 are reserved
116 * 1023 is "spurious" (no interrupt)
117 *
118 * For now, we ignore all local interrupts so only return an
119 * interrupt if it's between 30 and 1020. The test_for_ipi
120 * routine below will pick up on IPIs.
121 * A simple read from the controller will tell us the number
122 * of the highest priority enabled interrupt.
123 * We then just need to check whether it is in the
124 * valid range for an IRQ (30-1020 inclusive).
125 */
126 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
127 ldr \base, =OMAP44XX_VA_GIC_CPU_BASE
128 ldr \irqstat, [\base, #GIC_CPU_INTACK]
129
130 ldr \tmp, =1021
131
132 bic \irqnr, \irqstat, #0x1c00
133
134 cmp \irqnr, #29
135 cmpcc \irqnr, \irqnr
136 cmpne \irqnr, \tmp
137 cmpcs \irqnr, \irqnr
138 .endm
139
140 /* We assume that irqstat (the raw value of the IRQ acknowledge
141 * register) is preserved from the macro above.
142 * If there is an IPI, we immediately signal end of interrupt
143 * on the controller, since this requires the original irqstat
144 * value which we won't easily be able to recreate later.
145 */
146
147 .macro test_for_ipi, irqnr, irqstat, base, tmp
148 bic \irqnr, \irqstat, #0x1c00
149 cmp \irqnr, #16
150 it cc
151 strcc \irqstat, [\base, #GIC_CPU_EOI]
152 it cs
153 cmpcs \irqnr, \irqnr
154 .endm
155
156 /* As above, this assumes that irqstat and base are preserved */
157
158 .macro test_for_ltirq, irqnr, irqstat, base, tmp
159 bic \irqnr, \irqstat, #0x1c00
160 mov \tmp, #0
161 cmp \irqnr, #29
162 itt eq
163 moveq \tmp, #1
164 streq \irqstat, [\base, #GIC_CPU_EOI]
165 cmp \tmp, #0
166 .endm
167#endif
95 168
96 .macro irq_prio_table 169 .macro irq_prio_table
97 .endm 170 .endm
diff --git a/arch/arm/plat-omap/include/mach/gpmc-smc91x.h b/arch/arm/plat-omap/include/mach/gpmc-smc91x.h
new file mode 100644
index 000000000000..b64fbee4d567
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/gpmc-smc91x.h
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/plat-omap/include/mach/gpmc-smc91x.h
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__
12
13#define GPMC_TIMINGS_SMC91C96 (1 << 4)
14#define GPMC_MUX_ADD_DATA (1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
15#define GPMC_READ_MON (1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
16#define GPMC_WRITE_MON (1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
17
18struct omap_smc91x_platform_data {
19 int cs;
20 int gpio_irq;
21 int gpio_pwrdwn;
22 int gpio_reset;
23 int wait_pin; /* Optional GPMC_CONFIG1_WAITPINSELECT */
24 u32 flags;
25 int (*retime)(void);
26};
27
28#if defined(CONFIG_SMC91X) || \
29 defined(CONFIG_SMC91X_MODULE)
30
31extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
32
33#else
34
35#define board_smc91x_data NULL
36
37static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
38{
39}
40
41#endif
42#endif
diff --git a/arch/arm/plat-omap/include/mach/hardware.h b/arch/arm/plat-omap/include/mach/hardware.h
index 3dc423ed3e80..26c1fbff08aa 100644
--- a/arch/arm/plat-omap/include/mach/hardware.h
+++ b/arch/arm/plat-omap/include/mach/hardware.h
@@ -285,5 +285,6 @@
285#include "omap16xx.h" 285#include "omap16xx.h"
286#include "omap24xx.h" 286#include "omap24xx.h"
287#include "omap34xx.h" 287#include "omap34xx.h"
288#include "omap44xx.h"
288 289
289#endif /* __ASM_ARCH_OMAP_HARDWARE_H */ 290#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/arch/arm/plat-omap/include/mach/hwa742.h b/arch/arm/plat-omap/include/mach/hwa742.h
index 577f492f2d3c..886248d32b49 100644
--- a/arch/arm/plat-omap/include/mach/hwa742.h
+++ b/arch/arm/plat-omap/include/mach/hwa742.h
@@ -2,10 +2,6 @@
2#define _HWA742_H 2#define _HWA742_H
3 3
4struct hwa742_platform_data { 4struct hwa742_platform_data {
5 void (*power_up)(struct device *dev);
6 void (*power_down)(struct device *dev);
7 unsigned long (*get_clock_rate)(struct device *dev);
8
9 unsigned te_connected:1; 5 unsigned te_connected:1;
10}; 6};
11 7
diff --git a/arch/arm/plat-omap/include/mach/io.h b/arch/arm/plat-omap/include/mach/io.h
index 0610d7e2b3d7..3b2814720569 100644
--- a/arch/arm/plat-omap/include/mach/io.h
+++ b/arch/arm/plat-omap/include/mach/io.h
@@ -6,6 +6,9 @@
6 * Copied from arch/arm/mach-sa1100/include/mach/io.h 6 * Copied from arch/arm/mach-sa1100/include/mach/io.h
7 * Copyright (C) 1997-1999 Russell King 7 * Copyright (C) 1997-1999 Russell King
8 * 8 *
9 * Copyright (C) 2009 Texas Instruments
10 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
11 *
9 * This program is free software; you can redistribute it and/or modify it 12 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the 13 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your 14 * Free Software Foundation; either version 2 of the License, or (at your
@@ -157,6 +160,40 @@
157#define DSP_MMU_34XX_VIRT 0xe2000000 160#define DSP_MMU_34XX_VIRT 0xe2000000
158#define DSP_MMU_34XX_SIZE SZ_4K 161#define DSP_MMU_34XX_SIZE SZ_4K
159 162
163
164#elif defined(CONFIG_ARCH_OMAP4)
165/* We map both L3 and L4 on OMAP4 */
166#define L3_44XX_PHYS L3_44XX_BASE
167#define L3_44XX_VIRT 0xd4000000
168#define L3_44XX_SIZE SZ_1M
169
170#define L4_44XX_PHYS L4_44XX_BASE
171#define L4_44XX_VIRT 0xda000000
172#define L4_44XX_SIZE SZ_4M
173
174
175#define L4_WK_44XX_PHYS L4_WK_44XX_BASE
176#define L4_WK_44XX_VIRT 0xda300000
177#define L4_WK_44XX_SIZE SZ_1M
178
179#define L4_PER_44XX_PHYS L4_PER_44XX_BASE
180#define L4_PER_44XX_VIRT 0xd8000000
181#define L4_PER_44XX_SIZE SZ_4M
182
183#define L4_EMU_44XX_PHYS L4_EMU_44XX_BASE
184#define L4_EMU_44XX_VIRT 0xe4000000
185#define L4_EMU_44XX_SIZE SZ_64M
186
187#define OMAP44XX_GPMC_PHYS OMAP44XX_GPMC_BASE
188#define OMAP44XX_GPMC_VIRT 0xe0000000
189#define OMAP44XX_GPMC_SIZE SZ_1M
190
191
192#define IO_OFFSET 0x90000000
193#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
194#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
195#define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */
196
160#endif 197#endif
161 198
162#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) 199#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa))
diff --git a/arch/arm/plat-omap/include/mach/iommu.h b/arch/arm/plat-omap/include/mach/iommu.h
new file mode 100644
index 000000000000..769b00b4c34a
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/iommu.h
@@ -0,0 +1,168 @@
1/*
2 * omap iommu: main structures
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __MACH_IOMMU_H
14#define __MACH_IOMMU_H
15
16struct iotlb_entry {
17 u32 da;
18 u32 pa;
19 u32 pgsz, prsvd, valid;
20 union {
21 u16 ap;
22 struct {
23 u32 endian, elsz, mixed;
24 };
25 };
26};
27
28struct iommu {
29 const char *name;
30 struct module *owner;
31 struct clk *clk;
32 void __iomem *regbase;
33 struct device *dev;
34
35 unsigned int refcount;
36 struct mutex iommu_lock; /* global for this whole object */
37
38 /*
39 * We don't change iopgd for a situation like pgd for a task,
40 * but share it globally for each iommu.
41 */
42 u32 *iopgd;
43 spinlock_t page_table_lock; /* protect iopgd */
44
45 int nr_tlb_entries;
46
47 struct list_head mmap;
48 struct mutex mmap_lock; /* protect mmap */
49
50 int (*isr)(struct iommu *obj);
51
52 void *ctx; /* iommu context: registres saved area */
53};
54
55struct cr_regs {
56 union {
57 struct {
58 u16 cam_l;
59 u16 cam_h;
60 };
61 u32 cam;
62 };
63 union {
64 struct {
65 u16 ram_l;
66 u16 ram_h;
67 };
68 u32 ram;
69 };
70};
71
72struct iotlb_lock {
73 short base;
74 short vict;
75};
76
77/* architecture specific functions */
78struct iommu_functions {
79 unsigned long version;
80
81 int (*enable)(struct iommu *obj);
82 void (*disable)(struct iommu *obj);
83 u32 (*fault_isr)(struct iommu *obj, u32 *ra);
84
85 void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
86 void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
87
88 struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e);
89 int (*cr_valid)(struct cr_regs *cr);
90 u32 (*cr_to_virt)(struct cr_regs *cr);
91 void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e);
92 ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf);
93
94 u32 (*get_pte_attr)(struct iotlb_entry *e);
95
96 void (*save_ctx)(struct iommu *obj);
97 void (*restore_ctx)(struct iommu *obj);
98 ssize_t (*dump_ctx)(struct iommu *obj, char *buf);
99};
100
101struct iommu_platform_data {
102 const char *name;
103 const char *clk_name;
104 const int nr_tlb_entries;
105};
106
107#if defined(CONFIG_ARCH_OMAP1)
108#error "iommu for this processor not implemented yet"
109#else
110#include <mach/iommu2.h>
111#endif
112
113/*
114 * utilities for super page(16MB, 1MB, 64KB and 4KB)
115 */
116
117#define iopgsz_max(bytes) \
118 (((bytes) >= SZ_16M) ? SZ_16M : \
119 ((bytes) >= SZ_1M) ? SZ_1M : \
120 ((bytes) >= SZ_64K) ? SZ_64K : \
121 ((bytes) >= SZ_4K) ? SZ_4K : 0)
122
123#define bytes_to_iopgsz(bytes) \
124 (((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M : \
125 ((bytes) == SZ_1M) ? MMU_CAM_PGSZ_1M : \
126 ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K : \
127 ((bytes) == SZ_4K) ? MMU_CAM_PGSZ_4K : -1)
128
129#define iopgsz_to_bytes(iopgsz) \
130 (((iopgsz) == MMU_CAM_PGSZ_16M) ? SZ_16M : \
131 ((iopgsz) == MMU_CAM_PGSZ_1M) ? SZ_1M : \
132 ((iopgsz) == MMU_CAM_PGSZ_64K) ? SZ_64K : \
133 ((iopgsz) == MMU_CAM_PGSZ_4K) ? SZ_4K : 0)
134
135#define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
136
137/*
138 * global functions
139 */
140extern u32 iommu_arch_version(void);
141
142extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
143extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
144
145extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
146extern void flush_iotlb_page(struct iommu *obj, u32 da);
147extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
148extern void flush_iotlb_all(struct iommu *obj);
149
150extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
151extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
152
153extern struct iommu *iommu_get(const char *name);
154extern void iommu_put(struct iommu *obj);
155
156extern void iommu_save_ctx(struct iommu *obj);
157extern void iommu_restore_ctx(struct iommu *obj);
158
159extern int install_iommu_arch(const struct iommu_functions *ops);
160extern void uninstall_iommu_arch(const struct iommu_functions *ops);
161
162extern int foreach_iommu_device(void *data,
163 int (*fn)(struct device *, void *));
164
165extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf);
166extern size_t dump_tlb_entries(struct iommu *obj, char *buf);
167
168#endif /* __MACH_IOMMU_H */
diff --git a/arch/arm/plat-omap/include/mach/iommu2.h b/arch/arm/plat-omap/include/mach/iommu2.h
new file mode 100644
index 000000000000..10ad05f410e9
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/iommu2.h
@@ -0,0 +1,96 @@
1/*
2 * omap iommu: omap2 architecture specific definitions
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __MACH_IOMMU2_H
14#define __MACH_IOMMU2_H
15
16#include <linux/io.h>
17
18/*
19 * MMU Register offsets
20 */
21#define MMU_REVISION 0x00
22#define MMU_SYSCONFIG 0x10
23#define MMU_SYSSTATUS 0x14
24#define MMU_IRQSTATUS 0x18
25#define MMU_IRQENABLE 0x1c
26#define MMU_WALKING_ST 0x40
27#define MMU_CNTL 0x44
28#define MMU_FAULT_AD 0x48
29#define MMU_TTB 0x4c
30#define MMU_LOCK 0x50
31#define MMU_LD_TLB 0x54
32#define MMU_CAM 0x58
33#define MMU_RAM 0x5c
34#define MMU_GFLUSH 0x60
35#define MMU_FLUSH_ENTRY 0x64
36#define MMU_READ_CAM 0x68
37#define MMU_READ_RAM 0x6c
38#define MMU_EMU_FAULT_AD 0x70
39
40#define MMU_REG_SIZE 256
41
42/*
43 * MMU Register bit definitions
44 */
45#define MMU_LOCK_BASE_SHIFT 10
46#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
47#define MMU_LOCK_BASE(x) \
48 ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
49
50#define MMU_LOCK_VICT_SHIFT 4
51#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
52#define MMU_LOCK_VICT(x) \
53 ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
54
55#define MMU_CAM_VATAG_SHIFT 12
56#define MMU_CAM_VATAG_MASK \
57 ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
58#define MMU_CAM_P (1 << 3)
59#define MMU_CAM_V (1 << 2)
60#define MMU_CAM_PGSZ_MASK 3
61#define MMU_CAM_PGSZ_1M (0 << 0)
62#define MMU_CAM_PGSZ_64K (1 << 0)
63#define MMU_CAM_PGSZ_4K (2 << 0)
64#define MMU_CAM_PGSZ_16M (3 << 0)
65
66#define MMU_RAM_PADDR_SHIFT 12
67#define MMU_RAM_PADDR_MASK \
68 ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
69#define MMU_RAM_ENDIAN_SHIFT 9
70#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
71#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
72#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
73#define MMU_RAM_ELSZ_SHIFT 7
74#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
75#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
76#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
77#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
78#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
79#define MMU_RAM_MIXED_SHIFT 6
80#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
81#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
82
83/*
84 * register accessors
85 */
86static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
87{
88 return __raw_readl(obj->regbase + offs);
89}
90
91static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
92{
93 __raw_writel(val, obj->regbase + offs);
94}
95
96#endif /* __MACH_IOMMU2_H */
diff --git a/arch/arm/plat-omap/include/mach/iovmm.h b/arch/arm/plat-omap/include/mach/iovmm.h
new file mode 100644
index 000000000000..bdc7ce5d7a4a
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/iovmm.h
@@ -0,0 +1,94 @@
1/*
2 * omap iommu: simple virtual address space management
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __IOMMU_MMAP_H
14#define __IOMMU_MMAP_H
15
16struct iovm_struct {
17 struct iommu *iommu; /* iommu object which this belongs to */
18 u32 da_start; /* area definition */
19 u32 da_end;
20 u32 flags; /* IOVMF_: see below */
21 struct list_head list; /* linked in ascending order */
22 const struct sg_table *sgt; /* keep 'page' <-> 'da' mapping */
23 void *va; /* mpu side mapped address */
24};
25
26/*
27 * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
28 *
29 * lower 16 bit is used for h/w and upper 16 bit is for s/w.
30 */
31#define IOVMF_SW_SHIFT 16
32#define IOVMF_HW_SIZE (1 << IOVMF_SW_SHIFT)
33#define IOVMF_HW_MASK (IOVMF_HW_SIZE - 1)
34#define IOVMF_SW_MASK (~IOVMF_HW_MASK)UL
35
36/*
37 * iovma: h/w flags derived from cam and ram attribute
38 */
39#define IOVMF_CAM_MASK (~((1 << 10) - 1))
40#define IOVMF_RAM_MASK (~IOVMF_CAM_MASK)
41
42#define IOVMF_PGSZ_MASK (3 << 0)
43#define IOVMF_PGSZ_1M MMU_CAM_PGSZ_1M
44#define IOVMF_PGSZ_64K MMU_CAM_PGSZ_64K
45#define IOVMF_PGSZ_4K MMU_CAM_PGSZ_4K
46#define IOVMF_PGSZ_16M MMU_CAM_PGSZ_16M
47
48#define IOVMF_ENDIAN_MASK (1 << 9)
49#define IOVMF_ENDIAN_BIG MMU_RAM_ENDIAN_BIG
50#define IOVMF_ENDIAN_LITTLE MMU_RAM_ENDIAN_LITTLE
51
52#define IOVMF_ELSZ_MASK (3 << 7)
53#define IOVMF_ELSZ_8 MMU_RAM_ELSZ_8
54#define IOVMF_ELSZ_16 MMU_RAM_ELSZ_16
55#define IOVMF_ELSZ_32 MMU_RAM_ELSZ_32
56#define IOVMF_ELSZ_NONE MMU_RAM_ELSZ_NONE
57
58#define IOVMF_MIXED_MASK (1 << 6)
59#define IOVMF_MIXED MMU_RAM_MIXED
60
61/*
62 * iovma: s/w flags, used for mapping and umapping internally.
63 */
64#define IOVMF_MMIO (1 << IOVMF_SW_SHIFT)
65#define IOVMF_ALLOC (2 << IOVMF_SW_SHIFT)
66#define IOVMF_ALLOC_MASK (3 << IOVMF_SW_SHIFT)
67
68/* "superpages" is supported just with physically linear pages */
69#define IOVMF_DISCONT (1 << (2 + IOVMF_SW_SHIFT))
70#define IOVMF_LINEAR (2 << (2 + IOVMF_SW_SHIFT))
71#define IOVMF_LINEAR_MASK (3 << (2 + IOVMF_SW_SHIFT))
72
73#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
74#define IOVMF_DA_ANON (2 << (4 + IOVMF_SW_SHIFT))
75#define IOVMF_DA_MASK (3 << (4 + IOVMF_SW_SHIFT))
76
77
78extern struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da);
79extern u32 iommu_vmap(struct iommu *obj, u32 da,
80 const struct sg_table *sgt, u32 flags);
81extern struct sg_table *iommu_vunmap(struct iommu *obj, u32 da);
82extern u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes,
83 u32 flags);
84extern void iommu_vfree(struct iommu *obj, const u32 da);
85extern u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
86 u32 flags);
87extern void iommu_kunmap(struct iommu *obj, u32 da);
88extern u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes,
89 u32 flags);
90extern void iommu_kfree(struct iommu *obj, u32 da);
91
92extern void *da_to_va(struct iommu *obj, u32 da);
93
94#endif /* __IOMMU_MMAP_H */
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index 7f57ee66f364..fb7cb7723990 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -4,6 +4,9 @@
4 * Copyright (C) Greg Lonnon 2001 4 * Copyright (C) Greg Lonnon 2001
5 * Updated for OMAP-1610 by Tony Lindgren <tony@atomide.com> 5 * Updated for OMAP-1610 by Tony Lindgren <tony@atomide.com>
6 * 6 *
7 * Copyright (C) 2009 Texas Instruments
8 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
9 *
7 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
@@ -422,6 +425,94 @@
422 425
423#define INT_34XX_BENCH_MPU_EMUL 3 426#define INT_34XX_BENCH_MPU_EMUL 3
424 427
428
429#define IRQ_GIC_START 32
430#define INT_44XX_LOCALTIMER_IRQ 29
431#define INT_44XX_LOCALWDT_IRQ 30
432
433#define INT_44XX_BENCH_MPU_EMUL (3 + IRQ_GIC_START)
434#define INT_44XX_SSM_ABORT_IRQ (6 + IRQ_GIC_START)
435#define INT_44XX_SYS_NIRQ (7 + IRQ_GIC_START)
436#define INT_44XX_D2D_FW_IRQ (8 + IRQ_GIC_START)
437#define INT_44XX_PRCM_MPU_IRQ (11 + IRQ_GIC_START)
438#define INT_44XX_SDMA_IRQ0 (12 + IRQ_GIC_START)
439#define INT_44XX_SDMA_IRQ1 (13 + IRQ_GIC_START)
440#define INT_44XX_SDMA_IRQ2 (14 + IRQ_GIC_START)
441#define INT_44XX_SDMA_IRQ3 (15 + IRQ_GIC_START)
442#define INT_44XX_ISS_IRQ (24 + IRQ_GIC_START)
443#define INT_44XX_DSS_IRQ (25 + IRQ_GIC_START)
444#define INT_44XX_MAIL_U0_MPU (26 + IRQ_GIC_START)
445#define INT_44XX_DSP_MMU (28 + IRQ_GIC_START)
446#define INT_44XX_GPTIMER1 (37 + IRQ_GIC_START)
447#define INT_44XX_GPTIMER2 (38 + IRQ_GIC_START)
448#define INT_44XX_GPTIMER3 (39 + IRQ_GIC_START)
449#define INT_44XX_GPTIMER4 (40 + IRQ_GIC_START)
450#define INT_44XX_GPTIMER5 (41 + IRQ_GIC_START)
451#define INT_44XX_GPTIMER6 (42 + IRQ_GIC_START)
452#define INT_44XX_GPTIMER7 (43 + IRQ_GIC_START)
453#define INT_44XX_GPTIMER8 (44 + IRQ_GIC_START)
454#define INT_44XX_GPTIMER9 (45 + IRQ_GIC_START)
455#define INT_44XX_GPTIMER10 (46 + IRQ_GIC_START)
456#define INT_44XX_GPTIMER11 (47 + IRQ_GIC_START)
457#define INT_44XX_GPTIMER12 (95 + IRQ_GIC_START)
458#define INT_44XX_SHA1MD5 (51 + IRQ_GIC_START)
459#define INT_44XX_I2C1_IRQ (56 + IRQ_GIC_START)
460#define INT_44XX_I2C2_IRQ (57 + IRQ_GIC_START)
461#define INT_44XX_HDQ_IRQ (58 + IRQ_GIC_START)
462#define INT_44XX_SPI1_IRQ (65 + IRQ_GIC_START)
463#define INT_44XX_SPI2_IRQ (66 + IRQ_GIC_START)
464#define INT_44XX_HSI_1_IRQ0 (67 + IRQ_GIC_START)
465#define INT_44XX_HSI_2_IRQ1 (68 + IRQ_GIC_START)
466#define INT_44XX_HSI_1_DMAIRQ (71 + IRQ_GIC_START)
467#define INT_44XX_UART1_IRQ (72 + IRQ_GIC_START)
468#define INT_44XX_UART2_IRQ (73 + IRQ_GIC_START)
469#define INT_44XX_UART3_IRQ (74 + IRQ_GIC_START)
470#define INT_44XX_UART4_IRQ (70 + IRQ_GIC_START)
471#define INT_44XX_USB_IRQ_NISO (76 + IRQ_GIC_START)
472#define INT_44XX_USB_IRQ_ISO (77 + IRQ_GIC_START)
473#define INT_44XX_USB_IRQ_HGEN (78 + IRQ_GIC_START)
474#define INT_44XX_USB_IRQ_HSOF (79 + IRQ_GIC_START)
475#define INT_44XX_USB_IRQ_OTG (80 + IRQ_GIC_START)
476#define INT_44XX_MCBSP4_IRQ_TX (81 + IRQ_GIC_START)
477#define INT_44XX_MCBSP4_IRQ_RX (82 + IRQ_GIC_START)
478#define INT_44XX_MMC_IRQ (83 + IRQ_GIC_START)
479#define INT_44XX_MMC2_IRQ (86 + IRQ_GIC_START)
480#define INT_44XX_MCBSP2_IRQ_TX (89 + IRQ_GIC_START)
481#define INT_44XX_MCBSP2_IRQ_RX (90 + IRQ_GIC_START)
482#define INT_44XX_SPI3_IRQ (91 + IRQ_GIC_START)
483#define INT_44XX_SPI5_IRQ (69 + IRQ_GIC_START)
484
485#define INT_44XX_MCBSP5_IRQ (16 + IRQ_GIC_START)
486#define INT_44xX_MCBSP1_IRQ (17 + IRQ_GIC_START)
487#define INT_44XX_MCBSP2_IRQ (22 + IRQ_GIC_START)
488#define INT_44XX_MCBSP3_IRQ (23 + IRQ_GIC_START)
489#define INT_44XX_MCBSP4_IRQ (27 + IRQ_GIC_START)
490#define INT_44XX_HS_USB_MC (92 + IRQ_GIC_START)
491#define INT_44XX_HS_USB_DMA (93 + IRQ_GIC_START)
492
493#define INT_44XX_GPIO_BANK1 (29 + IRQ_GIC_START)
494#define INT_44XX_GPIO_BANK2 (30 + IRQ_GIC_START)
495#define INT_44XX_GPIO_BANK3 (31 + IRQ_GIC_START)
496#define INT_44XX_GPIO_BANK4 (32 + IRQ_GIC_START)
497#define INT_44XX_GPIO_BANK5 (33 + IRQ_GIC_START)
498#define INT_44XX_GPIO_BANK6 (34 + IRQ_GIC_START)
499#define INT_44XX_USIM_IRQ (35 + IRQ_GIC_START)
500#define INT_44XX_WDT3_IRQ (36 + IRQ_GIC_START)
501#define INT_44XX_SPI4_IRQ (48 + IRQ_GIC_START)
502#define INT_44XX_SHA1MD52_IRQ (49 + IRQ_GIC_START)
503#define INT_44XX_FPKA_READY_IRQ (50 + IRQ_GIC_START)
504#define INT_44XX_SHA1MD51_IRQ (51 + IRQ_GIC_START)
505#define INT_44XX_RNG_IRQ (52 + IRQ_GIC_START)
506#define INT_44XX_I2C3_IRQ (61 + IRQ_GIC_START)
507#define INT_44XX_FPKA_ERROR_IRQ (64 + IRQ_GIC_START)
508#define INT_44XX_PBIAS_IRQ (75 + IRQ_GIC_START)
509#define INT_44XX_OHCI_IRQ (76 + IRQ_GIC_START)
510#define INT_44XX_EHCI_IRQ (77 + IRQ_GIC_START)
511#define INT_44XX_TLL_IRQ (78 + IRQ_GIC_START)
512#define INT_44XX_PARTHASH_IRQ (79 + IRQ_GIC_START)
513#define INT_44XX_MMC3_IRQ (94 + IRQ_GIC_START)
514
515
425/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and 516/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
426 * 16 MPUIO lines */ 517 * 16 MPUIO lines */
427#define OMAP_MAX_GPIO_LINES 192 518#define OMAP_MAX_GPIO_LINES 192
@@ -467,6 +558,7 @@
467 558
468#ifndef __ASSEMBLY__ 559#ifndef __ASSEMBLY__
469extern void omap_init_irq(void); 560extern void omap_init_irq(void);
561extern int omap_irq_pending(void);
470#endif 562#endif
471 563
472#include <mach/hardware.h> 564#include <mach/hardware.h>
diff --git a/arch/arm/plat-omap/include/mach/keypad.h b/arch/arm/plat-omap/include/mach/keypad.h
index 232923aaf61d..45ea3ae3c995 100644
--- a/arch/arm/plat-omap/include/mach/keypad.h
+++ b/arch/arm/plat-omap/include/mach/keypad.h
@@ -33,7 +33,11 @@ struct omap_kp_platform_data {
33#define GROUP_3 (3 << 16) 33#define GROUP_3 (3 << 16)
34#define GROUP_MASK GROUP_3 34#define GROUP_MASK GROUP_3
35 35
36#define KEY_PERSISTENT 0x00800000
37#define KEYNUM_MASK 0x00EFFFFF
36#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val)) 38#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
39#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
40 KEY_PERSISTENT)
37 41
38#endif 42#endif
39 43
diff --git a/arch/arm/plat-omap/include/mach/memory.h b/arch/arm/plat-omap/include/mach/memory.h
index 99ed564d9277..9ad41dc484c1 100644
--- a/arch/arm/plat-omap/include/mach/memory.h
+++ b/arch/arm/plat-omap/include/mach/memory.h
@@ -38,7 +38,8 @@
38 */ 38 */
39#if defined(CONFIG_ARCH_OMAP1) 39#if defined(CONFIG_ARCH_OMAP1)
40#define PHYS_OFFSET UL(0x10000000) 40#define PHYS_OFFSET UL(0x10000000)
41#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 41#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
42 defined(CONFIG_ARCH_OMAP4)
42#define PHYS_OFFSET UL(0x80000000) 43#define PHYS_OFFSET UL(0x80000000)
43#endif 44#endif
44 45
diff --git a/arch/arm/plat-omap/include/mach/omap24xx.h b/arch/arm/plat-omap/include/mach/omap24xx.h
index 24335d4932f5..696edfc145a6 100644
--- a/arch/arm/plat-omap/include/mach/omap24xx.h
+++ b/arch/arm/plat-omap/include/mach/omap24xx.h
@@ -85,23 +85,5 @@
85#define OMAP24XX_SEC_AES_BASE (OMAP24XX_SEC_BASE + 0x6000) 85#define OMAP24XX_SEC_AES_BASE (OMAP24XX_SEC_BASE + 0x6000)
86#define OMAP24XX_SEC_PKA_BASE (OMAP24XX_SEC_BASE + 0x8000) 86#define OMAP24XX_SEC_PKA_BASE (OMAP24XX_SEC_BASE + 0x8000)
87 87
88#if defined(CONFIG_ARCH_OMAP2420)
89
90#define OMAP2_32KSYNCT_BASE OMAP2420_32KSYNCT_BASE
91#define OMAP2_PRCM_BASE OMAP2420_PRCM_BASE
92#define OMAP2_CM_BASE OMAP2420_CM_BASE
93#define OMAP2_PRM_BASE OMAP2420_PRM_BASE
94#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
95
96#elif defined(CONFIG_ARCH_OMAP2430)
97
98#define OMAP2_32KSYNCT_BASE OMAP2430_32KSYNCT_BASE
99#define OMAP2_PRCM_BASE OMAP2430_PRCM_BASE
100#define OMAP2_CM_BASE OMAP2430_CM_BASE
101#define OMAP2_PRM_BASE OMAP2430_PRM_BASE
102#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
103
104#endif
105
106#endif /* __ASM_ARCH_OMAP24XX_H */ 88#endif /* __ASM_ARCH_OMAP24XX_H */
107 89
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index ab640151d3ec..f8d186a73712 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -31,13 +31,9 @@
31 31
32#define L4_34XX_BASE 0x48000000 32#define L4_34XX_BASE 0x48000000
33#define L4_WK_34XX_BASE 0x48300000 33#define L4_WK_34XX_BASE 0x48300000
34#define L4_WK_OMAP_BASE L4_WK_34XX_BASE
35#define L4_PER_34XX_BASE 0x49000000 34#define L4_PER_34XX_BASE 0x49000000
36#define L4_PER_OMAP_BASE L4_PER_34XX_BASE
37#define L4_EMU_34XX_BASE 0x54000000 35#define L4_EMU_34XX_BASE 0x54000000
38#define L4_EMU_BASE L4_EMU_34XX_BASE
39#define L3_34XX_BASE 0x68000000 36#define L3_34XX_BASE 0x68000000
40#define L3_OMAP_BASE L3_34XX_BASE
41 37
42#define OMAP3430_32KSYNCT_BASE 0x48320000 38#define OMAP3430_32KSYNCT_BASE 0x48320000
43#define OMAP3430_CM_BASE 0x48004800 39#define OMAP3430_CM_BASE 0x48004800
@@ -83,15 +79,6 @@
83 79
84#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000) 80#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
85 81
86#if defined(CONFIG_ARCH_OMAP3430)
87
88#define OMAP2_32KSYNCT_BASE OMAP3430_32KSYNCT_BASE
89#define OMAP2_CM_BASE OMAP3430_CM_BASE
90#define OMAP2_PRM_BASE OMAP3430_PRM_BASE
91#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE)
92
93#endif
94
95#define OMAP34XX_DSP_BASE 0x58000000 82#define OMAP34XX_DSP_BASE 0x58000000
96#define OMAP34XX_DSP_MEM_BASE (OMAP34XX_DSP_BASE + 0x0) 83#define OMAP34XX_DSP_MEM_BASE (OMAP34XX_DSP_BASE + 0x0)
97#define OMAP34XX_DSP_IPI_BASE (OMAP34XX_DSP_BASE + 0x1000000) 84#define OMAP34XX_DSP_IPI_BASE (OMAP34XX_DSP_BASE + 0x1000000)
diff --git a/arch/arm/plat-omap/include/mach/omap44xx.h b/arch/arm/plat-omap/include/mach/omap44xx.h
new file mode 100644
index 000000000000..15dec7f1c7c0
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap44xx.h
@@ -0,0 +1,46 @@
1/*:
2 * Address mappings and base address for OMAP4 interconnects
3 * and peripherals.
4 *
5 * Copyright (C) 2009 Texas Instruments
6 *
7 * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef __ASM_ARCH_OMAP44XX_H
14#define __ASM_ARCH_OMAP44XX_H
15
16/*
17 * Please place only base defines here and put the rest in device
18 * specific headers.
19 */
20#define L4_44XX_BASE 0x4a000000
21#define L4_WK_44XX_BASE 0x4a300000
22#define L4_PER_44XX_BASE 0x48000000
23#define L4_EMU_44XX_BASE 0x54000000
24#define L3_44XX_BASE 0x44000000
25#define OMAP4430_32KSYNCT_BASE 0x4a304000
26#define OMAP4430_CM_BASE 0x4a004000
27#define OMAP4430_PRM_BASE 0x48306000
28#define OMAP44XX_GPMC_BASE 0x50000000
29#define OMAP443X_SCM_BASE 0x4a002000
30#define OMAP443X_CTRL_BASE OMAP443X_SCM_BASE
31#define OMAP44XX_IC_BASE 0x48200000
32#define OMAP44XX_IVA_INTC_BASE 0x40000000
33#define IRQ_SIR_IRQ 0x0040
34#define OMAP44XX_GIC_DIST_BASE 0x48241000
35#define OMAP44XX_GIC_CPU_BASE 0x48240100
36#define OMAP44XX_VA_GIC_CPU_BASE IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
37#define OMAP44XX_SCU_BASE 0x48240000
38#define OMAP44XX_VA_SCU_BASE IO_ADDRESS(OMAP44XX_SCU_BASE)
39#define OMAP44XX_LOCAL_TWD_BASE 0x48240600
40#define OMAP44XX_VA_LOCAL_TWD_BASE IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE)
41#define OMAP44XX_LOCAL_TWD_SIZE 0x00000100
42#define OMAP44XX_WKUPGEN_BASE 0x48281000
43#define OMAP44XX_VA_WKUPGEN_BASE IO_ADDRESS(OMAP44XX_WKUPGEN_BASE)
44
45#endif /* __ASM_ARCH_OMAP44XX_H */
46
diff --git a/arch/arm/plat-omap/include/mach/onenand.h b/arch/arm/plat-omap/include/mach/onenand.h
index 4649d302c263..72f433d7d827 100644
--- a/arch/arm/plat-omap/include/mach/onenand.h
+++ b/arch/arm/plat-omap/include/mach/onenand.h
@@ -9,8 +9,12 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/mtd/mtd.h>
12#include <linux/mtd/partitions.h> 13#include <linux/mtd/partitions.h>
13 14
15#define ONENAND_SYNC_READ (1 << 0)
16#define ONENAND_SYNC_READWRITE (1 << 1)
17
14struct omap_onenand_platform_data { 18struct omap_onenand_platform_data {
15 int cs; 19 int cs;
16 int gpio_irq; 20 int gpio_irq;
@@ -18,8 +22,22 @@ struct omap_onenand_platform_data {
18 int nr_parts; 22 int nr_parts;
19 int (*onenand_setup)(void __iomem *, int freq); 23 int (*onenand_setup)(void __iomem *, int freq);
20 int dma_channel; 24 int dma_channel;
25 u8 flags;
21}; 26};
22 27
23int omap2_onenand_rephase(void);
24
25#define ONENAND_MAX_PARTITIONS 8 28#define ONENAND_MAX_PARTITIONS 8
29
30#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
31 defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
32
33extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
34
35#else
36
37#define board_onenand_data NULL
38
39static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
40{
41}
42
43#endif
diff --git a/arch/arm/plat-omap/include/mach/pm.h b/arch/arm/plat-omap/include/mach/pm.h
deleted file mode 100644
index ce6ee7927537..000000000000
--- a/arch/arm/plat-omap/include/mach/pm.h
+++ /dev/null
@@ -1,345 +0,0 @@
1/*
2 * arch/arm/plat-omap/include/mach/pm.h
3 *
4 * Header file for OMAP Power Management Routines
5 *
6 * Author: MontaVista Software, Inc.
7 * support@mvista.com
8 *
9 * Copyright 2002 MontaVista Software Inc.
10 *
11 * Cleanup 2004 for Linux 2.6 by Dirk Behme <dirk.behme@de.bosch.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34#ifndef __ASM_ARCH_OMAP_PM_H
35#define __ASM_ARCH_OMAP_PM_H
36
37/*
38 * ----------------------------------------------------------------------------
39 * Register and offset definitions to be used in PM assembler code
40 * ----------------------------------------------------------------------------
41 */
42#define CLKGEN_REG_ASM_BASE IO_ADDRESS(0xfffece00)
43#define ARM_IDLECT1_ASM_OFFSET 0x04
44#define ARM_IDLECT2_ASM_OFFSET 0x08
45
46#define TCMIF_ASM_BASE IO_ADDRESS(0xfffecc00)
47#define EMIFS_CONFIG_ASM_OFFSET 0x0c
48#define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20
49
50/*
51 * ----------------------------------------------------------------------------
52 * Power management bitmasks
53 * ----------------------------------------------------------------------------
54 */
55#define IDLE_WAIT_CYCLES 0x00000fff
56#define PERIPHERAL_ENABLE 0x2
57
58#define SELF_REFRESH_MODE 0x0c000001
59#define IDLE_EMIFS_REQUEST 0xc
60#define MODEM_32K_EN 0x1
61#define PER_EN 0x1
62
63#define CPU_SUSPEND_SIZE 200
64#define ULPD_LOW_PWR_EN 0x0001
65#define ULPD_DEEP_SLEEP_TRANSITION_EN 0x0010
66#define ULPD_SETUP_ANALOG_CELL_3_VAL 0
67#define ULPD_POWER_CTRL_REG_VAL 0x0219
68
69#define DSP_IDLE_DELAY 10
70#define DSP_IDLE 0x0040
71#define DSP_RST 0x0004
72#define DSP_ENABLE 0x0002
73#define SUFFICIENT_DSP_RESET_TIME 1000
74#define DEFAULT_MPUI_CONFIG 0x05cf
75#define ENABLE_XORCLK 0x2
76#define DSP_CLOCK_ENABLE 0x2000
77#define DSP_IDLE_MODE 0x2
78#define TC_IDLE_REQUEST (0x0000000c)
79
80#define IRQ_LEVEL2 (1<<0)
81#define IRQ_KEYBOARD (1<<1)
82#define IRQ_UART2 (1<<15)
83
84#define PDE_BIT 0x08
85#define PWD_EN_BIT 0x04
86#define EN_PERCK_BIT 0x04
87
88#define OMAP1510_DEEP_SLEEP_REQUEST 0x0ec7
89#define OMAP1510_BIG_SLEEP_REQUEST 0x0cc5
90#define OMAP1510_IDLE_LOOP_REQUEST 0x0c00
91#define OMAP1510_IDLE_CLOCK_DOMAINS 0x2
92
93/* Both big sleep and deep sleep use same values. Difference is in ULPD. */
94#define OMAP1610_IDLECT1_SLEEP_VAL 0x13c7
95#define OMAP1610_IDLECT2_SLEEP_VAL 0x09c7
96#define OMAP1610_IDLECT3_VAL 0x3f
97#define OMAP1610_IDLECT3_SLEEP_ORMASK 0x2c
98#define OMAP1610_IDLECT3 0xfffece24
99#define OMAP1610_IDLE_LOOP_REQUEST 0x0400
100
101#define OMAP730_IDLECT1_SLEEP_VAL 0x16c7
102#define OMAP730_IDLECT2_SLEEP_VAL 0x09c7
103#define OMAP730_IDLECT3_VAL 0x3f
104#define OMAP730_IDLECT3 0xfffece24
105#define OMAP730_IDLE_LOOP_REQUEST 0x0C00
106
107#if !defined(CONFIG_ARCH_OMAP730) && \
108 !defined(CONFIG_ARCH_OMAP15XX) && \
109 !defined(CONFIG_ARCH_OMAP16XX) && \
110 !defined(CONFIG_ARCH_OMAP24XX)
111#warning "Power management for this processor not implemented yet"
112#endif
113
114#ifndef __ASSEMBLER__
115
116#include <linux/clk.h>
117
118extern void prevent_idle_sleep(void);
119extern void allow_idle_sleep(void);
120
121extern void omap_pm_idle(void);
122extern void omap_pm_suspend(void);
123extern void omap730_cpu_suspend(unsigned short, unsigned short);
124extern void omap1510_cpu_suspend(unsigned short, unsigned short);
125extern void omap1610_cpu_suspend(unsigned short, unsigned short);
126extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
127 void __iomem *sdrc_power);
128extern void omap730_idle_loop_suspend(void);
129extern void omap1510_idle_loop_suspend(void);
130extern void omap1610_idle_loop_suspend(void);
131extern void omap24xx_idle_loop_suspend(void);
132
133extern unsigned int omap730_cpu_suspend_sz;
134extern unsigned int omap1510_cpu_suspend_sz;
135extern unsigned int omap1610_cpu_suspend_sz;
136extern unsigned int omap24xx_cpu_suspend_sz;
137extern unsigned int omap730_idle_loop_suspend_sz;
138extern unsigned int omap1510_idle_loop_suspend_sz;
139extern unsigned int omap1610_idle_loop_suspend_sz;
140extern unsigned int omap24xx_idle_loop_suspend_sz;
141
142#ifdef CONFIG_OMAP_SERIAL_WAKE
143extern void omap_serial_wake_trigger(int enable);
144#else
145#define omap_serial_wakeup_init() {}
146#define omap_serial_wake_trigger(x) {}
147#endif /* CONFIG_OMAP_SERIAL_WAKE */
148
149#define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x)
150#define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x))
151#define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x]
152
153#define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x)
154#define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x))
155#define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x]
156
157#define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x)
158#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
159#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
160
161#define MPUI730_SAVE(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x] = omap_readl(x)
162#define MPUI730_RESTORE(x) omap_writel((mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]), (x))
163#define MPUI730_SHOW(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]
164
165#define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x)
166#define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x))
167#define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]
168
169#define MPUI1610_SAVE(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] = omap_readl(x)
170#define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x))
171#define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]
172
173#define OMAP24XX_SAVE(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x] = x
174#define OMAP24XX_RESTORE(x) x = omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
175#define OMAP24XX_SHOW(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
176
177/*
178 * List of global OMAP registers to preserve.
179 * More ones like CP and general purpose register values are preserved
180 * with the stack pointer in sleep.S.
181 */
182
183enum arm_save_state {
184 ARM_SLEEP_SAVE_START = 0,
185 /*
186 * MPU control registers 32 bits
187 */
188 ARM_SLEEP_SAVE_ARM_CKCTL,
189 ARM_SLEEP_SAVE_ARM_IDLECT1,
190 ARM_SLEEP_SAVE_ARM_IDLECT2,
191 ARM_SLEEP_SAVE_ARM_IDLECT3,
192 ARM_SLEEP_SAVE_ARM_EWUPCT,
193 ARM_SLEEP_SAVE_ARM_RSTCT1,
194 ARM_SLEEP_SAVE_ARM_RSTCT2,
195 ARM_SLEEP_SAVE_ARM_SYSST,
196 ARM_SLEEP_SAVE_SIZE
197};
198
199enum dsp_save_state {
200 DSP_SLEEP_SAVE_START = 0,
201 /*
202 * DSP registers 16 bits
203 */
204 DSP_SLEEP_SAVE_DSP_IDLECT2,
205 DSP_SLEEP_SAVE_SIZE
206};
207
208enum ulpd_save_state {
209 ULPD_SLEEP_SAVE_START = 0,
210 /*
211 * ULPD registers 16 bits
212 */
213 ULPD_SLEEP_SAVE_ULPD_IT_STATUS,
214 ULPD_SLEEP_SAVE_ULPD_CLOCK_CTRL,
215 ULPD_SLEEP_SAVE_ULPD_SOFT_REQ,
216 ULPD_SLEEP_SAVE_ULPD_STATUS_REQ,
217 ULPD_SLEEP_SAVE_ULPD_DPLL_CTRL,
218 ULPD_SLEEP_SAVE_ULPD_POWER_CTRL,
219 ULPD_SLEEP_SAVE_SIZE
220};
221
222enum mpui1510_save_state {
223 MPUI1510_SLEEP_SAVE_START = 0,
224 /*
225 * MPUI registers 32 bits
226 */
227 MPUI1510_SLEEP_SAVE_MPUI_CTRL,
228 MPUI1510_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
229 MPUI1510_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
230 MPUI1510_SLEEP_SAVE_MPUI_DSP_STATUS,
231 MPUI1510_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
232 MPUI1510_SLEEP_SAVE_EMIFS_CONFIG,
233 MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR,
234 MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR,
235#if defined(CONFIG_ARCH_OMAP15XX)
236 MPUI1510_SLEEP_SAVE_SIZE
237#else
238 MPUI1510_SLEEP_SAVE_SIZE = 0
239#endif
240};
241
242enum mpui730_save_state {
243 MPUI730_SLEEP_SAVE_START = 0,
244 /*
245 * MPUI registers 32 bits
246 */
247 MPUI730_SLEEP_SAVE_MPUI_CTRL,
248 MPUI730_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
249 MPUI730_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
250 MPUI730_SLEEP_SAVE_MPUI_DSP_STATUS,
251 MPUI730_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
252 MPUI730_SLEEP_SAVE_EMIFS_CONFIG,
253 MPUI730_SLEEP_SAVE_OMAP_IH1_MIR,
254 MPUI730_SLEEP_SAVE_OMAP_IH2_0_MIR,
255 MPUI730_SLEEP_SAVE_OMAP_IH2_1_MIR,
256#if defined(CONFIG_ARCH_OMAP730)
257 MPUI730_SLEEP_SAVE_SIZE
258#else
259 MPUI730_SLEEP_SAVE_SIZE = 0
260#endif
261};
262
263enum mpui1610_save_state {
264 MPUI1610_SLEEP_SAVE_START = 0,
265 /*
266 * MPUI registers 32 bits
267 */
268 MPUI1610_SLEEP_SAVE_MPUI_CTRL,
269 MPUI1610_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
270 MPUI1610_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
271 MPUI1610_SLEEP_SAVE_MPUI_DSP_STATUS,
272 MPUI1610_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
273 MPUI1610_SLEEP_SAVE_EMIFS_CONFIG,
274 MPUI1610_SLEEP_SAVE_OMAP_IH1_MIR,
275 MPUI1610_SLEEP_SAVE_OMAP_IH2_0_MIR,
276 MPUI1610_SLEEP_SAVE_OMAP_IH2_1_MIR,
277 MPUI1610_SLEEP_SAVE_OMAP_IH2_2_MIR,
278 MPUI1610_SLEEP_SAVE_OMAP_IH2_3_MIR,
279#if defined(CONFIG_ARCH_OMAP16XX)
280 MPUI1610_SLEEP_SAVE_SIZE
281#else
282 MPUI1610_SLEEP_SAVE_SIZE = 0
283#endif
284};
285
286enum omap24xx_save_state {
287 OMAP24XX_SLEEP_SAVE_START = 0,
288 OMAP24XX_SLEEP_SAVE_INTC_MIR0,
289 OMAP24XX_SLEEP_SAVE_INTC_MIR1,
290 OMAP24XX_SLEEP_SAVE_INTC_MIR2,
291
292 OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_MPU,
293 OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_CORE,
294 OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_GFX,
295 OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_DSP,
296 OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_MDM,
297
298 OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_MPU,
299 OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_CORE,
300 OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_GFX,
301 OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_DSP,
302 OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_MDM,
303
304 OMAP24XX_SLEEP_SAVE_CM_IDLEST1_CORE,
305 OMAP24XX_SLEEP_SAVE_CM_IDLEST2_CORE,
306 OMAP24XX_SLEEP_SAVE_CM_IDLEST3_CORE,
307 OMAP24XX_SLEEP_SAVE_CM_IDLEST4_CORE,
308 OMAP24XX_SLEEP_SAVE_CM_IDLEST_GFX,
309 OMAP24XX_SLEEP_SAVE_CM_IDLEST_WKUP,
310 OMAP24XX_SLEEP_SAVE_CM_IDLEST_CKGEN,
311 OMAP24XX_SLEEP_SAVE_CM_IDLEST_DSP,
312 OMAP24XX_SLEEP_SAVE_CM_IDLEST_MDM,
313
314 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE1_CORE,
315 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE2_CORE,
316 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE3_CORE,
317 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE4_CORE,
318 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_WKUP,
319 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_PLL,
320 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_DSP,
321 OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_MDM,
322
323 OMAP24XX_SLEEP_SAVE_CM_FCLKEN1_CORE,
324 OMAP24XX_SLEEP_SAVE_CM_FCLKEN2_CORE,
325 OMAP24XX_SLEEP_SAVE_CM_ICLKEN1_CORE,
326 OMAP24XX_SLEEP_SAVE_CM_ICLKEN2_CORE,
327 OMAP24XX_SLEEP_SAVE_CM_ICLKEN3_CORE,
328 OMAP24XX_SLEEP_SAVE_CM_ICLKEN4_CORE,
329 OMAP24XX_SLEEP_SAVE_GPIO1_IRQENABLE1,
330 OMAP24XX_SLEEP_SAVE_GPIO2_IRQENABLE1,
331 OMAP24XX_SLEEP_SAVE_GPIO3_IRQENABLE1,
332 OMAP24XX_SLEEP_SAVE_GPIO4_IRQENABLE1,
333 OMAP24XX_SLEEP_SAVE_GPIO3_OE,
334 OMAP24XX_SLEEP_SAVE_GPIO4_OE,
335 OMAP24XX_SLEEP_SAVE_GPIO3_RISINGDETECT,
336 OMAP24XX_SLEEP_SAVE_GPIO3_FALLINGDETECT,
337 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SPI1_NCS2,
338 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_MCBSP1_DX,
339 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SSI1_FLAG_TX,
340 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SYS_NIRQW0,
341 OMAP24XX_SLEEP_SAVE_SIZE
342};
343
344#endif /* ASSEMBLER */
345#endif /* __ASM_ARCH_OMAP_PM_H */
diff --git a/arch/arm/plat-omap/include/mach/serial.h b/arch/arm/plat-omap/include/mach/serial.h
index 8a676a04be48..13abd02d1527 100644
--- a/arch/arm/plat-omap/include/mach/serial.h
+++ b/arch/arm/plat-omap/include/mach/serial.h
@@ -1,5 +1,8 @@
1/* 1/*
2 * arch/arm/plat-omap/include/mach/serial.h 2 * arch/arm/plat-omap/include/mach/serial.h
3 *
4 * Copyright (C) 2009 Texas Instruments
5 * Addded OMAP4 support- Santosh Shilimkar <santosh.shilimkar@ti.com>
3 * 6 *
4 * This program is distributed in the hope that it will be useful, 7 * This program is distributed in the hope that it will be useful,
5 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,19 +18,28 @@
15#define OMAP_UART1_BASE 0xfffb0000 18#define OMAP_UART1_BASE 0xfffb0000
16#define OMAP_UART2_BASE 0xfffb0800 19#define OMAP_UART2_BASE 0xfffb0800
17#define OMAP_UART3_BASE 0xfffb9800 20#define OMAP_UART3_BASE 0xfffb9800
21#define OMAP_MAX_NR_PORTS 3
18#elif defined(CONFIG_ARCH_OMAP2) 22#elif defined(CONFIG_ARCH_OMAP2)
19/* OMAP2 serial ports */ 23/* OMAP2 serial ports */
20#define OMAP_UART1_BASE 0x4806a000 24#define OMAP_UART1_BASE 0x4806a000
21#define OMAP_UART2_BASE 0x4806c000 25#define OMAP_UART2_BASE 0x4806c000
22#define OMAP_UART3_BASE 0x4806e000 26#define OMAP_UART3_BASE 0x4806e000
27#define OMAP_MAX_NR_PORTS 3
23#elif defined(CONFIG_ARCH_OMAP3) 28#elif defined(CONFIG_ARCH_OMAP3)
24/* OMAP3 serial ports */ 29/* OMAP3 serial ports */
25#define OMAP_UART1_BASE 0x4806a000 30#define OMAP_UART1_BASE 0x4806a000
26#define OMAP_UART2_BASE 0x4806c000 31#define OMAP_UART2_BASE 0x4806c000
27#define OMAP_UART3_BASE 0x49020000 32#define OMAP_UART3_BASE 0x49020000
33#define OMAP_MAX_NR_PORTS 3
34#elif defined(CONFIG_ARCH_OMAP4)
35/* OMAP4 serial ports */
36#define OMAP_UART1_BASE 0x4806a000
37#define OMAP_UART2_BASE 0x4806c000
38#define OMAP_UART3_BASE 0x48020000
39#define OMAP_UART4_BASE 0x4806e000
40#define OMAP_MAX_NR_PORTS 4
28#endif 41#endif
29 42
30#define OMAP_MAX_NR_PORTS 3
31#define OMAP1510_BASE_BAUD (12000000/16) 43#define OMAP1510_BASE_BAUD (12000000/16)
32#define OMAP16XX_BASE_BAUD (48000000/16) 44#define OMAP16XX_BASE_BAUD (48000000/16)
33#define OMAP24XX_BASE_BAUD (48000000/16) 45#define OMAP24XX_BASE_BAUD (48000000/16)
@@ -40,4 +52,13 @@
40 __ret; \ 52 __ret; \
41 }) 53 })
42 54
55#ifndef __ASSEMBLER__
56extern void omap_serial_init(void);
57extern int omap_uart_can_sleep(void);
58extern void omap_uart_check_wakeup(void);
59extern void omap_uart_prepare_suspend(void);
60extern void omap_uart_prepare_idle(int num);
61extern void omap_uart_resume_idle(int num);
62#endif
63
43#endif 64#endif
diff --git a/arch/arm/plat-omap/include/mach/smp.h b/arch/arm/plat-omap/include/mach/smp.h
new file mode 100644
index 000000000000..dcaa8fde7063
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/smp.h
@@ -0,0 +1,51 @@
1/*
2 * OMAP4 machine specific smp.h
3 *
4 * Copyright (C) 2009 Texas Instruments, Inc.
5 *
6 * Author:
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * Interface functions needed for the SMP. This file is based on arm
10 * realview smp platform.
11 * Copyright (c) 2003 ARM Limited.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17#ifndef OMAP_ARCH_SMP_H
18#define OMAP_ARCH_SMP_H
19
20#include <asm/hardware/gic.h>
21
22/*
23 * set_event() is used to wake up secondary core from wfe using sev. ROM
24 * code puts the second core into wfe(standby).
25 *
26 */
27#define set_event() __asm__ __volatile__ ("sev" : : : "memory")
28
29/* Needed for secondary core boot */
30extern void omap_secondary_startup(void);
31
32/*
33 * We use Soft IRQ1 as the IPI
34 */
35static inline void smp_cross_call(const struct cpumask *mask)
36{
37 gic_raise_softirq(mask, 1);
38}
39
40/*
41 * Read MPIDR: Multiprocessor affinity register
42 */
43#define hard_smp_processor_id() \
44 ({ \
45 unsigned int cpunum; \
46 __asm__("mrc p15, 0, %0, c0, c0, 5" \
47 : "=r" (cpunum)); \
48 cpunum &= 0x0F; \
49 })
50
51#endif
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index ab35d622dcf5..dca7c16ae903 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -23,7 +23,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
23 23
24extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, 24extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
25 u32 sdrc_actim_ctrla, 25 u32 sdrc_actim_ctrla,
26 u32 sdrc_actim_ctrlb, u32 m2); 26 u32 sdrc_actim_ctrlb, u32 m2,
27 u32 unlock_dll);
27 28
28/* Do not use these */ 29/* Do not use these */
29extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); 30extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
@@ -60,7 +61,8 @@ extern unsigned long omap243x_sram_reprogram_sdrc_sz;
60 61
61extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl, 62extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
62 u32 sdrc_actim_ctrla, 63 u32 sdrc_actim_ctrla,
63 u32 sdrc_actim_ctrlb, u32 m2); 64 u32 sdrc_actim_ctrlb, u32 m2,
65 u32 unlock_dll);
64extern unsigned long omap3_sram_configure_core_dpll_sz; 66extern unsigned long omap3_sram_configure_core_dpll_sz;
65 67
66#endif 68#endif
diff --git a/arch/arm/plat-omap/include/mach/usb.h b/arch/arm/plat-omap/include/mach/usb.h
index 69f0ceed500b..f337e1761e2c 100644
--- a/arch/arm/plat-omap/include/mach/usb.h
+++ b/arch/arm/plat-omap/include/mach/usb.h
@@ -27,13 +27,7 @@
27#define UDC_BASE OMAP2_UDC_BASE 27#define UDC_BASE OMAP2_UDC_BASE
28#define OMAP_OHCI_BASE OMAP2_OHCI_BASE 28#define OMAP_OHCI_BASE OMAP2_OHCI_BASE
29 29
30#ifdef CONFIG_USB_MUSB_SOC
31extern void usb_musb_init(void); 30extern void usb_musb_init(void);
32#else
33static inline void usb_musb_init(void)
34{
35}
36#endif
37 31
38#endif 32#endif
39 33
diff --git a/arch/arm/plat-omap/include/mach/vmalloc.h b/arch/arm/plat-omap/include/mach/vmalloc.h
index dc104cd96197..b97dfafeebda 100644
--- a/arch/arm/plat-omap/include/mach/vmalloc.h
+++ b/arch/arm/plat-omap/include/mach/vmalloc.h
@@ -17,5 +17,5 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 20#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
21 21
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
index af326efc1ad3..9b42d72d96cf 100644
--- a/arch/arm/plat-omap/io.c
+++ b/arch/arm/plat-omap/io.c
@@ -1,3 +1,14 @@
1/*
2 * Common io.c file
3 * This file is created by Russell King <rmk+kernel@arm.linux.org.uk>
4 *
5 * Copyright (C) 2009 Texas Instruments
6 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
1#include <linux/module.h> 12#include <linux/module.h>
2#include <linux/io.h> 13#include <linux/io.h>
3#include <linux/mm.h> 14#include <linux/mm.h>
@@ -7,6 +18,7 @@
7#include <mach/omap16xx.h> 18#include <mach/omap16xx.h>
8#include <mach/omap24xx.h> 19#include <mach/omap24xx.h>
9#include <mach/omap34xx.h> 20#include <mach/omap34xx.h>
21#include <mach/omap44xx.h>
10 22
11#define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz))) 23#define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz)))
12#define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst))) 24#define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst)))
@@ -92,7 +104,22 @@ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
92 return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT); 104 return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT);
93 } 105 }
94#endif 106#endif
95 107#ifdef CONFIG_ARCH_OMAP4
108 if (cpu_is_omap44xx()) {
109 if (BETWEEN(p, L3_44XX_PHYS, L3_44XX_SIZE))
110 return XLATE(p, L3_44XX_PHYS, L3_44XX_VIRT);
111 if (BETWEEN(p, L4_44XX_PHYS, L4_44XX_SIZE))
112 return XLATE(p, L4_44XX_PHYS, L4_44XX_VIRT);
113 if (BETWEEN(p, L4_WK_44XX_PHYS, L4_WK_44XX_SIZE))
114 return XLATE(p, L4_WK_44XX_PHYS, L4_WK_44XX_VIRT);
115 if (BETWEEN(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_SIZE))
116 return XLATE(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_VIRT);
117 if (BETWEEN(p, L4_PER_44XX_PHYS, L4_PER_44XX_SIZE))
118 return XLATE(p, L4_PER_44XX_PHYS, L4_PER_44XX_VIRT);
119 if (BETWEEN(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_SIZE))
120 return XLATE(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_VIRT);
121 }
122#endif
96 return __arm_ioremap(p, size, type); 123 return __arm_ioremap(p, size, type);
97} 124}
98EXPORT_SYMBOL(omap_ioremap); 125EXPORT_SYMBOL(omap_ioremap);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
new file mode 100644
index 000000000000..4cf449fa2cb5
--- /dev/null
+++ b/arch/arm/plat-omap/iommu.c
@@ -0,0 +1,996 @@
1/*
2 * omap iommu: tlb and pagetable primitives
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
7 * Paul Mundt and Toshihiro Kobayashi
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/err.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/clk.h>
19#include <linux/platform_device.h>
20
21#include <asm/cacheflush.h>
22
23#include <mach/iommu.h>
24
25#include "iopgtable.h"
26
27/* accommodate the difference between omap1 and omap2/3 */
28static const struct iommu_functions *arch_iommu;
29
30static struct platform_driver omap_iommu_driver;
31static struct kmem_cache *iopte_cachep;
32
33/**
34 * install_iommu_arch - Install archtecure specific iommu functions
35 * @ops: a pointer to architecture specific iommu functions
36 *
37 * There are several kind of iommu algorithm(tlb, pagetable) among
38 * omap series. This interface installs such an iommu algorighm.
39 **/
40int install_iommu_arch(const struct iommu_functions *ops)
41{
42 if (arch_iommu)
43 return -EBUSY;
44
45 arch_iommu = ops;
46 return 0;
47}
48EXPORT_SYMBOL_GPL(install_iommu_arch);
49
50/**
51 * uninstall_iommu_arch - Uninstall archtecure specific iommu functions
52 * @ops: a pointer to architecture specific iommu functions
53 *
54 * This interface uninstalls the iommu algorighm installed previously.
55 **/
56void uninstall_iommu_arch(const struct iommu_functions *ops)
57{
58 if (arch_iommu != ops)
59 pr_err("%s: not your arch\n", __func__);
60
61 arch_iommu = NULL;
62}
63EXPORT_SYMBOL_GPL(uninstall_iommu_arch);
64
65/**
66 * iommu_save_ctx - Save registers for pm off-mode support
67 * @obj: target iommu
68 **/
69void iommu_save_ctx(struct iommu *obj)
70{
71 arch_iommu->save_ctx(obj);
72}
73EXPORT_SYMBOL_GPL(iommu_save_ctx);
74
75/**
76 * iommu_restore_ctx - Restore registers for pm off-mode support
77 * @obj: target iommu
78 **/
79void iommu_restore_ctx(struct iommu *obj)
80{
81 arch_iommu->restore_ctx(obj);
82}
83EXPORT_SYMBOL_GPL(iommu_restore_ctx);
84
85/**
86 * iommu_arch_version - Return running iommu arch version
87 **/
88u32 iommu_arch_version(void)
89{
90 return arch_iommu->version;
91}
92EXPORT_SYMBOL_GPL(iommu_arch_version);
93
94static int iommu_enable(struct iommu *obj)
95{
96 int err;
97
98 if (!obj)
99 return -EINVAL;
100
101 clk_enable(obj->clk);
102
103 err = arch_iommu->enable(obj);
104
105 clk_disable(obj->clk);
106 return err;
107}
108
109static void iommu_disable(struct iommu *obj)
110{
111 if (!obj)
112 return;
113
114 clk_enable(obj->clk);
115
116 arch_iommu->disable(obj);
117
118 clk_disable(obj->clk);
119}
120
121/*
122 * TLB operations
123 */
124void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
125{
126 BUG_ON(!cr || !e);
127
128 arch_iommu->cr_to_e(cr, e);
129}
130EXPORT_SYMBOL_GPL(iotlb_cr_to_e);
131
132static inline int iotlb_cr_valid(struct cr_regs *cr)
133{
134 if (!cr)
135 return -EINVAL;
136
137 return arch_iommu->cr_valid(cr);
138}
139
140static inline struct cr_regs *iotlb_alloc_cr(struct iommu *obj,
141 struct iotlb_entry *e)
142{
143 if (!e)
144 return NULL;
145
146 return arch_iommu->alloc_cr(obj, e);
147}
148
149u32 iotlb_cr_to_virt(struct cr_regs *cr)
150{
151 return arch_iommu->cr_to_virt(cr);
152}
153EXPORT_SYMBOL_GPL(iotlb_cr_to_virt);
154
155static u32 get_iopte_attr(struct iotlb_entry *e)
156{
157 return arch_iommu->get_pte_attr(e);
158}
159
160static u32 iommu_report_fault(struct iommu *obj, u32 *da)
161{
162 return arch_iommu->fault_isr(obj, da);
163}
164
165static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l)
166{
167 u32 val;
168
169 val = iommu_read_reg(obj, MMU_LOCK);
170
171 l->base = MMU_LOCK_BASE(val);
172 l->vict = MMU_LOCK_VICT(val);
173
174 BUG_ON(l->base != 0); /* Currently no preservation is used */
175}
176
177static void iotlb_lock_set(struct iommu *obj, struct iotlb_lock *l)
178{
179 u32 val;
180
181 BUG_ON(l->base != 0); /* Currently no preservation is used */
182
183 val = (l->base << MMU_LOCK_BASE_SHIFT);
184 val |= (l->vict << MMU_LOCK_VICT_SHIFT);
185
186 iommu_write_reg(obj, val, MMU_LOCK);
187}
188
189static void iotlb_read_cr(struct iommu *obj, struct cr_regs *cr)
190{
191 arch_iommu->tlb_read_cr(obj, cr);
192}
193
194static void iotlb_load_cr(struct iommu *obj, struct cr_regs *cr)
195{
196 arch_iommu->tlb_load_cr(obj, cr);
197
198 iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
199 iommu_write_reg(obj, 1, MMU_LD_TLB);
200}
201
202/**
203 * iotlb_dump_cr - Dump an iommu tlb entry into buf
204 * @obj: target iommu
205 * @cr: contents of cam and ram register
206 * @buf: output buffer
207 **/
208static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
209 char *buf)
210{
211 BUG_ON(!cr || !buf);
212
213 return arch_iommu->dump_cr(obj, cr, buf);
214}
215
216/**
217 * load_iotlb_entry - Set an iommu tlb entry
218 * @obj: target iommu
219 * @e: an iommu tlb entry info
220 **/
221int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
222{
223 int i;
224 int err = 0;
225 struct iotlb_lock l;
226 struct cr_regs *cr;
227
228 if (!obj || !obj->nr_tlb_entries || !e)
229 return -EINVAL;
230
231 clk_enable(obj->clk);
232
233 for (i = 0; i < obj->nr_tlb_entries; i++) {
234 struct cr_regs tmp;
235
236 iotlb_lock_get(obj, &l);
237 l.vict = i;
238 iotlb_lock_set(obj, &l);
239 iotlb_read_cr(obj, &tmp);
240 if (!iotlb_cr_valid(&tmp))
241 break;
242 }
243
244 if (i == obj->nr_tlb_entries) {
245 dev_dbg(obj->dev, "%s: full: no entry\n", __func__);
246 err = -EBUSY;
247 goto out;
248 }
249
250 cr = iotlb_alloc_cr(obj, e);
251 if (IS_ERR(cr)) {
252 clk_disable(obj->clk);
253 return PTR_ERR(cr);
254 }
255
256 iotlb_load_cr(obj, cr);
257 kfree(cr);
258
259 /* increment victim for next tlb load */
260 if (++l.vict == obj->nr_tlb_entries)
261 l.vict = 0;
262 iotlb_lock_set(obj, &l);
263out:
264 clk_disable(obj->clk);
265 return err;
266}
267EXPORT_SYMBOL_GPL(load_iotlb_entry);
268
269/**
270 * flush_iotlb_page - Clear an iommu tlb entry
271 * @obj: target iommu
272 * @da: iommu device virtual address
273 *
274 * Clear an iommu tlb entry which includes 'da' address.
275 **/
276void flush_iotlb_page(struct iommu *obj, u32 da)
277{
278 struct iotlb_lock l;
279 int i;
280
281 clk_enable(obj->clk);
282
283 for (i = 0; i < obj->nr_tlb_entries; i++) {
284 struct cr_regs cr;
285 u32 start;
286 size_t bytes;
287
288 iotlb_lock_get(obj, &l);
289 l.vict = i;
290 iotlb_lock_set(obj, &l);
291 iotlb_read_cr(obj, &cr);
292 if (!iotlb_cr_valid(&cr))
293 continue;
294
295 start = iotlb_cr_to_virt(&cr);
296 bytes = iopgsz_to_bytes(cr.cam & 3);
297
298 if ((start <= da) && (da < start + bytes)) {
299 dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
300 __func__, start, da, bytes);
301
302 iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
303 }
304 }
305 clk_disable(obj->clk);
306
307 if (i == obj->nr_tlb_entries)
308 dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da);
309}
310EXPORT_SYMBOL_GPL(flush_iotlb_page);
311
312/**
313 * flush_iotlb_range - Clear an iommu tlb entries
314 * @obj: target iommu
315 * @start: iommu device virtual address(start)
316 * @end: iommu device virtual address(end)
317 *
318 * Clear an iommu tlb entry which includes 'da' address.
319 **/
320void flush_iotlb_range(struct iommu *obj, u32 start, u32 end)
321{
322 u32 da = start;
323
324 while (da < end) {
325 flush_iotlb_page(obj, da);
326 /* FIXME: Optimize for multiple page size */
327 da += IOPTE_SIZE;
328 }
329}
330EXPORT_SYMBOL_GPL(flush_iotlb_range);
331
332/**
333 * flush_iotlb_all - Clear all iommu tlb entries
334 * @obj: target iommu
335 **/
336void flush_iotlb_all(struct iommu *obj)
337{
338 struct iotlb_lock l;
339
340 clk_enable(obj->clk);
341
342 l.base = 0;
343 l.vict = 0;
344 iotlb_lock_set(obj, &l);
345
346 iommu_write_reg(obj, 1, MMU_GFLUSH);
347
348 clk_disable(obj->clk);
349}
350EXPORT_SYMBOL_GPL(flush_iotlb_all);
351
352#if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
353
354ssize_t iommu_dump_ctx(struct iommu *obj, char *buf)
355{
356 ssize_t bytes;
357
358 if (!obj || !buf)
359 return -EINVAL;
360
361 clk_enable(obj->clk);
362
363 bytes = arch_iommu->dump_ctx(obj, buf);
364
365 clk_disable(obj->clk);
366
367 return bytes;
368}
369EXPORT_SYMBOL_GPL(iommu_dump_ctx);
370
371static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs)
372{
373 int i;
374 struct iotlb_lock saved, l;
375 struct cr_regs *p = crs;
376
377 clk_enable(obj->clk);
378
379 iotlb_lock_get(obj, &saved);
380 memcpy(&l, &saved, sizeof(saved));
381
382 for (i = 0; i < obj->nr_tlb_entries; i++) {
383 struct cr_regs tmp;
384
385 iotlb_lock_get(obj, &l);
386 l.vict = i;
387 iotlb_lock_set(obj, &l);
388 iotlb_read_cr(obj, &tmp);
389 if (!iotlb_cr_valid(&tmp))
390 continue;
391
392 *p++ = tmp;
393 }
394 iotlb_lock_set(obj, &saved);
395 clk_disable(obj->clk);
396
397 return p - crs;
398}
399
400/**
401 * dump_tlb_entries - dump cr arrays to given buffer
402 * @obj: target iommu
403 * @buf: output buffer
404 **/
405size_t dump_tlb_entries(struct iommu *obj, char *buf)
406{
407 int i, n;
408 struct cr_regs *cr;
409 char *p = buf;
410
411 cr = kcalloc(obj->nr_tlb_entries, sizeof(*cr), GFP_KERNEL);
412 if (!cr)
413 return 0;
414
415 n = __dump_tlb_entries(obj, cr);
416 for (i = 0; i < n; i++)
417 p += iotlb_dump_cr(obj, cr + i, p);
418 kfree(cr);
419
420 return p - buf;
421}
422EXPORT_SYMBOL_GPL(dump_tlb_entries);
423
424int foreach_iommu_device(void *data, int (*fn)(struct device *, void *))
425{
426 return driver_for_each_device(&omap_iommu_driver.driver,
427 NULL, data, fn);
428}
429EXPORT_SYMBOL_GPL(foreach_iommu_device);
430
431#endif /* CONFIG_OMAP_IOMMU_DEBUG_MODULE */
432
433/*
434 * H/W pagetable operations
435 */
436static void flush_iopgd_range(u32 *first, u32 *last)
437{
438 /* FIXME: L2 cache should be taken care of if it exists */
439 do {
440 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pgd"
441 : : "r" (first));
442 first += L1_CACHE_BYTES / sizeof(*first);
443 } while (first <= last);
444}
445
446static void flush_iopte_range(u32 *first, u32 *last)
447{
448 /* FIXME: L2 cache should be taken care of if it exists */
449 do {
450 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pte"
451 : : "r" (first));
452 first += L1_CACHE_BYTES / sizeof(*first);
453 } while (first <= last);
454}
455
456static void iopte_free(u32 *iopte)
457{
458 /* Note: freed iopte's must be clean ready for re-use */
459 kmem_cache_free(iopte_cachep, iopte);
460}
461
462static u32 *iopte_alloc(struct iommu *obj, u32 *iopgd, u32 da)
463{
464 u32 *iopte;
465
466 /* a table has already existed */
467 if (*iopgd)
468 goto pte_ready;
469
470 /*
471 * do the allocation outside the page table lock
472 */
473 spin_unlock(&obj->page_table_lock);
474 iopte = kmem_cache_zalloc(iopte_cachep, GFP_KERNEL);
475 spin_lock(&obj->page_table_lock);
476
477 if (!*iopgd) {
478 if (!iopte)
479 return ERR_PTR(-ENOMEM);
480
481 *iopgd = virt_to_phys(iopte) | IOPGD_TABLE;
482 flush_iopgd_range(iopgd, iopgd);
483
484 dev_vdbg(obj->dev, "%s: a new pte:%p\n", __func__, iopte);
485 } else {
486 /* We raced, free the reduniovant table */
487 iopte_free(iopte);
488 }
489
490pte_ready:
491 iopte = iopte_offset(iopgd, da);
492
493 dev_vdbg(obj->dev,
494 "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
495 __func__, da, iopgd, *iopgd, iopte, *iopte);
496
497 return iopte;
498}
499
500static int iopgd_alloc_section(struct iommu *obj, u32 da, u32 pa, u32 prot)
501{
502 u32 *iopgd = iopgd_offset(obj, da);
503
504 *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION;
505 flush_iopgd_range(iopgd, iopgd);
506 return 0;
507}
508
509static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot)
510{
511 u32 *iopgd = iopgd_offset(obj, da);
512 int i;
513
514 for (i = 0; i < 16; i++)
515 *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER;
516 flush_iopgd_range(iopgd, iopgd + 15);
517 return 0;
518}
519
520static int iopte_alloc_page(struct iommu *obj, u32 da, u32 pa, u32 prot)
521{
522 u32 *iopgd = iopgd_offset(obj, da);
523 u32 *iopte = iopte_alloc(obj, iopgd, da);
524
525 if (IS_ERR(iopte))
526 return PTR_ERR(iopte);
527
528 *iopte = (pa & IOPAGE_MASK) | prot | IOPTE_SMALL;
529 flush_iopte_range(iopte, iopte);
530
531 dev_vdbg(obj->dev, "%s: da:%08x pa:%08x pte:%p *pte:%08x\n",
532 __func__, da, pa, iopte, *iopte);
533
534 return 0;
535}
536
537static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot)
538{
539 u32 *iopgd = iopgd_offset(obj, da);
540 u32 *iopte = iopte_alloc(obj, iopgd, da);
541 int i;
542
543 if (IS_ERR(iopte))
544 return PTR_ERR(iopte);
545
546 for (i = 0; i < 16; i++)
547 *(iopte + i) = (pa & IOLARGE_MASK) | prot | IOPTE_LARGE;
548 flush_iopte_range(iopte, iopte + 15);
549 return 0;
550}
551
552static int iopgtable_store_entry_core(struct iommu *obj, struct iotlb_entry *e)
553{
554 int (*fn)(struct iommu *, u32, u32, u32);
555 u32 prot;
556 int err;
557
558 if (!obj || !e)
559 return -EINVAL;
560
561 switch (e->pgsz) {
562 case MMU_CAM_PGSZ_16M:
563 fn = iopgd_alloc_super;
564 break;
565 case MMU_CAM_PGSZ_1M:
566 fn = iopgd_alloc_section;
567 break;
568 case MMU_CAM_PGSZ_64K:
569 fn = iopte_alloc_large;
570 break;
571 case MMU_CAM_PGSZ_4K:
572 fn = iopte_alloc_page;
573 break;
574 default:
575 fn = NULL;
576 BUG();
577 break;
578 }
579
580 prot = get_iopte_attr(e);
581
582 spin_lock(&obj->page_table_lock);
583 err = fn(obj, e->da, e->pa, prot);
584 spin_unlock(&obj->page_table_lock);
585
586 return err;
587}
588
589/**
590 * iopgtable_store_entry - Make an iommu pte entry
591 * @obj: target iommu
592 * @e: an iommu tlb entry info
593 **/
594int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e)
595{
596 int err;
597
598 flush_iotlb_page(obj, e->da);
599 err = iopgtable_store_entry_core(obj, e);
600#ifdef PREFETCH_IOTLB
601 if (!err)
602 load_iotlb_entry(obj, e);
603#endif
604 return err;
605}
606EXPORT_SYMBOL_GPL(iopgtable_store_entry);
607
608/**
609 * iopgtable_lookup_entry - Lookup an iommu pte entry
610 * @obj: target iommu
611 * @da: iommu device virtual address
612 * @ppgd: iommu pgd entry pointer to be returned
613 * @ppte: iommu pte entry pointer to be returned
614 **/
615void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte)
616{
617 u32 *iopgd, *iopte = NULL;
618
619 iopgd = iopgd_offset(obj, da);
620 if (!*iopgd)
621 goto out;
622
623 if (*iopgd & IOPGD_TABLE)
624 iopte = iopte_offset(iopgd, da);
625out:
626 *ppgd = iopgd;
627 *ppte = iopte;
628}
629EXPORT_SYMBOL_GPL(iopgtable_lookup_entry);
630
631static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da)
632{
633 size_t bytes;
634 u32 *iopgd = iopgd_offset(obj, da);
635 int nent = 1;
636
637 if (!*iopgd)
638 return 0;
639
640 if (*iopgd & IOPGD_TABLE) {
641 int i;
642 u32 *iopte = iopte_offset(iopgd, da);
643
644 bytes = IOPTE_SIZE;
645 if (*iopte & IOPTE_LARGE) {
646 nent *= 16;
647 /* rewind to the 1st entry */
648 iopte = (u32 *)((u32)iopte & IOLARGE_MASK);
649 }
650 bytes *= nent;
651 memset(iopte, 0, nent * sizeof(*iopte));
652 flush_iopte_range(iopte, iopte + (nent - 1) * sizeof(*iopte));
653
654 /*
655 * do table walk to check if this table is necessary or not
656 */
657 iopte = iopte_offset(iopgd, 0);
658 for (i = 0; i < PTRS_PER_IOPTE; i++)
659 if (iopte[i])
660 goto out;
661
662 iopte_free(iopte);
663 nent = 1; /* for the next L1 entry */
664 } else {
665 bytes = IOPGD_SIZE;
666 if (*iopgd & IOPGD_SUPER) {
667 nent *= 16;
668 /* rewind to the 1st entry */
669 iopgd = (u32 *)((u32)iopgd & IOSUPER_MASK);
670 }
671 bytes *= nent;
672 }
673 memset(iopgd, 0, nent * sizeof(*iopgd));
674 flush_iopgd_range(iopgd, iopgd + (nent - 1) * sizeof(*iopgd));
675out:
676 return bytes;
677}
678
679/**
680 * iopgtable_clear_entry - Remove an iommu pte entry
681 * @obj: target iommu
682 * @da: iommu device virtual address
683 **/
684size_t iopgtable_clear_entry(struct iommu *obj, u32 da)
685{
686 size_t bytes;
687
688 spin_lock(&obj->page_table_lock);
689
690 bytes = iopgtable_clear_entry_core(obj, da);
691 flush_iotlb_page(obj, da);
692
693 spin_unlock(&obj->page_table_lock);
694
695 return bytes;
696}
697EXPORT_SYMBOL_GPL(iopgtable_clear_entry);
698
699static void iopgtable_clear_entry_all(struct iommu *obj)
700{
701 int i;
702
703 spin_lock(&obj->page_table_lock);
704
705 for (i = 0; i < PTRS_PER_IOPGD; i++) {
706 u32 da;
707 u32 *iopgd;
708
709 da = i << IOPGD_SHIFT;
710 iopgd = iopgd_offset(obj, da);
711
712 if (!*iopgd)
713 continue;
714
715 if (*iopgd & IOPGD_TABLE)
716 iopte_free(iopte_offset(iopgd, 0));
717
718 *iopgd = 0;
719 flush_iopgd_range(iopgd, iopgd);
720 }
721
722 flush_iotlb_all(obj);
723
724 spin_unlock(&obj->page_table_lock);
725}
726
727/*
728 * Device IOMMU generic operations
729 */
730static irqreturn_t iommu_fault_handler(int irq, void *data)
731{
732 u32 stat, da;
733 u32 *iopgd, *iopte;
734 int err = -EIO;
735 struct iommu *obj = data;
736
737 if (!obj->refcount)
738 return IRQ_NONE;
739
740 /* Dynamic loading TLB or PTE */
741 if (obj->isr)
742 err = obj->isr(obj);
743
744 if (!err)
745 return IRQ_HANDLED;
746
747 clk_enable(obj->clk);
748 stat = iommu_report_fault(obj, &da);
749 clk_disable(obj->clk);
750 if (!stat)
751 return IRQ_HANDLED;
752
753 iopgd = iopgd_offset(obj, da);
754
755 if (!(*iopgd & IOPGD_TABLE)) {
756 dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__,
757 da, iopgd, *iopgd);
758 return IRQ_NONE;
759 }
760
761 iopte = iopte_offset(iopgd, da);
762
763 dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
764 __func__, da, iopgd, *iopgd, iopte, *iopte);
765
766 return IRQ_NONE;
767}
768
769static int device_match_by_alias(struct device *dev, void *data)
770{
771 struct iommu *obj = to_iommu(dev);
772 const char *name = data;
773
774 pr_debug("%s: %s %s\n", __func__, obj->name, name);
775
776 return strcmp(obj->name, name) == 0;
777}
778
779/**
780 * iommu_get - Get iommu handler
781 * @name: target iommu name
782 **/
783struct iommu *iommu_get(const char *name)
784{
785 int err = -ENOMEM;
786 struct device *dev;
787 struct iommu *obj;
788
789 dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
790 device_match_by_alias);
791 if (!dev)
792 return ERR_PTR(-ENODEV);
793
794 obj = to_iommu(dev);
795
796 mutex_lock(&obj->iommu_lock);
797
798 if (obj->refcount++ == 0) {
799 err = iommu_enable(obj);
800 if (err)
801 goto err_enable;
802 flush_iotlb_all(obj);
803 }
804
805 if (!try_module_get(obj->owner))
806 goto err_module;
807
808 mutex_unlock(&obj->iommu_lock);
809
810 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
811 return obj;
812
813err_module:
814 if (obj->refcount == 1)
815 iommu_disable(obj);
816err_enable:
817 obj->refcount--;
818 mutex_unlock(&obj->iommu_lock);
819 return ERR_PTR(err);
820}
821EXPORT_SYMBOL_GPL(iommu_get);
822
823/**
824 * iommu_put - Put back iommu handler
825 * @obj: target iommu
826 **/
827void iommu_put(struct iommu *obj)
828{
829 if (!obj && IS_ERR(obj))
830 return;
831
832 mutex_lock(&obj->iommu_lock);
833
834 if (--obj->refcount == 0)
835 iommu_disable(obj);
836
837 module_put(obj->owner);
838
839 mutex_unlock(&obj->iommu_lock);
840
841 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
842}
843EXPORT_SYMBOL_GPL(iommu_put);
844
845/*
846 * OMAP Device MMU(IOMMU) detection
847 */
848static int __devinit omap_iommu_probe(struct platform_device *pdev)
849{
850 int err = -ENODEV;
851 void *p;
852 int irq;
853 struct iommu *obj;
854 struct resource *res;
855 struct iommu_platform_data *pdata = pdev->dev.platform_data;
856
857 if (pdev->num_resources != 2)
858 return -EINVAL;
859
860 obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
861 if (!obj)
862 return -ENOMEM;
863
864 obj->clk = clk_get(&pdev->dev, pdata->clk_name);
865 if (IS_ERR(obj->clk))
866 goto err_clk;
867
868 obj->nr_tlb_entries = pdata->nr_tlb_entries;
869 obj->name = pdata->name;
870 obj->dev = &pdev->dev;
871 obj->ctx = (void *)obj + sizeof(*obj);
872
873 mutex_init(&obj->iommu_lock);
874 mutex_init(&obj->mmap_lock);
875 spin_lock_init(&obj->page_table_lock);
876 INIT_LIST_HEAD(&obj->mmap);
877
878 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
879 if (!res) {
880 err = -ENODEV;
881 goto err_mem;
882 }
883 obj->regbase = ioremap(res->start, resource_size(res));
884 if (!obj->regbase) {
885 err = -ENOMEM;
886 goto err_mem;
887 }
888
889 res = request_mem_region(res->start, resource_size(res),
890 dev_name(&pdev->dev));
891 if (!res) {
892 err = -EIO;
893 goto err_mem;
894 }
895
896 irq = platform_get_irq(pdev, 0);
897 if (irq < 0) {
898 err = -ENODEV;
899 goto err_irq;
900 }
901 err = request_irq(irq, iommu_fault_handler, IRQF_SHARED,
902 dev_name(&pdev->dev), obj);
903 if (err < 0)
904 goto err_irq;
905 platform_set_drvdata(pdev, obj);
906
907 p = (void *)__get_free_pages(GFP_KERNEL, get_order(IOPGD_TABLE_SIZE));
908 if (!p) {
909 err = -ENOMEM;
910 goto err_pgd;
911 }
912 memset(p, 0, IOPGD_TABLE_SIZE);
913 clean_dcache_area(p, IOPGD_TABLE_SIZE);
914 obj->iopgd = p;
915
916 BUG_ON(!IS_ALIGNED((unsigned long)obj->iopgd, IOPGD_TABLE_SIZE));
917
918 dev_info(&pdev->dev, "%s registered\n", obj->name);
919 return 0;
920
921err_pgd:
922 free_irq(irq, obj);
923err_irq:
924 release_mem_region(res->start, resource_size(res));
925 iounmap(obj->regbase);
926err_mem:
927 clk_put(obj->clk);
928err_clk:
929 kfree(obj);
930 return err;
931}
932
933static int __devexit omap_iommu_remove(struct platform_device *pdev)
934{
935 int irq;
936 struct resource *res;
937 struct iommu *obj = platform_get_drvdata(pdev);
938
939 platform_set_drvdata(pdev, NULL);
940
941 iopgtable_clear_entry_all(obj);
942 free_pages((unsigned long)obj->iopgd, get_order(IOPGD_TABLE_SIZE));
943
944 irq = platform_get_irq(pdev, 0);
945 free_irq(irq, obj);
946 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
947 release_mem_region(res->start, resource_size(res));
948 iounmap(obj->regbase);
949
950 clk_put(obj->clk);
951 dev_info(&pdev->dev, "%s removed\n", obj->name);
952 kfree(obj);
953 return 0;
954}
955
956static struct platform_driver omap_iommu_driver = {
957 .probe = omap_iommu_probe,
958 .remove = __devexit_p(omap_iommu_remove),
959 .driver = {
960 .name = "omap-iommu",
961 },
962};
963
964static void iopte_cachep_ctor(void *iopte)
965{
966 clean_dcache_area(iopte, IOPTE_TABLE_SIZE);
967}
968
969static int __init omap_iommu_init(void)
970{
971 struct kmem_cache *p;
972 const unsigned long flags = SLAB_HWCACHE_ALIGN;
973 size_t align = 1 << 10; /* L2 pagetable alignement */
974
975 p = kmem_cache_create("iopte_cache", IOPTE_TABLE_SIZE, align, flags,
976 iopte_cachep_ctor);
977 if (!p)
978 return -ENOMEM;
979 iopte_cachep = p;
980
981 return platform_driver_register(&omap_iommu_driver);
982}
983module_init(omap_iommu_init);
984
985static void __exit omap_iommu_exit(void)
986{
987 kmem_cache_destroy(iopte_cachep);
988
989 platform_driver_unregister(&omap_iommu_driver);
990}
991module_exit(omap_iommu_exit);
992
993MODULE_DESCRIPTION("omap iommu: tlb and pagetable primitives");
994MODULE_ALIAS("platform:omap-iommu");
995MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
996MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/iopgtable.h b/arch/arm/plat-omap/iopgtable.h
new file mode 100644
index 000000000000..37dac434c7a1
--- /dev/null
+++ b/arch/arm/plat-omap/iopgtable.h
@@ -0,0 +1,72 @@
1/*
2 * omap iommu: pagetable definitions
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __PLAT_OMAP_IOMMU_H
14#define __PLAT_OMAP_IOMMU_H
15
16#define IOPGD_SHIFT 20
17#define IOPGD_SIZE (1 << IOPGD_SHIFT)
18#define IOPGD_MASK (~(IOPGD_SIZE - 1))
19#define IOSECTION_MASK IOPGD_MASK
20#define PTRS_PER_IOPGD (1 << (32 - IOPGD_SHIFT))
21#define IOPGD_TABLE_SIZE (PTRS_PER_IOPGD * sizeof(u32))
22
23#define IOSUPER_SIZE (IOPGD_SIZE << 4)
24#define IOSUPER_MASK (~(IOSUPER_SIZE - 1))
25
26#define IOPTE_SHIFT 12
27#define IOPTE_SIZE (1 << IOPTE_SHIFT)
28#define IOPTE_MASK (~(IOPTE_SIZE - 1))
29#define IOPAGE_MASK IOPTE_MASK
30#define PTRS_PER_IOPTE (1 << (IOPGD_SHIFT - IOPTE_SHIFT))
31#define IOPTE_TABLE_SIZE (PTRS_PER_IOPTE * sizeof(u32))
32
33#define IOLARGE_SIZE (IOPTE_SIZE << 4)
34#define IOLARGE_MASK (~(IOLARGE_SIZE - 1))
35
36#define IOPGD_TABLE (1 << 0)
37#define IOPGD_SECTION (2 << 0)
38#define IOPGD_SUPER (1 << 18 | 2 << 0)
39
40#define IOPTE_SMALL (2 << 0)
41#define IOPTE_LARGE (1 << 0)
42
43#define iopgd_index(da) (((da) >> IOPGD_SHIFT) & (PTRS_PER_IOPGD - 1))
44#define iopgd_offset(obj, da) ((obj)->iopgd + iopgd_index(da))
45
46#define iopte_paddr(iopgd) (*iopgd & ~((1 << 10) - 1))
47#define iopte_vaddr(iopgd) ((u32 *)phys_to_virt(iopte_paddr(iopgd)))
48
49#define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
50#define iopte_offset(iopgd, da) (iopte_vaddr(iopgd) + iopte_index(da))
51
52static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
53 u32 flags)
54{
55 memset(e, 0, sizeof(*e));
56
57 e->da = da;
58 e->pa = pa;
59 e->valid = 1;
60 /* FIXME: add OMAP1 support */
61 e->pgsz = flags & MMU_CAM_PGSZ_MASK;
62 e->endian = flags & MMU_RAM_ENDIAN_MASK;
63 e->elsz = flags & MMU_RAM_ELSZ_MASK;
64 e->mixed = flags & MMU_RAM_MIXED_MASK;
65
66 return iopgsz_to_bytes(e->pgsz);
67}
68
69#define to_iommu(dev) \
70 (struct iommu *)platform_get_drvdata(to_platform_device(dev))
71
72#endif /* __PLAT_OMAP_IOMMU_H */
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
new file mode 100644
index 000000000000..2fce2c151a95
--- /dev/null
+++ b/arch/arm/plat-omap/iovmm.c
@@ -0,0 +1,896 @@
1/*
2 * omap iommu: simple virtual address space management
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/err.h>
14#include <linux/vmalloc.h>
15#include <linux/device.h>
16#include <linux/scatterlist.h>
17
18#include <asm/cacheflush.h>
19#include <asm/mach/map.h>
20
21#include <mach/iommu.h>
22#include <mach/iovmm.h>
23
24#include "iopgtable.h"
25
26/*
27 * A device driver needs to create address mappings between:
28 *
29 * - iommu/device address
30 * - physical address
31 * - mpu virtual address
32 *
33 * There are 4 possible patterns for them:
34 *
35 * |iova/ mapping iommu_ page
36 * | da pa va (d)-(p)-(v) function type
37 * ---------------------------------------------------------------------------
38 * 1 | c c c 1 - 1 - 1 _kmap() / _kunmap() s
39 * 2 | c c,a c 1 - 1 - 1 _kmalloc()/ _kfree() s
40 * 3 | c d c 1 - n - 1 _vmap() / _vunmap() s
41 * 4 | c d,a c 1 - n - 1 _vmalloc()/ _vfree() n*
42 *
43 *
44 * 'iova': device iommu virtual address
45 * 'da': alias of 'iova'
46 * 'pa': physical address
47 * 'va': mpu virtual address
48 *
49 * 'c': contiguous memory area
50 * 'd': dicontiguous memory area
51 * 'a': anonymous memory allocation
52 * '()': optional feature
53 *
54 * 'n': a normal page(4KB) size is used.
55 * 's': multiple iommu superpage(16MB, 1MB, 64KB, 4KB) size is used.
56 *
57 * '*': not yet, but feasible.
58 */
59
60static struct kmem_cache *iovm_area_cachep;
61
62/* return total bytes of sg buffers */
63static size_t sgtable_len(const struct sg_table *sgt)
64{
65 unsigned int i, total = 0;
66 struct scatterlist *sg;
67
68 if (!sgt)
69 return 0;
70
71 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
72 size_t bytes;
73
74 bytes = sg_dma_len(sg);
75
76 if (!iopgsz_ok(bytes)) {
77 pr_err("%s: sg[%d] not iommu pagesize(%x)\n",
78 __func__, i, bytes);
79 return 0;
80 }
81
82 total += bytes;
83 }
84
85 return total;
86}
87#define sgtable_ok(x) (!!sgtable_len(x))
88
89/*
90 * calculate the optimal number sg elements from total bytes based on
91 * iommu superpages
92 */
93static unsigned int sgtable_nents(size_t bytes)
94{
95 int i;
96 unsigned int nr_entries;
97 const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
98
99 if (!IS_ALIGNED(bytes, PAGE_SIZE)) {
100 pr_err("%s: wrong size %08x\n", __func__, bytes);
101 return 0;
102 }
103
104 nr_entries = 0;
105 for (i = 0; i < ARRAY_SIZE(pagesize); i++) {
106 if (bytes >= pagesize[i]) {
107 nr_entries += (bytes / pagesize[i]);
108 bytes %= pagesize[i];
109 }
110 }
111 BUG_ON(bytes);
112
113 return nr_entries;
114}
115
116/* allocate and initialize sg_table header(a kind of 'superblock') */
117static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
118{
119 unsigned int nr_entries;
120 int err;
121 struct sg_table *sgt;
122
123 if (!bytes)
124 return ERR_PTR(-EINVAL);
125
126 if (!IS_ALIGNED(bytes, PAGE_SIZE))
127 return ERR_PTR(-EINVAL);
128
129 /* FIXME: IOVMF_DA_FIXED should support 'superpages' */
130 if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) {
131 nr_entries = sgtable_nents(bytes);
132 if (!nr_entries)
133 return ERR_PTR(-EINVAL);
134 } else
135 nr_entries = bytes / PAGE_SIZE;
136
137 sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
138 if (!sgt)
139 return ERR_PTR(-ENOMEM);
140
141 err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
142 if (err)
143 return ERR_PTR(err);
144
145 pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries);
146
147 return sgt;
148}
149
150/* free sg_table header(a kind of superblock) */
151static void sgtable_free(struct sg_table *sgt)
152{
153 if (!sgt)
154 return;
155
156 sg_free_table(sgt);
157 kfree(sgt);
158
159 pr_debug("%s: sgt:%p\n", __func__, sgt);
160}
161
162/* map 'sglist' to a contiguous mpu virtual area and return 'va' */
163static void *vmap_sg(const struct sg_table *sgt)
164{
165 u32 va;
166 size_t total;
167 unsigned int i;
168 struct scatterlist *sg;
169 struct vm_struct *new;
170 const struct mem_type *mtype;
171
172 mtype = get_mem_type(MT_DEVICE);
173 if (!mtype)
174 return ERR_PTR(-EINVAL);
175
176 total = sgtable_len(sgt);
177 if (!total)
178 return ERR_PTR(-EINVAL);
179
180 new = __get_vm_area(total, VM_IOREMAP, VMALLOC_START, VMALLOC_END);
181 if (!new)
182 return ERR_PTR(-ENOMEM);
183 va = (u32)new->addr;
184
185 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
186 size_t bytes;
187 u32 pa;
188 int err;
189
190 pa = sg_phys(sg);
191 bytes = sg_dma_len(sg);
192
193 BUG_ON(bytes != PAGE_SIZE);
194
195 err = ioremap_page(va, pa, mtype);
196 if (err)
197 goto err_out;
198
199 va += bytes;
200 }
201
202 flush_cache_vmap(new->addr, total);
203 return new->addr;
204
205err_out:
206 WARN_ON(1); /* FIXME: cleanup some mpu mappings */
207 vunmap(new->addr);
208 return ERR_PTR(-EAGAIN);
209}
210
211static inline void vunmap_sg(const void *va)
212{
213 vunmap(va);
214}
215
216static struct iovm_struct *__find_iovm_area(struct iommu *obj, const u32 da)
217{
218 struct iovm_struct *tmp;
219
220 list_for_each_entry(tmp, &obj->mmap, list) {
221 if ((da >= tmp->da_start) && (da < tmp->da_end)) {
222 size_t len;
223
224 len = tmp->da_end - tmp->da_start;
225
226 dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n",
227 __func__, tmp->da_start, da, tmp->da_end, len,
228 tmp->flags);
229
230 return tmp;
231 }
232 }
233
234 return NULL;
235}
236
237/**
238 * find_iovm_area - find iovma which includes @da
239 * @da: iommu device virtual address
240 *
241 * Find the existing iovma starting at @da
242 */
243struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da)
244{
245 struct iovm_struct *area;
246
247 mutex_lock(&obj->mmap_lock);
248 area = __find_iovm_area(obj, da);
249 mutex_unlock(&obj->mmap_lock);
250
251 return area;
252}
253EXPORT_SYMBOL_GPL(find_iovm_area);
254
255/*
256 * This finds the hole(area) which fits the requested address and len
257 * in iovmas mmap, and returns the new allocated iovma.
258 */
259static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
260 size_t bytes, u32 flags)
261{
262 struct iovm_struct *new, *tmp;
263 u32 start, prev_end, alignement;
264
265 if (!obj || !bytes)
266 return ERR_PTR(-EINVAL);
267
268 start = da;
269 alignement = PAGE_SIZE;
270
271 if (flags & IOVMF_DA_ANON) {
272 /*
273 * Reserve the first page for NULL
274 */
275 start = PAGE_SIZE;
276 if (flags & IOVMF_LINEAR)
277 alignement = iopgsz_max(bytes);
278 start = roundup(start, alignement);
279 }
280
281 tmp = NULL;
282 if (list_empty(&obj->mmap))
283 goto found;
284
285 prev_end = 0;
286 list_for_each_entry(tmp, &obj->mmap, list) {
287
288 if ((prev_end <= start) && (start + bytes < tmp->da_start))
289 goto found;
290
291 if (flags & IOVMF_DA_ANON)
292 start = roundup(tmp->da_end, alignement);
293
294 prev_end = tmp->da_end;
295 }
296
297 if ((start >= prev_end) && (ULONG_MAX - start >= bytes))
298 goto found;
299
300 dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n",
301 __func__, da, bytes, flags);
302
303 return ERR_PTR(-EINVAL);
304
305found:
306 new = kmem_cache_zalloc(iovm_area_cachep, GFP_KERNEL);
307 if (!new)
308 return ERR_PTR(-ENOMEM);
309
310 new->iommu = obj;
311 new->da_start = start;
312 new->da_end = start + bytes;
313 new->flags = flags;
314
315 /*
316 * keep ascending order of iovmas
317 */
318 if (tmp)
319 list_add_tail(&new->list, &tmp->list);
320 else
321 list_add(&new->list, &obj->mmap);
322
323 dev_dbg(obj->dev, "%s: found %08x-%08x-%08x(%x) %08x\n",
324 __func__, new->da_start, start, new->da_end, bytes, flags);
325
326 return new;
327}
328
329static void free_iovm_area(struct iommu *obj, struct iovm_struct *area)
330{
331 size_t bytes;
332
333 BUG_ON(!obj || !area);
334
335 bytes = area->da_end - area->da_start;
336
337 dev_dbg(obj->dev, "%s: %08x-%08x(%x) %08x\n",
338 __func__, area->da_start, area->da_end, bytes, area->flags);
339
340 list_del(&area->list);
341 kmem_cache_free(iovm_area_cachep, area);
342}
343
344/**
345 * da_to_va - convert (d) to (v)
346 * @obj: objective iommu
347 * @da: iommu device virtual address
348 * @va: mpu virtual address
349 *
350 * Returns mpu virtual addr which corresponds to a given device virtual addr
351 */
352void *da_to_va(struct iommu *obj, u32 da)
353{
354 void *va = NULL;
355 struct iovm_struct *area;
356
357 mutex_lock(&obj->mmap_lock);
358
359 area = __find_iovm_area(obj, da);
360 if (!area) {
361 dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
362 goto out;
363 }
364 va = area->va;
365 mutex_unlock(&obj->mmap_lock);
366out:
367 return va;
368}
369EXPORT_SYMBOL_GPL(da_to_va);
370
371static void sgtable_fill_vmalloc(struct sg_table *sgt, void *_va)
372{
373 unsigned int i;
374 struct scatterlist *sg;
375 void *va = _va;
376 void *va_end;
377
378 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
379 struct page *pg;
380 const size_t bytes = PAGE_SIZE;
381
382 /*
383 * iommu 'superpage' isn't supported with 'iommu_vmalloc()'
384 */
385 pg = vmalloc_to_page(va);
386 BUG_ON(!pg);
387 sg_set_page(sg, pg, bytes, 0);
388
389 va += bytes;
390 }
391
392 va_end = _va + PAGE_SIZE * i;
393 flush_cache_vmap(_va, va_end);
394}
395
396static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
397{
398 /*
399 * Actually this is not necessary at all, just exists for
400 * consistency of the code readibility.
401 */
402 BUG_ON(!sgt);
403}
404
405static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len)
406{
407 unsigned int i;
408 struct scatterlist *sg;
409 void *va;
410
411 va = phys_to_virt(pa);
412
413 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
414 size_t bytes;
415
416 bytes = iopgsz_max(len);
417
418 BUG_ON(!iopgsz_ok(bytes));
419
420 sg_set_buf(sg, phys_to_virt(pa), bytes);
421 /*
422 * 'pa' is cotinuous(linear).
423 */
424 pa += bytes;
425 len -= bytes;
426 }
427 BUG_ON(len);
428
429 clean_dcache_area(va, len);
430}
431
432static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
433{
434 /*
435 * Actually this is not necessary at all, just exists for
436 * consistency of the code readibility
437 */
438 BUG_ON(!sgt);
439}
440
441/* create 'da' <-> 'pa' mapping from 'sgt' */
442static int map_iovm_area(struct iommu *obj, struct iovm_struct *new,
443 const struct sg_table *sgt, u32 flags)
444{
445 int err;
446 unsigned int i, j;
447 struct scatterlist *sg;
448 u32 da = new->da_start;
449
450 if (!obj || !new || !sgt)
451 return -EINVAL;
452
453 BUG_ON(!sgtable_ok(sgt));
454
455 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
456 u32 pa;
457 int pgsz;
458 size_t bytes;
459 struct iotlb_entry e;
460
461 pa = sg_phys(sg);
462 bytes = sg_dma_len(sg);
463
464 flags &= ~IOVMF_PGSZ_MASK;
465 pgsz = bytes_to_iopgsz(bytes);
466 if (pgsz < 0)
467 goto err_out;
468 flags |= pgsz;
469
470 pr_debug("%s: [%d] %08x %08x(%x)\n", __func__,
471 i, da, pa, bytes);
472
473 iotlb_init_entry(&e, da, pa, flags);
474 err = iopgtable_store_entry(obj, &e);
475 if (err)
476 goto err_out;
477
478 da += bytes;
479 }
480 return 0;
481
482err_out:
483 da = new->da_start;
484
485 for_each_sg(sgt->sgl, sg, i, j) {
486 size_t bytes;
487
488 bytes = iopgtable_clear_entry(obj, da);
489
490 BUG_ON(!iopgsz_ok(bytes));
491
492 da += bytes;
493 }
494 return err;
495}
496
497/* release 'da' <-> 'pa' mapping */
498static void unmap_iovm_area(struct iommu *obj, struct iovm_struct *area)
499{
500 u32 start;
501 size_t total = area->da_end - area->da_start;
502
503 BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE));
504
505 start = area->da_start;
506 while (total > 0) {
507 size_t bytes;
508
509 bytes = iopgtable_clear_entry(obj, start);
510 if (bytes == 0)
511 bytes = PAGE_SIZE;
512 else
513 dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n",
514 __func__, start, bytes, area->flags);
515
516 BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE));
517
518 total -= bytes;
519 start += bytes;
520 }
521 BUG_ON(total);
522}
523
524/* template function for all unmapping */
525static struct sg_table *unmap_vm_area(struct iommu *obj, const u32 da,
526 void (*fn)(const void *), u32 flags)
527{
528 struct sg_table *sgt = NULL;
529 struct iovm_struct *area;
530
531 if (!IS_ALIGNED(da, PAGE_SIZE)) {
532 dev_err(obj->dev, "%s: alignment err(%08x)\n", __func__, da);
533 return NULL;
534 }
535
536 mutex_lock(&obj->mmap_lock);
537
538 area = __find_iovm_area(obj, da);
539 if (!area) {
540 dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
541 goto out;
542 }
543
544 if ((area->flags & flags) != flags) {
545 dev_err(obj->dev, "%s: wrong flags(%08x)\n", __func__,
546 area->flags);
547 goto out;
548 }
549 sgt = (struct sg_table *)area->sgt;
550
551 unmap_iovm_area(obj, area);
552
553 fn(area->va);
554
555 dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n", __func__,
556 area->da_start, da, area->da_end,
557 area->da_end - area->da_start, area->flags);
558
559 free_iovm_area(obj, area);
560out:
561 mutex_unlock(&obj->mmap_lock);
562
563 return sgt;
564}
565
566static u32 map_iommu_region(struct iommu *obj, u32 da,
567 const struct sg_table *sgt, void *va, size_t bytes, u32 flags)
568{
569 int err = -ENOMEM;
570 struct iovm_struct *new;
571
572 mutex_lock(&obj->mmap_lock);
573
574 new = alloc_iovm_area(obj, da, bytes, flags);
575 if (IS_ERR(new)) {
576 err = PTR_ERR(new);
577 goto err_alloc_iovma;
578 }
579 new->va = va;
580 new->sgt = sgt;
581
582 if (map_iovm_area(obj, new, sgt, new->flags))
583 goto err_map;
584
585 mutex_unlock(&obj->mmap_lock);
586
587 dev_dbg(obj->dev, "%s: da:%08x(%x) flags:%08x va:%p\n",
588 __func__, new->da_start, bytes, new->flags, va);
589
590 return new->da_start;
591
592err_map:
593 free_iovm_area(obj, new);
594err_alloc_iovma:
595 mutex_unlock(&obj->mmap_lock);
596 return err;
597}
598
599static inline u32 __iommu_vmap(struct iommu *obj, u32 da,
600 const struct sg_table *sgt, void *va, size_t bytes, u32 flags)
601{
602 return map_iommu_region(obj, da, sgt, va, bytes, flags);
603}
604
605/**
606 * iommu_vmap - (d)-(p)-(v) address mapper
607 * @obj: objective iommu
608 * @sgt: address of scatter gather table
609 * @flags: iovma and page property
610 *
611 * Creates 1-n-1 mapping with given @sgt and returns @da.
612 * All @sgt element must be io page size aligned.
613 */
614u32 iommu_vmap(struct iommu *obj, u32 da, const struct sg_table *sgt,
615 u32 flags)
616{
617 size_t bytes;
618 void *va;
619
620 if (!obj || !obj->dev || !sgt)
621 return -EINVAL;
622
623 bytes = sgtable_len(sgt);
624 if (!bytes)
625 return -EINVAL;
626 bytes = PAGE_ALIGN(bytes);
627
628 va = vmap_sg(sgt);
629 if (IS_ERR(va))
630 return PTR_ERR(va);
631
632 flags &= IOVMF_HW_MASK;
633 flags |= IOVMF_DISCONT;
634 flags |= IOVMF_MMIO;
635 flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
636
637 da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
638 if (IS_ERR_VALUE(da))
639 vunmap_sg(va);
640
641 return da;
642}
643EXPORT_SYMBOL_GPL(iommu_vmap);
644
645/**
646 * iommu_vunmap - release virtual mapping obtained by 'iommu_vmap()'
647 * @obj: objective iommu
648 * @da: iommu device virtual address
649 *
650 * Free the iommu virtually contiguous memory area starting at
651 * @da, which was returned by 'iommu_vmap()'.
652 */
653struct sg_table *iommu_vunmap(struct iommu *obj, u32 da)
654{
655 struct sg_table *sgt;
656 /*
657 * 'sgt' is allocated before 'iommu_vmalloc()' is called.
658 * Just returns 'sgt' to the caller to free
659 */
660 sgt = unmap_vm_area(obj, da, vunmap_sg, IOVMF_DISCONT | IOVMF_MMIO);
661 if (!sgt)
662 dev_dbg(obj->dev, "%s: No sgt\n", __func__);
663 return sgt;
664}
665EXPORT_SYMBOL_GPL(iommu_vunmap);
666
667/**
668 * iommu_vmalloc - (d)-(p)-(v) address allocator and mapper
669 * @obj: objective iommu
670 * @da: contiguous iommu virtual memory
671 * @bytes: allocation size
672 * @flags: iovma and page property
673 *
674 * Allocate @bytes linearly and creates 1-n-1 mapping and returns
675 * @da again, which might be adjusted if 'IOVMF_DA_ANON' is set.
676 */
677u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
678{
679 void *va;
680 struct sg_table *sgt;
681
682 if (!obj || !obj->dev || !bytes)
683 return -EINVAL;
684
685 bytes = PAGE_ALIGN(bytes);
686
687 va = vmalloc(bytes);
688 if (!va)
689 return -ENOMEM;
690
691 sgt = sgtable_alloc(bytes, flags);
692 if (IS_ERR(sgt)) {
693 da = PTR_ERR(sgt);
694 goto err_sgt_alloc;
695 }
696 sgtable_fill_vmalloc(sgt, va);
697
698 flags &= IOVMF_HW_MASK;
699 flags |= IOVMF_DISCONT;
700 flags |= IOVMF_ALLOC;
701 flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
702
703 da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
704 if (IS_ERR_VALUE(da))
705 goto err_iommu_vmap;
706
707 return da;
708
709err_iommu_vmap:
710 sgtable_drain_vmalloc(sgt);
711 sgtable_free(sgt);
712err_sgt_alloc:
713 vfree(va);
714 return da;
715}
716EXPORT_SYMBOL_GPL(iommu_vmalloc);
717
718/**
719 * iommu_vfree - release memory allocated by 'iommu_vmalloc()'
720 * @obj: objective iommu
721 * @da: iommu device virtual address
722 *
723 * Frees the iommu virtually continuous memory area starting at
724 * @da, as obtained from 'iommu_vmalloc()'.
725 */
726void iommu_vfree(struct iommu *obj, const u32 da)
727{
728 struct sg_table *sgt;
729
730 sgt = unmap_vm_area(obj, da, vfree, IOVMF_DISCONT | IOVMF_ALLOC);
731 if (!sgt)
732 dev_dbg(obj->dev, "%s: No sgt\n", __func__);
733 sgtable_free(sgt);
734}
735EXPORT_SYMBOL_GPL(iommu_vfree);
736
737static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va,
738 size_t bytes, u32 flags)
739{
740 struct sg_table *sgt;
741
742 sgt = sgtable_alloc(bytes, flags);
743 if (IS_ERR(sgt))
744 return PTR_ERR(sgt);
745
746 sgtable_fill_kmalloc(sgt, pa, bytes);
747
748 da = map_iommu_region(obj, da, sgt, va, bytes, flags);
749 if (IS_ERR_VALUE(da)) {
750 sgtable_drain_kmalloc(sgt);
751 sgtable_free(sgt);
752 }
753
754 return da;
755}
756
757/**
758 * iommu_kmap - (d)-(p)-(v) address mapper
759 * @obj: objective iommu
760 * @da: contiguous iommu virtual memory
761 * @pa: contiguous physical memory
762 * @flags: iovma and page property
763 *
764 * Creates 1-1-1 mapping and returns @da again, which can be
765 * adjusted if 'IOVMF_DA_ANON' is set.
766 */
767u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
768 u32 flags)
769{
770 void *va;
771
772 if (!obj || !obj->dev || !bytes)
773 return -EINVAL;
774
775 bytes = PAGE_ALIGN(bytes);
776
777 va = ioremap(pa, bytes);
778 if (!va)
779 return -ENOMEM;
780
781 flags &= IOVMF_HW_MASK;
782 flags |= IOVMF_LINEAR;
783 flags |= IOVMF_MMIO;
784 flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
785
786 da = __iommu_kmap(obj, da, pa, va, bytes, flags);
787 if (IS_ERR_VALUE(da))
788 iounmap(va);
789
790 return da;
791}
792EXPORT_SYMBOL_GPL(iommu_kmap);
793
794/**
795 * iommu_kunmap - release virtual mapping obtained by 'iommu_kmap()'
796 * @obj: objective iommu
797 * @da: iommu device virtual address
798 *
799 * Frees the iommu virtually contiguous memory area starting at
800 * @da, which was passed to and was returned by'iommu_kmap()'.
801 */
802void iommu_kunmap(struct iommu *obj, u32 da)
803{
804 struct sg_table *sgt;
805 typedef void (*func_t)(const void *);
806
807 sgt = unmap_vm_area(obj, da, (func_t)__iounmap,
808 IOVMF_LINEAR | IOVMF_MMIO);
809 if (!sgt)
810 dev_dbg(obj->dev, "%s: No sgt\n", __func__);
811 sgtable_free(sgt);
812}
813EXPORT_SYMBOL_GPL(iommu_kunmap);
814
815/**
816 * iommu_kmalloc - (d)-(p)-(v) address allocator and mapper
817 * @obj: objective iommu
818 * @da: contiguous iommu virtual memory
819 * @bytes: bytes for allocation
820 * @flags: iovma and page property
821 *
822 * Allocate @bytes linearly and creates 1-1-1 mapping and returns
823 * @da again, which might be adjusted if 'IOVMF_DA_ANON' is set.
824 */
825u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
826{
827 void *va;
828 u32 pa;
829
830 if (!obj || !obj->dev || !bytes)
831 return -EINVAL;
832
833 bytes = PAGE_ALIGN(bytes);
834
835 va = kmalloc(bytes, GFP_KERNEL | GFP_DMA);
836 if (!va)
837 return -ENOMEM;
838 pa = virt_to_phys(va);
839
840 flags &= IOVMF_HW_MASK;
841 flags |= IOVMF_LINEAR;
842 flags |= IOVMF_ALLOC;
843 flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON);
844
845 da = __iommu_kmap(obj, da, pa, va, bytes, flags);
846 if (IS_ERR_VALUE(da))
847 kfree(va);
848
849 return da;
850}
851EXPORT_SYMBOL_GPL(iommu_kmalloc);
852
853/**
854 * iommu_kfree - release virtual mapping obtained by 'iommu_kmalloc()'
855 * @obj: objective iommu
856 * @da: iommu device virtual address
857 *
858 * Frees the iommu virtually contiguous memory area starting at
859 * @da, which was passed to and was returned by'iommu_kmalloc()'.
860 */
861void iommu_kfree(struct iommu *obj, u32 da)
862{
863 struct sg_table *sgt;
864
865 sgt = unmap_vm_area(obj, da, kfree, IOVMF_LINEAR | IOVMF_ALLOC);
866 if (!sgt)
867 dev_dbg(obj->dev, "%s: No sgt\n", __func__);
868 sgtable_free(sgt);
869}
870EXPORT_SYMBOL_GPL(iommu_kfree);
871
872
873static int __init iovmm_init(void)
874{
875 const unsigned long flags = SLAB_HWCACHE_ALIGN;
876 struct kmem_cache *p;
877
878 p = kmem_cache_create("iovm_area_cache", sizeof(struct iovm_struct), 0,
879 flags, NULL);
880 if (!p)
881 return -ENOMEM;
882 iovm_area_cachep = p;
883
884 return 0;
885}
886module_init(iovmm_init);
887
888static void __exit iovmm_exit(void)
889{
890 kmem_cache_destroy(iovm_area_cachep);
891}
892module_exit(iovmm_exit);
893
894MODULE_DESCRIPTION("omap iommu: simple virtual address space management");
895MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
896MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 28b0a824b8cf..efa0e0111f38 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -91,11 +91,20 @@ static void omap_mcbsp_dump_reg(u8 id)
91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) 91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
92{ 92{
93 struct omap_mcbsp *mcbsp_tx = dev_id; 93 struct omap_mcbsp *mcbsp_tx = dev_id;
94 u16 irqst_spcr2;
94 95
95 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", 96 irqst_spcr2 = OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2);
96 OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); 97 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
97 98
98 complete(&mcbsp_tx->tx_irq_completion); 99 if (irqst_spcr2 & XSYNC_ERR) {
100 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
101 irqst_spcr2);
102 /* Writing zero to XSYNC_ERR clears the IRQ */
103 OMAP_MCBSP_WRITE(mcbsp_tx->io_base, SPCR2,
104 irqst_spcr2 & ~(XSYNC_ERR));
105 } else {
106 complete(&mcbsp_tx->tx_irq_completion);
107 }
99 108
100 return IRQ_HANDLED; 109 return IRQ_HANDLED;
101} 110}
@@ -103,11 +112,20 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
103static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) 112static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
104{ 113{
105 struct omap_mcbsp *mcbsp_rx = dev_id; 114 struct omap_mcbsp *mcbsp_rx = dev_id;
115 u16 irqst_spcr1;
106 116
107 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", 117 irqst_spcr1 = OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR1);
108 OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); 118 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
109 119
110 complete(&mcbsp_rx->rx_irq_completion); 120 if (irqst_spcr1 & RSYNC_ERR) {
121 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
122 irqst_spcr1);
123 /* Writing zero to RSYNC_ERR clears the IRQ */
124 OMAP_MCBSP_WRITE(mcbsp_rx->io_base, SPCR1,
125 irqst_spcr1 & ~(RSYNC_ERR));
126 } else {
127 complete(&mcbsp_rx->tx_irq_completion);
128 }
111 129
112 return IRQ_HANDLED; 130 return IRQ_HANDLED;
113} 131}
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index 80b040fd5ca7..8d329fb20740 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -54,6 +54,9 @@ int __init_or_module omap_cfg_reg(const unsigned long index)
54{ 54{
55 struct pin_config *reg; 55 struct pin_config *reg;
56 56
57 if (cpu_is_omap44xx())
58 return 0;
59
57 if (mux_cfg == NULL) { 60 if (mux_cfg == NULL) {
58 printk(KERN_ERR "Pin mux table not initialized\n"); 61 printk(KERN_ERR "Pin mux table not initialized\n");
59 return -ENODEV; 62 return -ENODEV;
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index fa5297d643d3..a5b9bcd6b108 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -6,6 +6,9 @@
6 * Copyright (C) 2005 Nokia Corporation 6 * Copyright (C) 2005 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com> 7 * Written by Tony Lindgren <tony@atomide.com>
8 * 8 *
9 * Copyright (C) 2009 Texas Instruments
10 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
11 *
9 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
@@ -38,12 +41,14 @@
38#define OMAP1_SRAM_VA VMALLOC_END 41#define OMAP1_SRAM_VA VMALLOC_END
39#define OMAP2_SRAM_PA 0x40200000 42#define OMAP2_SRAM_PA 0x40200000
40#define OMAP2_SRAM_PUB_PA 0x4020f800 43#define OMAP2_SRAM_PUB_PA 0x4020f800
41#define OMAP2_SRAM_VA VMALLOC_END 44#define OMAP2_SRAM_VA 0xe3000000
42#define OMAP2_SRAM_PUB_VA (VMALLOC_END + 0x800) 45#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
43#define OMAP3_SRAM_PA 0x40200000 46#define OMAP3_SRAM_PA 0x40200000
44#define OMAP3_SRAM_VA 0xd7000000 47#define OMAP3_SRAM_VA 0xd7000000
45#define OMAP3_SRAM_PUB_PA 0x40208000 48#define OMAP3_SRAM_PUB_PA 0x40208000
46#define OMAP3_SRAM_PUB_VA 0xd7008000 49#define OMAP3_SRAM_PUB_VA 0xd7008000
50#define OMAP4_SRAM_PA 0x40200000 /*0x402f0000*/
51#define OMAP4_SRAM_VA 0xd7000000 /*0xd70f0000*/
47 52
48#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 53#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
49#define SRAM_BOOTLOADER_SZ 0x00 54#define SRAM_BOOTLOADER_SZ 0x00
@@ -87,6 +92,10 @@ static int is_sram_locked(void)
87{ 92{
88 int type = 0; 93 int type = 0;
89 94
95 if (cpu_is_omap44xx())
96 /* Not yet supported */
97 return 0;
98
90 if (cpu_is_omap242x()) 99 if (cpu_is_omap242x())
91 type = omap_rev() & OMAP2_DEVICETYPE_MASK; 100 type = omap_rev() & OMAP2_DEVICETYPE_MASK;
92 101
@@ -135,6 +144,10 @@ void __init omap_detect_sram(void)
135 omap_sram_base = OMAP3_SRAM_VA; 144 omap_sram_base = OMAP3_SRAM_VA;
136 omap_sram_start = OMAP3_SRAM_PA; 145 omap_sram_start = OMAP3_SRAM_PA;
137 omap_sram_size = 0x10000; /* 64K */ 146 omap_sram_size = 0x10000; /* 64K */
147 } else if (cpu_is_omap44xx()) {
148 omap_sram_base = OMAP4_SRAM_VA;
149 omap_sram_start = OMAP4_SRAM_PA;
150 omap_sram_size = 0x8000; /* 32K */
138 } else { 151 } else {
139 omap_sram_base = OMAP2_SRAM_VA; 152 omap_sram_base = OMAP2_SRAM_VA;
140 omap_sram_start = OMAP2_SRAM_PA; 153 omap_sram_start = OMAP2_SRAM_PA;
@@ -201,8 +214,23 @@ void __init omap_map_sram(void)
201 base = OMAP3_SRAM_PA; 214 base = OMAP3_SRAM_PA;
202 base = ROUND_DOWN(base, PAGE_SIZE); 215 base = ROUND_DOWN(base, PAGE_SIZE);
203 omap_sram_io_desc[0].pfn = __phys_to_pfn(base); 216 omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
217
218 /*
219 * SRAM must be marked as non-cached on OMAP3 since the
220 * CORE DPLL M2 divider change code (in SRAM) runs with the
221 * SDRAM controller disabled, and if it is marked cached,
222 * the ARM may attempt to write cache lines back to SDRAM
223 * which will cause the system to hang.
224 */
225 omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
204 } 226 }
205 227
228 if (cpu_is_omap44xx()) {
229 omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA;
230 base = OMAP4_SRAM_PA;
231 base = ROUND_DOWN(base, PAGE_SIZE);
232 omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
233 }
206 omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ 234 omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */
207 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); 235 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
208 236
@@ -242,20 +270,13 @@ void * omap_sram_push(void * start, unsigned long size)
242 return (void *)omap_sram_ceil; 270 return (void *)omap_sram_ceil;
243} 271}
244 272
245static void omap_sram_error(void)
246{
247 panic("Uninitialized SRAM function\n");
248}
249
250#ifdef CONFIG_ARCH_OMAP1 273#ifdef CONFIG_ARCH_OMAP1
251 274
252static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); 275static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
253 276
254void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) 277void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
255{ 278{
256 if (!_omap_sram_reprogram_clock) 279 BUG_ON(!_omap_sram_reprogram_clock);
257 omap_sram_error();
258
259 _omap_sram_reprogram_clock(dpllctl, ckctl); 280 _omap_sram_reprogram_clock(dpllctl, ckctl);
260} 281}
261 282
@@ -280,9 +301,7 @@ static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
280void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, 301void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
281 u32 base_cs, u32 force_unlock) 302 u32 base_cs, u32 force_unlock)
282{ 303{
283 if (!_omap2_sram_ddr_init) 304 BUG_ON(!_omap2_sram_ddr_init);
284 omap_sram_error();
285
286 _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, 305 _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
287 base_cs, force_unlock); 306 base_cs, force_unlock);
288} 307}
@@ -292,9 +311,7 @@ static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
292 311
293void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) 312void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
294{ 313{
295 if (!_omap2_sram_reprogram_sdrc) 314 BUG_ON(!_omap2_sram_reprogram_sdrc);
296 omap_sram_error();
297
298 _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); 315 _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
299} 316}
300 317
@@ -302,9 +319,7 @@ static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
302 319
303u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) 320u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
304{ 321{
305 if (!_omap2_set_prcm) 322 BUG_ON(!_omap2_set_prcm);
306 omap_sram_error();
307
308 return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); 323 return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
309} 324}
310#endif 325#endif
@@ -356,16 +371,15 @@ static inline int omap243x_sram_init(void)
356static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl, 371static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
357 u32 sdrc_actim_ctrla, 372 u32 sdrc_actim_ctrla,
358 u32 sdrc_actim_ctrlb, 373 u32 sdrc_actim_ctrlb,
359 u32 m2); 374 u32 m2, u32 unlock_dll);
360u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, 375u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
361 u32 sdrc_actim_ctrlb, u32 m2) 376 u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll)
362{ 377{
363 if (!_omap3_sram_configure_core_dpll) 378 BUG_ON(!_omap3_sram_configure_core_dpll);
364 omap_sram_error();
365
366 return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl, 379 return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
367 sdrc_actim_ctrla, 380 sdrc_actim_ctrla,
368 sdrc_actim_ctrlb, m2); 381 sdrc_actim_ctrlb, m2,
382 unlock_dll);
369} 383}
370 384
371/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ 385/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
@@ -406,6 +420,8 @@ int __init omap_sram_init(void)
406 omap243x_sram_init(); 420 omap243x_sram_init();
407 else if (cpu_is_omap34xx()) 421 else if (cpu_is_omap34xx())
408 omap34xx_sram_init(); 422 omap34xx_sram_init();
423 else if (cpu_is_omap44xx())
424 omap34xx_sram_init(); /* FIXME: */
409 425
410 return 0; 426 return 0;
411} 427}