aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Kconfig14
-rw-r--r--arch/arm/mach-omap2/Makefile30
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c114
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c87
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c94
-rw-r--r--arch/arm/mach-omap2/board-ldp.c219
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c108
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c329
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c197
-rw-r--r--arch/arm/mach-omap2/board-overo.c79
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c232
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c160
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c110
-rw-r--r--arch/arm/mach-omap2/clock.c18
-rw-r--r--arch/arm/mach-omap2/clock24xx.c23
-rw-r--r--arch/arm/mach-omap2/clock24xx.h11
-rw-r--r--arch/arm/mach-omap2/clock34xx.c23
-rw-r--r--arch/arm/mach-omap2/clock34xx.h35
-rw-r--r--arch/arm/mach-omap2/clockdomains.h2
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h14
-rw-r--r--arch/arm/mach-omap2/cm.h6
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c330
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c189
-rw-r--r--arch/arm/mach-omap2/gpmc.c6
-rw-r--r--arch/arm/mach-omap2/id.c8
-rw-r--r--arch/arm/mach-omap2/io.c52
-rw-r--r--arch/arm/mach-omap2/irq.c18
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.c280
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.h3
-rw-r--r--arch/arm/mach-omap2/pm-debug.c152
-rw-r--r--arch/arm/mach-omap2/pm.c111
-rw-r--r--arch/arm/mach-omap2/pm.h38
-rw-r--r--arch/arm/mach-omap2/pm24xx.c549
-rw-r--r--arch/arm/mach-omap2/pm34xx.c710
-rw-r--r--arch/arm/mach-omap2/prcm-common.h2
-rw-r--r--arch/arm/mach-omap2/prm.h207
-rw-r--r--arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h55
-rw-r--r--arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h54
-rw-r--r--arch/arm/mach-omap2/sdrc.c24
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c5
-rw-r--r--arch/arm/mach-omap2/serial.c465
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S1
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S436
-rw-r--r--arch/arm/mach-omap2/sram242x.S10
-rw-r--r--arch/arm/mach-omap2/sram243x.S10
-rw-r--r--arch/arm/mach-omap2/sram34xx.S129
-rw-r--r--arch/arm/mach-omap2/timer-gp.c9
-rw-r--r--arch/arm/mach-omap2/usb-musb.c21
48 files changed, 4973 insertions, 806 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 64ab386a65c7..a755eb5e2361 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -25,7 +25,7 @@ config ARCH_OMAP3430
25 select ARCH_OMAP_OTG 25 select ARCH_OMAP_OTG
26 26
27comment "OMAP Board Type" 27comment "OMAP Board Type"
28 depends on ARCH_OMAP2 || ARCH_OMAP3 28 depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4
29 29
30config MACH_OMAP_GENERIC 30config MACH_OMAP_GENERIC
31 bool "Generic OMAP board" 31 bool "Generic OMAP board"
@@ -56,6 +56,10 @@ config MACH_OVERO
56 bool "Gumstix Overo board" 56 bool "Gumstix Overo board"
57 depends on ARCH_OMAP3 && ARCH_OMAP34XX 57 depends on ARCH_OMAP3 && ARCH_OMAP34XX
58 58
59config MACH_OMAP3EVM
60 bool "OMAP 3530 EVM board"
61 depends on ARCH_OMAP3 && ARCH_OMAP34XX
62
59config MACH_OMAP3_PANDORA 63config MACH_OMAP3_PANDORA
60 bool "OMAP3 Pandora" 64 bool "OMAP3 Pandora"
61 depends on ARCH_OMAP3 && ARCH_OMAP34XX 65 depends on ARCH_OMAP3 && ARCH_OMAP34XX
@@ -67,3 +71,11 @@ config MACH_OMAP_3430SDP
67config MACH_NOKIA_RX51 71config MACH_NOKIA_RX51
68 bool "Nokia RX-51 board" 72 bool "Nokia RX-51 board"
69 depends on ARCH_OMAP3 && ARCH_OMAP34XX 73 depends on ARCH_OMAP3 && ARCH_OMAP34XX
74
75config MACH_OMAP_ZOOM2
76 bool "OMAP3 Zoom2 board"
77 depends on ARCH_OMAP3 && ARCH_OMAP34XX
78
79config MACH_OMAP_4430SDP
80 bool "OMAP 4430 SDP board"
81 depends on ARCH_OMAP4
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 88629a7455a6..6226e64d99a1 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,9 +3,14 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \ 6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
7 devices.o serial.o gpmc.o timer-gp.o powerdomain.o \ 7
8 clockdomain.o 8omap-2-3-common = irq.o sdrc.o
9prcm-common = prcm.o powerdomain.o
10clock-common = clock.o clockdomain.o
11
12obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
13obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common)
9 14
10obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 15obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
11 16
@@ -20,8 +25,10 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
20 25
21# Power Management 26# Power Management
22ifeq ($(CONFIG_PM),y) 27ifeq ($(CONFIG_PM),y)
23obj-y += pm.o 28obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
24obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o 29obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o
30obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
31obj-$(CONFIG_PM_DEBUG) += pm-debug.o
25endif 32endif
26 33
27# Clock framework 34# Clock framework
@@ -45,6 +52,8 @@ obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
45 mmc-twl4030.o 52 mmc-twl4030.o
46obj-$(CONFIG_MACH_OVERO) += board-overo.o \ 53obj-$(CONFIG_MACH_OVERO) += board-overo.o \
47 mmc-twl4030.o 54 mmc-twl4030.o
55obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
56 mmc-twl4030.o
48obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ 57obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
49 mmc-twl4030.o 58 mmc-twl4030.o
50obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ 59obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
@@ -53,8 +62,17 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
53obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ 62obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
54 board-rx51-peripherals.o \ 63 board-rx51-peripherals.o \
55 mmc-twl4030.o 64 mmc-twl4030.o
65obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \
66 mmc-twl4030.o \
67 board-zoom-debugboard.o
68
69obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o
56 70
57# Platform specific device init code 71# Platform specific device init code
58ifeq ($(CONFIG_USB_MUSB_SOC),y)
59obj-y += usb-musb.o 72obj-y += usb-musb.o
60endif 73
74onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o
75obj-y += $(onenand-m) $(onenand-y)
76
77smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o
78obj-y += $(smc91x-m) $(smc91x-y)
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 22143651037e..9c3fdcdf76c3 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -36,14 +36,12 @@
36#include <mach/common.h> 36#include <mach/common.h>
37#include <mach/gpmc.h> 37#include <mach/gpmc.h>
38#include <mach/usb.h> 38#include <mach/usb.h>
39#include <mach/gpmc-smc91x.h>
39 40
40#include "mmc-twl4030.h" 41#include "mmc-twl4030.h"
41 42
42#define SDP2430_CS0_BASE 0x04000000 43#define SDP2430_CS0_BASE 0x04000000
43#define SDP2430_FLASH_CS 0 44#define SECONDARY_LCD_GPIO 147
44#define SDP2430_SMC91X_CS 5
45
46#define SDP2430_ETHR_GPIO_IRQ 149
47 45
48static struct mtd_partition sdp2430_partitions[] = { 46static struct mtd_partition sdp2430_partitions[] = {
49 /* bootloader (U-Boot, etc) in first sector */ 47 /* bootloader (U-Boot, etc) in first sector */
@@ -99,100 +97,53 @@ static struct platform_device sdp2430_flash_device = {
99 .resource = &sdp2430_flash_resource, 97 .resource = &sdp2430_flash_resource,
100}; 98};
101 99
102static struct resource sdp2430_smc91x_resources[] = { 100static struct platform_device sdp2430_lcd_device = {
103 [0] = { 101 .name = "sdp2430_lcd",
104 .start = SDP2430_CS0_BASE,
105 .end = SDP2430_CS0_BASE + SZ_64M - 1,
106 .flags = IORESOURCE_MEM,
107 },
108 [1] = {
109 .start = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
110 .end = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
111 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
112 },
113};
114
115static struct platform_device sdp2430_smc91x_device = {
116 .name = "smc91x",
117 .id = -1, 102 .id = -1,
118 .num_resources = ARRAY_SIZE(sdp2430_smc91x_resources),
119 .resource = sdp2430_smc91x_resources,
120}; 103};
121 104
122static struct platform_device *sdp2430_devices[] __initdata = { 105static struct platform_device *sdp2430_devices[] __initdata = {
123 &sdp2430_smc91x_device,
124 &sdp2430_flash_device, 106 &sdp2430_flash_device,
107 &sdp2430_lcd_device,
125}; 108};
126 109
127static inline void __init sdp2430_init_smc91x(void) 110static struct omap_lcd_config sdp2430_lcd_config __initdata = {
128{ 111 .ctrl_name = "internal",
129 int eth_cs; 112};
130 unsigned long cs_mem_base;
131 unsigned int rate;
132 struct clk *gpmc_fck;
133 113
134 eth_cs = SDP2430_SMC91X_CS; 114#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
135 115
136 gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ 116static struct omap_smc91x_platform_data board_smc91x_data = {
137 if (IS_ERR(gpmc_fck)) { 117 .cs = 5,
138 WARN_ON(1); 118 .gpio_irq = 149,
139 return; 119 .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
140 } 120 IORESOURCE_IRQ_LOWLEVEL,
141 121
142 clk_enable(gpmc_fck); 122};
143 rate = clk_get_rate(gpmc_fck);
144
145 /* Make sure CS1 timings are correct, for 2430 always muxed */
146 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
147
148 if (rate >= 160000000) {
149 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
150 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
151 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
152 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
153 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
154 } else if (rate >= 130000000) {
155 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
156 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
157 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
158 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
159 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
160 } else { /* rate = 100000000 */
161 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
162 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
163 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
164 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
165 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
166 }
167 123
168 if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { 124static void __init board_smc91x_init(void)
169 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); 125{
170 goto out; 126 if (omap_rev() > OMAP3430_REV_ES1_0)
171 } 127 board_smc91x_data.gpio_irq = 6;
128 else
129 board_smc91x_data.gpio_irq = 29;
172 130
173 sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300; 131 gpmc_smc91x_init(&board_smc91x_data);
174 sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f; 132}
175 udelay(100);
176 133
177 if (gpio_request(SDP2430_ETHR_GPIO_IRQ, "SMC91x irq") < 0) { 134#else
178 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
179 SDP2430_ETHR_GPIO_IRQ);
180 gpmc_cs_free(eth_cs);
181 goto out;
182 }
183 gpio_direction_input(SDP2430_ETHR_GPIO_IRQ);
184 135
185out: 136static inline void board_smc91x_init(void)
186 clk_disable(gpmc_fck); 137{
187 clk_put(gpmc_fck);
188} 138}
189 139
140#endif
141
190static void __init omap_2430sdp_init_irq(void) 142static void __init omap_2430sdp_init_irq(void)
191{ 143{
192 omap2_init_common_hw(NULL); 144 omap2_init_common_hw(NULL);
193 omap_init_irq(); 145 omap_init_irq();
194 omap_gpio_init(); 146 omap_gpio_init();
195 sdp2430_init_smc91x();
196} 147}
197 148
198static struct omap_uart_config sdp2430_uart_config __initdata = { 149static struct omap_uart_config sdp2430_uart_config __initdata = {
@@ -201,6 +152,7 @@ static struct omap_uart_config sdp2430_uart_config __initdata = {
201 152
202static struct omap_board_config_kernel sdp2430_config[] = { 153static struct omap_board_config_kernel sdp2430_config[] = {
203 {OMAP_TAG_UART, &sdp2430_uart_config}, 154 {OMAP_TAG_UART, &sdp2430_uart_config},
155 {OMAP_TAG_LCD, &sdp2430_lcd_config},
204}; 156};
205 157
206 158
@@ -248,6 +200,8 @@ static struct twl4030_hsmmc_info mmc[] __initdata = {
248 200
249static void __init omap_2430sdp_init(void) 201static void __init omap_2430sdp_init(void)
250{ 202{
203 int ret;
204
251 omap2430_i2c_init(); 205 omap2430_i2c_init();
252 206
253 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); 207 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
@@ -256,6 +210,12 @@ static void __init omap_2430sdp_init(void)
256 omap_serial_init(); 210 omap_serial_init();
257 twl4030_mmc_init(mmc); 211 twl4030_mmc_init(mmc);
258 usb_musb_init(); 212 usb_musb_init();
213 board_smc91x_init();
214
215 /* Turn off secondary LCD backlight */
216 ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight");
217 if (ret == 0)
218 gpio_direction_output(SECONDARY_LCD_GPIO, 0);
259} 219}
260 220
261static void __init omap_2430sdp_map_io(void) 221static void __init omap_2430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index ed9274972122..496a90e4ea7a 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -39,15 +39,13 @@
39 39
40#include <mach/control.h> 40#include <mach/control.h>
41#include <mach/keypad.h> 41#include <mach/keypad.h>
42#include <mach/gpmc-smc91x.h>
42 43
44#include "sdram-qimonda-hyb18m512160af-6.h"
43#include "mmc-twl4030.h" 45#include "mmc-twl4030.h"
44 46
45#define CONFIG_DISABLE_HFCLK 1 47#define CONFIG_DISABLE_HFCLK 1
46 48
47#define SDP3430_ETHR_GPIO_IRQ_SDPV1 29
48#define SDP3430_ETHR_GPIO_IRQ_SDPV2 6
49#define SDP3430_SMC91X_CS 3
50
51#define SDP3430_TS_GPIO_IRQ_SDPV1 3 49#define SDP3430_TS_GPIO_IRQ_SDPV1 3
52#define SDP3430_TS_GPIO_IRQ_SDPV2 2 50#define SDP3430_TS_GPIO_IRQ_SDPV2 2
53 51
@@ -56,24 +54,6 @@
56 54
57#define TWL4030_MSECURE_GPIO 22 55#define TWL4030_MSECURE_GPIO 22
58 56
59static struct resource sdp3430_smc91x_resources[] = {
60 [0] = {
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64 .start = 0,
65 .end = 0,
66 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
67 },
68};
69
70static struct platform_device sdp3430_smc91x_device = {
71 .name = "smc91x",
72 .id = -1,
73 .num_resources = ARRAY_SIZE(sdp3430_smc91x_resources),
74 .resource = sdp3430_smc91x_resources,
75};
76
77static int sdp3430_keymap[] = { 57static int sdp3430_keymap[] = {
78 KEY(0, 0, KEY_LEFT), 58 KEY(0, 0, KEY_LEFT),
79 KEY(0, 1, KEY_RIGHT), 59 KEY(0, 1, KEY_RIGHT),
@@ -184,48 +164,14 @@ static struct regulator_consumer_supply sdp3430_vdvi_supply = {
184}; 164};
185 165
186static struct platform_device *sdp3430_devices[] __initdata = { 166static struct platform_device *sdp3430_devices[] __initdata = {
187 &sdp3430_smc91x_device,
188 &sdp3430_lcd_device, 167 &sdp3430_lcd_device,
189}; 168};
190 169
191static inline void __init sdp3430_init_smc91x(void)
192{
193 int eth_cs;
194 unsigned long cs_mem_base;
195 int eth_gpio = 0;
196
197 eth_cs = SDP3430_SMC91X_CS;
198
199 if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
200 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
201 return;
202 }
203
204 sdp3430_smc91x_resources[0].start = cs_mem_base + 0x300;
205 sdp3430_smc91x_resources[0].end = cs_mem_base + 0x30f;
206 udelay(100);
207
208 if (omap_rev() > OMAP3430_REV_ES1_0)
209 eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV2;
210 else
211 eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV1;
212
213 sdp3430_smc91x_resources[1].start = gpio_to_irq(eth_gpio);
214
215 if (gpio_request(eth_gpio, "SMC91x irq") < 0) {
216 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
217 eth_gpio);
218 return;
219 }
220 gpio_direction_input(eth_gpio);
221}
222
223static void __init omap_3430sdp_init_irq(void) 170static void __init omap_3430sdp_init_irq(void)
224{ 171{
225 omap2_init_common_hw(NULL); 172 omap2_init_common_hw(hyb18m512160af6_sdrc_params);
226 omap_init_irq(); 173 omap_init_irq();
227 omap_gpio_init(); 174 omap_gpio_init();
228 sdp3430_init_smc91x();
229} 175}
230 176
231static struct omap_uart_config sdp3430_uart_config __initdata = { 177static struct omap_uart_config sdp3430_uart_config __initdata = {
@@ -506,6 +452,32 @@ static int __init omap3430_i2c_init(void)
506 return 0; 452 return 0;
507} 453}
508 454
455#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
456
457static struct omap_smc91x_platform_data board_smc91x_data = {
458 .cs = 3,
459 .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
460 IORESOURCE_IRQ_LOWLEVEL,
461};
462
463static void __init board_smc91x_init(void)
464{
465 if (omap_rev() > OMAP3430_REV_ES1_0)
466 board_smc91x_data.gpio_irq = 6;
467 else
468 board_smc91x_data.gpio_irq = 29;
469
470 gpmc_smc91x_init(&board_smc91x_data);
471}
472
473#else
474
475static inline void board_smc91x_init(void)
476{
477}
478
479#endif
480
509static void __init omap_3430sdp_init(void) 481static void __init omap_3430sdp_init(void)
510{ 482{
511 omap3430_i2c_init(); 483 omap3430_i2c_init();
@@ -522,6 +494,7 @@ static void __init omap_3430sdp_init(void)
522 ads7846_dev_init(); 494 ads7846_dev_init();
523 omap_serial_init(); 495 omap_serial_init();
524 usb_musb_init(); 496 usb_musb_init();
497 board_smc91x_init();
525} 498}
526 499
527static void __init omap_3430sdp_map_io(void) 500static void __init omap_3430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
new file mode 100644
index 000000000000..57e477bd89c6
--- /dev/null
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -0,0 +1,94 @@
1/*
2 * Board support file for OMAP4430 SDP.
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
7 *
8 * Based on mach-omap2/board-3430sdp.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/io.h>
19#include <linux/gpio.h>
20
21#include <mach/hardware.h>
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25
26#include <mach/board.h>
27#include <mach/common.h>
28#include <mach/control.h>
29#include <mach/timer-gp.h>
30#include <asm/hardware/gic.h>
31
32static struct platform_device sdp4430_lcd_device = {
33 .name = "sdp4430_lcd",
34 .id = -1,
35};
36
37static struct platform_device *sdp4430_devices[] __initdata = {
38 &sdp4430_lcd_device,
39};
40
41static struct omap_uart_config sdp4430_uart_config __initdata = {
42 .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2),
43};
44
45static struct omap_lcd_config sdp4430_lcd_config __initdata = {
46 .ctrl_name = "internal",
47};
48
49static struct omap_board_config_kernel sdp4430_config[] __initdata = {
50 { OMAP_TAG_UART, &sdp4430_uart_config },
51 { OMAP_TAG_LCD, &sdp4430_lcd_config },
52};
53
54static void __init gic_init_irq(void)
55{
56 gic_dist_init(0, IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29);
57 gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
58}
59
60static void __init omap_4430sdp_init_irq(void)
61{
62 omap2_init_common_hw(NULL);
63#ifdef CONFIG_OMAP_32K_TIMER
64 omap2_gp_clockevent_set_gptimer(1);
65#endif
66 gic_init_irq();
67 omap_gpio_init();
68}
69
70
71static void __init omap_4430sdp_init(void)
72{
73 platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
74 omap_board_config = sdp4430_config;
75 omap_board_config_size = ARRAY_SIZE(sdp4430_config);
76 omap_serial_init();
77}
78
79static void __init omap_4430sdp_map_io(void)
80{
81 omap2_set_globals_443x();
82 omap2_map_common_io();
83}
84
85MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
86 /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
87 .phys_io = 0x48000000,
88 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
89 .boot_params = 0x80000100,
90 .map_io = omap_4430sdp_map_io,
91 .init_irq = omap_4430sdp_init_irq,
92 .init_machine = omap_4430sdp_init,
93 .timer = &omap_timer,
94MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index da57b0fcda14..d8bc0a7dcb8d 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -16,11 +16,13 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/input.h> 18#include <linux/input.h>
19#include <linux/gpio_keys.h>
19#include <linux/workqueue.h> 20#include <linux/workqueue.h>
20#include <linux/err.h> 21#include <linux/err.h>
21#include <linux/clk.h> 22#include <linux/clk.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <linux/spi/ads7846.h> 24#include <linux/spi/ads7846.h>
25#include <linux/regulator/machine.h>
24#include <linux/i2c/twl4030.h> 26#include <linux/i2c/twl4030.h>
25#include <linux/io.h> 27#include <linux/io.h>
26#include <linux/smsc911x.h> 28#include <linux/smsc911x.h>
@@ -39,6 +41,7 @@
39#include <asm/delay.h> 41#include <asm/delay.h>
40#include <mach/control.h> 42#include <mach/control.h>
41#include <mach/usb.h> 43#include <mach/usb.h>
44#include <mach/keypad.h>
42 45
43#include "mmc-twl4030.h" 46#include "mmc-twl4030.h"
44 47
@@ -77,8 +80,163 @@ static struct platform_device ldp_smsc911x_device = {
77 }, 80 },
78}; 81};
79 82
80static struct platform_device *ldp_devices[] __initdata = { 83static int ldp_twl4030_keymap[] = {
81 &ldp_smsc911x_device, 84 KEY(0, 0, KEY_1),
85 KEY(1, 0, KEY_2),
86 KEY(2, 0, KEY_3),
87 KEY(0, 1, KEY_4),
88 KEY(1, 1, KEY_5),
89 KEY(2, 1, KEY_6),
90 KEY(3, 1, KEY_F5),
91 KEY(0, 2, KEY_7),
92 KEY(1, 2, KEY_8),
93 KEY(2, 2, KEY_9),
94 KEY(3, 2, KEY_F6),
95 KEY(0, 3, KEY_F7),
96 KEY(1, 3, KEY_0),
97 KEY(2, 3, KEY_F8),
98 PERSISTENT_KEY(4, 5),
99 KEY(4, 4, KEY_VOLUMEUP),
100 KEY(5, 5, KEY_VOLUMEDOWN),
101 0
102};
103
104static struct twl4030_keypad_data ldp_kp_twl4030_data = {
105 .rows = 6,
106 .cols = 6,
107 .keymap = ldp_twl4030_keymap,
108 .keymapsize = ARRAY_SIZE(ldp_twl4030_keymap),
109 .rep = 1,
110};
111
112static struct gpio_keys_button ldp_gpio_keys_buttons[] = {
113 [0] = {
114 .code = KEY_ENTER,
115 .gpio = 101,
116 .desc = "enter sw",
117 .active_low = 1,
118 .debounce_interval = 30,
119 },
120 [1] = {
121 .code = KEY_F1,
122 .gpio = 102,
123 .desc = "func 1",
124 .active_low = 1,
125 .debounce_interval = 30,
126 },
127 [2] = {
128 .code = KEY_F2,
129 .gpio = 103,
130 .desc = "func 2",
131 .active_low = 1,
132 .debounce_interval = 30,
133 },
134 [3] = {
135 .code = KEY_F3,
136 .gpio = 104,
137 .desc = "func 3",
138 .active_low = 1,
139 .debounce_interval = 30,
140 },
141 [4] = {
142 .code = KEY_F4,
143 .gpio = 105,
144 .desc = "func 4",
145 .active_low = 1,
146 .debounce_interval = 30,
147 },
148 [5] = {
149 .code = KEY_LEFT,
150 .gpio = 106,
151 .desc = "left sw",
152 .active_low = 1,
153 .debounce_interval = 30,
154 },
155 [6] = {
156 .code = KEY_RIGHT,
157 .gpio = 107,
158 .desc = "right sw",
159 .active_low = 1,
160 .debounce_interval = 30,
161 },
162 [7] = {
163 .code = KEY_UP,
164 .gpio = 108,
165 .desc = "up sw",
166 .active_low = 1,
167 .debounce_interval = 30,
168 },
169 [8] = {
170 .code = KEY_DOWN,
171 .gpio = 109,
172 .desc = "down sw",
173 .active_low = 1,
174 .debounce_interval = 30,
175 },
176};
177
178static struct gpio_keys_platform_data ldp_gpio_keys = {
179 .buttons = ldp_gpio_keys_buttons,
180 .nbuttons = ARRAY_SIZE(ldp_gpio_keys_buttons),
181 .rep = 1,
182};
183
184static struct platform_device ldp_gpio_keys_device = {
185 .name = "gpio-keys",
186 .id = -1,
187 .dev = {
188 .platform_data = &ldp_gpio_keys,
189 },
190};
191
192static int ts_gpio;
193
194/**
195 * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
196 *
197 * @return - void. If request gpio fails then Flag KERN_ERR.
198 */
199static void ads7846_dev_init(void)
200{
201 if (gpio_request(ts_gpio, "ads7846 irq") < 0) {
202 printk(KERN_ERR "can't get ads746 pen down GPIO\n");
203 return;
204 }
205
206 gpio_direction_input(ts_gpio);
207 omap_set_gpio_debounce(ts_gpio, 1);
208 omap_set_gpio_debounce_time(ts_gpio, 0xa);
209}
210
211static int ads7846_get_pendown_state(void)
212{
213 return !gpio_get_value(ts_gpio);
214}
215
216static struct ads7846_platform_data tsc2046_config __initdata = {
217 .get_pendown_state = ads7846_get_pendown_state,
218 .keep_vref_on = 1,
219};
220
221static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
222 .turbo_mode = 0,
223 .single_channel = 1, /* 0: slave, 1: master */
224};
225
226static struct spi_board_info ldp_spi_board_info[] __initdata = {
227 [0] = {
228 /*
229 * TSC2046 operates at a max freqency of 2MHz, so
230 * operate slightly below at 1.5MHz
231 */
232 .modalias = "ads7846",
233 .bus_num = 1,
234 .chip_select = 0,
235 .max_speed_hz = 1500000,
236 .controller_data = &tsc2046_mcspi_config,
237 .irq = 0,
238 .platform_data = &tsc2046_config,
239 },
82}; 240};
83 241
84static inline void __init ldp_init_smsc911x(void) 242static inline void __init ldp_init_smsc911x(void)
@@ -122,8 +280,22 @@ static struct omap_uart_config ldp_uart_config __initdata = {
122 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 280 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
123}; 281};
124 282
283static struct platform_device ldp_lcd_device = {
284 .name = "ldp_lcd",
285 .id = -1,
286};
287
288static struct omap_lcd_config ldp_lcd_config __initdata = {
289 .ctrl_name = "internal",
290};
291
125static struct omap_board_config_kernel ldp_config[] __initdata = { 292static struct omap_board_config_kernel ldp_config[] __initdata = {
126 { OMAP_TAG_UART, &ldp_uart_config }, 293 { OMAP_TAG_UART, &ldp_uart_config },
294 { OMAP_TAG_LCD, &ldp_lcd_config },
295};
296
297static struct twl4030_usb_data ldp_usb_data = {
298 .usb_mode = T2_USB_MODE_ULPI,
127}; 299};
128 300
129static struct twl4030_gpio_platform_data ldp_gpio_data = { 301static struct twl4030_gpio_platform_data ldp_gpio_data = {
@@ -132,12 +304,39 @@ static struct twl4030_gpio_platform_data ldp_gpio_data = {
132 .irq_end = TWL4030_GPIO_IRQ_END, 304 .irq_end = TWL4030_GPIO_IRQ_END,
133}; 305};
134 306
307static struct twl4030_madc_platform_data ldp_madc_data = {
308 .irq_line = 1,
309};
310
311static struct regulator_consumer_supply ldp_vmmc1_supply = {
312 .supply = "vmmc",
313};
314
315/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
316static struct regulator_init_data ldp_vmmc1 = {
317 .constraints = {
318 .min_uV = 1850000,
319 .max_uV = 3150000,
320 .valid_modes_mask = REGULATOR_MODE_NORMAL
321 | REGULATOR_MODE_STANDBY,
322 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
323 | REGULATOR_CHANGE_MODE
324 | REGULATOR_CHANGE_STATUS,
325 },
326 .num_consumer_supplies = 1,
327 .consumer_supplies = &ldp_vmmc1_supply,
328};
329
135static struct twl4030_platform_data ldp_twldata = { 330static struct twl4030_platform_data ldp_twldata = {
136 .irq_base = TWL4030_IRQ_BASE, 331 .irq_base = TWL4030_IRQ_BASE,
137 .irq_end = TWL4030_IRQ_END, 332 .irq_end = TWL4030_IRQ_END,
138 333
139 /* platform_data for children goes here */ 334 /* platform_data for children goes here */
335 .madc = &ldp_madc_data,
336 .usb = &ldp_usb_data,
337 .vmmc1 = &ldp_vmmc1,
140 .gpio = &ldp_gpio_data, 338 .gpio = &ldp_gpio_data,
339 .keypad = &ldp_kp_twl4030_data,
141}; 340};
142 341
143static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { 342static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
@@ -168,15 +367,29 @@ static struct twl4030_hsmmc_info mmc[] __initdata = {
168 {} /* Terminator */ 367 {} /* Terminator */
169}; 368};
170 369
370static struct platform_device *ldp_devices[] __initdata = {
371 &ldp_smsc911x_device,
372 &ldp_lcd_device,
373 &ldp_gpio_keys_device,
374};
375
171static void __init omap_ldp_init(void) 376static void __init omap_ldp_init(void)
172{ 377{
173 omap_i2c_init(); 378 omap_i2c_init();
174 platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); 379 platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
175 omap_board_config = ldp_config; 380 omap_board_config = ldp_config;
176 omap_board_config_size = ARRAY_SIZE(ldp_config); 381 omap_board_config_size = ARRAY_SIZE(ldp_config);
382 ts_gpio = 54;
383 ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
384 spi_register_board_info(ldp_spi_board_info,
385 ARRAY_SIZE(ldp_spi_board_info));
386 ads7846_dev_init();
177 omap_serial_init(); 387 omap_serial_init();
178 twl4030_mmc_init(mmc);
179 usb_musb_init(); 388 usb_musb_init();
389
390 twl4030_mmc_init(mmc);
391 /* link regulators to MMC adapters */
392 ldp_vmmc1_supply.dev = mmc[0].dev;
180} 393}
181 394
182static void __init omap_ldp_map_io(void) 395static void __init omap_ldp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 3a7a29d1f9a7..991ac9c38032 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -28,6 +28,7 @@
28#include <linux/mtd/partitions.h> 28#include <linux/mtd/partitions.h>
29#include <linux/mtd/nand.h> 29#include <linux/mtd/nand.h>
30 30
31#include <linux/regulator/machine.h>
31#include <linux/i2c/twl4030.h> 32#include <linux/i2c/twl4030.h>
32 33
33#include <mach/hardware.h> 34#include <mach/hardware.h>
@@ -105,6 +106,8 @@ static struct platform_device omap3beagle_nand_device = {
105 .resource = &omap3beagle_nand_resource, 106 .resource = &omap3beagle_nand_resource,
106}; 107};
107 108
109#include "sdram-micron-mt46h32m32lf-6.h"
110
108static struct omap_uart_config omap3_beagle_uart_config __initdata = { 111static struct omap_uart_config omap3_beagle_uart_config __initdata = {
109 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 112 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
110}; 113};
@@ -118,6 +121,23 @@ static struct twl4030_hsmmc_info mmc[] = {
118 {} /* Terminator */ 121 {} /* Terminator */
119}; 122};
120 123
124static struct platform_device omap3_beagle_lcd_device = {
125 .name = "omap3beagle_lcd",
126 .id = -1,
127};
128
129static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
130 .ctrl_name = "internal",
131};
132
133static struct regulator_consumer_supply beagle_vmmc1_supply = {
134 .supply = "vmmc",
135};
136
137static struct regulator_consumer_supply beagle_vsim_supply = {
138 .supply = "vmmc_aux",
139};
140
121static struct gpio_led gpio_leds[]; 141static struct gpio_led gpio_leds[];
122 142
123static int beagle_twl_gpio_setup(struct device *dev, 143static int beagle_twl_gpio_setup(struct device *dev,
@@ -128,6 +148,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
128 mmc[0].gpio_cd = gpio + 0; 148 mmc[0].gpio_cd = gpio + 0;
129 twl4030_mmc_init(mmc); 149 twl4030_mmc_init(mmc);
130 150
151 /* link regulators to MMC adapters */
152 beagle_vmmc1_supply.dev = mmc[0].dev;
153 beagle_vsim_supply.dev = mmc[0].dev;
154
131 /* REVISIT: need ehci-omap hooks for external VBUS 155 /* REVISIT: need ehci-omap hooks for external VBUS
132 * power switch and overcurrent detect 156 * power switch and overcurrent detect
133 */ 157 */
@@ -156,12 +180,85 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = {
156 .setup = beagle_twl_gpio_setup, 180 .setup = beagle_twl_gpio_setup,
157}; 181};
158 182
183static struct regulator_consumer_supply beagle_vdac_supply = {
184 .supply = "vdac",
185 .dev = &omap3_beagle_lcd_device.dev,
186};
187
188static struct regulator_consumer_supply beagle_vdvi_supply = {
189 .supply = "vdvi",
190 .dev = &omap3_beagle_lcd_device.dev,
191};
192
193/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
194static struct regulator_init_data beagle_vmmc1 = {
195 .constraints = {
196 .min_uV = 1850000,
197 .max_uV = 3150000,
198 .valid_modes_mask = REGULATOR_MODE_NORMAL
199 | REGULATOR_MODE_STANDBY,
200 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
201 | REGULATOR_CHANGE_MODE
202 | REGULATOR_CHANGE_STATUS,
203 },
204 .num_consumer_supplies = 1,
205 .consumer_supplies = &beagle_vmmc1_supply,
206};
207
208/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
209static struct regulator_init_data beagle_vsim = {
210 .constraints = {
211 .min_uV = 1800000,
212 .max_uV = 3000000,
213 .valid_modes_mask = REGULATOR_MODE_NORMAL
214 | REGULATOR_MODE_STANDBY,
215 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
216 | REGULATOR_CHANGE_MODE
217 | REGULATOR_CHANGE_STATUS,
218 },
219 .num_consumer_supplies = 1,
220 .consumer_supplies = &beagle_vsim_supply,
221};
222
223/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
224static struct regulator_init_data beagle_vdac = {
225 .constraints = {
226 .min_uV = 1800000,
227 .max_uV = 1800000,
228 .valid_modes_mask = REGULATOR_MODE_NORMAL
229 | REGULATOR_MODE_STANDBY,
230 .valid_ops_mask = REGULATOR_CHANGE_MODE
231 | REGULATOR_CHANGE_STATUS,
232 },
233 .num_consumer_supplies = 1,
234 .consumer_supplies = &beagle_vdac_supply,
235};
236
237/* VPLL2 for digital video outputs */
238static struct regulator_init_data beagle_vpll2 = {
239 .constraints = {
240 .name = "VDVI",
241 .min_uV = 1800000,
242 .max_uV = 1800000,
243 .valid_modes_mask = REGULATOR_MODE_NORMAL
244 | REGULATOR_MODE_STANDBY,
245 .valid_ops_mask = REGULATOR_CHANGE_MODE
246 | REGULATOR_CHANGE_STATUS,
247 },
248 .num_consumer_supplies = 1,
249 .consumer_supplies = &beagle_vdvi_supply,
250};
251
159static struct twl4030_platform_data beagle_twldata = { 252static struct twl4030_platform_data beagle_twldata = {
160 .irq_base = TWL4030_IRQ_BASE, 253 .irq_base = TWL4030_IRQ_BASE,
161 .irq_end = TWL4030_IRQ_END, 254 .irq_end = TWL4030_IRQ_END,
162 255
163 /* platform_data for children goes here */ 256 /* platform_data for children goes here */
164 .gpio = &beagle_gpio_data, 257 .gpio = &beagle_gpio_data,
258 .vmmc1 = &beagle_vmmc1,
259 .vsim = &beagle_vsim,
260 .vdac = &beagle_vdac,
261 .vpll2 = &beagle_vpll2,
165}; 262};
166 263
167static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { 264static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
@@ -185,7 +282,7 @@ static int __init omap3_beagle_i2c_init(void)
185 282
186static void __init omap3_beagle_init_irq(void) 283static void __init omap3_beagle_init_irq(void)
187{ 284{
188 omap2_init_common_hw(NULL); 285 omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
189 omap_init_irq(); 286 omap_init_irq();
190#ifdef CONFIG_OMAP_32K_TIMER 287#ifdef CONFIG_OMAP_32K_TIMER
191 omap2_gp_clockevent_set_gptimer(12); 288 omap2_gp_clockevent_set_gptimer(12);
@@ -193,15 +290,6 @@ static void __init omap3_beagle_init_irq(void)
193 omap_gpio_init(); 290 omap_gpio_init();
194} 291}
195 292
196static struct platform_device omap3_beagle_lcd_device = {
197 .name = "omap3beagle_lcd",
198 .id = -1,
199};
200
201static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
202 .ctrl_name = "internal",
203};
204
205static struct gpio_led gpio_leds[] = { 293static struct gpio_led gpio_leds[] = {
206 { 294 {
207 .name = "beagleboard::usr0", 295 .name = "beagleboard::usr0",
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
new file mode 100644
index 000000000000..d3cc145814d0
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -0,0 +1,329 @@
1/*
2 * linux/arch/arm/mach-omap2/board-omap3evm.c
3 *
4 * Copyright (C) 2008 Texas Instruments
5 *
6 * Modified from mach-omap2/board-3430sdp.c
7 *
8 * Initial code: Syed Mohammed Khasim
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/clk.h>
21#include <linux/gpio.h>
22#include <linux/input.h>
23#include <linux/leds.h>
24
25#include <linux/spi/spi.h>
26#include <linux/spi/ads7846.h>
27#include <linux/i2c/twl4030.h>
28
29#include <mach/hardware.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33
34#include <mach/board.h>
35#include <mach/mux.h>
36#include <mach/usb.h>
37#include <mach/common.h>
38#include <mach/mcspi.h>
39#include <mach/keypad.h>
40
41#include "sdram-micron-mt46h32m32lf-6.h"
42#include "mmc-twl4030.h"
43
44#define OMAP3_EVM_TS_GPIO 175
45
46#define OMAP3EVM_ETHR_START 0x2c000000
47#define OMAP3EVM_ETHR_SIZE 1024
48#define OMAP3EVM_ETHR_GPIO_IRQ 176
49#define OMAP3EVM_SMC911X_CS 5
50
51static struct resource omap3evm_smc911x_resources[] = {
52 [0] = {
53 .start = OMAP3EVM_ETHR_START,
54 .end = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
55 .flags = IORESOURCE_MEM,
56 },
57 [1] = {
58 .start = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
59 .end = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
60 .flags = IORESOURCE_IRQ,
61 },
62};
63
64static struct platform_device omap3evm_smc911x_device = {
65 .name = "smc911x",
66 .id = -1,
67 .num_resources = ARRAY_SIZE(omap3evm_smc911x_resources),
68 .resource = &omap3evm_smc911x_resources[0],
69};
70
71static inline void __init omap3evm_init_smc911x(void)
72{
73 int eth_cs;
74 struct clk *l3ck;
75 unsigned int rate;
76
77 eth_cs = OMAP3EVM_SMC911X_CS;
78
79 l3ck = clk_get(NULL, "l3_ck");
80 if (IS_ERR(l3ck))
81 rate = 100000000;
82 else
83 rate = clk_get_rate(l3ck);
84
85 if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
86 printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
87 OMAP3EVM_ETHR_GPIO_IRQ);
88 return;
89 }
90
91 gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
92}
93
94static struct omap_uart_config omap3_evm_uart_config __initdata = {
95 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
96};
97
98static struct twl4030_hsmmc_info mmc[] = {
99 {
100 .mmc = 1,
101 .wires = 4,
102 .gpio_cd = -EINVAL,
103 .gpio_wp = 63,
104 },
105 {} /* Terminator */
106};
107
108static struct gpio_led gpio_leds[] = {
109 {
110 .name = "omap3evm::ledb",
111 /* normally not visible (board underside) */
112 .default_trigger = "default-on",
113 .gpio = -EINVAL, /* gets replaced */
114 .active_low = true,
115 },
116};
117
118static struct gpio_led_platform_data gpio_led_info = {
119 .leds = gpio_leds,
120 .num_leds = ARRAY_SIZE(gpio_leds),
121};
122
123static struct platform_device leds_gpio = {
124 .name = "leds-gpio",
125 .id = -1,
126 .dev = {
127 .platform_data = &gpio_led_info,
128 },
129};
130
131
132static int omap3evm_twl_gpio_setup(struct device *dev,
133 unsigned gpio, unsigned ngpio)
134{
135 /* gpio + 0 is "mmc0_cd" (input/IRQ) */
136 omap_cfg_reg(L8_34XX_GPIO63);
137 mmc[0].gpio_cd = gpio + 0;
138 twl4030_mmc_init(mmc);
139
140 /*
141 * Most GPIOs are for USB OTG. Some are mostly sent to
142 * the P2 connector; notably LEDA for the LCD backlight.
143 */
144
145 /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
146 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
147
148 platform_device_register(&leds_gpio);
149
150 return 0;
151}
152
153static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
154 .gpio_base = OMAP_MAX_GPIO_LINES,
155 .irq_base = TWL4030_GPIO_IRQ_BASE,
156 .irq_end = TWL4030_GPIO_IRQ_END,
157 .use_leds = true,
158 .setup = omap3evm_twl_gpio_setup,
159};
160
161static struct twl4030_usb_data omap3evm_usb_data = {
162 .usb_mode = T2_USB_MODE_ULPI,
163};
164
165static int omap3evm_keymap[] = {
166 KEY(0, 0, KEY_LEFT),
167 KEY(0, 1, KEY_RIGHT),
168 KEY(0, 2, KEY_A),
169 KEY(0, 3, KEY_B),
170 KEY(1, 0, KEY_DOWN),
171 KEY(1, 1, KEY_UP),
172 KEY(1, 2, KEY_E),
173 KEY(1, 3, KEY_F),
174 KEY(2, 0, KEY_ENTER),
175 KEY(2, 1, KEY_I),
176 KEY(2, 2, KEY_J),
177 KEY(2, 3, KEY_K),
178 KEY(3, 0, KEY_M),
179 KEY(3, 1, KEY_N),
180 KEY(3, 2, KEY_O),
181 KEY(3, 3, KEY_P)
182};
183
184static struct twl4030_keypad_data omap3evm_kp_data = {
185 .rows = 4,
186 .cols = 4,
187 .keymap = omap3evm_keymap,
188 .keymapsize = ARRAY_SIZE(omap3evm_keymap),
189 .rep = 1,
190};
191
192static struct twl4030_madc_platform_data omap3evm_madc_data = {
193 .irq_line = 1,
194};
195
196static struct twl4030_platform_data omap3evm_twldata = {
197 .irq_base = TWL4030_IRQ_BASE,
198 .irq_end = TWL4030_IRQ_END,
199
200 /* platform_data for children goes here */
201 .keypad = &omap3evm_kp_data,
202 .madc = &omap3evm_madc_data,
203 .usb = &omap3evm_usb_data,
204 .gpio = &omap3evm_gpio_data,
205};
206
207static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
208 {
209 I2C_BOARD_INFO("twl4030", 0x48),
210 .flags = I2C_CLIENT_WAKE,
211 .irq = INT_34XX_SYS_NIRQ,
212 .platform_data = &omap3evm_twldata,
213 },
214};
215
216static int __init omap3_evm_i2c_init(void)
217{
218 omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
219 ARRAY_SIZE(omap3evm_i2c_boardinfo));
220 omap_register_i2c_bus(2, 400, NULL, 0);
221 omap_register_i2c_bus(3, 400, NULL, 0);
222 return 0;
223}
224
225static struct platform_device omap3_evm_lcd_device = {
226 .name = "omap3evm_lcd",
227 .id = -1,
228};
229
230static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
231 .ctrl_name = "internal",
232};
233
234static void ads7846_dev_init(void)
235{
236 if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
237 printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
238
239 gpio_direction_input(OMAP3_EVM_TS_GPIO);
240
241 omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1);
242 omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa);
243}
244
245static int ads7846_get_pendown_state(void)
246{
247 return !gpio_get_value(OMAP3_EVM_TS_GPIO);
248}
249
250struct ads7846_platform_data ads7846_config = {
251 .x_max = 0x0fff,
252 .y_max = 0x0fff,
253 .x_plate_ohms = 180,
254 .pressure_max = 255,
255 .debounce_max = 10,
256 .debounce_tol = 3,
257 .debounce_rep = 1,
258 .get_pendown_state = ads7846_get_pendown_state,
259 .keep_vref_on = 1,
260 .settle_delay_usecs = 150,
261};
262
263static struct omap2_mcspi_device_config ads7846_mcspi_config = {
264 .turbo_mode = 0,
265 .single_channel = 1, /* 0: slave, 1: master */
266};
267
268struct spi_board_info omap3evm_spi_board_info[] = {
269 [0] = {
270 .modalias = "ads7846",
271 .bus_num = 1,
272 .chip_select = 0,
273 .max_speed_hz = 1500000,
274 .controller_data = &ads7846_mcspi_config,
275 .irq = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO),
276 .platform_data = &ads7846_config,
277 },
278};
279
280static void __init omap3_evm_init_irq(void)
281{
282 omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
283 omap_init_irq();
284 omap_gpio_init();
285 omap3evm_init_smc911x();
286}
287
288static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
289 { OMAP_TAG_UART, &omap3_evm_uart_config },
290 { OMAP_TAG_LCD, &omap3_evm_lcd_config },
291};
292
293static struct platform_device *omap3_evm_devices[] __initdata = {
294 &omap3_evm_lcd_device,
295 &omap3evm_smc911x_device,
296};
297
298static void __init omap3_evm_init(void)
299{
300 omap3_evm_i2c_init();
301
302 platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
303 omap_board_config = omap3_evm_config;
304 omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
305
306 spi_register_board_info(omap3evm_spi_board_info,
307 ARRAY_SIZE(omap3evm_spi_board_info));
308
309 omap_serial_init();
310 usb_musb_init();
311 ads7846_dev_init();
312}
313
314static void __init omap3_evm_map_io(void)
315{
316 omap2_set_globals_343x();
317 omap2_map_common_io();
318}
319
320MACHINE_START(OMAP3EVM, "OMAP3 EVM")
321 /* Maintainer: Syed Mohammed Khasim - Texas Instruments */
322 .phys_io = 0x48000000,
323 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
324 .boot_params = 0x80000100,
325 .map_io = omap3_evm_map_io,
326 .init_irq = omap3_evm_init_irq,
327 .init_machine = omap3_evm_init,
328 .timer = &omap_timer,
329MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 402f09c6cf10..e32aa23ce962 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -23,7 +23,11 @@
23 23
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25#include <linux/spi/ads7846.h> 25#include <linux/spi/ads7846.h>
26#include <linux/regulator/machine.h>
26#include <linux/i2c/twl4030.h> 27#include <linux/i2c/twl4030.h>
28#include <linux/leds.h>
29#include <linux/input.h>
30#include <linux/gpio_keys.h>
27 31
28#include <asm/mach-types.h> 32#include <asm/mach-types.h>
29#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
@@ -35,11 +39,154 @@
35#include <mach/hardware.h> 39#include <mach/hardware.h>
36#include <mach/mcspi.h> 40#include <mach/mcspi.h>
37#include <mach/usb.h> 41#include <mach/usb.h>
42#include <mach/keypad.h>
38 43
44#include "sdram-micron-mt46h32m32lf-6.h"
39#include "mmc-twl4030.h" 45#include "mmc-twl4030.h"
40 46
41#define OMAP3_PANDORA_TS_GPIO 94 47#define OMAP3_PANDORA_TS_GPIO 94
42 48
49/* hardware debounce: (value + 1) * 31us */
50#define GPIO_DEBOUNCE_TIME 127
51
52static struct gpio_led pandora_gpio_leds[] = {
53 {
54 .name = "pandora::sd1",
55 .default_trigger = "mmc0",
56 .gpio = 128,
57 }, {
58 .name = "pandora::sd2",
59 .default_trigger = "mmc1",
60 .gpio = 129,
61 }, {
62 .name = "pandora::bluetooth",
63 .gpio = 158,
64 }, {
65 .name = "pandora::wifi",
66 .gpio = 159,
67 },
68};
69
70static struct gpio_led_platform_data pandora_gpio_led_data = {
71 .leds = pandora_gpio_leds,
72 .num_leds = ARRAY_SIZE(pandora_gpio_leds),
73};
74
75static struct platform_device pandora_leds_gpio = {
76 .name = "leds-gpio",
77 .id = -1,
78 .dev = {
79 .platform_data = &pandora_gpio_led_data,
80 },
81};
82
83#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \
84{ \
85 .gpio = gpio_num, \
86 .type = ev_type, \
87 .code = ev_code, \
88 .active_low = act_low, \
89 .desc = "btn " descr, \
90}
91
92#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \
93 GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description)
94
95static struct gpio_keys_button pandora_gpio_keys[] = {
96 GPIO_BUTTON_LOW(110, KEY_UP, "up"),
97 GPIO_BUTTON_LOW(103, KEY_DOWN, "down"),
98 GPIO_BUTTON_LOW(96, KEY_LEFT, "left"),
99 GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"),
100 GPIO_BUTTON_LOW(111, BTN_A, "a"),
101 GPIO_BUTTON_LOW(106, BTN_B, "b"),
102 GPIO_BUTTON_LOW(109, BTN_X, "x"),
103 GPIO_BUTTON_LOW(101, BTN_Y, "y"),
104 GPIO_BUTTON_LOW(102, BTN_TL, "l"),
105 GPIO_BUTTON_LOW(97, BTN_TL2, "l2"),
106 GPIO_BUTTON_LOW(105, BTN_TR, "r"),
107 GPIO_BUTTON_LOW(107, BTN_TR2, "r2"),
108 GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"),
109 GPIO_BUTTON_LOW(99, KEY_MENU, "menu"),
110 GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"),
111 GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"),
112 GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"),
113};
114
115static struct gpio_keys_platform_data pandora_gpio_key_info = {
116 .buttons = pandora_gpio_keys,
117 .nbuttons = ARRAY_SIZE(pandora_gpio_keys),
118};
119
120static struct platform_device pandora_keys_gpio = {
121 .name = "gpio-keys",
122 .id = -1,
123 .dev = {
124 .platform_data = &pandora_gpio_key_info,
125 },
126};
127
128static void __init pandora_keys_gpio_init(void)
129{
130 /* set debounce time for GPIO banks 4 and 6 */
131 omap_set_gpio_debounce_time(32 * 3, GPIO_DEBOUNCE_TIME);
132 omap_set_gpio_debounce_time(32 * 5, GPIO_DEBOUNCE_TIME);
133}
134
135static int pandora_keypad_map[] = {
136 /* col, row, code */
137 KEY(0, 0, KEY_9),
138 KEY(0, 1, KEY_0),
139 KEY(0, 2, KEY_BACKSPACE),
140 KEY(0, 3, KEY_O),
141 KEY(0, 4, KEY_P),
142 KEY(0, 5, KEY_K),
143 KEY(0, 6, KEY_L),
144 KEY(0, 7, KEY_ENTER),
145 KEY(1, 0, KEY_8),
146 KEY(1, 1, KEY_7),
147 KEY(1, 2, KEY_6),
148 KEY(1, 3, KEY_5),
149 KEY(1, 4, KEY_4),
150 KEY(1, 5, KEY_3),
151 KEY(1, 6, KEY_2),
152 KEY(1, 7, KEY_1),
153 KEY(2, 0, KEY_I),
154 KEY(2, 1, KEY_U),
155 KEY(2, 2, KEY_Y),
156 KEY(2, 3, KEY_T),
157 KEY(2, 4, KEY_R),
158 KEY(2, 5, KEY_E),
159 KEY(2, 6, KEY_W),
160 KEY(2, 7, KEY_Q),
161 KEY(3, 0, KEY_J),
162 KEY(3, 1, KEY_H),
163 KEY(3, 2, KEY_G),
164 KEY(3, 3, KEY_F),
165 KEY(3, 4, KEY_D),
166 KEY(3, 5, KEY_S),
167 KEY(3, 6, KEY_A),
168 KEY(3, 7, KEY_LEFTSHIFT),
169 KEY(4, 0, KEY_N),
170 KEY(4, 1, KEY_B),
171 KEY(4, 2, KEY_V),
172 KEY(4, 3, KEY_C),
173 KEY(4, 4, KEY_X),
174 KEY(4, 5, KEY_Z),
175 KEY(4, 6, KEY_DOT),
176 KEY(4, 7, KEY_COMMA),
177 KEY(5, 0, KEY_M),
178 KEY(5, 1, KEY_SPACE),
179 KEY(5, 2, KEY_FN),
180};
181
182static struct twl4030_keypad_data pandora_kp_data = {
183 .rows = 8,
184 .cols = 6,
185 .keymap = pandora_keypad_map,
186 .keymapsize = ARRAY_SIZE(pandora_keypad_map),
187 .rep = 1,
188};
189
43static struct twl4030_hsmmc_info omap3pandora_mmc[] = { 190static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
44 { 191 {
45 .mmc = 1, 192 .mmc = 1,
@@ -69,6 +216,14 @@ static struct omap_uart_config omap3pandora_uart_config __initdata = {
69 .enabled_uarts = (1 << 2), /* UART3 */ 216 .enabled_uarts = (1 << 2), /* UART3 */
70}; 217};
71 218
219static struct regulator_consumer_supply pandora_vmmc1_supply = {
220 .supply = "vmmc",
221};
222
223static struct regulator_consumer_supply pandora_vmmc2_supply = {
224 .supply = "vmmc",
225};
226
72static int omap3pandora_twl_gpio_setup(struct device *dev, 227static int omap3pandora_twl_gpio_setup(struct device *dev,
73 unsigned gpio, unsigned ngpio) 228 unsigned gpio, unsigned ngpio)
74{ 229{
@@ -77,6 +232,10 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
77 omap3pandora_mmc[1].gpio_cd = gpio + 1; 232 omap3pandora_mmc[1].gpio_cd = gpio + 1;
78 twl4030_mmc_init(omap3pandora_mmc); 233 twl4030_mmc_init(omap3pandora_mmc);
79 234
235 /* link regulators to MMC adapters */
236 pandora_vmmc1_supply.dev = omap3pandora_mmc[0].dev;
237 pandora_vmmc2_supply.dev = omap3pandora_mmc[1].dev;
238
80 return 0; 239 return 0;
81} 240}
82 241
@@ -87,6 +246,36 @@ static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
87 .setup = omap3pandora_twl_gpio_setup, 246 .setup = omap3pandora_twl_gpio_setup,
88}; 247};
89 248
249/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
250static struct regulator_init_data pandora_vmmc1 = {
251 .constraints = {
252 .min_uV = 1850000,
253 .max_uV = 3150000,
254 .valid_modes_mask = REGULATOR_MODE_NORMAL
255 | REGULATOR_MODE_STANDBY,
256 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
257 | REGULATOR_CHANGE_MODE
258 | REGULATOR_CHANGE_STATUS,
259 },
260 .num_consumer_supplies = 1,
261 .consumer_supplies = &pandora_vmmc1_supply,
262};
263
264/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */
265static struct regulator_init_data pandora_vmmc2 = {
266 .constraints = {
267 .min_uV = 1850000,
268 .max_uV = 3150000,
269 .valid_modes_mask = REGULATOR_MODE_NORMAL
270 | REGULATOR_MODE_STANDBY,
271 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
272 | REGULATOR_CHANGE_MODE
273 | REGULATOR_CHANGE_STATUS,
274 },
275 .num_consumer_supplies = 1,
276 .consumer_supplies = &pandora_vmmc2_supply,
277};
278
90static struct twl4030_usb_data omap3pandora_usb_data = { 279static struct twl4030_usb_data omap3pandora_usb_data = {
91 .usb_mode = T2_USB_MODE_ULPI, 280 .usb_mode = T2_USB_MODE_ULPI,
92}; 281};
@@ -96,6 +285,9 @@ static struct twl4030_platform_data omap3pandora_twldata = {
96 .irq_end = TWL4030_IRQ_END, 285 .irq_end = TWL4030_IRQ_END,
97 .gpio = &omap3pandora_gpio_data, 286 .gpio = &omap3pandora_gpio_data,
98 .usb = &omap3pandora_usb_data, 287 .usb = &omap3pandora_usb_data,
288 .vmmc1 = &pandora_vmmc1,
289 .vmmc2 = &pandora_vmmc2,
290 .keypad = &pandora_kp_data,
99}; 291};
100 292
101static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { 293static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
@@ -118,7 +310,7 @@ static int __init omap3pandora_i2c_init(void)
118 310
119static void __init omap3pandora_init_irq(void) 311static void __init omap3pandora_init_irq(void)
120{ 312{
121 omap2_init_common_hw(NULL); 313 omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
122 omap_init_irq(); 314 omap_init_irq();
123 omap_gpio_init(); 315 omap_gpio_init();
124} 316}
@@ -188,6 +380,8 @@ static struct omap_board_config_kernel omap3pandora_config[] __initdata = {
188 380
189static struct platform_device *omap3pandora_devices[] __initdata = { 381static struct platform_device *omap3pandora_devices[] __initdata = {
190 &omap3pandora_lcd_device, 382 &omap3pandora_lcd_device,
383 &pandora_leds_gpio,
384 &pandora_keys_gpio,
191}; 385};
192 386
193static void __init omap3pandora_init(void) 387static void __init omap3pandora_init(void)
@@ -201,6 +395,7 @@ static void __init omap3pandora_init(void)
201 spi_register_board_info(omap3pandora_spi_board_info, 395 spi_register_board_info(omap3pandora_spi_board_info,
202 ARRAY_SIZE(omap3pandora_spi_board_info)); 396 ARRAY_SIZE(omap3pandora_spi_board_info));
203 omap3pandora_ads7846_init(); 397 omap3pandora_ads7846_init();
398 pandora_keys_gpio_init();
204 usb_musb_init(); 399 usb_musb_init();
205} 400}
206 401
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b1f23bea863f..dff5528fbfb5 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h> 29#include <linux/i2c/twl4030.h>
30#include <linux/regulator/machine.h>
30 31
31#include <linux/mtd/mtd.h> 32#include <linux/mtd/mtd.h>
32#include <linux/mtd/nand.h> 33#include <linux/mtd/nand.h>
@@ -45,6 +46,7 @@
45#include <mach/nand.h> 46#include <mach/nand.h>
46#include <mach/usb.h> 47#include <mach/usb.h>
47 48
49#include "sdram-micron-mt46h32m32lf-6.h"
48#include "mmc-twl4030.h" 50#include "mmc-twl4030.h"
49 51
50#define OVERO_GPIO_BT_XGATE 15 52#define OVERO_GPIO_BT_XGATE 15
@@ -271,21 +273,76 @@ static struct omap_uart_config overo_uart_config __initdata = {
271 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 273 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
272}; 274};
273 275
276static struct twl4030_hsmmc_info mmc[] = {
277 {
278 .mmc = 1,
279 .wires = 4,
280 .gpio_cd = -EINVAL,
281 .gpio_wp = -EINVAL,
282 },
283 {
284 .mmc = 2,
285 .wires = 4,
286 .gpio_cd = -EINVAL,
287 .gpio_wp = -EINVAL,
288 .transceiver = true,
289 .ocr_mask = 0x00100000, /* 3.3V */
290 },
291 {} /* Terminator */
292};
293
294static struct regulator_consumer_supply overo_vmmc1_supply = {
295 .supply = "vmmc",
296};
297
298static int overo_twl_gpio_setup(struct device *dev,
299 unsigned gpio, unsigned ngpio)
300{
301 twl4030_mmc_init(mmc);
302
303 overo_vmmc1_supply.dev = mmc[0].dev;
304
305 return 0;
306}
307
274static struct twl4030_gpio_platform_data overo_gpio_data = { 308static struct twl4030_gpio_platform_data overo_gpio_data = {
275 .gpio_base = OMAP_MAX_GPIO_LINES, 309 .gpio_base = OMAP_MAX_GPIO_LINES,
276 .irq_base = TWL4030_GPIO_IRQ_BASE, 310 .irq_base = TWL4030_GPIO_IRQ_BASE,
277 .irq_end = TWL4030_GPIO_IRQ_END, 311 .irq_end = TWL4030_GPIO_IRQ_END,
312 .setup = overo_twl_gpio_setup,
313};
314
315static struct twl4030_usb_data overo_usb_data = {
316 .usb_mode = T2_USB_MODE_ULPI,
317};
318
319static struct regulator_init_data overo_vmmc1 = {
320 .constraints = {
321 .min_uV = 1850000,
322 .max_uV = 3150000,
323 .valid_modes_mask = REGULATOR_MODE_NORMAL
324 | REGULATOR_MODE_STANDBY,
325 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
326 | REGULATOR_CHANGE_MODE
327 | REGULATOR_CHANGE_STATUS,
328 },
329 .num_consumer_supplies = 1,
330 .consumer_supplies = &overo_vmmc1_supply,
278}; 331};
279 332
333/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
334
280static struct twl4030_platform_data overo_twldata = { 335static struct twl4030_platform_data overo_twldata = {
281 .irq_base = TWL4030_IRQ_BASE, 336 .irq_base = TWL4030_IRQ_BASE,
282 .irq_end = TWL4030_IRQ_END, 337 .irq_end = TWL4030_IRQ_END,
283 .gpio = &overo_gpio_data, 338 .gpio = &overo_gpio_data,
339 .usb = &overo_usb_data,
340 .vmmc1 = &overo_vmmc1,
284}; 341};
285 342
286static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { 343static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
287 { 344 {
288 I2C_BOARD_INFO("twl4030", 0x48), 345 I2C_BOARD_INFO("tps65950", 0x48),
289 .flags = I2C_CLIENT_WAKE, 346 .flags = I2C_CLIENT_WAKE,
290 .irq = INT_34XX_SYS_NIRQ, 347 .irq = INT_34XX_SYS_NIRQ,
291 .platform_data = &overo_twldata, 348 .platform_data = &overo_twldata,
@@ -303,7 +360,7 @@ static int __init overo_i2c_init(void)
303 360
304static void __init overo_init_irq(void) 361static void __init overo_init_irq(void)
305{ 362{
306 omap2_init_common_hw(NULL); 363 omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
307 omap_init_irq(); 364 omap_init_irq();
308 omap_gpio_init(); 365 omap_gpio_init();
309} 366}
@@ -326,23 +383,6 @@ static struct platform_device *overo_devices[] __initdata = {
326 &overo_lcd_device, 383 &overo_lcd_device,
327}; 384};
328 385
329static struct twl4030_hsmmc_info mmc[] __initdata = {
330 {
331 .mmc = 1,
332 .wires = 4,
333 .gpio_cd = -EINVAL,
334 .gpio_wp = -EINVAL,
335 },
336 {
337 .mmc = 2,
338 .wires = 4,
339 .gpio_cd = -EINVAL,
340 .gpio_wp = -EINVAL,
341 .transceiver = true,
342 },
343 {} /* Terminator */
344};
345
346static void __init overo_init(void) 386static void __init overo_init(void)
347{ 387{
348 overo_i2c_init(); 388 overo_i2c_init();
@@ -350,7 +390,6 @@ static void __init overo_init(void)
350 omap_board_config = overo_config; 390 omap_board_config = overo_config;
351 omap_board_config_size = ARRAY_SIZE(overo_config); 391 omap_board_config_size = ARRAY_SIZE(overo_config);
352 omap_serial_init(); 392 omap_serial_init();
353 twl4030_mmc_init(mmc);
354 overo_flash_init(); 393 overo_flash_init();
355 usb_musb_init(); 394 usb_musb_init();
356 overo_ads7846_init(); 395 overo_ads7846_init();
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index a7381729645c..da93b86234ed 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -27,30 +27,13 @@
27#include <mach/dma.h> 27#include <mach/dma.h>
28#include <mach/gpmc.h> 28#include <mach/gpmc.h>
29#include <mach/keypad.h> 29#include <mach/keypad.h>
30#include <mach/onenand.h>
31#include <mach/gpmc-smc91x.h>
30 32
31#include "mmc-twl4030.h" 33#include "mmc-twl4030.h"
32 34
33 35#define SYSTEM_REV_B_USES_VAUX3 0x1699
34#define SMC91X_CS 1 36#define SYSTEM_REV_S_USES_VAUX3 0x8
35#define SMC91X_GPIO_IRQ 54
36#define SMC91X_GPIO_RESET 164
37#define SMC91X_GPIO_PWRDWN 86
38
39static struct resource rx51_smc91x_resources[] = {
40 [0] = {
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
45 },
46};
47
48static struct platform_device rx51_smc91x_device = {
49 .name = "smc91x",
50 .id = -1,
51 .num_resources = ARRAY_SIZE(rx51_smc91x_resources),
52 .resource = rx51_smc91x_resources,
53};
54 37
55static int rx51_keymap[] = { 38static int rx51_keymap[] = {
56 KEY(0, 0, KEY_Q), 39 KEY(0, 0, KEY_Q),
@@ -107,98 +90,6 @@ static struct twl4030_keypad_data rx51_kp_data = {
107 .rep = 1, 90 .rep = 1,
108}; 91};
109 92
110static struct platform_device *rx51_peripherals_devices[] = {
111 &rx51_smc91x_device,
112};
113
114/*
115 * Timings are taken from smsc-lan91c96-ms.pdf
116 */
117static int smc91x_init_gpmc(int cs)
118{
119 struct gpmc_timings t;
120 const int t2_r = 45; /* t2 in Figure 12.10 */
121 const int t2_w = 30; /* t2 in Figure 12.11 */
122 const int t3 = 15; /* t3 in Figure 12.10 */
123 const int t5_r = 0; /* t5 in Figure 12.10 */
124 const int t6_r = 45; /* t6 in Figure 12.10 */
125 const int t6_w = 0; /* t6 in Figure 12.11 */
126 const int t7_w = 15; /* t7 in Figure 12.11 */
127 const int t15 = 12; /* t15 in Figure 12.2 */
128 const int t20 = 185; /* t20 in Figure 12.2 */
129
130 memset(&t, 0, sizeof(t));
131
132 t.cs_on = t15;
133 t.cs_rd_off = t3 + t2_r + t5_r; /* Figure 12.10 */
134 t.cs_wr_off = t3 + t2_w + t6_w; /* Figure 12.11 */
135 t.adv_on = t3; /* Figure 12.10 */
136 t.adv_rd_off = t3 + t2_r; /* Figure 12.10 */
137 t.adv_wr_off = t3 + t2_w; /* Figure 12.11 */
138 t.oe_off = t3 + t2_r + t5_r; /* Figure 12.10 */
139 t.oe_on = t.oe_off - t6_r; /* Figure 12.10 */
140 t.we_off = t3 + t2_w + t6_w; /* Figure 12.11 */
141 t.we_on = t.we_off - t7_w; /* Figure 12.11 */
142 t.rd_cycle = t20; /* Figure 12.2 */
143 t.wr_cycle = t20; /* Figure 12.4 */
144 t.access = t3 + t2_r + t5_r; /* Figure 12.10 */
145 t.wr_access = t3 + t2_w + t6_w; /* Figure 12.11 */
146
147 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16);
148
149 return gpmc_cs_set_timings(cs, &t);
150}
151
152static void __init rx51_init_smc91x(void)
153{
154 unsigned long cs_mem_base;
155 int ret;
156
157 omap_cfg_reg(U8_34XX_GPIO54_DOWN);
158 omap_cfg_reg(G25_34XX_GPIO86_OUT);
159 omap_cfg_reg(H19_34XX_GPIO164_OUT);
160
161 if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) {
162 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
163 return;
164 }
165
166 rx51_smc91x_resources[0].start = cs_mem_base + 0x300;
167 rx51_smc91x_resources[0].end = cs_mem_base + 0x30f;
168
169 smc91x_init_gpmc(SMC91X_CS);
170
171 if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0)
172 goto free1;
173
174 gpio_direction_input(SMC91X_GPIO_IRQ);
175 rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ);
176
177 ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown");
178 if (ret)
179 goto free2;
180 gpio_direction_output(SMC91X_GPIO_PWRDWN, 0);
181
182 ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset");
183 if (ret)
184 goto free3;
185 gpio_direction_output(SMC91X_GPIO_RESET, 0);
186 gpio_set_value(SMC91X_GPIO_RESET, 1);
187 msleep(100);
188 gpio_set_value(SMC91X_GPIO_RESET, 0);
189
190 return;
191
192free3:
193 gpio_free(SMC91X_GPIO_PWRDWN);
194free2:
195 gpio_free(SMC91X_GPIO_IRQ);
196free1:
197 gpmc_cs_free(SMC91X_CS);
198
199 printk(KERN_ERR "Could not initialize smc91x\n");
200}
201
202static struct twl4030_madc_platform_data rx51_madc_data = { 93static struct twl4030_madc_platform_data rx51_madc_data = {
203 .irq_line = 1, 94 .irq_line = 1,
204}; 95};
@@ -259,7 +150,7 @@ static struct regulator_init_data rx51_vaux2 = {
259}; 150};
260 151
261/* VAUX3 - adds more power to VIO_18 rail */ 152/* VAUX3 - adds more power to VIO_18 rail */
262static struct regulator_init_data rx51_vaux3 = { 153static struct regulator_init_data rx51_vaux3_cam = {
263 .constraints = { 154 .constraints = {
264 .name = "VCAM_DIG_18", 155 .name = "VCAM_DIG_18",
265 .min_uV = 1800000, 156 .min_uV = 1800000,
@@ -272,6 +163,22 @@ static struct regulator_init_data rx51_vaux3 = {
272 }, 163 },
273}; 164};
274 165
166static struct regulator_init_data rx51_vaux3_mmc = {
167 .constraints = {
168 .name = "VMMC2_30",
169 .min_uV = 2800000,
170 .max_uV = 3000000,
171 .apply_uV = true,
172 .valid_modes_mask = REGULATOR_MODE_NORMAL
173 | REGULATOR_MODE_STANDBY,
174 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
175 | REGULATOR_CHANGE_MODE
176 | REGULATOR_CHANGE_STATUS,
177 },
178 .num_consumer_supplies = 1,
179 .consumer_supplies = &rx51_vmmc2_supply,
180};
181
275static struct regulator_init_data rx51_vaux4 = { 182static struct regulator_init_data rx51_vaux4 = {
276 .constraints = { 183 .constraints = {
277 .name = "VCAM_ANA_28", 184 .name = "VCAM_ANA_28",
@@ -382,10 +289,8 @@ static struct twl4030_platform_data rx51_twldata = {
382 289
383 .vaux1 = &rx51_vaux1, 290 .vaux1 = &rx51_vaux1,
384 .vaux2 = &rx51_vaux2, 291 .vaux2 = &rx51_vaux2,
385 .vaux3 = &rx51_vaux3,
386 .vaux4 = &rx51_vaux4, 292 .vaux4 = &rx51_vaux4,
387 .vmmc1 = &rx51_vmmc1, 293 .vmmc1 = &rx51_vmmc1,
388 .vmmc2 = &rx51_vmmc2,
389 .vsim = &rx51_vsim, 294 .vsim = &rx51_vsim,
390 .vdac = &rx51_vdac, 295 .vdac = &rx51_vdac,
391}; 296};
@@ -401,6 +306,13 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
401 306
402static int __init rx51_i2c_init(void) 307static int __init rx51_i2c_init(void)
403{ 308{
309 if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
310 system_rev >= SYSTEM_REV_B_USES_VAUX3)
311 rx51_twldata.vaux3 = &rx51_vaux3_mmc;
312 else {
313 rx51_twldata.vaux3 = &rx51_vaux3_cam;
314 rx51_twldata.vmmc2 = &rx51_vmmc2;
315 }
404 omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, 316 omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
405 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); 317 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
406 omap_register_i2c_bus(2, 100, NULL, 0); 318 omap_register_i2c_bus(2, 100, NULL, 0);
@@ -408,12 +320,94 @@ static int __init rx51_i2c_init(void)
408 return 0; 320 return 0;
409} 321}
410 322
323#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
324 defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
325
326static struct mtd_partition onenand_partitions[] = {
327 {
328 .name = "bootloader",
329 .offset = 0,
330 .size = 0x20000,
331 .mask_flags = MTD_WRITEABLE, /* Force read-only */
332 },
333 {
334 .name = "config",
335 .offset = MTDPART_OFS_APPEND,
336 .size = 0x60000,
337 },
338 {
339 .name = "log",
340 .offset = MTDPART_OFS_APPEND,
341 .size = 0x40000,
342 },
343 {
344 .name = "kernel",
345 .offset = MTDPART_OFS_APPEND,
346 .size = 0x200000,
347 },
348 {
349 .name = "initfs",
350 .offset = MTDPART_OFS_APPEND,
351 .size = 0x200000,
352 },
353 {
354 .name = "rootfs",
355 .offset = MTDPART_OFS_APPEND,
356 .size = MTDPART_SIZ_FULL,
357 },
358};
359
360static struct omap_onenand_platform_data board_onenand_data = {
361 .cs = 0,
362 .gpio_irq = 65,
363 .parts = onenand_partitions,
364 .nr_parts = ARRAY_SIZE(onenand_partitions),
365};
366
367static void __init board_onenand_init(void)
368{
369 gpmc_onenand_init(&board_onenand_data);
370}
371
372#else
373
374static inline void board_onenand_init(void)
375{
376}
377
378#endif
379
380#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
381
382static struct omap_smc91x_platform_data board_smc91x_data = {
383 .cs = 1,
384 .gpio_irq = 54,
385 .gpio_pwrdwn = 86,
386 .gpio_reset = 164,
387 .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
388};
389
390static void __init board_smc91x_init(void)
391{
392 omap_cfg_reg(U8_34XX_GPIO54_DOWN);
393 omap_cfg_reg(G25_34XX_GPIO86_OUT);
394 omap_cfg_reg(H19_34XX_GPIO164_OUT);
395
396 gpmc_smc91x_init(&board_smc91x_data);
397}
398
399#else
400
401static inline void board_smc91x_init(void)
402{
403}
404
405#endif
411 406
412void __init rx51_peripherals_init(void) 407void __init rx51_peripherals_init(void)
413{ 408{
414 platform_add_devices(rx51_peripherals_devices,
415 ARRAY_SIZE(rx51_peripherals_devices));
416 rx51_i2c_init(); 409 rx51_i2c_init();
417 rx51_init_smc91x(); 410 board_onenand_init();
411 board_smc91x_init();
418} 412}
419 413
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
new file mode 100644
index 000000000000..bac5c4321ff7
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc.
3 * Mikkel Christensen <mlc@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/gpio.h>
13#include <linux/serial_8250.h>
14#include <linux/smsc911x.h>
15
16#include <mach/gpmc.h>
17
18#define ZOOM2_SMSC911X_CS 7
19#define ZOOM2_SMSC911X_GPIO 158
20#define ZOOM2_QUADUART_CS 3
21#define ZOOM2_QUADUART_GPIO 102
22#define QUART_CLK 1843200
23#define DEBUG_BASE 0x08000000
24#define ZOOM2_ETHR_START DEBUG_BASE
25
26static struct resource zoom2_smsc911x_resources[] = {
27 [0] = {
28 .start = ZOOM2_ETHR_START,
29 .end = ZOOM2_ETHR_START + SZ_4K,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
34 },
35};
36
37static struct smsc911x_platform_config zoom2_smsc911x_config = {
38 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
39 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
40 .flags = SMSC911X_USE_32BIT,
41 .phy_interface = PHY_INTERFACE_MODE_MII,
42};
43
44static struct platform_device zoom2_smsc911x_device = {
45 .name = "smsc911x",
46 .id = -1,
47 .num_resources = ARRAY_SIZE(zoom2_smsc911x_resources),
48 .resource = zoom2_smsc911x_resources,
49 .dev = {
50 .platform_data = &zoom2_smsc911x_config,
51 },
52};
53
54static inline void __init zoom2_init_smsc911x(void)
55{
56 int eth_cs;
57 unsigned long cs_mem_base;
58 int eth_gpio = 0;
59
60 eth_cs = ZOOM2_SMSC911X_CS;
61
62 if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
63 printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
64 return;
65 }
66
67 zoom2_smsc911x_resources[0].start = cs_mem_base + 0x0;
68 zoom2_smsc911x_resources[0].end = cs_mem_base + 0xff;
69
70 eth_gpio = ZOOM2_SMSC911X_GPIO;
71
72 zoom2_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
73
74 if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
75 printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
76 eth_gpio);
77 return;
78 }
79 gpio_direction_input(eth_gpio);
80}
81
82static struct plat_serial8250_port serial_platform_data[] = {
83 {
84 .mapbase = 0x10000000,
85 .irq = OMAP_GPIO_IRQ(102),
86 .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
87 .iotype = UPIO_MEM,
88 .regshift = 1,
89 .uartclk = QUART_CLK,
90 }, {
91 .flags = 0
92 }
93};
94
95static struct platform_device zoom2_debugboard_serial_device = {
96 .name = "serial8250",
97 .id = PLAT8250_DEV_PLATFORM1,
98 .dev = {
99 .platform_data = serial_platform_data,
100 },
101};
102
103static inline void __init zoom2_init_quaduart(void)
104{
105 int quart_cs;
106 unsigned long cs_mem_base;
107 int quart_gpio = 0;
108
109 quart_cs = ZOOM2_QUADUART_CS;
110
111 if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
112 printk(KERN_ERR "Failed to request GPMC mem"
113 "for Quad UART(TL16CP754C)\n");
114 return;
115 }
116
117 quart_gpio = ZOOM2_QUADUART_GPIO;
118
119 if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) {
120 printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
121 quart_gpio);
122 return;
123 }
124 gpio_direction_input(quart_gpio);
125}
126
127static inline int omap_zoom2_debugboard_detect(void)
128{
129 int debug_board_detect = 0;
130
131 debug_board_detect = ZOOM2_SMSC911X_GPIO;
132
133 if (gpio_request(debug_board_detect, "Zoom2 debug board detect") < 0) {
134 printk(KERN_ERR "Failed to request GPIO%d for Zoom2 debug"
135 "board detect\n", debug_board_detect);
136 return 0;
137 }
138 gpio_direction_input(debug_board_detect);
139
140 if (!gpio_get_value(debug_board_detect)) {
141 gpio_free(debug_board_detect);
142 return 0;
143 }
144 return 1;
145}
146
147static struct platform_device *zoom2_devices[] __initdata = {
148 &zoom2_smsc911x_device,
149 &zoom2_debugboard_serial_device,
150};
151
152int __init omap_zoom2_debugboard_init(void)
153{
154 if (!omap_zoom2_debugboard_detect())
155 return 0;
156
157 zoom2_init_smsc911x();
158 zoom2_init_quaduart();
159 return platform_add_devices(zoom2_devices, ARRAY_SIZE(zoom2_devices));
160}
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
new file mode 100644
index 000000000000..bcc0f7632dea
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc.
3 * Mikkel Christensen <mlc@ti.com>
4 *
5 * Modified from mach-omap2/board-ldp.c
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/gpio.h>
16#include <linux/i2c/twl4030.h>
17
18#include <asm/mach-types.h>
19#include <asm/mach/arch.h>
20
21#include <mach/common.h>
22#include <mach/usb.h>
23
24#include "mmc-twl4030.h"
25
26static void __init omap_zoom2_init_irq(void)
27{
28 omap2_init_common_hw(NULL);
29 omap_init_irq();
30 omap_gpio_init();
31}
32
33static struct omap_uart_config zoom2_uart_config __initdata = {
34 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
35};
36
37static struct omap_board_config_kernel zoom2_config[] __initdata = {
38 { OMAP_TAG_UART, &zoom2_uart_config },
39};
40
41static struct twl4030_gpio_platform_data zoom2_gpio_data = {
42 .gpio_base = OMAP_MAX_GPIO_LINES,
43 .irq_base = TWL4030_GPIO_IRQ_BASE,
44 .irq_end = TWL4030_GPIO_IRQ_END,
45};
46
47static struct twl4030_platform_data zoom2_twldata = {
48 .irq_base = TWL4030_IRQ_BASE,
49 .irq_end = TWL4030_IRQ_END,
50
51 /* platform_data for children goes here */
52 .gpio = &zoom2_gpio_data,
53};
54
55static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
56 {
57 I2C_BOARD_INFO("twl4030", 0x48),
58 .flags = I2C_CLIENT_WAKE,
59 .irq = INT_34XX_SYS_NIRQ,
60 .platform_data = &zoom2_twldata,
61 },
62};
63
64static int __init omap_i2c_init(void)
65{
66 omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
67 ARRAY_SIZE(zoom2_i2c_boardinfo));
68 omap_register_i2c_bus(2, 400, NULL, 0);
69 omap_register_i2c_bus(3, 400, NULL, 0);
70 return 0;
71}
72
73static struct twl4030_hsmmc_info mmc[] __initdata = {
74 {
75 .mmc = 1,
76 .wires = 4,
77 .gpio_cd = -EINVAL,
78 .gpio_wp = -EINVAL,
79 },
80 {} /* Terminator */
81};
82
83extern int __init omap_zoom2_debugboard_init(void);
84
85static void __init omap_zoom2_init(void)
86{
87 omap_i2c_init();
88 omap_board_config = zoom2_config;
89 omap_board_config_size = ARRAY_SIZE(zoom2_config);
90 omap_serial_init();
91 omap_zoom2_debugboard_init();
92 twl4030_mmc_init(mmc);
93 usb_musb_init();
94}
95
96static void __init omap_zoom2_map_io(void)
97{
98 omap2_set_globals_343x();
99 omap2_map_common_io();
100}
101
102MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
103 .phys_io = 0x48000000,
104 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
105 .boot_params = 0x80000100,
106 .map_io = omap_zoom2_map_io,
107 .init_irq = omap_zoom2_init_irq,
108 .init_machine = omap_zoom2_init,
109 .timer = &omap_timer,
110MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 4247a1534411..ba528f85749c 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -91,9 +91,9 @@ static void _omap2xxx_clk_commit(struct clk *clk)
91 return; 91 return;
92 92
93 prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD, 93 prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
94 OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); 94 OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
95 /* OCP barrier */ 95 /* OCP barrier */
96 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); 96 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
97} 97}
98 98
99/* 99/*
@@ -547,8 +547,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
547 const struct clksel_rate *clkr; 547 const struct clksel_rate *clkr;
548 u32 last_div = 0; 548 u32 last_div = 0;
549 549
550 printk(KERN_INFO "clock: clksel_round_rate_div: %s target_rate %ld\n", 550 pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
551 clk->name, target_rate); 551 clk->name, target_rate);
552 552
553 *new_div = 1; 553 *new_div = 1;
554 554
@@ -562,7 +562,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
562 562
563 /* Sanity check */ 563 /* Sanity check */
564 if (clkr->div <= last_div) 564 if (clkr->div <= last_div)
565 printk(KERN_ERR "clock: clksel_rate table not sorted " 565 pr_err("clock: clksel_rate table not sorted "
566 "for clock %s", clk->name); 566 "for clock %s", clk->name);
567 567
568 last_div = clkr->div; 568 last_div = clkr->div;
@@ -574,7 +574,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
574 } 574 }
575 575
576 if (!clkr->div) { 576 if (!clkr->div) {
577 printk(KERN_ERR "clock: Could not find divisor for target " 577 pr_err("clock: Could not find divisor for target "
578 "rate %ld for clock %s parent %s\n", target_rate, 578 "rate %ld for clock %s parent %s\n", target_rate,
579 clk->name, clk->parent->name); 579 clk->name, clk->parent->name);
580 return ~0; 580 return ~0;
@@ -582,8 +582,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
582 582
583 *new_div = clkr->div; 583 *new_div = clkr->div;
584 584
585 printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div, 585 pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
586 (clk->parent->rate / clkr->div)); 586 (clk->parent->rate / clkr->div));
587 587
588 return (clk->parent->rate / clkr->div); 588 return (clk->parent->rate / clkr->div);
589} 589}
@@ -1035,7 +1035,7 @@ void omap2_clk_disable_unused(struct clk *clk)
1035 if ((regval32 & (1 << clk->enable_bit)) == v) 1035 if ((regval32 & (1 << clk->enable_bit)) == v)
1036 return; 1036 return;
1037 1037
1038 printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); 1038 printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name);
1039 if (cpu_is_omap34xx()) { 1039 if (cpu_is_omap34xx()) {
1040 omap2_clk_enable(clk); 1040 omap2_clk_enable(clk);
1041 omap2_clk_disable(clk); 1041 omap2_clk_disable(clk);
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index e4cef333e291..44de0271fc2f 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -233,6 +233,8 @@ static struct prcm_config *curr_prcm_set;
233static struct clk *vclk; 233static struct clk *vclk;
234static struct clk *sclk; 234static struct clk *sclk;
235 235
236static void __iomem *prcm_clksrc_ctrl;
237
236/*------------------------------------------------------------------------- 238/*-------------------------------------------------------------------------
237 * Omap24xx specific clock functions 239 * Omap24xx specific clock functions
238 *-------------------------------------------------------------------------*/ 240 *-------------------------------------------------------------------------*/
@@ -269,10 +271,9 @@ static int omap2_enable_osc_ck(struct clk *clk)
269{ 271{
270 u32 pcc; 272 u32 pcc;
271 273
272 pcc = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); 274 pcc = __raw_readl(prcm_clksrc_ctrl);
273 275
274 __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, 276 __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
275 OMAP24XX_PRCM_CLKSRC_CTRL);
276 277
277 return 0; 278 return 0;
278} 279}
@@ -281,10 +282,9 @@ static void omap2_disable_osc_ck(struct clk *clk)
281{ 282{
282 u32 pcc; 283 u32 pcc;
283 284
284 pcc = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); 285 pcc = __raw_readl(prcm_clksrc_ctrl);
285 286
286 __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, 287 __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
287 OMAP24XX_PRCM_CLKSRC_CTRL);
288} 288}
289 289
290static const struct clkops clkops_oscck = { 290static const struct clkops clkops_oscck = {
@@ -654,7 +654,7 @@ static u32 omap2_get_sysclkdiv(void)
654{ 654{
655 u32 div; 655 u32 div;
656 656
657 div = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); 657 div = __raw_readl(prcm_clksrc_ctrl);
658 div &= OMAP_SYSCLKDIV_MASK; 658 div &= OMAP_SYSCLKDIV_MASK;
659 div >>= OMAP_SYSCLKDIV_SHIFT; 659 div >>= OMAP_SYSCLKDIV_SHIFT;
660 660
@@ -714,15 +714,18 @@ int __init omap2_clk_init(void)
714 struct omap_clk *c; 714 struct omap_clk *c;
715 u32 clkrate; 715 u32 clkrate;
716 716
717 if (cpu_is_omap242x()) 717 if (cpu_is_omap242x()) {
718 prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
718 cpu_mask = RATE_IN_242X; 719 cpu_mask = RATE_IN_242X;
719 else if (cpu_is_omap2430()) 720 } else if (cpu_is_omap2430()) {
721 prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
720 cpu_mask = RATE_IN_243X; 722 cpu_mask = RATE_IN_243X;
723 }
721 724
722 clk_init(&omap2_clk_functions); 725 clk_init(&omap2_clk_functions);
723 726
724 for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) 727 for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
725 clk_init_one(c->lk.clk); 728 clk_preinit(c->lk.clk);
726 729
727 osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); 730 osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
728 propagate_rate(&osc_ck); 731 propagate_rate(&osc_ck);
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index 88c5acb40fcf..458f00cdcbea 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -24,6 +24,17 @@
24#include "cm-regbits-24xx.h" 24#include "cm-regbits-24xx.h"
25#include "sdrc.h" 25#include "sdrc.h"
26 26
27/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
28#ifdef CONFIG_ARCH_OMAP2420
29#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
30#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP2420_PRCM_CLKOUT_CTRL
31#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP2420_PRCM_CLKEMUL_CTRL
32#else
33#define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
34#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP2430_PRCM_CLKOUT_CTRL
35#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP2430_PRCM_CLKEMUL_CTRL
36#endif
37
27static unsigned long omap2_table_mpu_recalc(struct clk *clk); 38static unsigned long omap2_table_mpu_recalc(struct clk *clk);
28static int omap2_select_table_rate(struct clk *clk, unsigned long rate); 39static int omap2_select_table_rate(struct clk *clk, unsigned long rate);
29static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate); 40static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index ba05aa42bd8e..9e43fe5209d3 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -129,6 +129,9 @@ static struct omap_clk omap34xx_clks[] = {
129 CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2), 129 CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2),
130 CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2), 130 CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2),
131 CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1), 131 CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
132 CLK(NULL, "modem_fck", &modem_fck, CK_343X),
133 CLK(NULL, "sad2d_ick", &sad2d_ick, CK_343X),
134 CLK(NULL, "mad2d_ick", &mad2d_ick, CK_343X),
132 CLK(NULL, "gpt10_fck", &gpt10_fck, CK_343X), 135 CLK(NULL, "gpt10_fck", &gpt10_fck, CK_343X),
133 CLK(NULL, "gpt11_fck", &gpt11_fck, CK_343X), 136 CLK(NULL, "gpt11_fck", &gpt11_fck, CK_343X),
134 CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2), 137 CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2),
@@ -281,6 +284,8 @@ static struct omap_clk omap34xx_clks[] = {
281 284
282#define MAX_DPLL_WAIT_TRIES 1000000 285#define MAX_DPLL_WAIT_TRIES 1000000
283 286
287#define MIN_SDRC_DLL_LOCK_FREQ 83000000
288
284/** 289/**
285 * omap3_dpll_recalc - recalculate DPLL rate 290 * omap3_dpll_recalc - recalculate DPLL rate
286 * @clk: DPLL struct clk 291 * @clk: DPLL struct clk
@@ -703,6 +708,7 @@ static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
703static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) 708static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
704{ 709{
705 u32 new_div = 0; 710 u32 new_div = 0;
711 u32 unlock_dll = 0;
706 unsigned long validrate, sdrcrate; 712 unsigned long validrate, sdrcrate;
707 struct omap_sdrc_params *sp; 713 struct omap_sdrc_params *sp;
708 714
@@ -729,17 +735,22 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
729 if (!sp) 735 if (!sp)
730 return -EINVAL; 736 return -EINVAL;
731 737
732 pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, 738 if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
733 validrate); 739 pr_debug("clock: will unlock SDRC DLL\n");
734 pr_info("clock: SDRC timing params used: %08x %08x %08x\n", 740 unlock_dll = 1;
735 sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb); 741 }
742
743 pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
744 validrate);
745 pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
746 sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
736 747
737 /* REVISIT: SRAM code doesn't support other M2 divisors yet */ 748 /* REVISIT: SRAM code doesn't support other M2 divisors yet */
738 WARN_ON(new_div != 1 && new_div != 2); 749 WARN_ON(new_div != 1 && new_div != 2);
739 750
740 /* REVISIT: Add SDRC_MR changing to this code also */ 751 /* REVISIT: Add SDRC_MR changing to this code also */
741 omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla, 752 omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
742 sp->actim_ctrlb, new_div); 753 sp->actim_ctrlb, new_div, unlock_dll);
743 754
744 return 0; 755 return 0;
745} 756}
@@ -956,7 +967,7 @@ int __init omap2_clk_init(void)
956 clk_init(&omap2_clk_functions); 967 clk_init(&omap2_clk_functions);
957 968
958 for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++) 969 for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
959 clk_init_one(c->lk.clk); 970 clk_preinit(c->lk.clk);
960 971
961 for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++) 972 for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
962 if (c->cpu & cpu_clkflg) { 973 if (c->cpu & cpu_clkflg) {
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 017a30e9aa1d..e433aec4efdd 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -27,6 +27,8 @@
27#include "prm.h" 27#include "prm.h"
28#include "prm-regbits-34xx.h" 28#include "prm-regbits-34xx.h"
29 29
30#define OMAP_CM_REGADDR OMAP34XX_CM_REGADDR
31
30static unsigned long omap3_dpll_recalc(struct clk *clk); 32static unsigned long omap3_dpll_recalc(struct clk *clk);
31static unsigned long omap3_clkoutx2_recalc(struct clk *clk); 33static unsigned long omap3_clkoutx2_recalc(struct clk *clk);
32static void omap3_dpll_allow_idle(struct clk *clk); 34static void omap3_dpll_allow_idle(struct clk *clk);
@@ -1228,6 +1230,37 @@ static struct clk d2d_26m_fck = {
1228 .recalc = &followparent_recalc, 1230 .recalc = &followparent_recalc,
1229}; 1231};
1230 1232
1233static struct clk modem_fck = {
1234 .name = "modem_fck",
1235 .ops = &clkops_omap2_dflt_wait,
1236 .parent = &sys_ck,
1237 .init = &omap2_init_clk_clkdm,
1238 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1239 .enable_bit = OMAP3430_EN_MODEM_SHIFT,
1240 .clkdm_name = "d2d_clkdm",
1241 .recalc = &followparent_recalc,
1242};
1243
1244static struct clk sad2d_ick = {
1245 .name = "sad2d_ick",
1246 .ops = &clkops_omap2_dflt_wait,
1247 .parent = &l3_ick,
1248 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
1249 .enable_bit = OMAP3430_EN_SAD2D_SHIFT,
1250 .clkdm_name = "d2d_clkdm",
1251 .recalc = &followparent_recalc,
1252};
1253
1254static struct clk mad2d_ick = {
1255 .name = "mad2d_ick",
1256 .ops = &clkops_omap2_dflt_wait,
1257 .parent = &l3_ick,
1258 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
1259 .enable_bit = OMAP3430_EN_MAD2D_SHIFT,
1260 .clkdm_name = "d2d_clkdm",
1261 .recalc = &followparent_recalc,
1262};
1263
1231static const struct clksel omap343x_gpt_clksel[] = { 1264static const struct clksel omap343x_gpt_clksel[] = {
1232 { .parent = &omap_32k_fck, .rates = gpt_32k_rates }, 1265 { .parent = &omap_32k_fck, .rates = gpt_32k_rates },
1233 { .parent = &sys_ck, .rates = gpt_sys_rates }, 1266 { .parent = &sys_ck, .rates = gpt_sys_rates },
@@ -1945,8 +1978,6 @@ static struct clk usb_l4_ick = {
1945 .recalc = &omap2_clksel_recalc, 1978 .recalc = &omap2_clksel_recalc,
1946}; 1979};
1947 1980
1948/* XXX MDM_INTC_ICK, SAD2D_ICK ?? */
1949
1950/* SECURITY_L4_ICK2 based clocks */ 1981/* SECURITY_L4_ICK2 based clocks */
1951 1982
1952static struct clk security_l4_ick2 = { 1983static struct clk security_l4_ick2 = {
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
index 281d5da19188..fe319ae4ca0a 100644
--- a/arch/arm/mach-omap2/clockdomains.h
+++ b/arch/arm/mach-omap2/clockdomains.h
@@ -195,7 +195,7 @@ static struct clockdomain sgx_clkdm = {
195static struct clockdomain d2d_clkdm = { 195static struct clockdomain d2d_clkdm = {
196 .name = "d2d_clkdm", 196 .name = "d2d_clkdm",
197 .pwrdm = { .name = "core_pwrdm" }, 197 .pwrdm = { .name = "core_pwrdm" },
198 .flags = CLKDM_CAN_HWSUP, 198 .flags = CLKDM_CAN_HWSUP_SWSUP,
199 .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK, 199 .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
200 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 200 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
201}; 201};
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 6f3f5a36aae6..6923deb98a28 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -145,6 +145,8 @@
145#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0) 145#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0)
146 146
147/* CM_FCLKEN1_CORE specific bits */ 147/* CM_FCLKEN1_CORE specific bits */
148#define OMAP3430_EN_MODEM (1 << 31)
149#define OMAP3430_EN_MODEM_SHIFT 31
148 150
149/* CM_ICLKEN1_CORE specific bits */ 151/* CM_ICLKEN1_CORE specific bits */
150#define OMAP3430_EN_ICR (1 << 29) 152#define OMAP3430_EN_ICR (1 << 29)
@@ -161,6 +163,8 @@
161#define OMAP3430_EN_MAILBOXES_SHIFT 7 163#define OMAP3430_EN_MAILBOXES_SHIFT 7
162#define OMAP3430_EN_OMAPCTRL (1 << 6) 164#define OMAP3430_EN_OMAPCTRL (1 << 6)
163#define OMAP3430_EN_OMAPCTRL_SHIFT 6 165#define OMAP3430_EN_OMAPCTRL_SHIFT 6
166#define OMAP3430_EN_SAD2D (1 << 3)
167#define OMAP3430_EN_SAD2D_SHIFT 3
164#define OMAP3430_EN_SDRC (1 << 1) 168#define OMAP3430_EN_SDRC (1 << 1)
165#define OMAP3430_EN_SDRC_SHIFT 1 169#define OMAP3430_EN_SDRC_SHIFT 1
166 170
@@ -176,6 +180,10 @@
176#define OMAP3430_EN_DES1 (1 << 0) 180#define OMAP3430_EN_DES1 (1 << 0)
177#define OMAP3430_EN_DES1_SHIFT 0 181#define OMAP3430_EN_DES1_SHIFT 0
178 182
183/* CM_ICLKEN3_CORE */
184#define OMAP3430_EN_MAD2D_SHIFT 3
185#define OMAP3430_EN_MAD2D (1 << 3)
186
179/* CM_FCLKEN3_CORE specific bits */ 187/* CM_FCLKEN3_CORE specific bits */
180#define OMAP3430ES2_EN_TS_SHIFT 1 188#define OMAP3430ES2_EN_TS_SHIFT 1
181#define OMAP3430ES2_EN_TS_MASK (1 << 1) 189#define OMAP3430ES2_EN_TS_MASK (1 << 1)
@@ -231,6 +239,8 @@
231#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0) 239#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0)
232 240
233/* CM_AUTOIDLE1_CORE */ 241/* CM_AUTOIDLE1_CORE */
242#define OMAP3430_AUTO_MODEM (1 << 31)
243#define OMAP3430_AUTO_MODEM_SHIFT 31
234#define OMAP3430ES2_AUTO_MMC3 (1 << 30) 244#define OMAP3430ES2_AUTO_MMC3 (1 << 30)
235#define OMAP3430ES2_AUTO_MMC3_SHIFT 30 245#define OMAP3430ES2_AUTO_MMC3_SHIFT 30
236#define OMAP3430ES2_AUTO_ICR (1 << 29) 246#define OMAP3430ES2_AUTO_ICR (1 << 29)
@@ -287,6 +297,8 @@
287#define OMAP3430_AUTO_HSOTGUSB_SHIFT 4 297#define OMAP3430_AUTO_HSOTGUSB_SHIFT 4
288#define OMAP3430ES1_AUTO_D2D (1 << 3) 298#define OMAP3430ES1_AUTO_D2D (1 << 3)
289#define OMAP3430ES1_AUTO_D2D_SHIFT 3 299#define OMAP3430ES1_AUTO_D2D_SHIFT 3
300#define OMAP3430_AUTO_SAD2D (1 << 3)
301#define OMAP3430_AUTO_SAD2D_SHIFT 3
290#define OMAP3430_AUTO_SSI (1 << 0) 302#define OMAP3430_AUTO_SSI (1 << 0)
291#define OMAP3430_AUTO_SSI_SHIFT 0 303#define OMAP3430_AUTO_SSI_SHIFT 0
292 304
@@ -308,6 +320,8 @@
308#define OMAP3430ES2_AUTO_USBTLL (1 << 2) 320#define OMAP3430ES2_AUTO_USBTLL (1 << 2)
309#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2 321#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2
310#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2) 322#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2)
323#define OMAP3430_AUTO_MAD2D_SHIFT 3
324#define OMAP3430_AUTO_MAD2D (1 << 3)
311 325
312/* CM_CLKSEL_CORE */ 326/* CM_CLKSEL_CORE */
313#define OMAP3430_CLKSEL_SSI_SHIFT 8 327#define OMAP3430_CLKSEL_SSI_SHIFT 8
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 65fdf78c91e1..1d3c93bf86d3 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -16,17 +16,12 @@
16 16
17#include "prcm-common.h" 17#include "prcm-common.h"
18 18
19#ifndef __ASSEMBLER__
20#define OMAP_CM_REGADDR(module, reg) \
21 IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg))
22#else
23#define OMAP2420_CM_REGADDR(module, reg) \ 19#define OMAP2420_CM_REGADDR(module, reg) \
24 IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) 20 IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
25#define OMAP2430_CM_REGADDR(module, reg) \ 21#define OMAP2430_CM_REGADDR(module, reg) \
26 IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) 22 IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
27#define OMAP34XX_CM_REGADDR(module, reg) \ 23#define OMAP34XX_CM_REGADDR(module, reg) \
28 IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) 24 IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
29#endif
30 25
31/* 26/*
32 * Architecture-specific global CM registers 27 * Architecture-specific global CM registers
@@ -38,6 +33,7 @@
38#define OMAP3430_CM_SYSCONFIG OMAP_CM_REGADDR(OCP_MOD, 0x0010) 33#define OMAP3430_CM_SYSCONFIG OMAP_CM_REGADDR(OCP_MOD, 0x0010)
39#define OMAP3430_CM_POLCTRL OMAP_CM_REGADDR(OCP_MOD, 0x009c) 34#define OMAP3430_CM_POLCTRL OMAP_CM_REGADDR(OCP_MOD, 0x009c)
40 35
36#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
41#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) 37#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
42 38
43/* 39/*
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
new file mode 100644
index 000000000000..2fd22f9c5f0e
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -0,0 +1,330 @@
1/*
2 * linux/arch/arm/mach-omap2/gpmc-onenand.c
3 *
4 * Copyright (C) 2006 - 2009 Nokia Corporation
5 * Contacts: Juha Yrjola
6 * Tony Lindgren
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/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/mtd/onenand_regs.h>
16#include <linux/io.h>
17
18#include <asm/mach/flash.h>
19
20#include <mach/onenand.h>
21#include <mach/board.h>
22#include <mach/gpmc.h>
23
24static struct omap_onenand_platform_data *gpmc_onenand_data;
25
26static struct platform_device gpmc_onenand_device = {
27 .name = "omap2-onenand",
28 .id = -1,
29};
30
31static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
32{
33 struct gpmc_timings t;
34
35 const int t_cer = 15;
36 const int t_avdp = 12;
37 const int t_aavdh = 7;
38 const int t_ce = 76;
39 const int t_aa = 76;
40 const int t_oe = 20;
41 const int t_cez = 20; /* max of t_cez, t_oez */
42 const int t_ds = 30;
43 const int t_wpl = 40;
44 const int t_wph = 30;
45
46 memset(&t, 0, sizeof(t));
47 t.sync_clk = 0;
48 t.cs_on = 0;
49 t.adv_on = 0;
50
51 /* Read */
52 t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
53 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
54 t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
55 t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
56 t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
57 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
58 t.cs_rd_off = t.oe_off;
59 t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
60
61 /* Write */
62 t.adv_wr_off = t.adv_rd_off;
63 t.we_on = t.oe_on;
64 if (cpu_is_omap34xx()) {
65 t.wr_data_mux_bus = t.we_on;
66 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
67 }
68 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
69 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
70 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
71
72 /* Configure GPMC for asynchronous read */
73 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
74 GPMC_CONFIG1_DEVICESIZE_16 |
75 GPMC_CONFIG1_MUXADDDATA);
76
77 return gpmc_cs_set_timings(cs, &t);
78}
79
80static void set_onenand_cfg(void __iomem *onenand_base, int latency,
81 int sync_read, int sync_write, int hf)
82{
83 u32 reg;
84
85 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
86 reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
87 reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
88 ONENAND_SYS_CFG1_BL_16;
89 if (sync_read)
90 reg |= ONENAND_SYS_CFG1_SYNC_READ;
91 else
92 reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
93 if (sync_write)
94 reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
95 else
96 reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
97 if (hf)
98 reg |= ONENAND_SYS_CFG1_HF;
99 else
100 reg &= ~ONENAND_SYS_CFG1_HF;
101 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
102}
103
104static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
105 void __iomem *onenand_base,
106 int freq)
107{
108 struct gpmc_timings t;
109 const int t_cer = 15;
110 const int t_avdp = 12;
111 const int t_cez = 20; /* max of t_cez, t_oez */
112 const int t_ds = 30;
113 const int t_wpl = 40;
114 const int t_wph = 30;
115 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
116 int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
117 int first_time = 0, hf = 0, sync_read = 0, sync_write = 0;
118 int err, ticks_cez;
119 int cs = cfg->cs;
120 u32 reg;
121
122 if (cfg->flags & ONENAND_SYNC_READ) {
123 sync_read = 1;
124 } else if (cfg->flags & ONENAND_SYNC_READWRITE) {
125 sync_read = 1;
126 sync_write = 1;
127 }
128
129 if (!freq) {
130 /* Very first call freq is not known */
131 err = omap2_onenand_set_async_mode(cs, onenand_base);
132 if (err)
133 return err;
134 reg = readw(onenand_base + ONENAND_REG_VERSION_ID);
135 switch ((reg >> 4) & 0xf) {
136 case 0:
137 freq = 40;
138 break;
139 case 1:
140 freq = 54;
141 break;
142 case 2:
143 freq = 66;
144 break;
145 case 3:
146 freq = 83;
147 break;
148 case 4:
149 freq = 104;
150 break;
151 default:
152 freq = 54;
153 break;
154 }
155 first_time = 1;
156 }
157
158 switch (freq) {
159 case 83:
160 min_gpmc_clk_period = 12; /* 83 MHz */
161 t_ces = 5;
162 t_avds = 4;
163 t_avdh = 2;
164 t_ach = 6;
165 t_aavdh = 6;
166 t_rdyo = 9;
167 break;
168 case 66:
169 min_gpmc_clk_period = 15; /* 66 MHz */
170 t_ces = 6;
171 t_avds = 5;
172 t_avdh = 2;
173 t_ach = 6;
174 t_aavdh = 6;
175 t_rdyo = 11;
176 break;
177 default:
178 min_gpmc_clk_period = 18; /* 54 MHz */
179 t_ces = 7;
180 t_avds = 7;
181 t_avdh = 7;
182 t_ach = 9;
183 t_aavdh = 7;
184 t_rdyo = 15;
185 sync_write = 0;
186 break;
187 }
188
189 tick_ns = gpmc_ticks_to_ns(1);
190 div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
191 gpmc_clk_ns = gpmc_ticks_to_ns(div);
192 if (gpmc_clk_ns < 15) /* >66Mhz */
193 hf = 1;
194 if (hf)
195 latency = 6;
196 else if (gpmc_clk_ns >= 25) /* 40 MHz*/
197 latency = 3;
198 else
199 latency = 4;
200
201 if (first_time)
202 set_onenand_cfg(onenand_base, latency,
203 sync_read, sync_write, hf);
204
205 if (div == 1) {
206 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
207 reg |= (1 << 7);
208 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
209 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
210 reg |= (1 << 7);
211 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
212 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
213 reg |= (1 << 7);
214 reg |= (1 << 23);
215 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
216 } else {
217 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
218 reg &= ~(1 << 7);
219 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
220 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
221 reg &= ~(1 << 7);
222 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
223 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
224 reg &= ~(1 << 7);
225 reg &= ~(1 << 23);
226 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
227 }
228
229 /* Set synchronous read timings */
230 memset(&t, 0, sizeof(t));
231 t.sync_clk = min_gpmc_clk_period;
232 t.cs_on = 0;
233 t.adv_on = 0;
234 fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
235 fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
236 t.page_burst_access = gpmc_clk_ns;
237
238 /* Read */
239 t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
240 t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
241 t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
242 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
243 t.cs_rd_off = t.oe_off;
244 ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
245 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
246 ticks_cez);
247
248 /* Write */
249 if (sync_write) {
250 t.adv_wr_off = t.adv_rd_off;
251 t.we_on = 0;
252 t.we_off = t.cs_rd_off;
253 t.cs_wr_off = t.cs_rd_off;
254 t.wr_cycle = t.rd_cycle;
255 if (cpu_is_omap34xx()) {
256 t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
257 gpmc_ns_to_ticks(min_gpmc_clk_period +
258 t_rdyo));
259 t.wr_access = t.access;
260 }
261 } else {
262 t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
263 t_avdp, t_cer));
264 t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
265 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
266 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
267 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
268 if (cpu_is_omap34xx()) {
269 t.wr_data_mux_bus = t.we_on;
270 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
271 }
272 }
273
274 /* Configure GPMC for synchronous read */
275 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
276 GPMC_CONFIG1_WRAPBURST_SUPP |
277 GPMC_CONFIG1_READMULTIPLE_SUPP |
278 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
279 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
280 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
281 GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
282 GPMC_CONFIG1_PAGE_LEN(2) |
283 (cpu_is_omap34xx() ? 0 :
284 (GPMC_CONFIG1_WAIT_READ_MON |
285 GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
286 GPMC_CONFIG1_DEVICESIZE_16 |
287 GPMC_CONFIG1_DEVICETYPE_NOR |
288 GPMC_CONFIG1_MUXADDDATA);
289
290 err = gpmc_cs_set_timings(cs, &t);
291 if (err)
292 return err;
293
294 set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf);
295
296 return 0;
297}
298
299static int gpmc_onenand_setup(void __iomem *onenand_base, int freq)
300{
301 struct device *dev = &gpmc_onenand_device.dev;
302
303 /* Set sync timings in GPMC */
304 if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
305 freq) < 0) {
306 dev_err(dev, "Unable to set synchronous mode\n");
307 return -EINVAL;
308 }
309
310 return 0;
311}
312
313void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
314{
315 gpmc_onenand_data = _onenand_data;
316 gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
317 gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
318
319 if (cpu_is_omap24xx() &&
320 (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
321 printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
322 gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
323 gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
324 }
325
326 if (platform_device_register(&gpmc_onenand_device) < 0) {
327 printk(KERN_ERR "Unable to register OneNAND device\n");
328 return;
329 }
330}
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
new file mode 100644
index 000000000000..df99d31d8b64
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -0,0 +1,189 @@
1/*
2 * linux/arch/arm/mach-omap2/gpmc-smc91x.c
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Contact: Tony Lindgren
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/gpio.h>
15#include <linux/delay.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/smc91x.h>
19
20#include <mach/board.h>
21#include <mach/gpmc.h>
22#include <mach/gpmc-smc91x.h>
23
24static struct omap_smc91x_platform_data *gpmc_cfg;
25
26static struct resource gpmc_smc91x_resources[] = {
27 [0] = {
28 .flags = IORESOURCE_MEM,
29 },
30 [1] = {
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static struct smc91x_platdata gpmc_smc91x_info = {
36 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
37};
38
39static struct platform_device gpmc_smc91x_device = {
40 .name = "smc91x",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(gpmc_smc91x_resources),
43 .resource = gpmc_smc91x_resources,
44 .dev = {
45 .platform_data = &gpmc_smc91x_info,
46 },
47};
48
49/*
50 * Set the gpmc timings for smc91c96. The timings are taken
51 * from the data sheet available at:
52 * http://www.smsc.com/main/catalog/lan91c96.html
53 * REVISIT: Level shifters can add at least to the access latency.
54 */
55static int smc91c96_gpmc_retime(void)
56{
57 struct gpmc_timings t;
58 const int t3 = 10; /* Figure 12.2 read and 12.4 write */
59 const int t4_r = 20; /* Figure 12.2 read */
60 const int t4_w = 5; /* Figure 12.4 write */
61 const int t5 = 25; /* Figure 12.2 read */
62 const int t6 = 15; /* Figure 12.2 read */
63 const int t7 = 5; /* Figure 12.4 write */
64 const int t8 = 5; /* Figure 12.4 write */
65 const int t20 = 185; /* Figure 12.2 read and 12.4 write */
66 u32 l;
67
68 memset(&t, 0, sizeof(t));
69
70 /* Read timings */
71 t.cs_on = 0;
72 t.adv_on = t.cs_on;
73 t.oe_on = t.adv_on + t3;
74 t.access = t.oe_on + t5;
75 t.oe_off = t.access;
76 t.adv_rd_off = t.oe_off + max(t4_r, t6);
77 t.cs_rd_off = t.oe_off;
78 t.rd_cycle = t20 - t.oe_on;
79
80 /* Write timings */
81 t.we_on = t.adv_on + t3;
82
83 if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
84 t.wr_data_mux_bus = t.we_on;
85 t.we_off = t.wr_data_mux_bus + t7;
86 } else
87 t.we_off = t.we_on + t7;
88 if (cpu_is_omap34xx())
89 t.wr_access = t.we_off;
90 t.adv_wr_off = t.we_off + max(t4_w, t8);
91 t.cs_wr_off = t.we_off + t4_w;
92 t.wr_cycle = t20 - t.we_on;
93
94 l = GPMC_CONFIG1_DEVICESIZE_16;
95 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
96 l |= GPMC_CONFIG1_MUXADDDATA;
97 if (gpmc_cfg->flags & GPMC_READ_MON)
98 l |= GPMC_CONFIG1_WAIT_READ_MON;
99 if (gpmc_cfg->flags & GPMC_WRITE_MON)
100 l |= GPMC_CONFIG1_WAIT_WRITE_MON;
101 if (gpmc_cfg->wait_pin)
102 l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
103 gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
104
105 /*
106 * FIXME: Calculate the address and data bus muxed timings.
107 * Note that at least adv_rd_off needs to be changed according
108 * to omap3430 TRM Figure 11-11. Are the sdp boards using the
109 * FPGA in between smc91x and omap as the timings are different
110 * from above?
111 */
112 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
113 return 0;
114
115 return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
116}
117
118/*
119 * Initialize smc91x device connected to the GPMC. Note that we
120 * assume that pin multiplexing is done in the board-*.c file,
121 * or in the bootloader.
122 */
123void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
124{
125 unsigned long cs_mem_base;
126 int ret;
127
128 gpmc_cfg = board_data;
129
130 if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96)
131 gpmc_cfg->retime = smc91c96_gpmc_retime;
132
133 if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
134 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
135 return;
136 }
137
138 gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
139 gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
140 gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
141
142 if (gpmc_cfg->retime) {
143 ret = gpmc_cfg->retime();
144 if (ret != 0)
145 goto free1;
146 }
147
148 if (gpio_request(gpmc_cfg->gpio_irq, "SMC91X irq") < 0)
149 goto free1;
150
151 gpio_direction_input(gpmc_cfg->gpio_irq);
152 gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
153
154 if (gpmc_cfg->gpio_pwrdwn) {
155 ret = gpio_request(gpmc_cfg->gpio_pwrdwn, "SMC91X powerdown");
156 if (ret)
157 goto free2;
158 gpio_direction_output(gpmc_cfg->gpio_pwrdwn, 0);
159 }
160
161 if (gpmc_cfg->gpio_reset) {
162 ret = gpio_request(gpmc_cfg->gpio_reset, "SMC91X reset");
163 if (ret)
164 goto free3;
165
166 gpio_direction_output(gpmc_cfg->gpio_reset, 0);
167 gpio_set_value(gpmc_cfg->gpio_reset, 1);
168 msleep(100);
169 gpio_set_value(gpmc_cfg->gpio_reset, 0);
170 }
171
172 if (platform_device_register(&gpmc_smc91x_device) < 0) {
173 printk(KERN_ERR "Unable to register smc91x device\n");
174 gpio_free(gpmc_cfg->gpio_reset);
175 goto free3;
176 }
177
178 return;
179
180free3:
181 if (gpmc_cfg->gpio_pwrdwn)
182 gpio_free(gpmc_cfg->gpio_pwrdwn);
183free2:
184 gpio_free(gpmc_cfg->gpio_irq);
185free1:
186 gpmc_cs_free(gpmc_cfg->cs);
187
188 printk(KERN_ERR "Could not initialize smc91x\n");
189}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 2249049c1d5a..f91934b2b092 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -5,6 +5,9 @@
5 * 5 *
6 * Author: Juha Yrjola 6 * Author: Juha Yrjola
7 * 7 *
8 * Copyright (C) 2009 Texas Instruments
9 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
10 *
8 * This program is free software; you can redistribute it and/or modify 11 * 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 12 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
@@ -424,6 +427,9 @@ void __init gpmc_init(void)
424 } else if (cpu_is_omap34xx()) { 427 } else if (cpu_is_omap34xx()) {
425 ck = "gpmc_fck"; 428 ck = "gpmc_fck";
426 l = OMAP34XX_GPMC_BASE; 429 l = OMAP34XX_GPMC_BASE;
430 } else if (cpu_is_omap44xx()) {
431 ck = "gpmc_fck";
432 l = OMAP44XX_GPMC_BASE;
427 } 433 }
428 434
429 gpmc_l3_clk = clk_get(NULL, ck); 435 gpmc_l3_clk = clk_get(NULL, ck);
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 34b5914e0f8b..458990e20c60 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.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.
@@ -200,7 +203,10 @@ void __init omap2_check_revision(void)
200 omap24xx_check_revision(); 203 omap24xx_check_revision();
201 else if (cpu_is_omap34xx()) 204 else if (cpu_is_omap34xx())
202 omap34xx_check_revision(); 205 omap34xx_check_revision();
203 else 206 else if (cpu_is_omap44xx()) {
207 printk(KERN_INFO "FIXME: CPU revision = OMAP4430\n");
208 return;
209 } else
204 pr_err("OMAP revision unknown, please fix!\n"); 210 pr_err("OMAP revision unknown, please fix!\n");
205 211
206 /* 212 /*
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 916fcd3a2328..32afd9448216 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -4,12 +4,14 @@
4 * OMAP2 I/O mapping code 4 * OMAP2 I/O mapping code
5 * 5 *
6 * Copyright (C) 2005 Nokia Corporation 6 * Copyright (C) 2005 Nokia Corporation
7 * Copyright (C) 2007 Texas Instruments 7 * Copyright (C) 2007-2009 Texas Instruments
8 * 8 *
9 * Author: 9 * Author:
10 * Juha Yrjola <juha.yrjola@nokia.com> 10 * Juha Yrjola <juha.yrjola@nokia.com>
11 * Syed Khasim <x0khasim@ti.com> 11 * Syed Khasim <x0khasim@ti.com>
12 * 12 *
13 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
14 *
13 * This program is free software; you can redistribute it and/or modify 15 * 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 16 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation. 17 * published by the Free Software Foundation.
@@ -30,6 +32,7 @@
30#include <mach/sdrc.h> 32#include <mach/sdrc.h>
31#include <mach/gpmc.h> 33#include <mach/gpmc.h>
32 34
35#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */
33#include "clock.h" 36#include "clock.h"
34 37
35#include <mach/powerdomain.h> 38#include <mach/powerdomain.h>
@@ -38,7 +41,7 @@
38 41
39#include <mach/clockdomain.h> 42#include <mach/clockdomain.h>
40#include "clockdomains.h" 43#include "clockdomains.h"
41 44#endif
42/* 45/*
43 * The machine specific code may provide the extra mapping besides the 46 * The machine specific code may provide the extra mapping besides the
44 * default mapping provided here. 47 * default mapping provided here.
@@ -166,6 +169,46 @@ static struct map_desc omap34xx_io_desc[] __initdata = {
166 }, 169 },
167}; 170};
168#endif 171#endif
172#ifdef CONFIG_ARCH_OMAP4
173static struct map_desc omap44xx_io_desc[] __initdata = {
174 {
175 .virtual = L3_44XX_VIRT,
176 .pfn = __phys_to_pfn(L3_44XX_PHYS),
177 .length = L3_44XX_SIZE,
178 .type = MT_DEVICE,
179 },
180 {
181 .virtual = L4_44XX_VIRT,
182 .pfn = __phys_to_pfn(L4_44XX_PHYS),
183 .length = L4_44XX_SIZE,
184 .type = MT_DEVICE,
185 },
186 {
187 .virtual = L4_WK_44XX_VIRT,
188 .pfn = __phys_to_pfn(L4_WK_44XX_PHYS),
189 .length = L4_WK_44XX_SIZE,
190 .type = MT_DEVICE,
191 },
192 {
193 .virtual = OMAP44XX_GPMC_VIRT,
194 .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
195 .length = OMAP44XX_GPMC_SIZE,
196 .type = MT_DEVICE,
197 },
198 {
199 .virtual = L4_PER_44XX_VIRT,
200 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
201 .length = L4_PER_44XX_SIZE,
202 .type = MT_DEVICE,
203 },
204 {
205 .virtual = L4_EMU_44XX_VIRT,
206 .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS),
207 .length = L4_EMU_44XX_SIZE,
208 .type = MT_DEVICE,
209 },
210};
211#endif
169 212
170void __init omap2_map_common_io(void) 213void __init omap2_map_common_io(void)
171{ 214{
@@ -183,6 +226,9 @@ void __init omap2_map_common_io(void)
183 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); 226 iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
184#endif 227#endif
185 228
229#if defined(CONFIG_ARCH_OMAP4)
230 iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
231#endif
186 /* Normally devicemaps_init() would flush caches and tlb after 232 /* Normally devicemaps_init() would flush caches and tlb after
187 * mdesc->map_io(), but we must also do it here because of the CPU 233 * mdesc->map_io(), but we must also do it here because of the CPU
188 * revision check below. 234 * revision check below.
@@ -198,9 +244,11 @@ void __init omap2_map_common_io(void)
198void __init omap2_init_common_hw(struct omap_sdrc_params *sp) 244void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
199{ 245{
200 omap2_mux_init(); 246 omap2_mux_init();
247#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
201 pwrdm_init(powerdomains_omap); 248 pwrdm_init(powerdomains_omap);
202 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); 249 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
203 omap2_clk_init(); 250 omap2_clk_init();
204 omap2_sdrc_init(sp); 251 omap2_sdrc_init(sp);
252#endif
205 gpmc_init(); 253 gpmc_init();
206} 254}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 998c5c45587e..b82863887f10 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -28,7 +28,6 @@
28#define INTC_MIR_CLEAR0 0x0088 28#define INTC_MIR_CLEAR0 0x0088
29#define INTC_MIR_SET0 0x008c 29#define INTC_MIR_SET0 0x008c
30#define INTC_PENDING_IRQ0 0x0098 30#define INTC_PENDING_IRQ0 0x0098
31
32/* Number of IRQ state bits in each MIR register */ 31/* Number of IRQ state bits in each MIR register */
33#define IRQ_BITS_PER_REG 32 32#define IRQ_BITS_PER_REG 32
34 33
@@ -134,7 +133,6 @@ static struct irq_chip omap_irq_chip = {
134 .ack = omap_mask_ack_irq, 133 .ack = omap_mask_ack_irq,
135 .mask = omap_mask_irq, 134 .mask = omap_mask_irq,
136 .unmask = omap_unmask_irq, 135 .unmask = omap_unmask_irq,
137 .disable = omap_mask_irq,
138}; 136};
139 137
140static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) 138static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
@@ -157,6 +155,22 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
157 intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG); 155 intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
158} 156}
159 157
158int omap_irq_pending(void)
159{
160 int i;
161
162 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
163 struct omap_irq_bank *bank = irq_banks + i;
164 int irq;
165
166 for (irq = 0; irq < bank->nr_irqs; irq += 32)
167 if (intc_bank_read_reg(bank, INTC_PENDING_IRQ0 +
168 ((irq >> 5) << 5)))
169 return 1;
170 }
171 return 0;
172}
173
160void __init omap_init_irq(void) 174void __init omap_init_irq(void)
161{ 175{
162 unsigned long nr_of_irqs = 0; 176 unsigned long nr_of_irqs = 0;
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
index dc40b3e72206..9756a878fd90 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -16,8 +16,8 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/i2c/twl4030.h> 19#include <linux/mmc/host.h>
20#include <linux/regulator/machine.h> 20#include <linux/regulator/consumer.h>
21 21
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <mach/control.h> 23#include <mach/control.h>
@@ -26,31 +26,9 @@
26 26
27#include "mmc-twl4030.h" 27#include "mmc-twl4030.h"
28 28
29#if defined(CONFIG_TWL4030_CORE) && \
30 (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
31 29
32#define LDO_CLR 0x00 30#if defined(CONFIG_REGULATOR) && \
33#define VSEL_S2_CLR 0x40 31 (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
34
35#define VMMC1_DEV_GRP 0x27
36#define VMMC1_CLR 0x00
37#define VMMC1_315V 0x03
38#define VMMC1_300V 0x02
39#define VMMC1_285V 0x01
40#define VMMC1_185V 0x00
41#define VMMC1_DEDICATED 0x2A
42
43#define VMMC2_DEV_GRP 0x2B
44#define VMMC2_CLR 0x40
45#define VMMC2_315V 0x0c
46#define VMMC2_300V 0x0b
47#define VMMC2_285V 0x0a
48#define VMMC2_280V 0x09
49#define VMMC2_260V 0x08
50#define VMMC2_185V 0x06
51#define VMMC2_DEDICATED 0x2E
52
53#define VMMC_DEV_GRP_P1 0x20
54 32
55static u16 control_pbias_offset; 33static u16 control_pbias_offset;
56static u16 control_devconf1_offset; 34static u16 control_devconf1_offset;
@@ -59,19 +37,16 @@ static u16 control_devconf1_offset;
59 37
60static struct twl_mmc_controller { 38static struct twl_mmc_controller {
61 struct omap_mmc_platform_data *mmc; 39 struct omap_mmc_platform_data *mmc;
62 u8 twl_vmmc_dev_grp; 40 /* Vcc == configured supply
63 u8 twl_mmc_dedicated; 41 * Vcc_alt == optional
64 char name[HSMMC_NAME_LEN + 1]; 42 * - MMC1, supply for DAT4..DAT7
65} hsmmc[OMAP34XX_NR_MMC] = { 43 * - MMC2/MMC2, external level shifter voltage supply, for
66 { 44 * chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
67 .twl_vmmc_dev_grp = VMMC1_DEV_GRP, 45 */
68 .twl_mmc_dedicated = VMMC1_DEDICATED, 46 struct regulator *vcc;
69 }, 47 struct regulator *vcc_aux;
70 { 48 char name[HSMMC_NAME_LEN + 1];
71 .twl_vmmc_dev_grp = VMMC2_DEV_GRP, 49} hsmmc[OMAP34XX_NR_MMC];
72 .twl_mmc_dedicated = VMMC2_DEDICATED,
73 },
74};
75 50
76static int twl_mmc_card_detect(int irq) 51static int twl_mmc_card_detect(int irq)
77{ 52{
@@ -117,16 +92,60 @@ static int twl_mmc_late_init(struct device *dev)
117 int ret = 0; 92 int ret = 0;
118 int i; 93 int i;
119 94
120 ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); 95 /* MMC/SD/SDIO doesn't require a card detect switch */
121 if (ret) 96 if (gpio_is_valid(mmc->slots[0].switch_pin)) {
122 goto done; 97 ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
123 ret = gpio_direction_input(mmc->slots[0].switch_pin); 98 if (ret)
124 if (ret) 99 goto done;
125 goto err; 100 ret = gpio_direction_input(mmc->slots[0].switch_pin);
101 if (ret)
102 goto err;
103 }
126 104
105 /* require at least main regulator */
127 for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { 106 for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
128 if (hsmmc[i].name == mmc->slots[0].name) { 107 if (hsmmc[i].name == mmc->slots[0].name) {
108 struct regulator *reg;
109
129 hsmmc[i].mmc = mmc; 110 hsmmc[i].mmc = mmc;
111
112 reg = regulator_get(dev, "vmmc");
113 if (IS_ERR(reg)) {
114 dev_dbg(dev, "vmmc regulator missing\n");
115 /* HACK: until fixed.c regulator is usable,
116 * we don't require a main regulator
117 * for MMC2 or MMC3
118 */
119 if (i != 0)
120 break;
121 ret = PTR_ERR(reg);
122 goto err;
123 }
124 hsmmc[i].vcc = reg;
125 mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg);
126
127 /* allow an aux regulator */
128 reg = regulator_get(dev, "vmmc_aux");
129 hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg;
130
131 /* UGLY HACK: workaround regulator framework bugs.
132 * When the bootloader leaves a supply active, it's
133 * initialized with zero usecount ... and we can't
134 * disable it without first enabling it. Until the
135 * framework is fixed, we need a workaround like this
136 * (which is safe for MMC, but not in general).
137 */
138 if (regulator_is_enabled(hsmmc[i].vcc) > 0) {
139 regulator_enable(hsmmc[i].vcc);
140 regulator_disable(hsmmc[i].vcc);
141 }
142 if (hsmmc[i].vcc_aux) {
143 if (regulator_is_enabled(reg) > 0) {
144 regulator_enable(reg);
145 regulator_disable(reg);
146 }
147 }
148
130 break; 149 break;
131 } 150 }
132 } 151 }
@@ -173,96 +192,6 @@ static int twl_mmc_resume(struct device *dev, int slot)
173#define twl_mmc_resume NULL 192#define twl_mmc_resume NULL
174#endif 193#endif
175 194
176/*
177 * Sets the MMC voltage in twl4030
178 */
179
180#define MMC1_OCR (MMC_VDD_165_195 \
181 |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
182#define MMC2_OCR (MMC_VDD_165_195 \
183 |MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \
184 |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
185
186static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
187{
188 int ret;
189 u8 vmmc = 0, dev_grp_val;
190
191 if (!vdd)
192 goto doit;
193
194 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) {
195 /* VMMC1: max 220 mA. And for 8-bit mode,
196 * VSIM: max 50 mA
197 */
198 switch (1 << vdd) {
199 case MMC_VDD_165_195:
200 vmmc = VMMC1_185V;
201 /* and VSIM_180V */
202 break;
203 case MMC_VDD_28_29:
204 vmmc = VMMC1_285V;
205 /* and VSIM_280V */
206 break;
207 case MMC_VDD_29_30:
208 case MMC_VDD_30_31:
209 vmmc = VMMC1_300V;
210 /* and VSIM_300V */
211 break;
212 case MMC_VDD_31_32:
213 vmmc = VMMC1_315V;
214 /* error if VSIM needed */
215 break;
216 default:
217 return -EINVAL;
218 }
219 } else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) {
220 /* VMMC2: max 100 mA */
221 switch (1 << vdd) {
222 case MMC_VDD_165_195:
223 vmmc = VMMC2_185V;
224 break;
225 case MMC_VDD_25_26:
226 case MMC_VDD_26_27:
227 vmmc = VMMC2_260V;
228 break;
229 case MMC_VDD_27_28:
230 vmmc = VMMC2_280V;
231 break;
232 case MMC_VDD_28_29:
233 vmmc = VMMC2_285V;
234 break;
235 case MMC_VDD_29_30:
236 case MMC_VDD_30_31:
237 vmmc = VMMC2_300V;
238 break;
239 case MMC_VDD_31_32:
240 vmmc = VMMC2_315V;
241 break;
242 default:
243 return -EINVAL;
244 }
245 } else {
246 return -EINVAL;
247 }
248
249doit:
250 if (vdd)
251 dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */
252 else
253 dev_grp_val = LDO_CLR; /* Power down */
254
255 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
256 dev_grp_val, c->twl_vmmc_dev_grp);
257 if (ret || !vdd)
258 return ret;
259
260 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
261 vmmc, c->twl_mmc_dedicated);
262
263 return ret;
264}
265
266static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, 195static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
267 int vdd) 196 int vdd)
268{ 197{
@@ -273,11 +202,13 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
273 202
274 /* 203 /*
275 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the 204 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
276 * card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both 205 * card with Vcc regulator (from twl4030 or whatever). OMAP has both
277 * 1.8V and 3.0V modes, controlled by the PBIAS register. 206 * 1.8V and 3.0V modes, controlled by the PBIAS register.
278 * 207 *
279 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which 208 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
280 * is most naturally TWL VSIM; those pins also use PBIAS. 209 * is most naturally TWL VSIM; those pins also use PBIAS.
210 *
211 * FIXME handle VMMC1A as needed ...
281 */ 212 */
282 if (power_on) { 213 if (power_on) {
283 if (cpu_is_omap2430()) { 214 if (cpu_is_omap2430()) {
@@ -300,7 +231,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
300 reg &= ~OMAP2_PBIASLITEPWRDNZ0; 231 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
301 omap_ctrl_writel(reg, control_pbias_offset); 232 omap_ctrl_writel(reg, control_pbias_offset);
302 233
303 ret = twl_mmc_set_voltage(c, vdd); 234 ret = mmc_regulator_set_ocr(c->vcc, vdd);
304 235
305 /* 100ms delay required for PBIAS configuration */ 236 /* 100ms delay required for PBIAS configuration */
306 msleep(100); 237 msleep(100);
@@ -316,7 +247,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
316 reg &= ~OMAP2_PBIASLITEPWRDNZ0; 247 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
317 omap_ctrl_writel(reg, control_pbias_offset); 248 omap_ctrl_writel(reg, control_pbias_offset);
318 249
319 ret = twl_mmc_set_voltage(c, 0); 250 ret = mmc_regulator_set_ocr(c->vcc, 0);
320 251
321 /* 100ms delay required for PBIAS configuration */ 252 /* 100ms delay required for PBIAS configuration */
322 msleep(100); 253 msleep(100);
@@ -329,19 +260,33 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
329 return ret; 260 return ret;
330} 261}
331 262
332static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd) 263static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd)
333{ 264{
334 int ret; 265 int ret = 0;
335 struct twl_mmc_controller *c = &hsmmc[1]; 266 struct twl_mmc_controller *c = &hsmmc[1];
336 struct omap_mmc_platform_data *mmc = dev->platform_data; 267 struct omap_mmc_platform_data *mmc = dev->platform_data;
337 268
269 /* If we don't see a Vcc regulator, assume it's a fixed
270 * voltage always-on regulator.
271 */
272 if (!c->vcc)
273 return 0;
274
338 /* 275 /*
339 * Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP 276 * Assume Vcc regulator is used only to power the card ... OMAP
340 * VDDS is used to power the pins, optionally with a transceiver to 277 * VDDS is used to power the pins, optionally with a transceiver to
341 * support cards using voltages other than VDDS (1.8V nominal). When a 278 * support cards using voltages other than VDDS (1.8V nominal). When a
342 * transceiver is used, DAT3..7 are muxed as transceiver control pins. 279 * transceiver is used, DAT3..7 are muxed as transceiver control pins.
280 *
281 * In some cases this regulator won't support enable/disable;
282 * e.g. it's a fixed rail for a WLAN chip.
283 *
284 * In other cases vcc_aux switches interface power. Example, for
285 * eMMC cards it represents VccQ. Sometimes transceivers or SDIO
286 * chips/cards need an interface voltage rail too.
343 */ 287 */
344 if (power_on) { 288 if (power_on) {
289 /* only MMC2 supports a CLKIN */
345 if (mmc->slots[0].internal_clock) { 290 if (mmc->slots[0].internal_clock) {
346 u32 reg; 291 u32 reg;
347 292
@@ -349,24 +294,23 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd
349 reg |= OMAP2_MMCSDIO2ADPCLKISEL; 294 reg |= OMAP2_MMCSDIO2ADPCLKISEL;
350 omap_ctrl_writel(reg, control_devconf1_offset); 295 omap_ctrl_writel(reg, control_devconf1_offset);
351 } 296 }
352 ret = twl_mmc_set_voltage(c, vdd); 297 ret = mmc_regulator_set_ocr(c->vcc, vdd);
298 /* enable interface voltage rail, if needed */
299 if (ret == 0 && c->vcc_aux) {
300 ret = regulator_enable(c->vcc_aux);
301 if (ret < 0)
302 ret = mmc_regulator_set_ocr(c->vcc, 0);
303 }
353 } else { 304 } else {
354 ret = twl_mmc_set_voltage(c, 0); 305 if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0)
306 ret = regulator_disable(c->vcc_aux);
307 if (ret == 0)
308 ret = mmc_regulator_set_ocr(c->vcc, 0);
355 } 309 }
356 310
357 return ret; 311 return ret;
358} 312}
359 313
360static int twl_mmc3_set_power(struct device *dev, int slot, int power_on,
361 int vdd)
362{
363 /*
364 * Assume MMC3 has self-powered device connected, for example on-board
365 * chip with external power source.
366 */
367 return 0;
368}
369
370static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; 314static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
371 315
372void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) 316void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -412,10 +356,10 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
412 mmc->slots[0].wires = c->wires; 356 mmc->slots[0].wires = c->wires;
413 mmc->slots[0].internal_clock = !c->ext_clock; 357 mmc->slots[0].internal_clock = !c->ext_clock;
414 mmc->dma_mask = 0xffffffff; 358 mmc->dma_mask = 0xffffffff;
359 mmc->init = twl_mmc_late_init;
415 360
416 /* note: twl4030 card detect GPIOs normally switch VMMCx ... */ 361 /* note: twl4030 card detect GPIOs can disable VMMCx ... */
417 if (gpio_is_valid(c->gpio_cd)) { 362 if (gpio_is_valid(c->gpio_cd)) {
418 mmc->init = twl_mmc_late_init;
419 mmc->cleanup = twl_mmc_cleanup; 363 mmc->cleanup = twl_mmc_cleanup;
420 mmc->suspend = twl_mmc_suspend; 364 mmc->suspend = twl_mmc_suspend;
421 mmc->resume = twl_mmc_resume; 365 mmc->resume = twl_mmc_resume;
@@ -439,26 +383,28 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
439 } else 383 } else
440 mmc->slots[0].gpio_wp = -EINVAL; 384 mmc->slots[0].gpio_wp = -EINVAL;
441 385
442 /* NOTE: we assume OMAP's MMC1 and MMC2 use 386 /* NOTE: MMC slots should have a Vcc regulator set up.
443 * the TWL4030's VMMC1 and VMMC2, respectively; 387 * This may be from a TWL4030-family chip, another
444 * and that MMC3 device has it's own power source. 388 * controllable regulator, or a fixed supply.
389 *
390 * temporary HACK: ocr_mask instead of fixed supply
445 */ 391 */
392 mmc->slots[0].ocr_mask = c->ocr_mask;
446 393
447 switch (c->mmc) { 394 switch (c->mmc) {
448 case 1: 395 case 1:
396 /* on-chip level shifting via PBIAS0/PBIAS1 */
449 mmc->slots[0].set_power = twl_mmc1_set_power; 397 mmc->slots[0].set_power = twl_mmc1_set_power;
450 mmc->slots[0].ocr_mask = MMC1_OCR;
451 break; 398 break;
452 case 2: 399 case 2:
453 mmc->slots[0].set_power = twl_mmc2_set_power; 400 if (c->ext_clock)
454 if (c->transceiver) 401 c->transceiver = 1;
455 mmc->slots[0].ocr_mask = MMC2_OCR; 402 if (c->transceiver && c->wires > 4)
456 else 403 c->wires = 4;
457 mmc->slots[0].ocr_mask = MMC_VDD_165_195; 404 /* FALLTHROUGH */
458 break;
459 case 3: 405 case 3:
460 mmc->slots[0].set_power = twl_mmc3_set_power; 406 /* off-chip level shifting, or none */
461 mmc->slots[0].ocr_mask = MMC_VDD_165_195; 407 mmc->slots[0].set_power = twl_mmc23_set_power;
462 break; 408 break;
463 default: 409 default:
464 pr_err("MMC%d configuration not supported!\n", c->mmc); 410 pr_err("MMC%d configuration not supported!\n", c->mmc);
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h
index ea59e8624290..3807c45c9a6c 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.h
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -16,9 +16,10 @@ struct twl4030_hsmmc_info {
16 int gpio_wp; /* or -EINVAL */ 16 int gpio_wp; /* or -EINVAL */
17 char *name; /* or NULL for default */ 17 char *name; /* or NULL for default */
18 struct device *dev; /* returned: pointer to mmc adapter */ 18 struct device *dev; /* returned: pointer to mmc adapter */
19 int ocr_mask; /* temporary HACK */
19}; 20};
20 21
21#if defined(CONFIG_TWL4030_CORE) && \ 22#if defined(CONFIG_REGULATOR) && \
22 (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ 23 (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
23 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) 24 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
24 25
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
new file mode 100644
index 000000000000..6cc375a275be
--- /dev/null
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -0,0 +1,152 @@
1/*
2 * OMAP Power Management debug routines
3 *
4 * Copyright (C) 2005 Texas Instruments, Inc.
5 * Copyright (C) 2006-2008 Nokia Corporation
6 *
7 * Written by:
8 * Richard Woodruff <r-woodruff2@ti.com>
9 * Tony Lindgren
10 * Juha Yrjola
11 * Amit Kucheria <amit.kucheria@nokia.com>
12 * Igor Stoppa <igor.stoppa@nokia.com>
13 * Jouni Hogander
14 *
15 * Based on pm.c for omap2
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/kernel.h>
23#include <linux/timer.h>
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/io.h>
27
28#include <mach/clock.h>
29#include <mach/board.h>
30
31#include "prm.h"
32#include "cm.h"
33#include "pm.h"
34
35int omap2_pm_debug;
36
37#define DUMP_PRM_MOD_REG(mod, reg) \
38 regs[reg_count].name = #mod "." #reg; \
39 regs[reg_count++].val = prm_read_mod_reg(mod, reg)
40#define DUMP_CM_MOD_REG(mod, reg) \
41 regs[reg_count].name = #mod "." #reg; \
42 regs[reg_count++].val = cm_read_mod_reg(mod, reg)
43#define DUMP_PRM_REG(reg) \
44 regs[reg_count].name = #reg; \
45 regs[reg_count++].val = __raw_readl(reg)
46#define DUMP_CM_REG(reg) \
47 regs[reg_count].name = #reg; \
48 regs[reg_count++].val = __raw_readl(reg)
49#define DUMP_INTC_REG(reg, off) \
50 regs[reg_count].name = #reg; \
51 regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
52
53void omap2_pm_dump(int mode, int resume, unsigned int us)
54{
55 struct reg {
56 const char *name;
57 u32 val;
58 } regs[32];
59 int reg_count = 0, i;
60 const char *s1 = NULL, *s2 = NULL;
61
62 if (!resume) {
63#if 0
64 /* MPU */
65 DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
66 DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
67 DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
68 DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
69 DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
70#endif
71#if 0
72 /* INTC */
73 DUMP_INTC_REG(INTC_MIR0, 0x0084);
74 DUMP_INTC_REG(INTC_MIR1, 0x00a4);
75 DUMP_INTC_REG(INTC_MIR2, 0x00c4);
76#endif
77#if 0
78 DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
79 if (cpu_is_omap24xx()) {
80 DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
81 DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
82 OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
83 DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
84 OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
85 }
86 DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
87 DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
88 DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
89 DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
90 DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
91 DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
92 DUMP_PRM_MOD_REG(CORE_MOD, PM_PWSTST);
93#endif
94#if 0
95 /* DSP */
96 if (cpu_is_omap24xx()) {
97 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
98 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
99 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
100 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
101 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
102 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
103 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
104 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
105 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
106 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
107 }
108#endif
109 } else {
110 DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
111 if (cpu_is_omap24xx())
112 DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
113 DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
114 DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
115#if 1
116 DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
117 DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
118 DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
119#endif
120 }
121
122 switch (mode) {
123 case 0:
124 s1 = "full";
125 s2 = "retention";
126 break;
127 case 1:
128 s1 = "MPU";
129 s2 = "retention";
130 break;
131 case 2:
132 s1 = "MPU";
133 s2 = "idle";
134 break;
135 }
136
137 if (!resume)
138#ifdef CONFIG_NO_HZ
139 printk(KERN_INFO
140 "--- Going to %s %s (next timer after %u ms)\n", s1, s2,
141 jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
142 jiffies));
143#else
144 printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
145#endif
146 else
147 printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
148 us / 1000, us % 1000);
149
150 for (i = 0; i < reg_count; i++)
151 printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
152}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
deleted file mode 100644
index ea8ceaed09cb..000000000000
--- a/arch/arm/mach-omap2/pm.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * linux/arch/arm/mach-omap2/pm.c
3 *
4 * OMAP2 Power Management Routines
5 *
6 * Copyright (C) 2006 Nokia Corporation
7 * Tony Lindgren <tony@atomide.com>
8 *
9 * Copyright (C) 2005 Texas Instruments, Inc.
10 * Richard Woodruff <r-woodruff2@ti.com>
11 *
12 * Based on pm.c for omap1
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/suspend.h>
20#include <linux/sched.h>
21#include <linux/proc_fs.h>
22#include <linux/interrupt.h>
23#include <linux/sysfs.h>
24#include <linux/module.h>
25#include <linux/delay.h>
26#include <linux/clk.h>
27#include <linux/io.h>
28
29#include <asm/irq.h>
30#include <asm/atomic.h>
31#include <asm/mach/time.h>
32#include <asm/mach/irq.h>
33
34#include <mach/irqs.h>
35#include <mach/clock.h>
36#include <mach/sram.h>
37#include <mach/pm.h>
38
39static struct clk *vclk;
40static void (*omap2_sram_idle)(void);
41static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
42static void (*saved_idle)(void);
43
44extern void __init pmdomain_init(void);
45extern void pmdomain_set_autoidle(void);
46
47static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
48
49void omap2_pm_idle(void)
50{
51 local_irq_disable();
52 local_fiq_disable();
53 if (need_resched()) {
54 local_fiq_enable();
55 local_irq_enable();
56 return;
57 }
58
59 omap2_sram_idle();
60 local_fiq_enable();
61 local_irq_enable();
62}
63
64static int omap2_pm_prepare(void)
65{
66 /* We cannot sleep in idle until we have resumed */
67 saved_idle = pm_idle;
68 pm_idle = NULL;
69 return 0;
70}
71
72static int omap2_pm_suspend(void)
73{
74 return 0;
75}
76
77static int omap2_pm_enter(suspend_state_t state)
78{
79 int ret = 0;
80
81 switch (state)
82 {
83 case PM_SUSPEND_STANDBY:
84 case PM_SUSPEND_MEM:
85 ret = omap2_pm_suspend();
86 break;
87 default:
88 ret = -EINVAL;
89 }
90
91 return ret;
92}
93
94static void omap2_pm_finish(void)
95{
96 pm_idle = saved_idle;
97}
98
99static struct platform_suspend_ops omap_pm_ops = {
100 .prepare = omap2_pm_prepare,
101 .enter = omap2_pm_enter,
102 .finish = omap2_pm_finish,
103 .valid = suspend_valid_only_mem,
104};
105
106static int __init omap2_pm_init(void)
107{
108 return 0;
109}
110
111__initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
new file mode 100644
index 000000000000..f7b3baf76678
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.h
@@ -0,0 +1,38 @@
1/*
2 * OMAP2/3 Power Management Routines
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 * Jouni Hogander
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
12#define __ARCH_ARM_MACH_OMAP2_PM_H
13
14extern int omap2_pm_init(void);
15extern int omap3_pm_init(void);
16
17#ifdef CONFIG_PM_DEBUG
18extern void omap2_pm_dump(int mode, int resume, unsigned int us);
19extern int omap2_pm_debug;
20#else
21#define omap2_pm_dump(mode, resume, us) do {} while (0);
22#define omap2_pm_debug 0
23#endif /* CONFIG_PM_DEBUG */
24
25extern void omap24xx_idle_loop_suspend(void);
26
27extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
28 void __iomem *sdrc_power);
29extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
30extern void save_secure_ram_context(u32 *addr);
31
32extern unsigned int omap24xx_idle_loop_suspend_sz;
33extern unsigned int omap34xx_suspend_sz;
34extern unsigned int save_secure_ram_context_sz;
35extern unsigned int omap24xx_cpu_suspend_sz;
36extern unsigned int omap34xx_cpu_suspend_sz;
37
38#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
new file mode 100644
index 000000000000..db1025562fb0
--- /dev/null
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -0,0 +1,549 @@
1/*
2 * OMAP2 Power Management Routines
3 *
4 * Copyright (C) 2005 Texas Instruments, Inc.
5 * Copyright (C) 2006-2008 Nokia Corporation
6 *
7 * Written by:
8 * Richard Woodruff <r-woodruff2@ti.com>
9 * Tony Lindgren
10 * Juha Yrjola
11 * Amit Kucheria <amit.kucheria@nokia.com>
12 * Igor Stoppa <igor.stoppa@nokia.com>
13 *
14 * Based on pm.c for omap1
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/suspend.h>
22#include <linux/sched.h>
23#include <linux/proc_fs.h>
24#include <linux/interrupt.h>
25#include <linux/sysfs.h>
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/clk.h>
29#include <linux/io.h>
30#include <linux/irq.h>
31#include <linux/time.h>
32#include <linux/gpio.h>
33
34#include <asm/mach/time.h>
35#include <asm/mach/irq.h>
36#include <asm/mach-types.h>
37
38#include <mach/irqs.h>
39#include <mach/clock.h>
40#include <mach/sram.h>
41#include <mach/control.h>
42#include <mach/mux.h>
43#include <mach/dma.h>
44#include <mach/board.h>
45
46#include "prm.h"
47#include "prm-regbits-24xx.h"
48#include "cm.h"
49#include "cm-regbits-24xx.h"
50#include "sdrc.h"
51#include "pm.h"
52
53#include <mach/powerdomain.h>
54#include <mach/clockdomain.h>
55
56static void (*omap2_sram_idle)(void);
57static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
58 void __iomem *sdrc_power);
59
60static struct powerdomain *mpu_pwrdm;
61static struct powerdomain *core_pwrdm;
62
63static struct clockdomain *dsp_clkdm;
64static struct clockdomain *gfx_clkdm;
65
66static struct clk *osc_ck, *emul_ck;
67
68static int omap2_fclks_active(void)
69{
70 u32 f1, f2;
71
72 f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
73 f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
74
75 /* Ignore UART clocks. These are handled by UART core (serial.c) */
76 f1 &= ~(OMAP24XX_EN_UART1 | OMAP24XX_EN_UART2);
77 f2 &= ~OMAP24XX_EN_UART3;
78
79 if (f1 | f2)
80 return 1;
81 return 0;
82}
83
84static void omap2_enter_full_retention(void)
85{
86 u32 l;
87 struct timespec ts_preidle, ts_postidle, ts_idle;
88
89 /* There is 1 reference hold for all children of the oscillator
90 * clock, the following will remove it. If no one else uses the
91 * oscillator itself it will be disabled if/when we enter retention
92 * mode.
93 */
94 clk_disable(osc_ck);
95
96 /* Clear old wake-up events */
97 /* REVISIT: These write to reserved bits? */
98 prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
99 prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
100 prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
101
102 /*
103 * Set MPU powerdomain's next power state to RETENTION;
104 * preserve logic state during retention
105 */
106 pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
107 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
108
109 /* Workaround to kill USB */
110 l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
111 omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
112
113 omap2_gpio_prepare_for_retention();
114
115 if (omap2_pm_debug) {
116 omap2_pm_dump(0, 0, 0);
117 getnstimeofday(&ts_preidle);
118 }
119
120 /* One last check for pending IRQs to avoid extra latency due
121 * to sleeping unnecessarily. */
122 if (omap_irq_pending())
123 goto no_sleep;
124
125 omap_uart_prepare_idle(0);
126 omap_uart_prepare_idle(1);
127 omap_uart_prepare_idle(2);
128
129 /* Jump to SRAM suspend code */
130 omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
131 OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
132 OMAP_SDRC_REGADDR(SDRC_POWER));
133
134 omap_uart_resume_idle(2);
135 omap_uart_resume_idle(1);
136 omap_uart_resume_idle(0);
137
138no_sleep:
139 if (omap2_pm_debug) {
140 unsigned long long tmp;
141
142 getnstimeofday(&ts_postidle);
143 ts_idle = timespec_sub(ts_postidle, ts_preidle);
144 tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
145 omap2_pm_dump(0, 1, tmp);
146 }
147 omap2_gpio_resume_after_retention();
148
149 clk_enable(osc_ck);
150
151 /* clear CORE wake-up events */
152 prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
153 prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
154
155 /* wakeup domain events - bit 1: GPT1, bit5 GPIO */
156 prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);
157
158 /* MPU domain wake events */
159 l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
160 if (l & 0x01)
161 prm_write_mod_reg(0x01, OCP_MOD,
162 OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
163 if (l & 0x20)
164 prm_write_mod_reg(0x20, OCP_MOD,
165 OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
166
167 /* Mask future PRCM-to-MPU interrupts */
168 prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
169}
170
171static int omap2_i2c_active(void)
172{
173 u32 l;
174
175 l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
176 return l & (OMAP2420_EN_I2C2 | OMAP2420_EN_I2C1);
177}
178
179static int sti_console_enabled;
180
181static int omap2_allow_mpu_retention(void)
182{
183 u32 l;
184
185 /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
186 l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
187 if (l & (OMAP2420_EN_MMC | OMAP24XX_EN_UART2 |
188 OMAP24XX_EN_UART1 | OMAP24XX_EN_MCSPI2 |
189 OMAP24XX_EN_MCSPI1 | OMAP24XX_EN_DSS1))
190 return 0;
191 /* Check for UART3. */
192 l = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
193 if (l & OMAP24XX_EN_UART3)
194 return 0;
195 if (sti_console_enabled)
196 return 0;
197
198 return 1;
199}
200
201static void omap2_enter_mpu_retention(void)
202{
203 int only_idle = 0;
204 struct timespec ts_preidle, ts_postidle, ts_idle;
205
206 /* Putting MPU into the WFI state while a transfer is active
207 * seems to cause the I2C block to timeout. Why? Good question. */
208 if (omap2_i2c_active())
209 return;
210
211 /* The peripherals seem not to be able to wake up the MPU when
212 * it is in retention mode. */
213 if (omap2_allow_mpu_retention()) {
214 /* REVISIT: These write to reserved bits? */
215 prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
216 prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
217 prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
218
219 /* Try to enter MPU retention */
220 prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
221 OMAP_LOGICRETSTATE,
222 MPU_MOD, PM_PWSTCTRL);
223 } else {
224 /* Block MPU retention */
225
226 prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL);
227 only_idle = 1;
228 }
229
230 if (omap2_pm_debug) {
231 omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
232 getnstimeofday(&ts_preidle);
233 }
234
235 omap2_sram_idle();
236
237 if (omap2_pm_debug) {
238 unsigned long long tmp;
239
240 getnstimeofday(&ts_postidle);
241 ts_idle = timespec_sub(ts_postidle, ts_preidle);
242 tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
243 omap2_pm_dump(only_idle ? 2 : 1, 1, tmp);
244 }
245}
246
247static int omap2_can_sleep(void)
248{
249 if (omap2_fclks_active())
250 return 0;
251 if (osc_ck->usecount > 1)
252 return 0;
253 if (omap_dma_running())
254 return 0;
255
256 return 1;
257}
258
259static void omap2_pm_idle(void)
260{
261 local_irq_disable();
262 local_fiq_disable();
263
264 if (!omap2_can_sleep()) {
265 if (omap_irq_pending())
266 goto out;
267 omap2_enter_mpu_retention();
268 goto out;
269 }
270
271 if (omap_irq_pending())
272 goto out;
273
274 omap2_enter_full_retention();
275
276out:
277 local_fiq_enable();
278 local_irq_enable();
279}
280
281static int omap2_pm_prepare(void)
282{
283 /* We cannot sleep in idle until we have resumed */
284 disable_hlt();
285 return 0;
286}
287
288static int omap2_pm_suspend(void)
289{
290 u32 wken_wkup, mir1;
291
292 wken_wkup = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
293 prm_write_mod_reg(wken_wkup & ~OMAP24XX_EN_GPT1, WKUP_MOD, PM_WKEN);
294
295 /* Mask GPT1 */
296 mir1 = omap_readl(0x480fe0a4);
297 omap_writel(1 << 5, 0x480fe0ac);
298
299 omap_uart_prepare_suspend();
300 omap2_enter_full_retention();
301
302 omap_writel(mir1, 0x480fe0a4);
303 prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
304
305 return 0;
306}
307
308static int omap2_pm_enter(suspend_state_t state)
309{
310 int ret = 0;
311
312 switch (state) {
313 case PM_SUSPEND_STANDBY:
314 case PM_SUSPEND_MEM:
315 ret = omap2_pm_suspend();
316 break;
317 default:
318 ret = -EINVAL;
319 }
320
321 return ret;
322}
323
324static void omap2_pm_finish(void)
325{
326 enable_hlt();
327}
328
329static struct platform_suspend_ops omap_pm_ops = {
330 .prepare = omap2_pm_prepare,
331 .enter = omap2_pm_enter,
332 .finish = omap2_pm_finish,
333 .valid = suspend_valid_only_mem,
334};
335
336static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm)
337{
338 omap2_clkdm_allow_idle(clkdm);
339 return 0;
340}
341
342static void __init prcm_setup_regs(void)
343{
344 int i, num_mem_banks;
345 struct powerdomain *pwrdm;
346
347 /* Enable autoidle */
348 prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD,
349 OMAP2_PRCM_SYSCONFIG_OFFSET);
350
351 /* Set all domain wakeup dependencies */
352 prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP);
353 prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP);
354 prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
355 prm_write_mod_reg(0, CORE_MOD, PM_WKDEP);
356 if (cpu_is_omap2430())
357 prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP);
358
359 /*
360 * Set CORE powerdomain memory banks to retain their contents
361 * during RETENTION
362 */
363 num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
364 for (i = 0; i < num_mem_banks; i++)
365 pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
366
367 /* Set CORE powerdomain's next power state to RETENTION */
368 pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
369
370 /*
371 * Set MPU powerdomain's next power state to RETENTION;
372 * preserve logic state during retention
373 */
374 pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
375 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
376
377 /* Force-power down DSP, GFX powerdomains */
378
379 pwrdm = clkdm_get_pwrdm(dsp_clkdm);
380 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
381 omap2_clkdm_sleep(dsp_clkdm);
382
383 pwrdm = clkdm_get_pwrdm(gfx_clkdm);
384 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
385 omap2_clkdm_sleep(gfx_clkdm);
386
387 /* Enable clockdomain hardware-supervised control for all clkdms */
388 clkdm_for_each(_pm_clkdm_enable_hwsup);
389
390 /* Enable clock autoidle for all domains */
391 cm_write_mod_reg(OMAP24XX_AUTO_CAM |
392 OMAP24XX_AUTO_MAILBOXES |
393 OMAP24XX_AUTO_WDT4 |
394 OMAP2420_AUTO_WDT3 |
395 OMAP24XX_AUTO_MSPRO |
396 OMAP2420_AUTO_MMC |
397 OMAP24XX_AUTO_FAC |
398 OMAP2420_AUTO_EAC |
399 OMAP24XX_AUTO_HDQ |
400 OMAP24XX_AUTO_UART2 |
401 OMAP24XX_AUTO_UART1 |
402 OMAP24XX_AUTO_I2C2 |
403 OMAP24XX_AUTO_I2C1 |
404 OMAP24XX_AUTO_MCSPI2 |
405 OMAP24XX_AUTO_MCSPI1 |
406 OMAP24XX_AUTO_MCBSP2 |
407 OMAP24XX_AUTO_MCBSP1 |
408 OMAP24XX_AUTO_GPT12 |
409 OMAP24XX_AUTO_GPT11 |
410 OMAP24XX_AUTO_GPT10 |
411 OMAP24XX_AUTO_GPT9 |
412 OMAP24XX_AUTO_GPT8 |
413 OMAP24XX_AUTO_GPT7 |
414 OMAP24XX_AUTO_GPT6 |
415 OMAP24XX_AUTO_GPT5 |
416 OMAP24XX_AUTO_GPT4 |
417 OMAP24XX_AUTO_GPT3 |
418 OMAP24XX_AUTO_GPT2 |
419 OMAP2420_AUTO_VLYNQ |
420 OMAP24XX_AUTO_DSS,
421 CORE_MOD, CM_AUTOIDLE1);
422 cm_write_mod_reg(OMAP24XX_AUTO_UART3 |
423 OMAP24XX_AUTO_SSI |
424 OMAP24XX_AUTO_USB,
425 CORE_MOD, CM_AUTOIDLE2);
426 cm_write_mod_reg(OMAP24XX_AUTO_SDRC |
427 OMAP24XX_AUTO_GPMC |
428 OMAP24XX_AUTO_SDMA,
429 CORE_MOD, CM_AUTOIDLE3);
430 cm_write_mod_reg(OMAP24XX_AUTO_PKA |
431 OMAP24XX_AUTO_AES |
432 OMAP24XX_AUTO_RNG |
433 OMAP24XX_AUTO_SHA |
434 OMAP24XX_AUTO_DES,
435 CORE_MOD, OMAP24XX_CM_AUTOIDLE4);
436
437 cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI, OMAP24XX_DSP_MOD, CM_AUTOIDLE);
438
439 /* Put DPLL and both APLLs into autoidle mode */
440 cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
441 (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
442 (0x03 << OMAP24XX_AUTO_54M_SHIFT),
443 PLL_MOD, CM_AUTOIDLE);
444
445 cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL |
446 OMAP24XX_AUTO_WDT1 |
447 OMAP24XX_AUTO_MPU_WDT |
448 OMAP24XX_AUTO_GPIOS |
449 OMAP24XX_AUTO_32KSYNC |
450 OMAP24XX_AUTO_GPT1,
451 WKUP_MOD, CM_AUTOIDLE);
452
453 /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
454 * stabilisation */
455 prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
456 OMAP2_PRCM_CLKSSETUP_OFFSET);
457
458 /* Configure automatic voltage transition */
459 prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
460 OMAP2_PRCM_VOLTSETUP_OFFSET);
461 prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT |
462 (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
463 OMAP24XX_MEMRETCTRL |
464 (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
465 (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
466 OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET);
467
468 /* Enable wake-up events */
469 prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1,
470 WKUP_MOD, PM_WKEN);
471}
472
473int __init omap2_pm_init(void)
474{
475 u32 l;
476
477 if (!cpu_is_omap24xx())
478 return -ENODEV;
479
480 printk(KERN_INFO "Power Management for OMAP2 initializing\n");
481 l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
482 printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
483
484 /* Look up important powerdomains, clockdomains */
485
486 mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
487 if (!mpu_pwrdm)
488 pr_err("PM: mpu_pwrdm not found\n");
489
490 core_pwrdm = pwrdm_lookup("core_pwrdm");
491 if (!core_pwrdm)
492 pr_err("PM: core_pwrdm not found\n");
493
494 dsp_clkdm = clkdm_lookup("dsp_clkdm");
495 if (!dsp_clkdm)
496 pr_err("PM: mpu_clkdm not found\n");
497
498 gfx_clkdm = clkdm_lookup("gfx_clkdm");
499 if (!gfx_clkdm)
500 pr_err("PM: gfx_clkdm not found\n");
501
502
503 osc_ck = clk_get(NULL, "osc_ck");
504 if (IS_ERR(osc_ck)) {
505 printk(KERN_ERR "could not get osc_ck\n");
506 return -ENODEV;
507 }
508
509 if (cpu_is_omap242x()) {
510 emul_ck = clk_get(NULL, "emul_ck");
511 if (IS_ERR(emul_ck)) {
512 printk(KERN_ERR "could not get emul_ck\n");
513 clk_put(osc_ck);
514 return -ENODEV;
515 }
516 }
517
518 prcm_setup_regs();
519
520 /* Hack to prevent MPU retention when STI console is enabled. */
521 {
522 const struct omap_sti_console_config *sti;
523
524 sti = omap_get_config(OMAP_TAG_STI_CONSOLE,
525 struct omap_sti_console_config);
526 if (sti != NULL && sti->enable)
527 sti_console_enabled = 1;
528 }
529
530 /*
531 * We copy the assembler sleep/wakeup routines to SRAM.
532 * These routines need to be in SRAM as that's the only
533 * memory the MPU can see when it wakes up.
534 */
535 if (cpu_is_omap24xx()) {
536 omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
537 omap24xx_idle_loop_suspend_sz);
538
539 omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
540 omap24xx_cpu_suspend_sz);
541 }
542
543 suspend_set_ops(&omap_pm_ops);
544 pm_idle = omap2_pm_idle;
545
546 return 0;
547}
548
549late_initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
new file mode 100644
index 000000000000..841d4c5ed8be
--- /dev/null
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -0,0 +1,710 @@
1/*
2 * OMAP3 Power Management Routines
3 *
4 * Copyright (C) 2006-2008 Nokia Corporation
5 * Tony Lindgren <tony@atomide.com>
6 * Jouni Hogander
7 *
8 * Copyright (C) 2005 Texas Instruments, Inc.
9 * Richard Woodruff <r-woodruff2@ti.com>
10 *
11 * Based on pm.c for omap1
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
18#include <linux/pm.h>
19#include <linux/suspend.h>
20#include <linux/interrupt.h>
21#include <linux/module.h>
22#include <linux/list.h>
23#include <linux/err.h>
24#include <linux/gpio.h>
25
26#include <mach/sram.h>
27#include <mach/clockdomain.h>
28#include <mach/powerdomain.h>
29#include <mach/control.h>
30#include <mach/serial.h>
31
32#include "cm.h"
33#include "cm-regbits-34xx.h"
34#include "prm-regbits-34xx.h"
35
36#include "prm.h"
37#include "pm.h"
38
39struct power_state {
40 struct powerdomain *pwrdm;
41 u32 next_state;
42 u32 saved_state;
43 struct list_head node;
44};
45
46static LIST_HEAD(pwrst_list);
47
48static void (*_omap_sram_idle)(u32 *addr, int save_state);
49
50static struct powerdomain *mpu_pwrdm;
51
52/* PRCM Interrupt Handler for wakeups */
53static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
54{
55 u32 wkst, irqstatus_mpu;
56 u32 fclk, iclk;
57
58 /* WKUP */
59 wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
60 if (wkst) {
61 iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
62 fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
63 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
64 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
65 prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
66 while (prm_read_mod_reg(WKUP_MOD, PM_WKST))
67 cpu_relax();
68 cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
69 cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
70 }
71
72 /* CORE */
73 wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
74 if (wkst) {
75 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
76 fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
77 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
78 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
79 prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
80 while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
81 cpu_relax();
82 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
83 cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
84 }
85 wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
86 if (wkst) {
87 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
88 fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
89 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
90 cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
91 prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
92 while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
93 cpu_relax();
94 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
95 cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
96 }
97
98 /* PER */
99 wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
100 if (wkst) {
101 iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
102 fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
103 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
104 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
105 prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
106 while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
107 cpu_relax();
108 cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
109 cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
110 }
111
112 if (omap_rev() > OMAP3430_REV_ES1_0) {
113 /* USBHOST */
114 wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
115 if (wkst) {
116 iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
117 CM_ICLKEN);
118 fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
119 CM_FCLKEN);
120 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
121 CM_ICLKEN);
122 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
123 CM_FCLKEN);
124 prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
125 PM_WKST);
126 while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
127 PM_WKST))
128 cpu_relax();
129 cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
130 CM_ICLKEN);
131 cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
132 CM_FCLKEN);
133 }
134 }
135
136 irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
137 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
138 prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
139 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
140
141 while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET))
142 cpu_relax();
143
144 return IRQ_HANDLED;
145}
146
147static void omap_sram_idle(void)
148{
149 /* Variable to tell what needs to be saved and restored
150 * in omap_sram_idle*/
151 /* save_state = 0 => Nothing to save and restored */
152 /* save_state = 1 => Only L1 and logic lost */
153 /* save_state = 2 => Only L2 lost */
154 /* save_state = 3 => L1, L2 and logic lost */
155 int save_state = 0, mpu_next_state;
156
157 if (!_omap_sram_idle)
158 return;
159
160 mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
161 switch (mpu_next_state) {
162 case PWRDM_POWER_RET:
163 /* No need to save context */
164 save_state = 0;
165 break;
166 default:
167 /* Invalid state */
168 printk(KERN_ERR "Invalid mpu state in sram_idle\n");
169 return;
170 }
171 omap2_gpio_prepare_for_retention();
172 omap_uart_prepare_idle(0);
173 omap_uart_prepare_idle(1);
174 omap_uart_prepare_idle(2);
175
176 _omap_sram_idle(NULL, save_state);
177 cpu_init();
178
179 omap_uart_resume_idle(2);
180 omap_uart_resume_idle(1);
181 omap_uart_resume_idle(0);
182 omap2_gpio_resume_after_retention();
183}
184
185/*
186 * Check if functional clocks are enabled before entering
187 * sleep. This function could be behind CONFIG_PM_DEBUG
188 * when all drivers are configuring their sysconfig registers
189 * properly and using their clocks properly.
190 */
191static int omap3_fclks_active(void)
192{
193 u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
194 fck_cam = 0, fck_per = 0, fck_usbhost = 0;
195
196 fck_core1 = cm_read_mod_reg(CORE_MOD,
197 CM_FCLKEN1);
198 if (omap_rev() > OMAP3430_REV_ES1_0) {
199 fck_core3 = cm_read_mod_reg(CORE_MOD,
200 OMAP3430ES2_CM_FCLKEN3);
201 fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
202 CM_FCLKEN);
203 fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
204 CM_FCLKEN);
205 } else
206 fck_sgx = cm_read_mod_reg(GFX_MOD,
207 OMAP3430ES2_CM_FCLKEN3);
208 fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
209 CM_FCLKEN);
210 fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
211 CM_FCLKEN);
212 fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
213 CM_FCLKEN);
214
215 /* Ignore UART clocks. These are handled by UART core (serial.c) */
216 fck_core1 &= ~(OMAP3430_EN_UART1 | OMAP3430_EN_UART2);
217 fck_per &= ~OMAP3430_EN_UART3;
218
219 if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
220 fck_cam | fck_per | fck_usbhost)
221 return 1;
222 return 0;
223}
224
225static int omap3_can_sleep(void)
226{
227 if (!omap_uart_can_sleep())
228 return 0;
229 if (omap3_fclks_active())
230 return 0;
231 return 1;
232}
233
234/* This sets pwrdm state (other than mpu & core. Currently only ON &
235 * RET are supported. Function is assuming that clkdm doesn't have
236 * hw_sup mode enabled. */
237static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
238{
239 u32 cur_state;
240 int sleep_switch = 0;
241 int ret = 0;
242
243 if (pwrdm == NULL || IS_ERR(pwrdm))
244 return -EINVAL;
245
246 while (!(pwrdm->pwrsts & (1 << state))) {
247 if (state == PWRDM_POWER_OFF)
248 return ret;
249 state--;
250 }
251
252 cur_state = pwrdm_read_next_pwrst(pwrdm);
253 if (cur_state == state)
254 return ret;
255
256 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
257 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
258 sleep_switch = 1;
259 pwrdm_wait_transition(pwrdm);
260 }
261
262 ret = pwrdm_set_next_pwrst(pwrdm, state);
263 if (ret) {
264 printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
265 pwrdm->name);
266 goto err;
267 }
268
269 if (sleep_switch) {
270 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
271 pwrdm_wait_transition(pwrdm);
272 }
273
274err:
275 return ret;
276}
277
278static void omap3_pm_idle(void)
279{
280 local_irq_disable();
281 local_fiq_disable();
282
283 if (!omap3_can_sleep())
284 goto out;
285
286 if (omap_irq_pending())
287 goto out;
288
289 omap_sram_idle();
290
291out:
292 local_fiq_enable();
293 local_irq_enable();
294}
295
296static int omap3_pm_prepare(void)
297{
298 disable_hlt();
299 return 0;
300}
301
302static int omap3_pm_suspend(void)
303{
304 struct power_state *pwrst;
305 int state, ret = 0;
306
307 /* Read current next_pwrsts */
308 list_for_each_entry(pwrst, &pwrst_list, node)
309 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
310 /* Set ones wanted by suspend */
311 list_for_each_entry(pwrst, &pwrst_list, node) {
312 if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
313 goto restore;
314 if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
315 goto restore;
316 }
317
318 omap_uart_prepare_suspend();
319 omap_sram_idle();
320
321restore:
322 /* Restore next_pwrsts */
323 list_for_each_entry(pwrst, &pwrst_list, node) {
324 set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
325 state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
326 if (state > pwrst->next_state) {
327 printk(KERN_INFO "Powerdomain (%s) didn't enter "
328 "target state %d\n",
329 pwrst->pwrdm->name, pwrst->next_state);
330 ret = -1;
331 }
332 }
333 if (ret)
334 printk(KERN_ERR "Could not enter target state in pm_suspend\n");
335 else
336 printk(KERN_INFO "Successfully put all powerdomains "
337 "to target state\n");
338
339 return ret;
340}
341
342static int omap3_pm_enter(suspend_state_t state)
343{
344 int ret = 0;
345
346 switch (state) {
347 case PM_SUSPEND_STANDBY:
348 case PM_SUSPEND_MEM:
349 ret = omap3_pm_suspend();
350 break;
351 default:
352 ret = -EINVAL;
353 }
354
355 return ret;
356}
357
358static void omap3_pm_finish(void)
359{
360 enable_hlt();
361}
362
363static struct platform_suspend_ops omap_pm_ops = {
364 .prepare = omap3_pm_prepare,
365 .enter = omap3_pm_enter,
366 .finish = omap3_pm_finish,
367 .valid = suspend_valid_only_mem,
368};
369
370
371/**
372 * omap3_iva_idle(): ensure IVA is in idle so it can be put into
373 * retention
374 *
375 * In cases where IVA2 is activated by bootcode, it may prevent
376 * full-chip retention or off-mode because it is not idle. This
377 * function forces the IVA2 into idle state so it can go
378 * into retention/off and thus allow full-chip retention/off.
379 *
380 **/
381static void __init omap3_iva_idle(void)
382{
383 /* ensure IVA2 clock is disabled */
384 cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
385
386 /* if no clock activity, nothing else to do */
387 if (!(cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
388 OMAP3430_CLKACTIVITY_IVA2_MASK))
389 return;
390
391 /* Reset IVA2 */
392 prm_write_mod_reg(OMAP3430_RST1_IVA2 |
393 OMAP3430_RST2_IVA2 |
394 OMAP3430_RST3_IVA2,
395 OMAP3430_IVA2_MOD, RM_RSTCTRL);
396
397 /* Enable IVA2 clock */
398 cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2,
399 OMAP3430_IVA2_MOD, CM_FCLKEN);
400
401 /* Set IVA2 boot mode to 'idle' */
402 omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
403 OMAP343X_CONTROL_IVA2_BOOTMOD);
404
405 /* Un-reset IVA2 */
406 prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
407
408 /* Disable IVA2 clock */
409 cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
410
411 /* Reset IVA2 */
412 prm_write_mod_reg(OMAP3430_RST1_IVA2 |
413 OMAP3430_RST2_IVA2 |
414 OMAP3430_RST3_IVA2,
415 OMAP3430_IVA2_MOD, RM_RSTCTRL);
416}
417
418static void __init omap3_d2d_idle(void)
419{
420 u16 mask, padconf;
421
422 /* In a stand alone OMAP3430 where there is not a stacked
423 * modem for the D2D Idle Ack and D2D MStandby must be pulled
424 * high. S CONTROL_PADCONF_SAD2D_IDLEACK and
425 * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */
426 mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
427 padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
428 padconf |= mask;
429 omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);
430
431 padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
432 padconf |= mask;
433 omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
434
435 /* reset modem */
436 prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON |
437 OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST,
438 CORE_MOD, RM_RSTCTRL);
439 prm_write_mod_reg(0, CORE_MOD, RM_RSTCTRL);
440}
441
442static void __init prcm_setup_regs(void)
443{
444 /* XXX Reset all wkdeps. This should be done when initializing
445 * powerdomains */
446 prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
447 prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
448 prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
449 prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
450 prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
451 prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
452 if (omap_rev() > OMAP3430_REV_ES1_0) {
453 prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
454 prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
455 } else
456 prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
457
458 /*
459 * Enable interface clock autoidle for all modules.
460 * Note that in the long run this should be done by clockfw
461 */
462 cm_write_mod_reg(
463 OMAP3430_AUTO_MODEM |
464 OMAP3430ES2_AUTO_MMC3 |
465 OMAP3430ES2_AUTO_ICR |
466 OMAP3430_AUTO_AES2 |
467 OMAP3430_AUTO_SHA12 |
468 OMAP3430_AUTO_DES2 |
469 OMAP3430_AUTO_MMC2 |
470 OMAP3430_AUTO_MMC1 |
471 OMAP3430_AUTO_MSPRO |
472 OMAP3430_AUTO_HDQ |
473 OMAP3430_AUTO_MCSPI4 |
474 OMAP3430_AUTO_MCSPI3 |
475 OMAP3430_AUTO_MCSPI2 |
476 OMAP3430_AUTO_MCSPI1 |
477 OMAP3430_AUTO_I2C3 |
478 OMAP3430_AUTO_I2C2 |
479 OMAP3430_AUTO_I2C1 |
480 OMAP3430_AUTO_UART2 |
481 OMAP3430_AUTO_UART1 |
482 OMAP3430_AUTO_GPT11 |
483 OMAP3430_AUTO_GPT10 |
484 OMAP3430_AUTO_MCBSP5 |
485 OMAP3430_AUTO_MCBSP1 |
486 OMAP3430ES1_AUTO_FAC | /* This is es1 only */
487 OMAP3430_AUTO_MAILBOXES |
488 OMAP3430_AUTO_OMAPCTRL |
489 OMAP3430ES1_AUTO_FSHOSTUSB |
490 OMAP3430_AUTO_HSOTGUSB |
491 OMAP3430_AUTO_SAD2D |
492 OMAP3430_AUTO_SSI,
493 CORE_MOD, CM_AUTOIDLE1);
494
495 cm_write_mod_reg(
496 OMAP3430_AUTO_PKA |
497 OMAP3430_AUTO_AES1 |
498 OMAP3430_AUTO_RNG |
499 OMAP3430_AUTO_SHA11 |
500 OMAP3430_AUTO_DES1,
501 CORE_MOD, CM_AUTOIDLE2);
502
503 if (omap_rev() > OMAP3430_REV_ES1_0) {
504 cm_write_mod_reg(
505 OMAP3430_AUTO_MAD2D |
506 OMAP3430ES2_AUTO_USBTLL,
507 CORE_MOD, CM_AUTOIDLE3);
508 }
509
510 cm_write_mod_reg(
511 OMAP3430_AUTO_WDT2 |
512 OMAP3430_AUTO_WDT1 |
513 OMAP3430_AUTO_GPIO1 |
514 OMAP3430_AUTO_32KSYNC |
515 OMAP3430_AUTO_GPT12 |
516 OMAP3430_AUTO_GPT1 ,
517 WKUP_MOD, CM_AUTOIDLE);
518
519 cm_write_mod_reg(
520 OMAP3430_AUTO_DSS,
521 OMAP3430_DSS_MOD,
522 CM_AUTOIDLE);
523
524 cm_write_mod_reg(
525 OMAP3430_AUTO_CAM,
526 OMAP3430_CAM_MOD,
527 CM_AUTOIDLE);
528
529 cm_write_mod_reg(
530 OMAP3430_AUTO_GPIO6 |
531 OMAP3430_AUTO_GPIO5 |
532 OMAP3430_AUTO_GPIO4 |
533 OMAP3430_AUTO_GPIO3 |
534 OMAP3430_AUTO_GPIO2 |
535 OMAP3430_AUTO_WDT3 |
536 OMAP3430_AUTO_UART3 |
537 OMAP3430_AUTO_GPT9 |
538 OMAP3430_AUTO_GPT8 |
539 OMAP3430_AUTO_GPT7 |
540 OMAP3430_AUTO_GPT6 |
541 OMAP3430_AUTO_GPT5 |
542 OMAP3430_AUTO_GPT4 |
543 OMAP3430_AUTO_GPT3 |
544 OMAP3430_AUTO_GPT2 |
545 OMAP3430_AUTO_MCBSP4 |
546 OMAP3430_AUTO_MCBSP3 |
547 OMAP3430_AUTO_MCBSP2,
548 OMAP3430_PER_MOD,
549 CM_AUTOIDLE);
550
551 if (omap_rev() > OMAP3430_REV_ES1_0) {
552 cm_write_mod_reg(
553 OMAP3430ES2_AUTO_USBHOST,
554 OMAP3430ES2_USBHOST_MOD,
555 CM_AUTOIDLE);
556 }
557
558 /*
559 * Set all plls to autoidle. This is needed until autoidle is
560 * enabled by clockfw
561 */
562 cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
563 OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
564 cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
565 MPU_MOD,
566 CM_AUTOIDLE2);
567 cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
568 (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
569 PLL_MOD,
570 CM_AUTOIDLE);
571 cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
572 PLL_MOD,
573 CM_AUTOIDLE2);
574
575 /*
576 * Enable control of expternal oscillator through
577 * sys_clkreq. In the long run clock framework should
578 * take care of this.
579 */
580 prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
581 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
582 OMAP3430_GR_MOD,
583 OMAP3_PRM_CLKSRC_CTRL_OFFSET);
584
585 /* setup wakup source */
586 prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 |
587 OMAP3430_EN_GPT1 | OMAP3430_EN_GPT12,
588 WKUP_MOD, PM_WKEN);
589 /* No need to write EN_IO, that is always enabled */
590 prm_write_mod_reg(OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1 |
591 OMAP3430_EN_GPT12,
592 WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
593 /* For some reason IO doesn't generate wakeup event even if
594 * it is selected to mpu wakeup goup */
595 prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
596 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
597
598 /* Don't attach IVA interrupts */
599 prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
600 prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
601 prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
602 prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
603
604 /* Clear any pending 'reset' flags */
605 prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
606 prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
607 prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
608 prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
609 prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
610 prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
611 prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
612
613 /* Clear any pending PRCM interrupts */
614 prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
615
616 omap3_iva_idle();
617 omap3_d2d_idle();
618}
619
620static int __init pwrdms_setup(struct powerdomain *pwrdm)
621{
622 struct power_state *pwrst;
623
624 if (!pwrdm->pwrsts)
625 return 0;
626
627 pwrst = kmalloc(sizeof(struct power_state), GFP_KERNEL);
628 if (!pwrst)
629 return -ENOMEM;
630 pwrst->pwrdm = pwrdm;
631 pwrst->next_state = PWRDM_POWER_RET;
632 list_add(&pwrst->node, &pwrst_list);
633
634 if (pwrdm_has_hdwr_sar(pwrdm))
635 pwrdm_enable_hdwr_sar(pwrdm);
636
637 return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
638}
639
640/*
641 * Enable hw supervised mode for all clockdomains if it's
642 * supported. Initiate sleep transition for other clockdomains, if
643 * they are not used
644 */
645static int __init clkdms_setup(struct clockdomain *clkdm)
646{
647 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
648 omap2_clkdm_allow_idle(clkdm);
649 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
650 atomic_read(&clkdm->usecount) == 0)
651 omap2_clkdm_sleep(clkdm);
652 return 0;
653}
654
655int __init omap3_pm_init(void)
656{
657 struct power_state *pwrst, *tmp;
658 int ret;
659
660 if (!cpu_is_omap34xx())
661 return -ENODEV;
662
663 printk(KERN_ERR "Power Management for TI OMAP3.\n");
664
665 /* XXX prcm_setup_regs needs to be before enabling hw
666 * supervised mode for powerdomains */
667 prcm_setup_regs();
668
669 ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
670 (irq_handler_t)prcm_interrupt_handler,
671 IRQF_DISABLED, "prcm", NULL);
672 if (ret) {
673 printk(KERN_ERR "request_irq failed to register for 0x%x\n",
674 INT_34XX_PRCM_MPU_IRQ);
675 goto err1;
676 }
677
678 ret = pwrdm_for_each(pwrdms_setup);
679 if (ret) {
680 printk(KERN_ERR "Failed to setup powerdomains\n");
681 goto err2;
682 }
683
684 (void) clkdm_for_each(clkdms_setup);
685
686 mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
687 if (mpu_pwrdm == NULL) {
688 printk(KERN_ERR "Failed to get mpu_pwrdm\n");
689 goto err2;
690 }
691
692 _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
693 omap34xx_cpu_suspend_sz);
694
695 suspend_set_ops(&omap_pm_ops);
696
697 pm_idle = omap3_pm_idle;
698
699err1:
700 return ret;
701err2:
702 free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
703 list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
704 list_del(&pwrst->node);
705 kfree(pwrst);
706 }
707 return ret;
708}
709
710late_initcall(omap3_pm_init);
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 812d50ee495d..cb1ae84e0925 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -276,6 +276,8 @@
276/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ 276/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
277#define OMAP3430_EN_GPIO1 (1 << 3) 277#define OMAP3430_EN_GPIO1 (1 << 3)
278#define OMAP3430_EN_GPIO1_SHIFT 3 278#define OMAP3430_EN_GPIO1_SHIFT 3
279#define OMAP3430_EN_GPT12 (1 << 1)
280#define OMAP3430_EN_GPT12_SHIFT 1
279#define OMAP3430_EN_GPT1 (1 << 0) 281#define OMAP3430_EN_GPT1 (1 << 0)
280#define OMAP3430_EN_GPT1_SHIFT 0 282#define OMAP3430_EN_GPT1_SHIFT 0
281 283
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 826d326b8062..9937e2814696 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -16,17 +16,12 @@
16 16
17#include "prcm-common.h" 17#include "prcm-common.h"
18 18
19#ifndef __ASSEMBLER__
20#define OMAP_PRM_REGADDR(module, reg) \
21 IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg))
22#else
23#define OMAP2420_PRM_REGADDR(module, reg) \ 19#define OMAP2420_PRM_REGADDR(module, reg) \
24 IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) 20 IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
25#define OMAP2430_PRM_REGADDR(module, reg) \ 21#define OMAP2430_PRM_REGADDR(module, reg) \
26 IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) 22 IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
27#define OMAP34XX_PRM_REGADDR(module, reg) \ 23#define OMAP34XX_PRM_REGADDR(module, reg) \
28 IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) 24 IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
29#endif
30 25
31/* 26/*
32 * Architecture-specific global PRM registers 27 * Architecture-specific global PRM registers
@@ -38,80 +33,132 @@
38 * 33 *
39 */ 34 */
40 35
41/* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */ 36#define OMAP2_PRCM_REVISION_OFFSET 0x0000
42#define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050 37#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
43#define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080 38#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
44 39#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
45/* 242x GR_MOD registers, use these only for assembly code */ 40
46#define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ 41#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
47 OMAP24XX_PRCM_VOLTCTRL_OFFSET) 42#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
48#define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ 43#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
49 OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) 44#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
50 45
51/* 243x GR_MOD registers, use these only for assembly code */ 46#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
52#define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ 47#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
53 OMAP24XX_PRCM_VOLTCTRL_OFFSET) 48#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
54#define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ 49#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
55 OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) 50#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
56 51#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
57/* These will disappear */ 52#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
58#define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) 53#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
59#define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) 54#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
60 55#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
61#define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) 56#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
62#define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) 57#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
63 58#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
64#define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) 59#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
65#define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) 60#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
66#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) 61#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
67#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0078) 62#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
68#define OMAP24XX_PRCM_CLKCFG_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0080) 63#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
69#define OMAP24XX_PRCM_CLKCFG_STATUS OMAP_PRM_REGADDR(OCP_MOD, 0x0084) 64#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
70#define OMAP24XX_PRCM_VOLTSETUP OMAP_PRM_REGADDR(OCP_MOD, 0x0090) 65#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
71#define OMAP24XX_PRCM_CLKSSETUP OMAP_PRM_REGADDR(OCP_MOD, 0x0094) 66
72#define OMAP24XX_PRCM_POLCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0098) 67#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
73 68#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
74#define OMAP3430_PRM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0004) 69
75#define OMAP3430_PRM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0014) 70#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
76 71#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
77#define OMAP3430_PRM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) 72
78#define OMAP3430_PRM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) 73#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
79 74#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
80 75#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
81#define OMAP3430_PRM_VC_SMPS_SA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020) 76#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
82#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024) 77#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
83#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028) 78#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
84#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c) 79#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
85#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030) 80#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
86#define OMAP3430_PRM_VC_CH_CONF OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034) 81#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
87#define OMAP3430_PRM_VC_I2C_CFG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038) 82#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
88#define OMAP3430_PRM_VC_BYPASS_VAL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c) 83
89#define OMAP3430_PRM_RSTCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050) 84#define OMAP3_PRM_REVISION_OFFSET 0x0004
90#define OMAP3430_PRM_RSTTIME OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054) 85#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
91#define OMAP3430_PRM_RSTST OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058) 86#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
92#define OMAP3430_PRM_VOLTCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060) 87#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
93#define OMAP3430_PRM_SRAM_PCHARGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064) 88
94#define OMAP3430_PRM_CLKSRC_CTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070) 89#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
95#define OMAP3430_PRM_VOLTSETUP1 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090) 90#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
96#define OMAP3430_PRM_VOLTOFFSET OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094) 91#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
97#define OMAP3430_PRM_CLKSETUP OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098) 92#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
98#define OMAP3430_PRM_POLCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c) 93
99#define OMAP3430_PRM_VOLTSETUP2 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0) 94
100#define OMAP3430_PRM_VP1_CONFIG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0) 95#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
101#define OMAP3430_PRM_VP1_VSTEPMIN OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4) 96#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
102#define OMAP3430_PRM_VP1_VSTEPMAX OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8) 97#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
103#define OMAP3430_PRM_VP1_VLIMITTO OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc) 98#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
104#define OMAP3430_PRM_VP1_VOLTAGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0) 99#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
105#define OMAP3430_PRM_VP1_STATUS OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4) 100#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
106#define OMAP3430_PRM_VP2_CONFIG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0) 101#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
107#define OMAP3430_PRM_VP2_VSTEPMIN OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4) 102#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
108#define OMAP3430_PRM_VP2_VSTEPMAX OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8) 103#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
109#define OMAP3430_PRM_VP2_VLIMITTO OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc) 104#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
110#define OMAP3430_PRM_VP2_VOLTAGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0) 105#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
111#define OMAP3430_PRM_VP2_STATUS OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4) 106#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
112 107#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
113#define OMAP3430_PRM_CLKSEL OMAP_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040) 108#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
114#define OMAP3430_PRM_CLKOUT_CTRL OMAP_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070) 109#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
110#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
111#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
112#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
113#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
114#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
115#define OMAP3_PRM_RSTST_OFFSET 0x0058
116#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
117#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
118#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
119#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
120#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
121#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
122#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
123#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
124#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
125#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
126#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
127#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
128#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
129#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
130#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
131#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
132#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
133#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
134#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
135#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
136#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
137#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
138#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
139#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
140#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
141#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
142#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
143#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
144#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
145#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
146#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
147#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
148#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
149#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
150#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
151#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
152#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
153#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
154#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
155#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
156#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
157
158#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
159#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
160#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
161#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
115 162
116/* 163/*
117 * Module specific PRM registers from PRM_BASE + domain offset 164 * Module specific PRM registers from PRM_BASE + domain offset
@@ -156,9 +203,11 @@
156 203
157#define OMAP3430_PM_MPUGRPSEL 0x00a4 204#define OMAP3430_PM_MPUGRPSEL 0x00a4
158#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL 205#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
206#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
159 207
160#define OMAP3430_PM_IVAGRPSEL 0x00a8 208#define OMAP3430_PM_IVAGRPSEL 0x00a8
161#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL 209#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
210#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
162 211
163#define OMAP3430_PM_PREPWSTST 0x00e8 212#define OMAP3430_PM_PREPWSTST 0x00e8
164 213
diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
new file mode 100644
index 000000000000..02e1c2d4705f
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
@@ -0,0 +1,55 @@
1/*
2 * SDRC register values for the Micron MT46H32M32LF-6
3 *
4 * Copyright (C) 2008 Texas Instruments, Inc.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Paul Walmsley
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#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
15#define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
16
17#include <mach/sdrc.h>
18
19/* Micron MT46H32M32LF-6 */
20/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
21static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = {
22 [0] = {
23 .rate = 166000000,
24 .actim_ctrla = 0x9a9db4c6,
25 .actim_ctrlb = 0x00011217,
26 .rfr_ctrl = 0x0004dc01,
27 .mr = 0x00000032,
28 },
29 [1] = {
30 .rate = 165941176,
31 .actim_ctrla = 0x9a9db4c6,
32 .actim_ctrlb = 0x00011217,
33 .rfr_ctrl = 0x0004dc01,
34 .mr = 0x00000032,
35 },
36 [2] = {
37 .rate = 83000000,
38 .actim_ctrla = 0x51512283,
39 .actim_ctrlb = 0x0001120c,
40 .rfr_ctrl = 0x00025501,
41 .mr = 0x00000032,
42 },
43 [3] = {
44 .rate = 82970588,
45 .actim_ctrla = 0x51512283,
46 .actim_ctrlb = 0x0001120c,
47 .rfr_ctrl = 0x00025501,
48 .mr = 0x00000032,
49 },
50 [4] = {
51 .rate = 0
52 },
53};
54
55#endif
diff --git a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
new file mode 100644
index 000000000000..3751d293cb1f
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
@@ -0,0 +1,54 @@
1/*
2 * SDRC register values for the Qimonda HYB18M512160AF-6
3 *
4 * Copyright (C) 2008-2009 Texas Instruments, Inc.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Paul Walmsley
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#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
15#define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
16
17#include <mach/sdrc.h>
18
19/* Qimonda HYB18M512160AF-6 */
20static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = {
21 [0] = {
22 .rate = 166000000,
23 .actim_ctrla = 0x629db4c6,
24 .actim_ctrlb = 0x00012214,
25 .rfr_ctrl = 0x0004dc01,
26 .mr = 0x00000032,
27 },
28 [1] = {
29 .rate = 165941176,
30 .actim_ctrla = 0x629db4c6,
31 .actim_ctrlb = 0x00012214,
32 .rfr_ctrl = 0x0004dc01,
33 .mr = 0x00000032,
34 },
35 [2] = {
36 .rate = 83000000,
37 .actim_ctrla = 0x31512283,
38 .actim_ctrlb = 0x0001220a,
39 .rfr_ctrl = 0x00025501,
40 .mr = 0x00000022,
41 },
42 [3] = {
43 .rate = 82970588,
44 .actim_ctrla = 0x31512283,
45 .actim_ctrlb = 0x0001220a,
46 .rfr_ctrl = 0x00025501,
47 .mr = 0x00000022,
48 },
49 [4] = {
50 .rate = 0
51 },
52};
53
54#endif
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 2a30060cb4b7..2045441e8385 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -37,6 +37,10 @@ static struct omap_sdrc_params *sdrc_init_params;
37void __iomem *omap2_sdrc_base; 37void __iomem *omap2_sdrc_base;
38void __iomem *omap2_sms_base; 38void __iomem *omap2_sms_base;
39 39
40/* SDRC_POWER register bits */
41#define SDRC_POWER_EXTCLKDIS_SHIFT 3
42#define SDRC_POWER_PWDENA_SHIFT 2
43#define SDRC_POWER_PAGEPOLICY_SHIFT 0
40 44
41/** 45/**
42 * omap2_sdrc_get_params - return SDRC register values for a given clock rate 46 * omap2_sdrc_get_params - return SDRC register values for a given clock rate
@@ -56,9 +60,12 @@ struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
56{ 60{
57 struct omap_sdrc_params *sp; 61 struct omap_sdrc_params *sp;
58 62
63 if (!sdrc_init_params)
64 return NULL;
65
59 sp = sdrc_init_params; 66 sp = sdrc_init_params;
60 67
61 while (sp->rate != r) 68 while (sp->rate && sp->rate != r)
62 sp++; 69 sp++;
63 70
64 if (!sp->rate) 71 if (!sp->rate)
@@ -74,7 +81,14 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
74 omap2_sms_base = omap2_globals->sms; 81 omap2_sms_base = omap2_globals->sms;
75} 82}
76 83
77/* turn on smart idle modes for SDRAM scheduler and controller */ 84/**
85 * omap2_sdrc_init - initialize SMS, SDRC devices on boot
86 * @sp: pointer to a null-terminated list of struct omap_sdrc_params
87 *
88 * Turn on smart idle modes for SDRAM scheduler and controller.
89 * Program a known-good configuration for the SDRC to deal with buggy
90 * bootloaders.
91 */
78void __init omap2_sdrc_init(struct omap_sdrc_params *sp) 92void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
79{ 93{
80 u32 l; 94 u32 l;
@@ -90,4 +104,10 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
90 sdrc_write_reg(l, SDRC_SYSCONFIG); 104 sdrc_write_reg(l, SDRC_SYSCONFIG);
91 105
92 sdrc_init_params = sp; 106 sdrc_init_params = sp;
107
108 /* XXX Enable SRFRONIDLEREQ here also? */
109 l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
110 (1 << SDRC_POWER_PWDENA_SHIFT) |
111 (1 << SDRC_POWER_PAGEPOLICY_SHIFT);
112 sdrc_write_reg(l, SDRC_POWER);
93} 113}
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
index 0afdad5ae9fb..feaec7eaf6bd 100644
--- a/arch/arm/mach-omap2/sdrc2xxx.c
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -99,7 +99,10 @@ u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
99 m_type = omap2xxx_sdrc_get_type(); 99 m_type = omap2xxx_sdrc_get_type();
100 100
101 local_irq_save(flags); 101 local_irq_save(flags);
102 __raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP); 102 if (cpu_is_omap2420())
103 __raw_writel(0xffff, OMAP2420_PRCM_VOLTSETUP);
104 else
105 __raw_writel(0xffff, OMAP2430_PRCM_VOLTSETUP);
103 omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type); 106 omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type);
104 curr_perf_level = level; 107 curr_perf_level = level;
105 local_irq_restore(flags); 108 local_irq_restore(flags);
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 4dcf39c285b9..b094c15bfe47 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -6,8 +6,13 @@
6 * Copyright (C) 2005-2008 Nokia Corporation 6 * Copyright (C) 2005-2008 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com> 7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 * 8 *
9 * Major rework for PM support by Kevin Hilman
10 *
9 * Based off of arch/arm/mach-omap/omap1/serial.c 11 * Based off of arch/arm/mach-omap/omap1/serial.c
10 * 12 *
13 * Copyright (C) 2009 Texas Instruments
14 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com
15 *
11 * This file is subject to the terms and conditions of the GNU General Public 16 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive 17 * License. See the file "COPYING" in the main directory of this archive
13 * for more details. 18 * for more details.
@@ -21,9 +26,50 @@
21 26
22#include <mach/common.h> 27#include <mach/common.h>
23#include <mach/board.h> 28#include <mach/board.h>
29#include <mach/clock.h>
30#include <mach/control.h>
31
32#include "prm.h"
33#include "pm.h"
34#include "prm-regbits-34xx.h"
35
36#define UART_OMAP_WER 0x17 /* Wake-up enable register */
37
38#define DEFAULT_TIMEOUT (5 * HZ)
24 39
25static struct clk *uart_ick[OMAP_MAX_NR_PORTS]; 40struct omap_uart_state {
26static struct clk *uart_fck[OMAP_MAX_NR_PORTS]; 41 int num;
42 int can_sleep;
43 struct timer_list timer;
44 u32 timeout;
45
46 void __iomem *wk_st;
47 void __iomem *wk_en;
48 u32 wk_mask;
49 u32 padconf;
50
51 struct clk *ick;
52 struct clk *fck;
53 int clocked;
54
55 struct plat_serial8250_port *p;
56 struct list_head node;
57
58#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
59 int context_valid;
60
61 /* Registers to be saved/restored for OFF-mode */
62 u16 dll;
63 u16 dlh;
64 u16 ier;
65 u16 sysc;
66 u16 scr;
67 u16 wer;
68#endif
69};
70
71static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS];
72static LIST_HEAD(uart_list);
27 73
28static struct plat_serial8250_port serial_platform_data[] = { 74static struct plat_serial8250_port serial_platform_data[] = {
29 { 75 {
@@ -74,33 +120,369 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
74 * properly. Note that the TX watermark initialization may not be needed 120 * properly. Note that the TX watermark initialization may not be needed
75 * once the 8250.c watermark handling code is merged. 121 * once the 8250.c watermark handling code is merged.
76 */ 122 */
77static inline void __init omap_serial_reset(struct plat_serial8250_port *p) 123static inline void __init omap_uart_reset(struct omap_uart_state *uart)
78{ 124{
125 struct plat_serial8250_port *p = uart->p;
126
79 serial_write_reg(p, UART_OMAP_MDR1, 0x07); 127 serial_write_reg(p, UART_OMAP_MDR1, 0x07);
80 serial_write_reg(p, UART_OMAP_SCR, 0x08); 128 serial_write_reg(p, UART_OMAP_SCR, 0x08);
81 serial_write_reg(p, UART_OMAP_MDR1, 0x00); 129 serial_write_reg(p, UART_OMAP_MDR1, 0x00);
82 serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0)); 130 serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
83} 131}
84 132
85void omap_serial_enable_clocks(int enable) 133#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
134
135static int enable_off_mode; /* to be removed by full off-mode patches */
136
137static void omap_uart_save_context(struct omap_uart_state *uart)
86{ 138{
87 int i; 139 u16 lcr = 0;
88 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { 140 struct plat_serial8250_port *p = uart->p;
89 if (uart_ick[i] && uart_fck[i]) { 141
90 if (enable) { 142 if (!enable_off_mode)
91 clk_enable(uart_ick[i]); 143 return;
92 clk_enable(uart_fck[i]); 144
93 } else { 145 lcr = serial_read_reg(p, UART_LCR);
94 clk_disable(uart_ick[i]); 146 serial_write_reg(p, UART_LCR, 0xBF);
95 clk_disable(uart_fck[i]); 147 uart->dll = serial_read_reg(p, UART_DLL);
148 uart->dlh = serial_read_reg(p, UART_DLM);
149 serial_write_reg(p, UART_LCR, lcr);
150 uart->ier = serial_read_reg(p, UART_IER);
151 uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
152 uart->scr = serial_read_reg(p, UART_OMAP_SCR);
153 uart->wer = serial_read_reg(p, UART_OMAP_WER);
154
155 uart->context_valid = 1;
156}
157
158static void omap_uart_restore_context(struct omap_uart_state *uart)
159{
160 u16 efr = 0;
161 struct plat_serial8250_port *p = uart->p;
162
163 if (!enable_off_mode)
164 return;
165
166 if (!uart->context_valid)
167 return;
168
169 uart->context_valid = 0;
170
171 serial_write_reg(p, UART_OMAP_MDR1, 0x7);
172 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
173 efr = serial_read_reg(p, UART_EFR);
174 serial_write_reg(p, UART_EFR, UART_EFR_ECB);
175 serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
176 serial_write_reg(p, UART_IER, 0x0);
177 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
178 serial_write_reg(p, UART_DLL, uart->dll);
179 serial_write_reg(p, UART_DLM, uart->dlh);
180 serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
181 serial_write_reg(p, UART_IER, uart->ier);
182 serial_write_reg(p, UART_FCR, 0xA1);
183 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
184 serial_write_reg(p, UART_EFR, efr);
185 serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
186 serial_write_reg(p, UART_OMAP_SCR, uart->scr);
187 serial_write_reg(p, UART_OMAP_WER, uart->wer);
188 serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
189 serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
190}
191#else
192static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
193static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
194#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
195
196static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
197{
198 if (uart->clocked)
199 return;
200
201 clk_enable(uart->ick);
202 clk_enable(uart->fck);
203 uart->clocked = 1;
204 omap_uart_restore_context(uart);
205}
206
207#ifdef CONFIG_PM
208
209static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
210{
211 if (!uart->clocked)
212 return;
213
214 omap_uart_save_context(uart);
215 uart->clocked = 0;
216 clk_disable(uart->ick);
217 clk_disable(uart->fck);
218}
219
220static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
221 int enable)
222{
223 struct plat_serial8250_port *p = uart->p;
224 u16 sysc;
225
226 sysc = serial_read_reg(p, UART_OMAP_SYSC) & 0x7;
227 if (enable)
228 sysc |= 0x2 << 3;
229 else
230 sysc |= 0x1 << 3;
231
232 serial_write_reg(p, UART_OMAP_SYSC, sysc);
233}
234
235static void omap_uart_block_sleep(struct omap_uart_state *uart)
236{
237 omap_uart_enable_clocks(uart);
238
239 omap_uart_smart_idle_enable(uart, 0);
240 uart->can_sleep = 0;
241 if (uart->timeout)
242 mod_timer(&uart->timer, jiffies + uart->timeout);
243 else
244 del_timer(&uart->timer);
245}
246
247static void omap_uart_allow_sleep(struct omap_uart_state *uart)
248{
249 if (!uart->clocked)
250 return;
251
252 omap_uart_smart_idle_enable(uart, 1);
253 uart->can_sleep = 1;
254 del_timer(&uart->timer);
255}
256
257static void omap_uart_idle_timer(unsigned long data)
258{
259 struct omap_uart_state *uart = (struct omap_uart_state *)data;
260
261 omap_uart_allow_sleep(uart);
262}
263
264void omap_uart_prepare_idle(int num)
265{
266 struct omap_uart_state *uart;
267
268 list_for_each_entry(uart, &uart_list, node) {
269 if (num == uart->num && uart->can_sleep) {
270 omap_uart_disable_clocks(uart);
271 return;
272 }
273 }
274}
275
276void omap_uart_resume_idle(int num)
277{
278 struct omap_uart_state *uart;
279
280 list_for_each_entry(uart, &uart_list, node) {
281 if (num == uart->num) {
282 omap_uart_enable_clocks(uart);
283
284 /* Check for IO pad wakeup */
285 if (cpu_is_omap34xx() && uart->padconf) {
286 u16 p = omap_ctrl_readw(uart->padconf);
287
288 if (p & OMAP3_PADCONF_WAKEUPEVENT0)
289 omap_uart_block_sleep(uart);
96 } 290 }
291
292 /* Check for normal UART wakeup */
293 if (__raw_readl(uart->wk_st) & uart->wk_mask)
294 omap_uart_block_sleep(uart);
295
296 return;
97 } 297 }
98 } 298 }
99} 299}
100 300
301void omap_uart_prepare_suspend(void)
302{
303 struct omap_uart_state *uart;
304
305 list_for_each_entry(uart, &uart_list, node) {
306 omap_uart_allow_sleep(uart);
307 }
308}
309
310int omap_uart_can_sleep(void)
311{
312 struct omap_uart_state *uart;
313 int can_sleep = 1;
314
315 list_for_each_entry(uart, &uart_list, node) {
316 if (!uart->clocked)
317 continue;
318
319 if (!uart->can_sleep) {
320 can_sleep = 0;
321 continue;
322 }
323
324 /* This UART can now safely sleep. */
325 omap_uart_allow_sleep(uart);
326 }
327
328 return can_sleep;
329}
330
331/**
332 * omap_uart_interrupt()
333 *
334 * This handler is used only to detect that *any* UART interrupt has
335 * occurred. It does _nothing_ to handle the interrupt. Rather,
336 * any UART interrupt will trigger the inactivity timer so the
337 * UART will not idle or sleep for its timeout period.
338 *
339 **/
340static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
341{
342 struct omap_uart_state *uart = dev_id;
343
344 omap_uart_block_sleep(uart);
345
346 return IRQ_NONE;
347}
348
349static u32 sleep_timeout = DEFAULT_TIMEOUT;
350
351static void omap_uart_idle_init(struct omap_uart_state *uart)
352{
353 u32 v;
354 struct plat_serial8250_port *p = uart->p;
355 int ret;
356
357 uart->can_sleep = 0;
358 uart->timeout = sleep_timeout;
359 setup_timer(&uart->timer, omap_uart_idle_timer,
360 (unsigned long) uart);
361 mod_timer(&uart->timer, jiffies + uart->timeout);
362 omap_uart_smart_idle_enable(uart, 0);
363
364 if (cpu_is_omap34xx()) {
365 u32 mod = (uart->num == 2) ? OMAP3430_PER_MOD : CORE_MOD;
366 u32 wk_mask = 0;
367 u32 padconf = 0;
368
369 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
370 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
371 switch (uart->num) {
372 case 0:
373 wk_mask = OMAP3430_ST_UART1_MASK;
374 padconf = 0x182;
375 break;
376 case 1:
377 wk_mask = OMAP3430_ST_UART2_MASK;
378 padconf = 0x17a;
379 break;
380 case 2:
381 wk_mask = OMAP3430_ST_UART3_MASK;
382 padconf = 0x19e;
383 break;
384 }
385 uart->wk_mask = wk_mask;
386 uart->padconf = padconf;
387 } else if (cpu_is_omap24xx()) {
388 u32 wk_mask = 0;
389
390 if (cpu_is_omap2430()) {
391 uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKEN1);
392 uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKST1);
393 } else if (cpu_is_omap2420()) {
394 uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1);
395 uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1);
396 }
397 switch (uart->num) {
398 case 0:
399 wk_mask = OMAP24XX_ST_UART1_MASK;
400 break;
401 case 1:
402 wk_mask = OMAP24XX_ST_UART2_MASK;
403 break;
404 case 2:
405 wk_mask = OMAP24XX_ST_UART3_MASK;
406 break;
407 }
408 uart->wk_mask = wk_mask;
409 } else {
410 uart->wk_en = 0;
411 uart->wk_st = 0;
412 uart->wk_mask = 0;
413 uart->padconf = 0;
414 }
415
416 /* Set wake-enable bit */
417 if (uart->wk_en && uart->wk_mask) {
418 v = __raw_readl(uart->wk_en);
419 v |= uart->wk_mask;
420 __raw_writel(v, uart->wk_en);
421 }
422
423 /* Ensure IOPAD wake-enables are set */
424 if (cpu_is_omap34xx() && uart->padconf) {
425 u16 v;
426
427 v = omap_ctrl_readw(uart->padconf);
428 v |= OMAP3_PADCONF_WAKEUPENABLE0;
429 omap_ctrl_writew(v, uart->padconf);
430 }
431
432 p->flags |= UPF_SHARE_IRQ;
433 ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
434 "serial idle", (void *)uart);
435 WARN_ON(ret);
436}
437
438static ssize_t sleep_timeout_show(struct kobject *kobj,
439 struct kobj_attribute *attr,
440 char *buf)
441{
442 return sprintf(buf, "%u\n", sleep_timeout / HZ);
443}
444
445static ssize_t sleep_timeout_store(struct kobject *kobj,
446 struct kobj_attribute *attr,
447 const char *buf, size_t n)
448{
449 struct omap_uart_state *uart;
450 unsigned int value;
451
452 if (sscanf(buf, "%u", &value) != 1) {
453 printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
454 return -EINVAL;
455 }
456 sleep_timeout = value * HZ;
457 list_for_each_entry(uart, &uart_list, node) {
458 uart->timeout = sleep_timeout;
459 if (uart->timeout)
460 mod_timer(&uart->timer, jiffies + uart->timeout);
461 else
462 /* A zero value means disable timeout feature */
463 omap_uart_block_sleep(uart);
464 }
465 return n;
466}
467
468static struct kobj_attribute sleep_timeout_attr =
469 __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
470
471#else
472static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
473#endif /* CONFIG_PM */
474
475static struct platform_device serial_device = {
476 .name = "serial8250",
477 .id = PLAT8250_DEV_PLATFORM,
478 .dev = {
479 .platform_data = serial_platform_data,
480 },
481};
482
101void __init omap_serial_init(void) 483void __init omap_serial_init(void)
102{ 484{
103 int i; 485 int i, err;
104 const struct omap_uart_config *info; 486 const struct omap_uart_config *info;
105 char name[16]; 487 char name[16];
106 488
@@ -114,9 +496,14 @@ void __init omap_serial_init(void)
114 496
115 if (info == NULL) 497 if (info == NULL)
116 return; 498 return;
499 if (cpu_is_omap44xx()) {
500 for (i = 0; i < OMAP_MAX_NR_PORTS; i++)
501 serial_platform_data[i].irq += 32;
502 }
117 503
118 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { 504 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
119 struct plat_serial8250_port *p = serial_platform_data + i; 505 struct plat_serial8250_port *p = serial_platform_data + i;
506 struct omap_uart_state *uart = &omap_uart[i];
120 507
121 if (!(info->enabled_uarts & (1 << i))) { 508 if (!(info->enabled_uarts & (1 << i))) {
122 p->membase = NULL; 509 p->membase = NULL;
@@ -125,35 +512,39 @@ void __init omap_serial_init(void)
125 } 512 }
126 513
127 sprintf(name, "uart%d_ick", i+1); 514 sprintf(name, "uart%d_ick", i+1);
128 uart_ick[i] = clk_get(NULL, name); 515 uart->ick = clk_get(NULL, name);
129 if (IS_ERR(uart_ick[i])) { 516 if (IS_ERR(uart->ick)) {
130 printk(KERN_ERR "Could not get uart%d_ick\n", i+1); 517 printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
131 uart_ick[i] = NULL; 518 uart->ick = NULL;
132 } else 519 }
133 clk_enable(uart_ick[i]);
134 520
135 sprintf(name, "uart%d_fck", i+1); 521 sprintf(name, "uart%d_fck", i+1);
136 uart_fck[i] = clk_get(NULL, name); 522 uart->fck = clk_get(NULL, name);
137 if (IS_ERR(uart_fck[i])) { 523 if (IS_ERR(uart->fck)) {
138 printk(KERN_ERR "Could not get uart%d_fck\n", i+1); 524 printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
139 uart_fck[i] = NULL; 525 uart->fck = NULL;
140 } else 526 }
141 clk_enable(uart_fck[i]);
142 527
143 omap_serial_reset(p); 528 if (!uart->ick || !uart->fck)
529 continue;
530
531 uart->num = i;
532 p->private_data = uart;
533 uart->p = p;
534 list_add(&uart->node, &uart_list);
535
536 omap_uart_enable_clocks(uart);
537 omap_uart_reset(uart);
538 omap_uart_idle_init(uart);
144 } 539 }
145}
146 540
147static struct platform_device serial_device = { 541 err = platform_device_register(&serial_device);
148 .name = "serial8250", 542
149 .id = PLAT8250_DEV_PLATFORM, 543#ifdef CONFIG_PM
150 .dev = { 544 if (!err)
151 .platform_data = serial_platform_data, 545 err = sysfs_create_file(&serial_device.dev.kobj,
152 }, 546 &sleep_timeout_attr.attr);
153}; 547#endif
154 548
155static int __init omap_init(void)
156{
157 return platform_device_register(&serial_device);
158} 549}
159arch_initcall(omap_init); 550
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
index bf9e96105e11..130aadbfa083 100644
--- a/arch/arm/mach-omap2/sleep24xx.S
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -28,7 +28,6 @@
28#include <linux/linkage.h> 28#include <linux/linkage.h>
29#include <asm/assembler.h> 29#include <asm/assembler.h>
30#include <mach/io.h> 30#include <mach/io.h>
31#include <mach/pm.h>
32 31
33#include <mach/omap24xx.h> 32#include <mach/omap24xx.h>
34 33
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
new file mode 100644
index 000000000000..e5e2553e79a6
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -0,0 +1,436 @@
1/*
2 * linux/arch/arm/mach-omap2/sleep.S
3 *
4 * (C) Copyright 2007
5 * Texas Instruments
6 * Karthik Dasu <karthik-dp@ti.com>
7 *
8 * (C) Copyright 2004
9 * Texas Instruments, <www.ti.com>
10 * Richard Woodruff <r-woodruff2@ti.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27#include <linux/linkage.h>
28#include <asm/assembler.h>
29#include <mach/io.h>
30#include <mach/control.h>
31
32#include "prm.h"
33#include "sdrc.h"
34
35#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
36 OMAP3430_PM_PREPWSTST)
37#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
38 OMAP3430_PM_PREPWSTST)
39#define PM_PWSTCTRL_MPU_P OMAP34XX_PRM_REGADDR(MPU_MOD, PM_PWSTCTRL)
40#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
41 * available */
42#define SCRATCHPAD_BASE_P OMAP343X_CTRL_REGADDR(\
43 OMAP343X_CONTROL_MEM_WKUP +\
44 SCRATCHPAD_MEM_OFFS)
45#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
46
47 .text
48/* Function call to get the restore pointer for resume from OFF */
49ENTRY(get_restore_pointer)
50 stmfd sp!, {lr} @ save registers on stack
51 adr r0, restore
52 ldmfd sp!, {pc} @ restore regs and return
53ENTRY(get_restore_pointer_sz)
54 .word . - get_restore_pointer_sz
55/*
56 * Forces OMAP into idle state
57 *
58 * omap34xx_suspend() - This bit of code just executes the WFI
59 * for normal idles.
60 *
61 * Note: This code get's copied to internal SRAM at boot. When the OMAP
62 * wakes up it continues execution at the point it went to sleep.
63 */
64ENTRY(omap34xx_cpu_suspend)
65 stmfd sp!, {r0-r12, lr} @ save registers on stack
66loop:
67 /*b loop*/ @Enable to debug by stepping through code
68 /* r0 contains restore pointer in sdram */
69 /* r1 contains information about saving context */
70 ldr r4, sdrc_power @ read the SDRC_POWER register
71 ldr r5, [r4] @ read the contents of SDRC_POWER
72 orr r5, r5, #0x40 @ enable self refresh on idle req
73 str r5, [r4] @ write back to SDRC_POWER register
74
75 cmp r1, #0x0
76 /* If context save is required, do that and execute wfi */
77 bne save_context_wfi
78 /* Data memory barrier and Data sync barrier */
79 mov r1, #0
80 mcr p15, 0, r1, c7, c10, 4
81 mcr p15, 0, r1, c7, c10, 5
82
83 wfi @ wait for interrupt
84
85 nop
86 nop
87 nop
88 nop
89 nop
90 nop
91 nop
92 nop
93 nop
94 nop
95 bl i_dll_wait
96
97 ldmfd sp!, {r0-r12, pc} @ restore regs and return
98restore:
99 /* b restore*/ @ Enable to debug restore code
100 /* Check what was the reason for mpu reset and store the reason in r9*/
101 /* 1 - Only L1 and logic lost */
102 /* 2 - Only L2 lost - In this case, we wont be here */
103 /* 3 - Both L1 and L2 lost */
104 ldr r1, pm_pwstctrl_mpu
105 ldr r2, [r1]
106 and r2, r2, #0x3
107 cmp r2, #0x0 @ Check if target power state was OFF or RET
108 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
109 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
110 bne logic_l1_restore
111 /* Execute smi to invalidate L2 cache */
112 mov r12, #0x1 @ set up to invalide L2
113smi: .word 0xE1600070 @ Call SMI monitor (smieq)
114logic_l1_restore:
115 mov r1, #0
116 /* Invalidate all instruction caches to PoU
117 * and flush branch target cache */
118 mcr p15, 0, r1, c7, c5, 0
119
120 ldr r4, scratchpad_base
121 ldr r3, [r4,#0xBC]
122 ldmia r3!, {r4-r6}
123 mov sp, r4
124 msr spsr_cxsf, r5
125 mov lr, r6
126
127 ldmia r3!, {r4-r9}
128 /* Coprocessor access Control Register */
129 mcr p15, 0, r4, c1, c0, 2
130
131 /* TTBR0 */
132 MCR p15, 0, r5, c2, c0, 0
133 /* TTBR1 */
134 MCR p15, 0, r6, c2, c0, 1
135 /* Translation table base control register */
136 MCR p15, 0, r7, c2, c0, 2
137 /*domain access Control Register */
138 MCR p15, 0, r8, c3, c0, 0
139 /* data fault status Register */
140 MCR p15, 0, r9, c5, c0, 0
141
142 ldmia r3!,{r4-r8}
143 /* instruction fault status Register */
144 MCR p15, 0, r4, c5, c0, 1
145 /*Data Auxiliary Fault Status Register */
146 MCR p15, 0, r5, c5, c1, 0
147 /*Instruction Auxiliary Fault Status Register*/
148 MCR p15, 0, r6, c5, c1, 1
149 /*Data Fault Address Register */
150 MCR p15, 0, r7, c6, c0, 0
151 /*Instruction Fault Address Register*/
152 MCR p15, 0, r8, c6, c0, 2
153 ldmia r3!,{r4-r7}
154
155 /* user r/w thread and process ID */
156 MCR p15, 0, r4, c13, c0, 2
157 /* user ro thread and process ID */
158 MCR p15, 0, r5, c13, c0, 3
159 /*Privileged only thread and process ID */
160 MCR p15, 0, r6, c13, c0, 4
161 /* cache size selection */
162 MCR p15, 2, r7, c0, c0, 0
163 ldmia r3!,{r4-r8}
164 /* Data TLB lockdown registers */
165 MCR p15, 0, r4, c10, c0, 0
166 /* Instruction TLB lockdown registers */
167 MCR p15, 0, r5, c10, c0, 1
168 /* Secure or Nonsecure Vector Base Address */
169 MCR p15, 0, r6, c12, c0, 0
170 /* FCSE PID */
171 MCR p15, 0, r7, c13, c0, 0
172 /* Context PID */
173 MCR p15, 0, r8, c13, c0, 1
174
175 ldmia r3!,{r4-r5}
176 /* primary memory remap register */
177 MCR p15, 0, r4, c10, c2, 0
178 /*normal memory remap register */
179 MCR p15, 0, r5, c10, c2, 1
180
181 /* Restore cpsr */
182 ldmia r3!,{r4} /*load CPSR from SDRAM*/
183 msr cpsr, r4 /*store cpsr */
184
185 /* Enabling MMU here */
186 mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
187 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
188 and r7, #0x7
189 cmp r7, #0x0
190 beq usettbr0
191ttbr_error:
192 /* More work needs to be done to support N[0:2] value other than 0
193 * So looping here so that the error can be detected
194 */
195 b ttbr_error
196usettbr0:
197 mrc p15, 0, r2, c2, c0, 0
198 ldr r5, ttbrbit_mask
199 and r2, r5
200 mov r4, pc
201 ldr r5, table_index_mask
202 and r4, r5 /* r4 = 31 to 20 bits of pc */
203 /* Extract the value to be written to table entry */
204 ldr r1, table_entry
205 add r1, r1, r4 /* r1 has value to be written to table entry*/
206 /* Getting the address of table entry to modify */
207 lsr r4, #18
208 add r2, r4 /* r2 has the location which needs to be modified */
209 /* Storing previous entry of location being modified */
210 ldr r5, scratchpad_base
211 ldr r4, [r2]
212 str r4, [r5, #0xC0]
213 /* Modify the table entry */
214 str r1, [r2]
215 /* Storing address of entry being modified
216 * - will be restored after enabling MMU */
217 ldr r5, scratchpad_base
218 str r2, [r5, #0xC4]
219
220 mov r0, #0
221 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
222 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
223 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
224 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
225 /* Restore control register but dont enable caches here*/
226 /* Caches will be enabled after restoring MMU table entry */
227 ldmia r3!, {r4}
228 /* Store previous value of control register in scratchpad */
229 str r4, [r5, #0xC8]
230 ldr r2, cache_pred_disable_mask
231 and r4, r2
232 mcr p15, 0, r4, c1, c0, 0
233
234 ldmfd sp!, {r0-r12, pc} @ restore regs and return
235save_context_wfi:
236 /*b save_context_wfi*/ @ enable to debug save code
237 mov r8, r0 /* Store SDRAM address in r8 */
238 /* Check what that target sleep state is:stored in r1*/
239 /* 1 - Only L1 and logic lost */
240 /* 2 - Only L2 lost */
241 /* 3 - Both L1 and L2 lost */
242 cmp r1, #0x2 /* Only L2 lost */
243 beq clean_l2
244 cmp r1, #0x1 /* L2 retained */
245 /* r9 stores whether to clean L2 or not*/
246 moveq r9, #0x0 /* Dont Clean L2 */
247 movne r9, #0x1 /* Clean L2 */
248l1_logic_lost:
249 /* Store sp and spsr to SDRAM */
250 mov r4, sp
251 mrs r5, spsr
252 mov r6, lr
253 stmia r8!, {r4-r6}
254 /* Save all ARM registers */
255 /* Coprocessor access control register */
256 mrc p15, 0, r6, c1, c0, 2
257 stmia r8!, {r6}
258 /* TTBR0, TTBR1 and Translation table base control */
259 mrc p15, 0, r4, c2, c0, 0
260 mrc p15, 0, r5, c2, c0, 1
261 mrc p15, 0, r6, c2, c0, 2
262 stmia r8!, {r4-r6}
263 /* Domain access control register, data fault status register,
264 and instruction fault status register */
265 mrc p15, 0, r4, c3, c0, 0
266 mrc p15, 0, r5, c5, c0, 0
267 mrc p15, 0, r6, c5, c0, 1
268 stmia r8!, {r4-r6}
269 /* Data aux fault status register, instruction aux fault status,
270 datat fault address register and instruction fault address register*/
271 mrc p15, 0, r4, c5, c1, 0
272 mrc p15, 0, r5, c5, c1, 1
273 mrc p15, 0, r6, c6, c0, 0
274 mrc p15, 0, r7, c6, c0, 2
275 stmia r8!, {r4-r7}
276 /* user r/w thread and process ID, user r/o thread and process ID,
277 priv only thread and process ID, cache size selection */
278 mrc p15, 0, r4, c13, c0, 2
279 mrc p15, 0, r5, c13, c0, 3
280 mrc p15, 0, r6, c13, c0, 4
281 mrc p15, 2, r7, c0, c0, 0
282 stmia r8!, {r4-r7}
283 /* Data TLB lockdown, instruction TLB lockdown registers */
284 mrc p15, 0, r5, c10, c0, 0
285 mrc p15, 0, r6, c10, c0, 1
286 stmia r8!, {r5-r6}
287 /* Secure or non secure vector base address, FCSE PID, Context PID*/
288 mrc p15, 0, r4, c12, c0, 0
289 mrc p15, 0, r5, c13, c0, 0
290 mrc p15, 0, r6, c13, c0, 1
291 stmia r8!, {r4-r6}
292 /* Primary remap, normal remap registers */
293 mrc p15, 0, r4, c10, c2, 0
294 mrc p15, 0, r5, c10, c2, 1
295 stmia r8!,{r4-r5}
296
297 /* Store current cpsr*/
298 mrs r2, cpsr
299 stmia r8!, {r2}
300
301 mrc p15, 0, r4, c1, c0, 0
302 /* save control register */
303 stmia r8!, {r4}
304clean_caches:
305 /* Clean Data or unified cache to POU*/
306 /* How to invalidate only L1 cache???? - #FIX_ME# */
307 /* mcr p15, 0, r11, c7, c11, 1 */
308 cmp r9, #1 /* Check whether L2 inval is required or not*/
309 bne skip_l2_inval
310clean_l2:
311 /* read clidr */
312 mrc p15, 1, r0, c0, c0, 1
313 /* extract loc from clidr */
314 ands r3, r0, #0x7000000
315 /* left align loc bit field */
316 mov r3, r3, lsr #23
317 /* if loc is 0, then no need to clean */
318 beq finished
319 /* start clean at cache level 0 */
320 mov r10, #0
321loop1:
322 /* work out 3x current cache level */
323 add r2, r10, r10, lsr #1
324 /* extract cache type bits from clidr*/
325 mov r1, r0, lsr r2
326 /* mask of the bits for current cache only */
327 and r1, r1, #7
328 /* see what cache we have at this level */
329 cmp r1, #2
330 /* skip if no cache, or just i-cache */
331 blt skip
332 /* select current cache level in cssr */
333 mcr p15, 2, r10, c0, c0, 0
334 /* isb to sych the new cssr&csidr */
335 isb
336 /* read the new csidr */
337 mrc p15, 1, r1, c0, c0, 0
338 /* extract the length of the cache lines */
339 and r2, r1, #7
340 /* add 4 (line length offset) */
341 add r2, r2, #4
342 ldr r4, assoc_mask
343 /* find maximum number on the way size */
344 ands r4, r4, r1, lsr #3
345 /* find bit position of way size increment */
346 clz r5, r4
347 ldr r7, numset_mask
348 /* extract max number of the index size*/
349 ands r7, r7, r1, lsr #13
350loop2:
351 mov r9, r4
352 /* create working copy of max way size*/
353loop3:
354 /* factor way and cache number into r11 */
355 orr r11, r10, r9, lsl r5
356 /* factor index number into r11 */
357 orr r11, r11, r7, lsl r2
358 /*clean & invalidate by set/way */
359 mcr p15, 0, r11, c7, c10, 2
360 /* decrement the way*/
361 subs r9, r9, #1
362 bge loop3
363 /*decrement the index */
364 subs r7, r7, #1
365 bge loop2
366skip:
367 add r10, r10, #2
368 /* increment cache number */
369 cmp r3, r10
370 bgt loop1
371finished:
372 /*swith back to cache level 0 */
373 mov r10, #0
374 /* select current cache level in cssr */
375 mcr p15, 2, r10, c0, c0, 0
376 isb
377skip_l2_inval:
378 /* Data memory barrier and Data sync barrier */
379 mov r1, #0
380 mcr p15, 0, r1, c7, c10, 4
381 mcr p15, 0, r1, c7, c10, 5
382
383 wfi @ wait for interrupt
384 nop
385 nop
386 nop
387 nop
388 nop
389 nop
390 nop
391 nop
392 nop
393 nop
394 bl i_dll_wait
395 /* restore regs and return */
396 ldmfd sp!, {r0-r12, pc}
397
398i_dll_wait:
399 ldr r4, clk_stabilize_delay
400
401i_dll_delay:
402 subs r4, r4, #0x1
403 bne i_dll_delay
404 ldr r4, sdrc_power
405 ldr r5, [r4]
406 bic r5, r5, #0x40
407 str r5, [r4]
408 bx lr
409pm_prepwstst_core:
410 .word PM_PREPWSTST_CORE_V
411pm_prepwstst_mpu:
412 .word PM_PREPWSTST_MPU_V
413pm_pwstctrl_mpu:
414 .word PM_PWSTCTRL_MPU_P
415scratchpad_base:
416 .word SCRATCHPAD_BASE_P
417sdrc_power:
418 .word SDRC_POWER_V
419context_mem:
420 .word 0x803E3E14
421clk_stabilize_delay:
422 .word 0x000001FF
423assoc_mask:
424 .word 0x3ff
425numset_mask:
426 .word 0x7fff
427ttbrbit_mask:
428 .word 0xFFFFC000
429table_index_mask:
430 .word 0xFFF00000
431table_entry:
432 .word 0x00000C02
433cache_pred_disable_mask:
434 .word 0xFFFFE7FB
435ENTRY(omap34xx_cpu_suspend_sz)
436 .word . - omap34xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index af4bd3490227..bb299851116d 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -124,11 +124,11 @@ omap242x_sdi_cm_clksel2_pll:
124omap242x_sdi_sdrc_dlla_ctrl: 124omap242x_sdi_sdrc_dlla_ctrl:
125 .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) 125 .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
126omap242x_sdi_prcm_voltctrl: 126omap242x_sdi_prcm_voltctrl:
127 .word OMAP242X_PRCM_VOLTCTRL 127 .word OMAP2420_PRCM_VOLTCTRL
128prcm_mask_val: 128prcm_mask_val:
129 .word 0xFFFF3FFC 129 .word 0xFFFF3FFC
130omap242x_sdi_timer_32ksynct_cr: 130omap242x_sdi_timer_32ksynct_cr:
131 .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) 131 .word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
132ENTRY(omap242x_sram_ddr_init_sz) 132ENTRY(omap242x_sram_ddr_init_sz)
133 .word . - omap242x_sram_ddr_init 133 .word . - omap242x_sram_ddr_init
134 134
@@ -220,11 +220,11 @@ omap242x_srs_sdrc_dlla_ctrl:
220omap242x_srs_sdrc_rfr_ctrl: 220omap242x_srs_sdrc_rfr_ctrl:
221 .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) 221 .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
222omap242x_srs_prcm_voltctrl: 222omap242x_srs_prcm_voltctrl:
223 .word OMAP242X_PRCM_VOLTCTRL 223 .word OMAP2420_PRCM_VOLTCTRL
224ddr_prcm_mask_val: 224ddr_prcm_mask_val:
225 .word 0xFFFF3FFC 225 .word 0xFFFF3FFC
226omap242x_srs_timer_32ksynct: 226omap242x_srs_timer_32ksynct:
227 .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) 227 .word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
228 228
229ENTRY(omap242x_sram_reprogram_sdrc_sz) 229ENTRY(omap242x_sram_reprogram_sdrc_sz)
230 .word . - omap242x_sram_reprogram_sdrc 230 .word . - omap242x_sram_reprogram_sdrc
@@ -305,7 +305,7 @@ wait_dll_lock:
305 ldmfd sp!, {r0-r12, pc} @ restore regs and return 305 ldmfd sp!, {r0-r12, pc} @ restore regs and return
306 306
307omap242x_ssp_set_config: 307omap242x_ssp_set_config:
308 .word OMAP242X_PRCM_CLKCFG_CTRL 308 .word OMAP2420_PRCM_CLKCFG_CTRL
309omap242x_ssp_pll_ctl: 309omap242x_ssp_pll_ctl:
310 .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) 310 .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN)
311omap242x_ssp_pll_stat: 311omap242x_ssp_pll_stat:
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index 84363e269e8c..9955abcaeb31 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -124,11 +124,11 @@ omap243x_sdi_cm_clksel2_pll:
124omap243x_sdi_sdrc_dlla_ctrl: 124omap243x_sdi_sdrc_dlla_ctrl:
125 .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) 125 .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
126omap243x_sdi_prcm_voltctrl: 126omap243x_sdi_prcm_voltctrl:
127 .word OMAP243X_PRCM_VOLTCTRL 127 .word OMAP2430_PRCM_VOLTCTRL
128prcm_mask_val: 128prcm_mask_val:
129 .word 0xFFFF3FFC 129 .word 0xFFFF3FFC
130omap243x_sdi_timer_32ksynct_cr: 130omap243x_sdi_timer_32ksynct_cr:
131 .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) 131 .word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
132ENTRY(omap243x_sram_ddr_init_sz) 132ENTRY(omap243x_sram_ddr_init_sz)
133 .word . - omap243x_sram_ddr_init 133 .word . - omap243x_sram_ddr_init
134 134
@@ -220,11 +220,11 @@ omap243x_srs_sdrc_dlla_ctrl:
220omap243x_srs_sdrc_rfr_ctrl: 220omap243x_srs_sdrc_rfr_ctrl:
221 .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) 221 .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
222omap243x_srs_prcm_voltctrl: 222omap243x_srs_prcm_voltctrl:
223 .word OMAP243X_PRCM_VOLTCTRL 223 .word OMAP2430_PRCM_VOLTCTRL
224ddr_prcm_mask_val: 224ddr_prcm_mask_val:
225 .word 0xFFFF3FFC 225 .word 0xFFFF3FFC
226omap243x_srs_timer_32ksynct: 226omap243x_srs_timer_32ksynct:
227 .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) 227 .word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
228 228
229ENTRY(omap243x_sram_reprogram_sdrc_sz) 229ENTRY(omap243x_sram_reprogram_sdrc_sz)
230 .word . - omap243x_sram_reprogram_sdrc 230 .word . - omap243x_sram_reprogram_sdrc
@@ -305,7 +305,7 @@ wait_dll_lock:
305 ldmfd sp!, {r0-r12, pc} @ restore regs and return 305 ldmfd sp!, {r0-r12, pc} @ restore regs and return
306 306
307omap243x_ssp_set_config: 307omap243x_ssp_set_config:
308 .word OMAP243X_PRCM_CLKCFG_CTRL 308 .word OMAP2430_PRCM_CLKCFG_CTRL
309omap243x_ssp_pll_ctl: 309omap243x_ssp_pll_ctl:
310 .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) 310 .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN)
311omap243x_ssp_pll_stat: 311omap243x_ssp_pll_stat:
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 2c7146136342..c080c82521e1 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -40,69 +40,74 @@
40/* 40/*
41 * Change frequency of core dpll 41 * Change frequency of core dpll
42 * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2 42 * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
43 * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
44 * SDRC rates < 83MHz
43 */ 45 */
44ENTRY(omap3_sram_configure_core_dpll) 46ENTRY(omap3_sram_configure_core_dpll)
45 stmfd sp!, {r1-r12, lr} @ store regs to stack 47 stmfd sp!, {r1-r12, lr} @ store regs to stack
48 ldr r4, [sp, #52] @ pull extra args off the stack
49 dsb @ flush buffered writes to interconnect
46 cmp r3, #0x2 50 cmp r3, #0x2
47 blne configure_sdrc 51 blne configure_sdrc
48 cmp r3, #0x2 52 cmp r4, #0x1
53 bleq unlock_dll
49 blne lock_dll 54 blne lock_dll
50 cmp r3, #0x1
51 blne unlock_dll
52 bl sdram_in_selfrefresh @ put the SDRAM in self refresh 55 bl sdram_in_selfrefresh @ put the SDRAM in self refresh
53 bl configure_core_dpll 56 bl configure_core_dpll
54 bl enable_sdrc 57 bl enable_sdrc
55 cmp r3, #0x1 58 cmp r4, #0x1
56 blne wait_dll_unlock 59 bleq wait_dll_unlock
57 cmp r3, #0x2
58 blne wait_dll_lock 60 blne wait_dll_lock
59 cmp r3, #0x1 61 cmp r3, #0x1
60 blne configure_sdrc 62 blne configure_sdrc
63 isb @ prevent speculative exec past here
61 mov r0, #0 @ return value 64 mov r0, #0 @ return value
62 ldmfd sp!, {r1-r12, pc} @ restore regs and return 65 ldmfd sp!, {r1-r12, pc} @ restore regs and return
63unlock_dll: 66unlock_dll:
64 ldr r4, omap3_sdrc_dlla_ctrl 67 ldr r11, omap3_sdrc_dlla_ctrl
65 ldr r5, [r4] 68 ldr r12, [r11]
66 orr r5, r5, #0x4 69 orr r12, r12, #0x4
67 str r5, [r4] 70 str r12, [r11] @ (no OCP barrier needed)
68 bx lr 71 bx lr
69lock_dll: 72lock_dll:
70 ldr r4, omap3_sdrc_dlla_ctrl 73 ldr r11, omap3_sdrc_dlla_ctrl
71 ldr r5, [r4] 74 ldr r12, [r11]
72 bic r5, r5, #0x4 75 bic r12, r12, #0x4
73 str r5, [r4] 76 str r12, [r11] @ (no OCP barrier needed)
74 bx lr 77 bx lr
75sdram_in_selfrefresh: 78sdram_in_selfrefresh:
76 mov r5, #0x0 @ Move 0 to R5 79 ldr r11, omap3_sdrc_power @ read the SDRC_POWER register
77 mcr p15, 0, r5, c7, c10, 5 @ memory barrier 80 ldr r12, [r11] @ read the contents of SDRC_POWER
78 ldr r4, omap3_sdrc_power @ read the SDRC_POWER register 81 mov r9, r12 @ keep a copy of SDRC_POWER bits
79 ldr r5, [r4] @ read the contents of SDRC_POWER 82 orr r12, r12, #0x40 @ enable self refresh on idle req
80 orr r5, r5, #0x40 @ enable self refresh on idle req 83 bic r12, r12, #0x4 @ clear PWDENA
81 str r5, [r4] @ write back to SDRC_POWER register 84 str r12, [r11] @ write back to SDRC_POWER register
82 ldr r4, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg 85 ldr r12, [r11] @ posted-write barrier for SDRC
83 ldr r5, [r4] 86 ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
84 bic r5, r5, #0x2 @ disable iclk bit for SRDC 87 ldr r12, [r11]
85 str r5, [r4] 88 bic r12, r12, #0x2 @ disable iclk bit for SDRC
89 str r12, [r11]
86wait_sdrc_idle: 90wait_sdrc_idle:
87 ldr r4, omap3_cm_idlest1_core 91 ldr r11, omap3_cm_idlest1_core
88 ldr r5, [r4] 92 ldr r12, [r11]
89 and r5, r5, #0x2 @ check for SDRC idle 93 and r12, r12, #0x2 @ check for SDRC idle
90 cmp r5, #2 94 cmp r12, #2
91 bne wait_sdrc_idle 95 bne wait_sdrc_idle
92 bx lr 96 bx lr
93configure_core_dpll: 97configure_core_dpll:
94 ldr r4, omap3_cm_clksel1_pll 98 ldr r11, omap3_cm_clksel1_pll
95 ldr r5, [r4] 99 ldr r12, [r11]
96 ldr r6, core_m2_mask_val @ modify m2 for core dpll 100 ldr r10, core_m2_mask_val @ modify m2 for core dpll
97 and r5, r5, r6 101 and r12, r12, r10
98 orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val 102 orr r12, r12, r3, lsl #0x1B @ r3 contains the M2 val
99 str r5, [r4] 103 str r12, [r11]
100 mov r5, #0x800 @ wait for the clock to stabilise 104 ldr r12, [r11] @ posted-write barrier for CM
105 mov r12, #0x800 @ wait for the clock to stabilise
101 cmp r3, #2 106 cmp r3, #2
102 bne wait_clk_stable 107 bne wait_clk_stable
103 bx lr 108 bx lr
104wait_clk_stable: 109wait_clk_stable:
105 subs r5, r5, #1 110 subs r12, r12, #1
106 bne wait_clk_stable 111 bne wait_clk_stable
107 nop 112 nop
108 nop 113 nop
@@ -116,42 +121,42 @@ wait_clk_stable:
116 nop 121 nop
117 bx lr 122 bx lr
118enable_sdrc: 123enable_sdrc:
119 ldr r4, omap3_cm_iclken1_core 124 ldr r11, omap3_cm_iclken1_core
120 ldr r5, [r4] 125 ldr r12, [r11]
121 orr r5, r5, #0x2 @ enable iclk bit for SDRC 126 orr r12, r12, #0x2 @ enable iclk bit for SDRC
122 str r5, [r4] 127 str r12, [r11]
123wait_sdrc_idle1: 128wait_sdrc_idle1:
124 ldr r4, omap3_cm_idlest1_core 129 ldr r11, omap3_cm_idlest1_core
125 ldr r5, [r4] 130 ldr r12, [r11]
126 and r5, r5, #0x2 131 and r12, r12, #0x2
127 cmp r5, #0 132 cmp r12, #0
128 bne wait_sdrc_idle1 133 bne wait_sdrc_idle1
129 ldr r4, omap3_sdrc_power 134restore_sdrc_power_val:
130 ldr r5, [r4] 135 ldr r11, omap3_sdrc_power
131 bic r5, r5, #0x40 136 str r9, [r11] @ restore SDRC_POWER, no barrier needed
132 str r5, [r4]
133 bx lr 137 bx lr
134wait_dll_lock: 138wait_dll_lock:
135 ldr r4, omap3_sdrc_dlla_status 139 ldr r11, omap3_sdrc_dlla_status
136 ldr r5, [r4] 140 ldr r12, [r11]
137 and r5, r5, #0x4 141 and r12, r12, #0x4
138 cmp r5, #0x4 142 cmp r12, #0x4
139 bne wait_dll_lock 143 bne wait_dll_lock
140 bx lr 144 bx lr
141wait_dll_unlock: 145wait_dll_unlock:
142 ldr r4, omap3_sdrc_dlla_status 146 ldr r11, omap3_sdrc_dlla_status
143 ldr r5, [r4] 147 ldr r12, [r11]
144 and r5, r5, #0x4 148 and r12, r12, #0x4
145 cmp r5, #0x0 149 cmp r12, #0x0
146 bne wait_dll_unlock 150 bne wait_dll_unlock
147 bx lr 151 bx lr
148configure_sdrc: 152configure_sdrc:
149 ldr r4, omap3_sdrc_rfr_ctrl 153 ldr r11, omap3_sdrc_rfr_ctrl
150 str r0, [r4] 154 str r0, [r11]
151 ldr r4, omap3_sdrc_actim_ctrla 155 ldr r11, omap3_sdrc_actim_ctrla
152 str r1, [r4] 156 str r1, [r11]
153 ldr r4, omap3_sdrc_actim_ctrlb 157 ldr r11, omap3_sdrc_actim_ctrlb
154 str r2, [r4] 158 str r2, [r11]
159 ldr r2, [r11] @ posted-write barrier for SDRC
155 bx lr 160 bx lr
156 161
157omap3_sdrc_power: 162omap3_sdrc_power:
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index f36aba12090e..2ce474a9d2b6 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -17,9 +17,10 @@
17 * 17 *
18 * Some parts based off of TI's 24xx code: 18 * Some parts based off of TI's 24xx code:
19 * 19 *
20 * Copyright (C) 2004 Texas Instruments, Inc. 20 * Copyright (C) 2004-2009 Texas Instruments, Inc.
21 * 21 *
22 * Roughly modelled after the OMAP1 MPU timer code. 22 * Roughly modelled after the OMAP1 MPU timer code.
23 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
23 * 24 *
24 * This file is subject to the terms and conditions of the GNU General Public 25 * This file is subject to the terms and conditions of the GNU General Public
25 * License. See the file "COPYING" in the main directory of this archive 26 * License. See the file "COPYING" in the main directory of this archive
@@ -82,7 +83,8 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
82 case CLOCK_EVT_MODE_PERIODIC: 83 case CLOCK_EVT_MODE_PERIODIC:
83 period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; 84 period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
84 period -= 1; 85 period -= 1;
85 86 if (cpu_is_omap44xx())
87 period = 0xff; /* FIXME: */
86 omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); 88 omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
87 break; 89 break;
88 case CLOCK_EVT_MODE_ONESHOT: 90 case CLOCK_EVT_MODE_ONESHOT:
@@ -145,6 +147,9 @@ static void __init omap2_gp_clockevent_init(void)
145 "timer-gp: omap_dm_timer_set_source() failed\n"); 147 "timer-gp: omap_dm_timer_set_source() failed\n");
146 148
147 tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); 149 tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
150 if (cpu_is_omap44xx())
151 /* Assuming 32kHz clk is driving GPT1 */
152 tick_rate = 32768; /* FIXME: */
148 153
149 pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", 154 pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
150 gptimer_id, tick_rate); 155 gptimer_id, tick_rate);
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 34a56a136efd..d85296dc896c 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -28,10 +28,20 @@
28 28
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/irqs.h> 30#include <mach/irqs.h>
31#include <mach/pm.h>
32#include <mach/mux.h> 31#include <mach/mux.h>
33#include <mach/usb.h> 32#include <mach/usb.h>
34 33
34#define OTG_SYSCONFIG (OMAP34XX_HSUSB_OTG_BASE + 0x404)
35
36static void __init usb_musb_pm_init(void)
37{
38 /* Ensure force-idle mode for OTG controller */
39 if (cpu_is_omap34xx())
40 omap_writel(0, OTG_SYSCONFIG);
41}
42
43#ifdef CONFIG_USB_MUSB_SOC
44
35static struct resource musb_resources[] = { 45static struct resource musb_resources[] = {
36 [0] = { /* start and end set dynamically */ 46 [0] = { /* start and end set dynamically */
37 .flags = IORESOURCE_MEM, 47 .flags = IORESOURCE_MEM,
@@ -184,4 +194,13 @@ void __init usb_musb_init(void)
184 printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); 194 printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
185 return; 195 return;
186 } 196 }
197
198 usb_musb_pm_init();
199}
200
201#else
202void __init usb_musb_init(void)
203{
204 usb_musb_pm_init();
187} 205}
206#endif /* CONFIG_USB_MUSB_SOC */