diff options
Diffstat (limited to 'arch/arm')
83 files changed, 5566 insertions, 895 deletions
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 1fe73d198888..9e1c1cceb735 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig | |||
@@ -379,7 +379,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 | |||
379 | # CONFIG_MTD_DOC2001 is not set | 379 | # CONFIG_MTD_DOC2001 is not set |
380 | # CONFIG_MTD_DOC2001PLUS is not set | 380 | # CONFIG_MTD_DOC2001PLUS is not set |
381 | CONFIG_MTD_AT91_DATAFLASH=y | 381 | CONFIG_MTD_AT91_DATAFLASH=y |
382 | CONFIG_MTD_AT91_DATAFLASH_CARD=y | 382 | # CONFIG_MTD_AT91_DATAFLASH_CARD is not set |
383 | 383 | ||
384 | # | 384 | # |
385 | # NAND Flash Device Drivers | 385 | # NAND Flash Device Drivers |
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index b7d934cdb1b7..6e0805a971d7 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig | |||
@@ -370,7 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 | |||
370 | # CONFIG_MTD_DOC2001 is not set | 370 | # CONFIG_MTD_DOC2001 is not set |
371 | # CONFIG_MTD_DOC2001PLUS is not set | 371 | # CONFIG_MTD_DOC2001PLUS is not set |
372 | CONFIG_MTD_AT91_DATAFLASH=y | 372 | CONFIG_MTD_AT91_DATAFLASH=y |
373 | CONFIG_MTD_AT91_DATAFLASH_CARD=y | 373 | # CONFIG_MTD_AT91_DATAFLASH_CARD is not set |
374 | 374 | ||
375 | # | 375 | # |
376 | # NAND Flash Device Drivers | 376 | # NAND Flash Device Drivers |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 1574941ebfe1..ee083b3f0522 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -100,23 +100,12 @@ EXPORT_SYMBOL(__raw_writesl); | |||
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | /* string / mem functions */ | 102 | /* string / mem functions */ |
103 | EXPORT_SYMBOL(strcpy); | ||
104 | EXPORT_SYMBOL(strncpy); | ||
105 | EXPORT_SYMBOL(strcat); | ||
106 | EXPORT_SYMBOL(strncat); | ||
107 | EXPORT_SYMBOL(strcmp); | ||
108 | EXPORT_SYMBOL(strncmp); | ||
109 | EXPORT_SYMBOL(strchr); | 103 | EXPORT_SYMBOL(strchr); |
110 | EXPORT_SYMBOL(strlen); | ||
111 | EXPORT_SYMBOL(strnlen); | ||
112 | EXPORT_SYMBOL(strpbrk); | 104 | EXPORT_SYMBOL(strpbrk); |
113 | EXPORT_SYMBOL(strrchr); | 105 | EXPORT_SYMBOL(strrchr); |
114 | EXPORT_SYMBOL(strstr); | ||
115 | EXPORT_SYMBOL(memset); | 106 | EXPORT_SYMBOL(memset); |
116 | EXPORT_SYMBOL(memcpy); | 107 | EXPORT_SYMBOL(memcpy); |
117 | EXPORT_SYMBOL(memmove); | 108 | EXPORT_SYMBOL(memmove); |
118 | EXPORT_SYMBOL(memcmp); | ||
119 | EXPORT_SYMBOL(memscan); | ||
120 | EXPORT_SYMBOL(memchr); | 109 | EXPORT_SYMBOL(memchr); |
121 | EXPORT_SYMBOL(__memzero); | 110 | EXPORT_SYMBOL(__memzero); |
122 | 111 | ||
@@ -190,8 +179,6 @@ EXPORT_SYMBOL(_find_next_bit_be); | |||
190 | 179 | ||
191 | /* syscalls */ | 180 | /* syscalls */ |
192 | EXPORT_SYMBOL(sys_write); | 181 | EXPORT_SYMBOL(sys_write); |
193 | EXPORT_SYMBOL(sys_read); | ||
194 | EXPORT_SYMBOL(sys_lseek); | 182 | EXPORT_SYMBOL(sys_lseek); |
195 | EXPORT_SYMBOL(sys_open); | ||
196 | EXPORT_SYMBOL(sys_exit); | 183 | EXPORT_SYMBOL(sys_exit); |
197 | EXPORT_SYMBOL(sys_wait4); | 184 | EXPORT_SYMBOL(sys_wait4); |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b7cd280bfd63..437528403959 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -252,6 +252,9 @@ static void __init dump_cpu_info(int cpu) | |||
252 | dump_cache("cache", cpu, CACHE_ISIZE(info)); | 252 | dump_cache("cache", cpu, CACHE_ISIZE(info)); |
253 | } | 253 | } |
254 | } | 254 | } |
255 | |||
256 | if (arch_is_coherent()) | ||
257 | printk("Cache coherency enabled\n"); | ||
255 | } | 258 | } |
256 | 259 | ||
257 | int cpu_architecture(void) | 260 | int cpu_architecture(void) |
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 75e6ee318ded..ef88c4128edc 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile | |||
@@ -16,11 +16,12 @@ obj-$(CONFIG_MACH_CSB637) += board-csb637.o | |||
16 | #obj-$(CONFIG_MACH_KB9200) += board-kb9202.o | 16 | #obj-$(CONFIG_MACH_KB9200) += board-kb9202.o |
17 | 17 | ||
18 | # LEDs support | 18 | # LEDs support |
19 | #led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o | 19 | led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o |
20 | #led-$(CONFIG_MACH_AT91RM9200EK) += leds.o | 20 | led-$(CONFIG_MACH_AT91RM9200EK) += leds.o |
21 | #led-$(CONFIG_MACH_CSB337) += leds.o | 21 | led-$(CONFIG_MACH_CSB337) += leds.o |
22 | #led-$(CONFIG_MACH_CSB637) += leds.o | 22 | led-$(CONFIG_MACH_CSB637) += leds.o |
23 | #led-$(CONFIG_MACH_KB9200) += leds.o | 23 | #led-$(CONFIG_MACH_KB9200) += leds.o |
24 | #led-$(CONFIG_MACH_KAFA) += leds.o | ||
24 | obj-$(CONFIG_LEDS) += $(led-y) | 25 | obj-$(CONFIG_LEDS) += $(led-y) |
25 | 26 | ||
26 | # VGA support | 27 | # VGA support |
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 54022e58d50d..f45104ceea8f 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c | |||
@@ -67,6 +67,9 @@ static void __init csb337_map_io(void) | |||
67 | /* Initialize clocks: 3.6864 MHz crystal */ | 67 | /* Initialize clocks: 3.6864 MHz crystal */ |
68 | at91_clock_init(3686400); | 68 | at91_clock_init(3686400); |
69 | 69 | ||
70 | /* Setup the LEDs */ | ||
71 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | ||
72 | |||
70 | #ifdef CONFIG_SERIAL_AT91 | 73 | #ifdef CONFIG_SERIAL_AT91 |
71 | at91_console_port = CSB337_SERIAL_CONSOLE; | 74 | at91_console_port = CSB337_SERIAL_CONSOLE; |
72 | memcpy(at91_serial_map, serial, sizeof(serial)); | 75 | memcpy(at91_serial_map, serial, sizeof(serial)); |
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c index 8195f9d919ea..f2c2d6e79bc6 100644 --- a/arch/arm/mach-at91rm9200/board-csb637.c +++ b/arch/arm/mach-at91rm9200/board-csb637.c | |||
@@ -67,6 +67,9 @@ static void __init csb637_map_io(void) | |||
67 | /* Initialize clocks: 3.6864 MHz crystal */ | 67 | /* Initialize clocks: 3.6864 MHz crystal */ |
68 | at91_clock_init(3686400); | 68 | at91_clock_init(3686400); |
69 | 69 | ||
70 | /* Setup the LEDs */ | ||
71 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | ||
72 | |||
70 | #ifdef CONFIG_SERIAL_AT91 | 73 | #ifdef CONFIG_SERIAL_AT91 |
71 | at91_console_port = CSB637_SERIAL_CONSOLE; | 74 | at91_console_port = CSB637_SERIAL_CONSOLE; |
72 | memcpy(at91_serial_map, serial, sizeof(serial)); | 75 | memcpy(at91_serial_map, serial, sizeof(serial)); |
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 8a783368366e..2d7200ed66ed 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c | |||
@@ -70,6 +70,9 @@ static void __init dk_map_io(void) | |||
70 | /* Initialize clocks: 18.432 MHz crystal */ | 70 | /* Initialize clocks: 18.432 MHz crystal */ |
71 | at91_clock_init(18432000); | 71 | at91_clock_init(18432000); |
72 | 72 | ||
73 | /* Setup the LEDs */ | ||
74 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | ||
75 | |||
73 | #ifdef CONFIG_SERIAL_AT91 | 76 | #ifdef CONFIG_SERIAL_AT91 |
74 | at91_console_port = DK_SERIAL_CONSOLE; | 77 | at91_console_port = DK_SERIAL_CONSOLE; |
75 | memcpy(at91_serial_map, serial, sizeof(serial)); | 78 | memcpy(at91_serial_map, serial, sizeof(serial)); |
@@ -118,9 +121,14 @@ static void __init dk_board_init(void) | |||
118 | at91_add_device_udc(&dk_udc_data); | 121 | at91_add_device_udc(&dk_udc_data); |
119 | /* Compact Flash */ | 122 | /* Compact Flash */ |
120 | at91_add_device_cf(&dk_cf_data); | 123 | at91_add_device_cf(&dk_cf_data); |
124 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
125 | /* DataFlash card */ | ||
126 | at91_set_gpio_output(AT91_PIN_PB7, 0); | ||
127 | #else | ||
121 | /* MMC */ | 128 | /* MMC */ |
122 | at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ | 129 | at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ |
123 | at91_add_device_mmc(&dk_mmc_data); | 130 | at91_add_device_mmc(&dk_mmc_data); |
131 | #endif | ||
124 | /* VGA */ | 132 | /* VGA */ |
125 | // dk_add_device_video(); | 133 | // dk_add_device_video(); |
126 | } | 134 | } |
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index fd0752eba897..80d90f5135a1 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c | |||
@@ -70,6 +70,9 @@ static void __init ek_map_io(void) | |||
70 | /* Initialize clocks: 18.432 MHz crystal */ | 70 | /* Initialize clocks: 18.432 MHz crystal */ |
71 | at91_clock_init(18432000); | 71 | at91_clock_init(18432000); |
72 | 72 | ||
73 | /* Setup the LEDs */ | ||
74 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); | ||
75 | |||
73 | #ifdef CONFIG_SERIAL_AT91 | 76 | #ifdef CONFIG_SERIAL_AT91 |
74 | at91_console_port = EK_SERIAL_CONSOLE; | 77 | at91_console_port = EK_SERIAL_CONSOLE; |
75 | memcpy(at91_serial_map, serial, sizeof(serial)); | 78 | memcpy(at91_serial_map, serial, sizeof(serial)); |
@@ -111,9 +114,14 @@ static void __init ek_board_init(void) | |||
111 | at91_add_device_usbh(&ek_usbh_data); | 114 | at91_add_device_usbh(&ek_usbh_data); |
112 | /* USB Device */ | 115 | /* USB Device */ |
113 | at91_add_device_udc(&ek_udc_data); | 116 | at91_add_device_udc(&ek_udc_data); |
117 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
118 | /* DataFlash card */ | ||
119 | at91_set_gpio_output(AT91_PIN_PB22, 0); | ||
120 | #else | ||
114 | /* MMC */ | 121 | /* MMC */ |
115 | at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ | 122 | at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ |
116 | at91_add_device_mmc(&ek_mmc_data); | 123 | at91_add_device_mmc(&ek_mmc_data); |
124 | #endif | ||
117 | /* VGA */ | 125 | /* VGA */ |
118 | // ek_add_device_video(); | 126 | // ek_add_device_video(); |
119 | } | 127 | } |
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index 57eedd5beaf6..1781b8f342c4 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c | |||
@@ -28,10 +28,10 @@ | |||
28 | static u64 ohci_dmamask = 0xffffffffUL; | 28 | static u64 ohci_dmamask = 0xffffffffUL; |
29 | static struct at91_usbh_data usbh_data; | 29 | static struct at91_usbh_data usbh_data; |
30 | 30 | ||
31 | static struct resource at91rm9200_usbh_resource[] = { | 31 | static struct resource at91_usbh_resource[] = { |
32 | [0] = { | 32 | [0] = { |
33 | .start = AT91_UHP_BASE, | 33 | .start = AT91_UHP_BASE, |
34 | .end = AT91_UHP_BASE + SZ_1M -1, | 34 | .end = AT91_UHP_BASE + SZ_1M - 1, |
35 | .flags = IORESOURCE_MEM, | 35 | .flags = IORESOURCE_MEM, |
36 | }, | 36 | }, |
37 | [1] = { | 37 | [1] = { |
@@ -49,8 +49,8 @@ static struct platform_device at91rm9200_usbh_device = { | |||
49 | .coherent_dma_mask = 0xffffffff, | 49 | .coherent_dma_mask = 0xffffffff, |
50 | .platform_data = &usbh_data, | 50 | .platform_data = &usbh_data, |
51 | }, | 51 | }, |
52 | .resource = at91rm9200_usbh_resource, | 52 | .resource = at91_usbh_resource, |
53 | .num_resources = ARRAY_SIZE(at91rm9200_usbh_resource), | 53 | .num_resources = ARRAY_SIZE(at91_usbh_resource), |
54 | }; | 54 | }; |
55 | 55 | ||
56 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | 56 | void __init at91_add_device_usbh(struct at91_usbh_data *data) |
@@ -121,6 +121,19 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} | |||
121 | static u64 eth_dmamask = 0xffffffffUL; | 121 | static u64 eth_dmamask = 0xffffffffUL; |
122 | static struct at91_eth_data eth_data; | 122 | static struct at91_eth_data eth_data; |
123 | 123 | ||
124 | static struct resource at91_eth_resources[] = { | ||
125 | [0] = { | ||
126 | .start = AT91_BASE_EMAC, | ||
127 | .end = AT91_BASE_EMAC + SZ_16K - 1, | ||
128 | .flags = IORESOURCE_MEM, | ||
129 | }, | ||
130 | [1] = { | ||
131 | .start = AT91_ID_EMAC, | ||
132 | .end = AT91_ID_EMAC, | ||
133 | .flags = IORESOURCE_IRQ, | ||
134 | }, | ||
135 | }; | ||
136 | |||
124 | static struct platform_device at91rm9200_eth_device = { | 137 | static struct platform_device at91rm9200_eth_device = { |
125 | .name = "at91_ether", | 138 | .name = "at91_ether", |
126 | .id = -1, | 139 | .id = -1, |
@@ -129,7 +142,8 @@ static struct platform_device at91rm9200_eth_device = { | |||
129 | .coherent_dma_mask = 0xffffffff, | 142 | .coherent_dma_mask = 0xffffffff, |
130 | .platform_data = ð_data, | 143 | .platform_data = ð_data, |
131 | }, | 144 | }, |
132 | .num_resources = 0, | 145 | .resource = at91_eth_resources, |
146 | .num_resources = ARRAY_SIZE(at91_eth_resources), | ||
133 | }; | 147 | }; |
134 | 148 | ||
135 | void __init at91_add_device_eth(struct at91_eth_data *data) | 149 | void __init at91_add_device_eth(struct at91_eth_data *data) |
@@ -224,15 +238,20 @@ static u64 mmc_dmamask = 0xffffffffUL; | |||
224 | static struct at91_mmc_data mmc_data; | 238 | static struct at91_mmc_data mmc_data; |
225 | 239 | ||
226 | static struct resource at91_mmc_resources[] = { | 240 | static struct resource at91_mmc_resources[] = { |
227 | { | 241 | [0] = { |
228 | .start = AT91_BASE_MCI, | 242 | .start = AT91_BASE_MCI, |
229 | .end = AT91_BASE_MCI + SZ_16K - 1, | 243 | .end = AT91_BASE_MCI + SZ_16K - 1, |
230 | .flags = IORESOURCE_MEM, | 244 | .flags = IORESOURCE_MEM, |
231 | } | 245 | }, |
246 | [1] = { | ||
247 | .start = AT91_ID_MCI, | ||
248 | .end = AT91_ID_MCI, | ||
249 | .flags = IORESOURCE_IRQ, | ||
250 | }, | ||
232 | }; | 251 | }; |
233 | 252 | ||
234 | static struct platform_device at91rm9200_mmc_device = { | 253 | static struct platform_device at91rm9200_mmc_device = { |
235 | .name = "at91rm9200_mci", | 254 | .name = "at91_mci", |
236 | .id = -1, | 255 | .id = -1, |
237 | .dev = { | 256 | .dev = { |
238 | .dma_mask = &mmc_dmamask, | 257 | .dma_mask = &mmc_dmamask, |
@@ -290,4 +309,123 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) | |||
290 | void __init at91_add_device_mmc(struct at91_mmc_data *data) {} | 309 | void __init at91_add_device_mmc(struct at91_mmc_data *data) {} |
291 | #endif | 310 | #endif |
292 | 311 | ||
312 | /* -------------------------------------------------------------------- | ||
313 | * NAND / SmartMedia | ||
314 | * -------------------------------------------------------------------- */ | ||
315 | |||
316 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
317 | static struct at91_nand_data nand_data; | ||
318 | |||
319 | static struct resource at91_nand_resources[] = { | ||
320 | { | ||
321 | .start = AT91_SMARTMEDIA_BASE, | ||
322 | .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, | ||
323 | .flags = IORESOURCE_MEM, | ||
324 | } | ||
325 | }; | ||
326 | |||
327 | static struct platform_device at91_nand_device = { | ||
328 | .name = "at91_nand", | ||
329 | .id = -1, | ||
330 | .dev = { | ||
331 | .platform_data = &nand_data, | ||
332 | }, | ||
333 | .resource = at91_nand_resources, | ||
334 | .num_resources = ARRAY_SIZE(at91_nand_resources), | ||
335 | }; | ||
336 | |||
337 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
338 | { | ||
339 | if (!data) | ||
340 | return; | ||
341 | |||
342 | /* enable pin */ | ||
343 | if (data->enable_pin) | ||
344 | at91_set_gpio_output(data->enable_pin, 1); | ||
345 | |||
346 | /* ready/busy pin */ | ||
347 | if (data->rdy_pin) | ||
348 | at91_set_gpio_input(data->rdy_pin, 1); | ||
349 | |||
350 | /* card detect pin */ | ||
351 | if (data->det_pin) | ||
352 | at91_set_gpio_input(data->det_pin, 1); | ||
353 | |||
354 | at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ | ||
355 | at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ | ||
356 | |||
357 | nand_data = *data; | ||
358 | platform_device_register(&at91_nand_device); | ||
359 | } | ||
360 | #else | ||
361 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
362 | #endif | ||
363 | |||
364 | |||
365 | /* -------------------------------------------------------------------- | ||
366 | * TWI (i2c) | ||
367 | * -------------------------------------------------------------------- */ | ||
368 | |||
369 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
370 | static struct platform_device at91rm9200_twi_device = { | ||
371 | .name = "at91_i2c", | ||
372 | .id = -1, | ||
373 | .num_resources = 0, | ||
374 | }; | ||
375 | |||
376 | void __init at91_add_device_i2c(void) | ||
377 | { | ||
378 | /* pins used for TWI interface */ | ||
379 | at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ | ||
380 | at91_set_multi_drive(AT91_PIN_PA25, 1); | ||
381 | |||
382 | at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ | ||
383 | at91_set_multi_drive(AT91_PIN_PA26, 1); | ||
384 | |||
385 | platform_device_register(&at91rm9200_twi_device); | ||
386 | } | ||
387 | #else | ||
388 | void __init at91_add_device_i2c(void) {} | ||
389 | #endif | ||
390 | |||
391 | |||
392 | /* -------------------------------------------------------------------- | ||
393 | * RTC | ||
394 | * -------------------------------------------------------------------- */ | ||
395 | |||
396 | #if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE) | ||
397 | static struct platform_device at91rm9200_rtc_device = { | ||
398 | .name = "at91_rtc", | ||
399 | .id = -1, | ||
400 | .num_resources = 0, | ||
401 | }; | ||
402 | |||
403 | void __init at91_add_device_rtc(void) | ||
404 | { | ||
405 | platform_device_register(&at91rm9200_rtc_device); | ||
406 | } | ||
407 | #else | ||
408 | void __init at91_add_device_rtc(void) {} | ||
409 | #endif | ||
410 | |||
411 | |||
412 | /* -------------------------------------------------------------------- | ||
413 | * LEDs | ||
414 | * -------------------------------------------------------------------- */ | ||
415 | |||
416 | #if defined(CONFIG_LEDS) | ||
417 | u8 at91_leds_cpu; | ||
418 | u8 at91_leds_timer; | ||
419 | |||
420 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
421 | { | ||
422 | at91_leds_cpu = cpu_led; | ||
423 | at91_leds_timer = timer_led; | ||
424 | } | ||
425 | |||
426 | #else | ||
427 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
428 | #endif | ||
429 | |||
430 | |||
293 | /* -------------------------------------------------------------------- */ | 431 | /* -------------------------------------------------------------------- */ |
diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91rm9200/leds.c new file mode 100644 index 000000000000..28150e8905ba --- /dev/null +++ b/arch/arm/mach-at91rm9200/leds.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * LED driver for Atmel AT91-based boards. | ||
3 | * | ||
4 | * Copyright (C) SAN People (Pty) Ltd | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | |||
17 | #include <asm/mach-types.h> | ||
18 | #include <asm/leds.h> | ||
19 | #include <asm/arch/board.h> | ||
20 | #include <asm/arch/gpio.h> | ||
21 | |||
22 | |||
23 | static inline void at91_led_on(unsigned int led) | ||
24 | { | ||
25 | at91_set_gpio_value(led, 0); | ||
26 | } | ||
27 | |||
28 | static inline void at91_led_off(unsigned int led) | ||
29 | { | ||
30 | at91_set_gpio_value(led, 1); | ||
31 | } | ||
32 | |||
33 | static inline void at91_led_toggle(unsigned int led) | ||
34 | { | ||
35 | unsigned long is_off = at91_get_gpio_value(led); | ||
36 | if (is_off) | ||
37 | at91_led_on(led); | ||
38 | else | ||
39 | at91_led_off(led); | ||
40 | } | ||
41 | |||
42 | |||
43 | /* | ||
44 | * Handle LED events. | ||
45 | */ | ||
46 | static void at91_leds_event(led_event_t evt) | ||
47 | { | ||
48 | unsigned long flags; | ||
49 | |||
50 | local_irq_save(flags); | ||
51 | |||
52 | switch(evt) { | ||
53 | case led_start: /* System startup */ | ||
54 | at91_led_on(at91_leds_cpu); | ||
55 | break; | ||
56 | |||
57 | case led_stop: /* System stop / suspend */ | ||
58 | at91_led_off(at91_leds_cpu); | ||
59 | break; | ||
60 | |||
61 | #ifdef CONFIG_LEDS_TIMER | ||
62 | case led_timer: /* Every 50 timer ticks */ | ||
63 | at91_led_toggle(at91_leds_timer); | ||
64 | break; | ||
65 | #endif | ||
66 | |||
67 | #ifdef CONFIG_LEDS_CPU | ||
68 | case led_idle_start: /* Entering idle state */ | ||
69 | at91_led_off(at91_leds_cpu); | ||
70 | break; | ||
71 | |||
72 | case led_idle_end: /* Exit idle state */ | ||
73 | at91_led_on(at91_leds_cpu); | ||
74 | break; | ||
75 | #endif | ||
76 | |||
77 | default: | ||
78 | break; | ||
79 | } | ||
80 | |||
81 | local_irq_restore(flags); | ||
82 | } | ||
83 | |||
84 | |||
85 | static int __init leds_init(void) | ||
86 | { | ||
87 | if (!at91_leds_timer || !at91_leds_cpu) | ||
88 | return -ENODEV; | ||
89 | |||
90 | /* Enable PIO to access the LEDs */ | ||
91 | at91_set_gpio_output(at91_leds_timer, 1); | ||
92 | at91_set_gpio_output(at91_leds_cpu, 1); | ||
93 | |||
94 | leds_event = at91_leds_event; | ||
95 | |||
96 | leds_event(led_start); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | __initcall(leds_init); | ||
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 2d892e4daa07..dcd417625389 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -424,6 +424,14 @@ static struct amba_device uart3_device = { | |||
424 | .periphid = 0x00041010, | 424 | .periphid = 0x00041010, |
425 | }; | 425 | }; |
426 | 426 | ||
427 | |||
428 | static struct platform_device ep93xx_rtc_device = { | ||
429 | .name = "ep93xx-rtc", | ||
430 | .id = -1, | ||
431 | .num_resources = 0, | ||
432 | }; | ||
433 | |||
434 | |||
427 | void __init ep93xx_init_devices(void) | 435 | void __init ep93xx_init_devices(void) |
428 | { | 436 | { |
429 | unsigned int v; | 437 | unsigned int v; |
@@ -439,4 +447,6 @@ void __init ep93xx_init_devices(void) | |||
439 | amba_device_register(&uart1_device, &iomem_resource); | 447 | amba_device_register(&uart1_device, &iomem_resource); |
440 | amba_device_register(&uart2_device, &iomem_resource); | 448 | amba_device_register(&uart2_device, &iomem_resource); |
441 | amba_device_register(&uart3_device, &iomem_resource); | 449 | amba_device_register(&uart3_device, &iomem_resource); |
450 | |||
451 | platform_device_register(&ep93xx_rtc_device); | ||
442 | } | 452 | } |
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 777e75daa8a5..9be01b0c3f48 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/m48t86.h> | ||
20 | #include <asm/io.h> | 22 | #include <asm/io.h> |
21 | #include <asm/hardware.h> | 23 | #include <asm/hardware.h> |
22 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
@@ -39,6 +41,16 @@ static struct map_desc ts72xx_io_desc[] __initdata = { | |||
39 | .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE), | 41 | .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE), |
40 | .length = TS72XX_OPTIONS2_SIZE, | 42 | .length = TS72XX_OPTIONS2_SIZE, |
41 | .type = MT_DEVICE, | 43 | .type = MT_DEVICE, |
44 | }, { | ||
45 | .virtual = TS72XX_RTC_INDEX_VIRT_BASE, | ||
46 | .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE), | ||
47 | .length = TS72XX_RTC_INDEX_SIZE, | ||
48 | .type = MT_DEVICE, | ||
49 | }, { | ||
50 | .virtual = TS72XX_RTC_DATA_VIRT_BASE, | ||
51 | .pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE), | ||
52 | .length = TS72XX_RTC_DATA_SIZE, | ||
53 | .type = MT_DEVICE, | ||
42 | } | 54 | } |
43 | }; | 55 | }; |
44 | 56 | ||
@@ -99,11 +111,38 @@ static void __init ts72xx_map_io(void) | |||
99 | } | 111 | } |
100 | } | 112 | } |
101 | 113 | ||
114 | static unsigned char ts72xx_rtc_readb(unsigned long addr) | ||
115 | { | ||
116 | __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); | ||
117 | return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); | ||
118 | } | ||
119 | |||
120 | static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr) | ||
121 | { | ||
122 | __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); | ||
123 | __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); | ||
124 | } | ||
125 | |||
126 | static struct m48t86_ops ts72xx_rtc_ops = { | ||
127 | .readb = ts72xx_rtc_readb, | ||
128 | .writeb = ts72xx_rtc_writeb, | ||
129 | }; | ||
130 | |||
131 | static struct platform_device ts72xx_rtc_device = { | ||
132 | .name = "rtc-m48t86", | ||
133 | .id = -1, | ||
134 | .dev = { | ||
135 | .platform_data = &ts72xx_rtc_ops, | ||
136 | }, | ||
137 | .num_resources = 0, | ||
138 | }; | ||
139 | |||
102 | static void __init ts72xx_init_machine(void) | 140 | static void __init ts72xx_init_machine(void) |
103 | { | 141 | { |
104 | ep93xx_init_devices(); | 142 | ep93xx_init_devices(); |
105 | if (board_is_ts7200()) | 143 | if (board_is_ts7200()) |
106 | physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL); | 144 | physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL); |
145 | platform_device_register(&ts72xx_rtc_device); | ||
107 | } | 146 | } |
108 | 147 | ||
109 | MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") | 148 | MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") |
diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c index 71a59e196166..4ca51dcf13ac 100644 --- a/arch/arm/mach-imx/dma.c +++ b/arch/arm/mach-imx/dma.c | |||
@@ -7,11 +7,18 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * 03/03/2004 Sascha Hauer <sascha@saschahauer.de> | 10 | * 2004-03-03 Sascha Hauer <sascha@saschahauer.de> |
11 | * initial version heavily inspired by | 11 | * initial version heavily inspired by |
12 | * linux/arch/arm/mach-pxa/dma.c | 12 | * linux/arch/arm/mach-pxa/dma.c |
13 | * | ||
14 | * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz> | ||
15 | * Changed to support scatter gather DMA | ||
16 | * by taking Russell's code from RiscPC | ||
17 | * | ||
13 | */ | 18 | */ |
14 | 19 | ||
20 | #undef DEBUG | ||
21 | |||
15 | #include <linux/module.h> | 22 | #include <linux/module.h> |
16 | #include <linux/init.h> | 23 | #include <linux/init.h> |
17 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
@@ -22,69 +29,368 @@ | |||
22 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
23 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
24 | #include <asm/dma.h> | 31 | #include <asm/dma.h> |
32 | #include <asm/arch/imx-dma.h> | ||
33 | |||
34 | struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS]; | ||
35 | |||
36 | /* | ||
37 | * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation | ||
38 | * @dma_ch: i.MX DMA channel number | ||
39 | * @lastcount: number of bytes transferred during last transfer | ||
40 | * | ||
41 | * Functions prepares DMA controller for next sg data chunk transfer. | ||
42 | * The @lastcount argument informs function about number of bytes transferred | ||
43 | * during last block. Zero value can be used for @lastcount to setup DMA | ||
44 | * for the first chunk. | ||
45 | */ | ||
46 | static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount) | ||
47 | { | ||
48 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
49 | unsigned int nextcount; | ||
50 | unsigned int nextaddr; | ||
51 | |||
52 | if (!imxdma->name) { | ||
53 | printk(KERN_CRIT "%s: called for not allocated channel %d\n", | ||
54 | __FUNCTION__, dma_ch); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | imxdma->resbytes -= lastcount; | ||
59 | |||
60 | if (!imxdma->sg) { | ||
61 | pr_debug("imxdma%d: no sg data\n", dma_ch); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | imxdma->sgbc += lastcount; | ||
66 | if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) { | ||
67 | if ((imxdma->sgcount <= 1) || !imxdma->resbytes) { | ||
68 | pr_debug("imxdma%d: sg transfer limit reached\n", | ||
69 | dma_ch); | ||
70 | imxdma->sgcount=0; | ||
71 | imxdma->sg = NULL; | ||
72 | return 0; | ||
73 | } else { | ||
74 | imxdma->sgcount--; | ||
75 | imxdma->sg++; | ||
76 | imxdma->sgbc = 0; | ||
77 | } | ||
78 | } | ||
79 | nextcount = imxdma->sg->length - imxdma->sgbc; | ||
80 | nextaddr = imxdma->sg->dma_address + imxdma->sgbc; | ||
25 | 81 | ||
26 | static struct dma_channel { | 82 | if(imxdma->resbytes < nextcount) |
27 | char *name; | 83 | nextcount = imxdma->resbytes; |
28 | void (*irq_handler) (int, void *, struct pt_regs *); | ||
29 | void (*err_handler) (int, void *, struct pt_regs *); | ||
30 | void *data; | ||
31 | } dma_channels[11]; | ||
32 | 84 | ||
33 | /* set err_handler to NULL to have the standard info-only error handler */ | 85 | if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ) |
86 | DAR(dma_ch) = nextaddr; | ||
87 | else | ||
88 | SAR(dma_ch) = nextaddr; | ||
89 | |||
90 | CNTR(dma_ch) = nextcount; | ||
91 | pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n", | ||
92 | dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch)); | ||
93 | |||
94 | return nextcount; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * imx_dma_setup_sg_base - scatter-gather DMA emulation | ||
99 | * @dma_ch: i.MX DMA channel number | ||
100 | * @sg: pointer to the scatter-gather list/vector | ||
101 | * @sgcount: scatter-gather list hungs count | ||
102 | * | ||
103 | * Functions sets up i.MX DMA state for emulated scatter-gather transfer | ||
104 | * and sets up channel registers to be ready for the first chunk | ||
105 | */ | ||
106 | static int | ||
107 | imx_dma_setup_sg_base(imx_dmach_t dma_ch, | ||
108 | struct scatterlist *sg, unsigned int sgcount) | ||
109 | { | ||
110 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
111 | |||
112 | imxdma->sg = sg; | ||
113 | imxdma->sgcount = sgcount; | ||
114 | imxdma->sgbc = 0; | ||
115 | return imx_dma_sg_next(dma_ch, 0); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer | ||
120 | * @dma_ch: i.MX DMA channel number | ||
121 | * @dma_address: the DMA/physical memory address of the linear data block | ||
122 | * to transfer | ||
123 | * @dma_length: length of the data block in bytes | ||
124 | * @dev_addr: physical device port address | ||
125 | * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory | ||
126 | * or %DMA_MODE_WRITE from memory to the device | ||
127 | * | ||
128 | * The function setups DMA channel source and destination addresses for transfer | ||
129 | * specified by provided parameters. The scatter-gather emulation is disabled, | ||
130 | * because linear data block | ||
131 | * form the physical address range is transfered. | ||
132 | * Return value: if incorrect parameters are provided -%EINVAL. | ||
133 | * Zero indicates success. | ||
134 | */ | ||
34 | int | 135 | int |
35 | imx_request_dma(char *name, imx_dma_prio prio, | 136 | imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address, |
36 | void (*irq_handler) (int, void *, struct pt_regs *), | 137 | unsigned int dma_length, unsigned int dev_addr, |
37 | void (*err_handler) (int, void *, struct pt_regs *), void *data) | 138 | dmamode_t dmamode) |
38 | { | 139 | { |
39 | unsigned long flags; | 140 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; |
40 | int i, found = 0; | ||
41 | 141 | ||
42 | /* basic sanity checks */ | 142 | imxdma->sg = NULL; |
43 | if (!name || !irq_handler) | 143 | imxdma->sgcount = 0; |
144 | imxdma->dma_mode = dmamode; | ||
145 | imxdma->resbytes = dma_length; | ||
146 | |||
147 | if (!dma_address) { | ||
148 | printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n", | ||
149 | dma_ch); | ||
44 | return -EINVAL; | 150 | return -EINVAL; |
151 | } | ||
45 | 152 | ||
46 | local_irq_save(flags); | 153 | if (!dma_length) { |
154 | printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n", | ||
155 | dma_ch); | ||
156 | return -EINVAL; | ||
157 | } | ||
47 | 158 | ||
48 | /* try grabbing a DMA channel with the requested priority */ | 159 | if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { |
49 | for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) { | 160 | pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n", |
50 | if (!dma_channels[i].name) { | 161 | dma_ch, (unsigned int)dma_address, dma_length, |
51 | found = 1; | 162 | dev_addr); |
52 | break; | 163 | SAR(dma_ch) = dev_addr; |
53 | } | 164 | DAR(dma_ch) = (unsigned int)dma_address; |
165 | } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { | ||
166 | pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n", | ||
167 | dma_ch, (unsigned int)dma_address, dma_length, | ||
168 | dev_addr); | ||
169 | SAR(dma_ch) = (unsigned int)dma_address; | ||
170 | DAR(dma_ch) = dev_addr; | ||
171 | } else { | ||
172 | printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n", | ||
173 | dma_ch); | ||
174 | return -EINVAL; | ||
54 | } | 175 | } |
55 | 176 | ||
56 | if (!found) { | 177 | CNTR(dma_ch) = dma_length; |
57 | /* requested prio group is full, try hier priorities */ | 178 | |
58 | for (i = prio - 1; i >= 0; i--) { | 179 | return 0; |
59 | if (!dma_channels[i].name) { | 180 | } |
60 | found = 1; | 181 | |
61 | break; | 182 | /** |
62 | } | 183 | * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer |
63 | } | 184 | * @dma_ch: i.MX DMA channel number |
185 | * @sg: pointer to the scatter-gather list/vector | ||
186 | * @sgcount: scatter-gather list hungs count | ||
187 | * @dma_length: total length of the transfer request in bytes | ||
188 | * @dev_addr: physical device port address | ||
189 | * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory | ||
190 | * or %DMA_MODE_WRITE from memory to the device | ||
191 | * | ||
192 | * The function setups DMA channel state and registers to be ready for transfer | ||
193 | * specified by provided parameters. The scatter-gather emulation is set up | ||
194 | * according to the parameters. | ||
195 | * | ||
196 | * The full preparation of the transfer requires setup of more register | ||
197 | * by the caller before imx_dma_enable() can be called. | ||
198 | * | ||
199 | * %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes | ||
200 | * | ||
201 | * %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx | ||
202 | * | ||
203 | * %CCR(dma_ch) has to specify transfer parameters, the next settings is typical | ||
204 | * for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified | ||
205 | * | ||
206 | * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x | ||
207 | * | ||
208 | * The typical setup for %DMA_MODE_WRITE is specified by next options combination | ||
209 | * | ||
210 | * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x | ||
211 | * | ||
212 | * Be carefull there and do not mistakenly mix source and target device | ||
213 | * port sizes constants, they are really different: | ||
214 | * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32, | ||
215 | * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32 | ||
216 | * | ||
217 | * Return value: if incorrect parameters are provided -%EINVAL. | ||
218 | * Zero indicates success. | ||
219 | */ | ||
220 | int | ||
221 | imx_dma_setup_sg(imx_dmach_t dma_ch, | ||
222 | struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, | ||
223 | unsigned int dev_addr, dmamode_t dmamode) | ||
224 | { | ||
225 | int res; | ||
226 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
227 | |||
228 | imxdma->sg = NULL; | ||
229 | imxdma->sgcount = 0; | ||
230 | imxdma->dma_mode = dmamode; | ||
231 | imxdma->resbytes = dma_length; | ||
232 | |||
233 | if (!sg || !sgcount) { | ||
234 | printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n", | ||
235 | dma_ch); | ||
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | if (!sg->length) { | ||
240 | printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n", | ||
241 | dma_ch); | ||
242 | return -EINVAL; | ||
64 | } | 243 | } |
65 | 244 | ||
66 | if (found) { | 245 | if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { |
67 | DIMR &= ~(1 << i); | 246 | pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n", |
68 | dma_channels[i].name = name; | 247 | dma_ch, sg, sgcount, dma_length, dev_addr); |
69 | dma_channels[i].irq_handler = irq_handler; | 248 | SAR(dma_ch) = dev_addr; |
70 | dma_channels[i].err_handler = err_handler; | 249 | } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { |
71 | dma_channels[i].data = data; | 250 | pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n", |
251 | dma_ch, sg, sgcount, dma_length, dev_addr); | ||
252 | DAR(dma_ch) = dev_addr; | ||
72 | } else { | 253 | } else { |
73 | printk(KERN_WARNING "No more available DMA channels for %s\n", | 254 | printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n", |
74 | name); | 255 | dma_ch); |
75 | i = -ENODEV; | 256 | return -EINVAL; |
257 | } | ||
258 | |||
259 | res = imx_dma_setup_sg_base(dma_ch, sg, sgcount); | ||
260 | if (res <= 0) { | ||
261 | printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch); | ||
262 | return -EINVAL; | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers | ||
270 | * @dma_ch: i.MX DMA channel number | ||
271 | * @irq_handler: the pointer to the function called if the transfer | ||
272 | * ends successfully | ||
273 | * @err_handler: the pointer to the function called if the premature | ||
274 | * end caused by error occurs | ||
275 | * @data: user specified value to be passed to the handlers | ||
276 | */ | ||
277 | int | ||
278 | imx_dma_setup_handlers(imx_dmach_t dma_ch, | ||
279 | void (*irq_handler) (int, void *, struct pt_regs *), | ||
280 | void (*err_handler) (int, void *, struct pt_regs *), | ||
281 | void *data) | ||
282 | { | ||
283 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
284 | unsigned long flags; | ||
285 | |||
286 | if (!imxdma->name) { | ||
287 | printk(KERN_CRIT "%s: called for not allocated channel %d\n", | ||
288 | __FUNCTION__, dma_ch); | ||
289 | return -ENODEV; | ||
290 | } | ||
291 | |||
292 | local_irq_save(flags); | ||
293 | DISR = (1 << dma_ch); | ||
294 | imxdma->irq_handler = irq_handler; | ||
295 | imxdma->err_handler = err_handler; | ||
296 | imxdma->data = data; | ||
297 | local_irq_restore(flags); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * imx_dma_enable - function to start i.MX DMA channel operation | ||
303 | * @dma_ch: i.MX DMA channel number | ||
304 | * | ||
305 | * The channel has to be allocated by driver through imx_dma_request() | ||
306 | * or imx_dma_request_by_prio() function. | ||
307 | * The transfer parameters has to be set to the channel registers through | ||
308 | * call of the imx_dma_setup_single() or imx_dma_setup_sg() function | ||
309 | * and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to | ||
310 | * be set prior this function call by the channel user. | ||
311 | */ | ||
312 | void imx_dma_enable(imx_dmach_t dma_ch) | ||
313 | { | ||
314 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
315 | unsigned long flags; | ||
316 | |||
317 | pr_debug("imxdma%d: imx_dma_enable\n", dma_ch); | ||
318 | |||
319 | if (!imxdma->name) { | ||
320 | printk(KERN_CRIT "%s: called for not allocated channel %d\n", | ||
321 | __FUNCTION__, dma_ch); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | local_irq_save(flags); | ||
326 | DISR = (1 << dma_ch); | ||
327 | DIMR &= ~(1 << dma_ch); | ||
328 | CCR(dma_ch) |= CCR_CEN; | ||
329 | local_irq_restore(flags); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * imx_dma_disable - stop, finish i.MX DMA channel operatin | ||
334 | * @dma_ch: i.MX DMA channel number | ||
335 | */ | ||
336 | void imx_dma_disable(imx_dmach_t dma_ch) | ||
337 | { | ||
338 | unsigned long flags; | ||
339 | |||
340 | pr_debug("imxdma%d: imx_dma_disable\n", dma_ch); | ||
341 | |||
342 | local_irq_save(flags); | ||
343 | DIMR |= (1 << dma_ch); | ||
344 | CCR(dma_ch) &= ~CCR_CEN; | ||
345 | DISR = (1 << dma_ch); | ||
346 | local_irq_restore(flags); | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * imx_dma_request - request/allocate specified channel number | ||
351 | * @dma_ch: i.MX DMA channel number | ||
352 | * @name: the driver/caller own non-%NULL identification | ||
353 | */ | ||
354 | int imx_dma_request(imx_dmach_t dma_ch, const char *name) | ||
355 | { | ||
356 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
357 | unsigned long flags; | ||
358 | |||
359 | /* basic sanity checks */ | ||
360 | if (!name) | ||
361 | return -EINVAL; | ||
362 | |||
363 | if (dma_ch >= IMX_DMA_CHANNELS) { | ||
364 | printk(KERN_CRIT "%s: called for non-existed channel %d\n", | ||
365 | __FUNCTION__, dma_ch); | ||
366 | return -EINVAL; | ||
76 | } | 367 | } |
77 | 368 | ||
369 | local_irq_save(flags); | ||
370 | if (imxdma->name) { | ||
371 | local_irq_restore(flags); | ||
372 | return -ENODEV; | ||
373 | } | ||
374 | |||
375 | imxdma->name = name; | ||
376 | imxdma->irq_handler = NULL; | ||
377 | imxdma->err_handler = NULL; | ||
378 | imxdma->data = NULL; | ||
379 | imxdma->sg = NULL; | ||
78 | local_irq_restore(flags); | 380 | local_irq_restore(flags); |
79 | return i; | 381 | return 0; |
80 | } | 382 | } |
81 | 383 | ||
82 | void | 384 | /** |
83 | imx_free_dma(int dma_ch) | 385 | * imx_dma_free - release previously acquired channel |
386 | * @dma_ch: i.MX DMA channel number | ||
387 | */ | ||
388 | void imx_dma_free(imx_dmach_t dma_ch) | ||
84 | { | 389 | { |
85 | unsigned long flags; | 390 | unsigned long flags; |
391 | struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; | ||
86 | 392 | ||
87 | if (!dma_channels[dma_ch].name) { | 393 | if (!imxdma->name) { |
88 | printk(KERN_CRIT | 394 | printk(KERN_CRIT |
89 | "%s: trying to free channel %d which is already freed\n", | 395 | "%s: trying to free channel %d which is already freed\n", |
90 | __FUNCTION__, dma_ch); | 396 | __FUNCTION__, dma_ch); |
@@ -92,27 +398,84 @@ imx_free_dma(int dma_ch) | |||
92 | } | 398 | } |
93 | 399 | ||
94 | local_irq_save(flags); | 400 | local_irq_save(flags); |
95 | DIMR &= ~(1 << dma_ch); | 401 | /* Disable interrupts */ |
96 | dma_channels[dma_ch].name = NULL; | 402 | DIMR |= (1 << dma_ch); |
403 | CCR(dma_ch) &= ~CCR_CEN; | ||
404 | imxdma->name = NULL; | ||
97 | local_irq_restore(flags); | 405 | local_irq_restore(flags); |
98 | } | 406 | } |
99 | 407 | ||
100 | static irqreturn_t | 408 | /** |
101 | dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) | 409 | * imx_dma_request_by_prio - find and request some of free channels best suiting requested priority |
410 | * @dma_ch: i.MX DMA channel number | ||
411 | * @name: the driver/caller own non-%NULL identification | ||
412 | * @prio: one of the hardware distinguished priority level: | ||
413 | * %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW | ||
414 | * | ||
415 | * This function tries to find free channel in the specified priority group | ||
416 | * if the priority cannot be achieved it tries to look for free channel | ||
417 | * in the higher and then even lower priority groups. | ||
418 | * | ||
419 | * Return value: If there is no free channel to allocate, -%ENODEV is returned. | ||
420 | * Zero value indicates successful channel allocation. | ||
421 | */ | ||
422 | int | ||
423 | imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, | ||
424 | imx_dma_prio prio) | ||
425 | { | ||
426 | int i; | ||
427 | int best; | ||
428 | |||
429 | switch (prio) { | ||
430 | case (DMA_PRIO_HIGH): | ||
431 | best = 8; | ||
432 | break; | ||
433 | case (DMA_PRIO_MEDIUM): | ||
434 | best = 4; | ||
435 | break; | ||
436 | case (DMA_PRIO_LOW): | ||
437 | default: | ||
438 | best = 0; | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | for (i = best; i < IMX_DMA_CHANNELS; i++) { | ||
443 | if (!imx_dma_request(i, name)) { | ||
444 | *pdma_ch = i; | ||
445 | return 0; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | for (i = best - 1; i >= 0; i--) { | ||
450 | if (!imx_dma_request(i, name)) { | ||
451 | *pdma_ch = i; | ||
452 | return 0; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__); | ||
457 | |||
458 | return -ENODEV; | ||
459 | } | ||
460 | |||
461 | static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
102 | { | 462 | { |
103 | int i, disr = DISR; | 463 | int i, disr = DISR; |
104 | struct dma_channel *channel; | 464 | struct imx_dma_channel *channel; |
105 | unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; | 465 | unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; |
106 | 466 | ||
107 | DISR = disr; | 467 | DISR = disr; |
108 | for (i = 0; i < 11; i++) { | 468 | for (i = 0; i < IMX_DMA_CHANNELS; i++) { |
109 | channel = &dma_channels[i]; | 469 | channel = &imx_dma_channels[i]; |
110 | 470 | ||
111 | if ( (err_mask & 1<<i) && channel->name && channel->err_handler) { | 471 | if ((err_mask & 1 << i) && channel->name |
472 | && channel->err_handler) { | ||
112 | channel->err_handler(i, channel->data, regs); | 473 | channel->err_handler(i, channel->data, regs); |
113 | continue; | 474 | continue; |
114 | } | 475 | } |
115 | 476 | ||
477 | imx_dma_channels[i].sg = NULL; | ||
478 | |||
116 | if (DBTOSR & (1 << i)) { | 479 | if (DBTOSR & (1 << i)) { |
117 | printk(KERN_WARNING | 480 | printk(KERN_WARNING |
118 | "Burst timeout on channel %d (%s)\n", | 481 | "Burst timeout on channel %d (%s)\n", |
@@ -141,17 +504,27 @@ dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
141 | return IRQ_HANDLED; | 504 | return IRQ_HANDLED; |
142 | } | 505 | } |
143 | 506 | ||
144 | static irqreturn_t | 507 | static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) |
145 | dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
146 | { | 508 | { |
147 | int i, disr = DISR; | 509 | int i, disr = DISR; |
148 | 510 | ||
511 | pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n", | ||
512 | disr); | ||
513 | |||
149 | DISR = disr; | 514 | DISR = disr; |
150 | for (i = 0; i < 11; i++) { | 515 | for (i = 0; i < IMX_DMA_CHANNELS; i++) { |
151 | if (disr & (1 << i)) { | 516 | if (disr & (1 << i)) { |
152 | struct dma_channel *channel = &dma_channels[i]; | 517 | struct imx_dma_channel *channel = &imx_dma_channels[i]; |
153 | if (channel->name && channel->irq_handler) { | 518 | if (channel->name) { |
154 | channel->irq_handler(i, channel->data, regs); | 519 | if (imx_dma_sg_next(i, CNTR(i))) { |
520 | CCR(i) &= ~CCR_CEN; | ||
521 | mb(); | ||
522 | CCR(i) |= CCR_CEN; | ||
523 | } else { | ||
524 | if (channel->irq_handler) | ||
525 | channel->irq_handler(i, | ||
526 | channel->data, regs); | ||
527 | } | ||
155 | } else { | 528 | } else { |
156 | /* | 529 | /* |
157 | * IRQ for an unregistered DMA channel: | 530 | * IRQ for an unregistered DMA channel: |
@@ -165,10 +538,10 @@ dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
165 | return IRQ_HANDLED; | 538 | return IRQ_HANDLED; |
166 | } | 539 | } |
167 | 540 | ||
168 | static int __init | 541 | static int __init imx_dma_init(void) |
169 | imx_dma_init(void) | ||
170 | { | 542 | { |
171 | int ret; | 543 | int ret; |
544 | int i; | ||
172 | 545 | ||
173 | /* reset DMA module */ | 546 | /* reset DMA module */ |
174 | DCR = DCR_DRST; | 547 | DCR = DCR_DRST; |
@@ -189,15 +562,27 @@ imx_dma_init(void) | |||
189 | DCR = DCR_DEN; | 562 | DCR = DCR_DEN; |
190 | 563 | ||
191 | /* clear all interrupts */ | 564 | /* clear all interrupts */ |
192 | DISR = 0x3ff; | 565 | DISR = (1 << IMX_DMA_CHANNELS) - 1; |
193 | 566 | ||
194 | /* enable interrupts */ | 567 | /* enable interrupts */ |
195 | DIMR = 0; | 568 | DIMR = (1 << IMX_DMA_CHANNELS) - 1; |
569 | |||
570 | for (i = 0; i < IMX_DMA_CHANNELS; i++) { | ||
571 | imx_dma_channels[i].sg = NULL; | ||
572 | imx_dma_channels[i].dma_num = i; | ||
573 | } | ||
196 | 574 | ||
197 | return ret; | 575 | return ret; |
198 | } | 576 | } |
199 | 577 | ||
200 | arch_initcall(imx_dma_init); | 578 | arch_initcall(imx_dma_init); |
201 | 579 | ||
202 | EXPORT_SYMBOL(imx_request_dma); | 580 | EXPORT_SYMBOL(imx_dma_setup_single); |
203 | EXPORT_SYMBOL(imx_free_dma); | 581 | EXPORT_SYMBOL(imx_dma_setup_sg); |
582 | EXPORT_SYMBOL(imx_dma_setup_handlers); | ||
583 | EXPORT_SYMBOL(imx_dma_enable); | ||
584 | EXPORT_SYMBOL(imx_dma_disable); | ||
585 | EXPORT_SYMBOL(imx_dma_request); | ||
586 | EXPORT_SYMBOL(imx_dma_free); | ||
587 | EXPORT_SYMBOL(imx_dma_request_by_prio); | ||
588 | EXPORT_SYMBOL(imx_dma_channels); | ||
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 8ab1b040288c..e34d0df90aed 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
26 | 26 | ||
27 | #include <asm/mach/arch.h> | 27 | #include <asm/mach/arch.h> |
28 | #include <asm/arch/mmc.h> | ||
28 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
29 | #include "generic.h" | 30 | #include "generic.h" |
30 | 31 | ||
@@ -51,12 +52,29 @@ static struct platform_device *devices[] __initdata = { | |||
51 | &cs89x0_device, | 52 | &cs89x0_device, |
52 | }; | 53 | }; |
53 | 54 | ||
55 | #ifdef CONFIG_MMC_IMX | ||
56 | static int mx1ads_mmc_card_present(void) | ||
57 | { | ||
58 | /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */ | ||
59 | return (SSR(1) & (1 << 20) ? 0 : 1); | ||
60 | } | ||
61 | |||
62 | static struct imxmmc_platform_data mx1ads_mmc_info = { | ||
63 | .card_present = mx1ads_mmc_card_present, | ||
64 | }; | ||
65 | #endif | ||
66 | |||
54 | static void __init | 67 | static void __init |
55 | mx1ads_init(void) | 68 | mx1ads_init(void) |
56 | { | 69 | { |
57 | #ifdef CONFIG_LEDS | 70 | #ifdef CONFIG_LEDS |
58 | imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2); | 71 | imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2); |
59 | #endif | 72 | #endif |
73 | #ifdef CONFIG_MMC_IMX | ||
74 | /* SD/MMC card detect */ | ||
75 | imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20); | ||
76 | imx_set_mmc_info(&mx1ads_mmc_info); | ||
77 | #endif | ||
60 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 78 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
61 | } | 79 | } |
62 | 80 | ||
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c index 2327c9790416..bf688c128630 100644 --- a/arch/arm/mach-ixp23xx/espresso.c +++ b/arch/arm/mach-ixp23xx/espresso.c | |||
@@ -44,6 +44,15 @@ | |||
44 | #include <asm/mach/irq.h> | 44 | #include <asm/mach/irq.h> |
45 | #include <asm/mach/pci.h> | 45 | #include <asm/mach/pci.h> |
46 | 46 | ||
47 | static int __init espresso_pci_init(void) | ||
48 | { | ||
49 | if (machine_is_espresso()) | ||
50 | ixp23xx_pci_slave_init(); | ||
51 | |||
52 | return 0; | ||
53 | }; | ||
54 | subsys_initcall(espresso_pci_init); | ||
55 | |||
47 | static void __init espresso_init(void) | 56 | static void __init espresso_init(void) |
48 | { | 57 | { |
49 | physmap_configure(0x90000000, 0x02000000, 2, NULL); | 58 | physmap_configure(0x90000000, 0x02000000, 2, NULL); |
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 5330ad78c1bb..ac72f94c5b4d 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c | |||
@@ -201,7 +201,7 @@ int clear_master_aborts(void) | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | void __init ixp23xx_pci_preinit(void) | 204 | static void __init ixp23xx_pci_common_init(void) |
205 | { | 205 | { |
206 | #ifdef __ARMEB__ | 206 | #ifdef __ARMEB__ |
207 | *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ | 207 | *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ |
@@ -219,7 +219,18 @@ void __init ixp23xx_pci_preinit(void) | |||
219 | *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); | 219 | *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); |
220 | } else { | 220 | } else { |
221 | *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); | 221 | *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); |
222 | |||
223 | /* | ||
224 | * Enable coherency on A2 silicon. | ||
225 | */ | ||
226 | if (arch_is_coherent()) | ||
227 | *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF; | ||
222 | } | 228 | } |
229 | } | ||
230 | |||
231 | void __init ixp23xx_pci_preinit(void) | ||
232 | { | ||
233 | ixp23xx_pci_common_init(); | ||
223 | 234 | ||
224 | hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, | 235 | hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, |
225 | "PCI config cycle to non-existent device"); | 236 | "PCI config cycle to non-existent device"); |
@@ -273,3 +284,8 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) | |||
273 | 284 | ||
274 | return 1; | 285 | return 1; |
275 | } | 286 | } |
287 | |||
288 | void ixp23xx_pci_slave_init(void) | ||
289 | { | ||
290 | ixp23xx_pci_common_init(); | ||
291 | } | ||
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 86a0f0d14345..f8d716ccc1df 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig | |||
@@ -69,12 +69,6 @@ config MACH_VOICEBLUE | |||
69 | Support for Voiceblue GSM/VoIP gateway. Say Y here if you have | 69 | Support for Voiceblue GSM/VoIP gateway. Say Y here if you have |
70 | such a board. | 70 | such a board. |
71 | 71 | ||
72 | config MACH_NETSTAR | ||
73 | bool "NetStar" | ||
74 | depends on ARCH_OMAP1 && ARCH_OMAP15XX | ||
75 | help | ||
76 | Support for NetStar PBX. Say Y here if you have such a board. | ||
77 | |||
78 | config MACH_OMAP_PALMTE | 72 | config MACH_OMAP_PALMTE |
79 | bool "Palm Tungsten E" | 73 | bool "Palm Tungsten E" |
80 | depends on ARCH_OMAP1 && ARCH_OMAP15XX | 74 | depends on ARCH_OMAP1 && ARCH_OMAP15XX |
@@ -85,6 +79,20 @@ config MACH_OMAP_PALMTE | |||
85 | informations. | 79 | informations. |
86 | Say Y here if you have such a PDA, say NO otherwise. | 80 | Say Y here if you have such a PDA, say NO otherwise. |
87 | 81 | ||
82 | config MACH_NOKIA770 | ||
83 | bool "Nokia 770" | ||
84 | depends on ARCH_OMAP1 && ARCH_OMAP16XX | ||
85 | help | ||
86 | Support for the Nokia 770 Internet Tablet. Say Y here if you | ||
87 | have such a device. | ||
88 | |||
89 | config MACH_AMS_DELTA | ||
90 | bool "Amstrad E3 (Delta)" | ||
91 | depends on ARCH_OMAP1 && ARCH_OMAP15XX | ||
92 | help | ||
93 | Support for the Amstrad E3 (codename Delta) videophone. Say Y here | ||
94 | if you have such a device. | ||
95 | |||
88 | config MACH_OMAP_GENERIC | 96 | config MACH_OMAP_GENERIC |
89 | bool "Generic OMAP board" | 97 | bool "Generic OMAP board" |
90 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) | 98 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) |
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index b0b00156faae..9ea719550ad3 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile | |||
@@ -3,7 +3,13 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o | 6 | obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o |
7 | |||
8 | obj-$(CONFIG_OMAP_MPU_TIMER) += time.o | ||
9 | |||
10 | # Power Management | ||
11 | obj-$(CONFIG_PM) += pm.o sleep.o | ||
12 | |||
7 | led-y := leds.o | 13 | led-y := leds.o |
8 | 14 | ||
9 | # Specific board support | 15 | # Specific board support |
@@ -14,8 +20,9 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o | |||
14 | obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o | 20 | obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o |
15 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o | 21 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o |
16 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o | 22 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o |
17 | obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o | ||
18 | obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o | 23 | obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o |
24 | obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o | ||
25 | obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o | ||
19 | 26 | ||
20 | ifeq ($(CONFIG_ARCH_OMAP15XX),y) | 27 | ifeq ($(CONFIG_ARCH_OMAP15XX),y) |
21 | # Innovator-1510 FPGA | 28 | # Innovator-1510 FPGA |
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c new file mode 100644 index 000000000000..6178f046f128 --- /dev/null +++ b/arch/arm/mach-omap1/board-ams-delta.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/board-ams-delta.c | ||
3 | * | ||
4 | * Modified from board-generic.c | ||
5 | * | ||
6 | * Board specific inits for the Amstrad E3 (codename Delta) videophone | ||
7 | * | ||
8 | * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> | ||
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 | |||
19 | #include <asm/hardware.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | |||
24 | #include <asm/arch/board-ams-delta.h> | ||
25 | #include <asm/arch/gpio.h> | ||
26 | #include <asm/arch/mux.h> | ||
27 | #include <asm/arch/usb.h> | ||
28 | #include <asm/arch/board.h> | ||
29 | #include <asm/arch/common.h> | ||
30 | |||
31 | static u8 ams_delta_latch1_reg; | ||
32 | static u16 ams_delta_latch2_reg; | ||
33 | |||
34 | void ams_delta_latch1_write(u8 mask, u8 value) | ||
35 | { | ||
36 | ams_delta_latch1_reg &= ~mask; | ||
37 | ams_delta_latch1_reg |= value; | ||
38 | *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg; | ||
39 | } | ||
40 | |||
41 | void ams_delta_latch2_write(u16 mask, u16 value) | ||
42 | { | ||
43 | ams_delta_latch2_reg &= ~mask; | ||
44 | ams_delta_latch2_reg |= value; | ||
45 | *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg; | ||
46 | } | ||
47 | |||
48 | static void __init ams_delta_init_irq(void) | ||
49 | { | ||
50 | omap1_init_common_hw(); | ||
51 | omap_init_irq(); | ||
52 | omap_gpio_init(); | ||
53 | } | ||
54 | |||
55 | static struct map_desc ams_delta_io_desc[] __initdata = { | ||
56 | // AMS_DELTA_LATCH1 | ||
57 | { | ||
58 | .virtual = AMS_DELTA_LATCH1_VIRT, | ||
59 | .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS), | ||
60 | .length = 0x01000000, | ||
61 | .type = MT_DEVICE | ||
62 | }, | ||
63 | // AMS_DELTA_LATCH2 | ||
64 | { | ||
65 | .virtual = AMS_DELTA_LATCH2_VIRT, | ||
66 | .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS), | ||
67 | .length = 0x01000000, | ||
68 | .type = MT_DEVICE | ||
69 | }, | ||
70 | // AMS_DELTA_MODEM | ||
71 | { | ||
72 | .virtual = AMS_DELTA_MODEM_VIRT, | ||
73 | .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS), | ||
74 | .length = 0x01000000, | ||
75 | .type = MT_DEVICE | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static struct omap_uart_config ams_delta_uart_config __initdata = { | ||
80 | .enabled_uarts = 1, | ||
81 | }; | ||
82 | |||
83 | static struct omap_board_config_kernel ams_delta_config[] = { | ||
84 | { OMAP_TAG_UART, &ams_delta_uart_config }, | ||
85 | }; | ||
86 | |||
87 | static void __init ams_delta_init(void) | ||
88 | { | ||
89 | iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); | ||
90 | |||
91 | omap_board_config = ams_delta_config; | ||
92 | omap_board_config_size = ARRAY_SIZE(ams_delta_config); | ||
93 | omap_serial_init(); | ||
94 | |||
95 | /* Clear latch2 (NAND, LCD, modem enable) */ | ||
96 | ams_delta_latch2_write(~0, 0); | ||
97 | } | ||
98 | |||
99 | static void __init ams_delta_map_io(void) | ||
100 | { | ||
101 | omap1_map_common_io(); | ||
102 | } | ||
103 | |||
104 | MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") | ||
105 | /* Maintainer: Jonathan McDowell <noodles@earth.li> */ | ||
106 | .phys_io = 0xfff00000, | ||
107 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | ||
108 | .boot_params = 0x10000100, | ||
109 | .map_io = ams_delta_map_io, | ||
110 | .init_irq = ams_delta_init_irq, | ||
111 | .init_machine = ams_delta_init, | ||
112 | .timer = &omap_timer, | ||
113 | MACHINE_END | ||
114 | |||
115 | EXPORT_SYMBOL(ams_delta_latch1_write); | ||
116 | EXPORT_SYMBOL(ams_delta_latch2_write); | ||
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index a177e78b2b87..33d01adab1ed 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c | |||
@@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = { | |||
88 | static void __init omap_generic_init(void) | 88 | static void __init omap_generic_init(void) |
89 | { | 89 | { |
90 | #ifdef CONFIG_ARCH_OMAP15XX | 90 | #ifdef CONFIG_ARCH_OMAP15XX |
91 | if (cpu_is_omap1510()) { | 91 | if (cpu_is_omap15xx()) { |
92 | generic_config[0].data = &generic1510_usb_config; | 92 | generic_config[0].data = &generic1510_usb_config; |
93 | } | 93 | } |
94 | #endif | 94 | #endif |
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 89f0cc74a519..cd3a06dfc0a8 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
@@ -24,7 +24,9 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
27 | #include <linux/mtd/nand.h> | ||
27 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
29 | #include <linux/input.h> | ||
28 | 30 | ||
29 | #include <asm/hardware.h> | 31 | #include <asm/hardware.h> |
30 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
@@ -35,12 +37,55 @@ | |||
35 | #include <asm/arch/gpio.h> | 37 | #include <asm/arch/gpio.h> |
36 | #include <asm/arch/mux.h> | 38 | #include <asm/arch/mux.h> |
37 | #include <asm/arch/tc.h> | 39 | #include <asm/arch/tc.h> |
40 | #include <asm/arch/irda.h> | ||
38 | #include <asm/arch/usb.h> | 41 | #include <asm/arch/usb.h> |
42 | #include <asm/arch/keypad.h> | ||
39 | #include <asm/arch/common.h> | 43 | #include <asm/arch/common.h> |
44 | #include <asm/arch/mcbsp.h> | ||
45 | #include <asm/arch/omap-alsa.h> | ||
40 | 46 | ||
41 | extern int omap_gpio_init(void); | 47 | extern int omap_gpio_init(void); |
42 | 48 | ||
43 | static struct mtd_partition h2_partitions[] = { | 49 | static int h2_keymap[] = { |
50 | KEY(0, 0, KEY_LEFT), | ||
51 | KEY(0, 1, KEY_RIGHT), | ||
52 | KEY(0, 2, KEY_3), | ||
53 | KEY(0, 3, KEY_F10), | ||
54 | KEY(0, 4, KEY_F5), | ||
55 | KEY(0, 5, KEY_9), | ||
56 | KEY(1, 0, KEY_DOWN), | ||
57 | KEY(1, 1, KEY_UP), | ||
58 | KEY(1, 2, KEY_2), | ||
59 | KEY(1, 3, KEY_F9), | ||
60 | KEY(1, 4, KEY_F7), | ||
61 | KEY(1, 5, KEY_0), | ||
62 | KEY(2, 0, KEY_ENTER), | ||
63 | KEY(2, 1, KEY_6), | ||
64 | KEY(2, 2, KEY_1), | ||
65 | KEY(2, 3, KEY_F2), | ||
66 | KEY(2, 4, KEY_F6), | ||
67 | KEY(2, 5, KEY_HOME), | ||
68 | KEY(3, 0, KEY_8), | ||
69 | KEY(3, 1, KEY_5), | ||
70 | KEY(3, 2, KEY_F12), | ||
71 | KEY(3, 3, KEY_F3), | ||
72 | KEY(3, 4, KEY_F8), | ||
73 | KEY(3, 5, KEY_END), | ||
74 | KEY(4, 0, KEY_7), | ||
75 | KEY(4, 1, KEY_4), | ||
76 | KEY(4, 2, KEY_F11), | ||
77 | KEY(4, 3, KEY_F1), | ||
78 | KEY(4, 4, KEY_F4), | ||
79 | KEY(4, 5, KEY_ESC), | ||
80 | KEY(5, 0, KEY_F13), | ||
81 | KEY(5, 1, KEY_F14), | ||
82 | KEY(5, 2, KEY_F15), | ||
83 | KEY(5, 3, KEY_F16), | ||
84 | KEY(5, 4, KEY_SLEEP), | ||
85 | 0 | ||
86 | }; | ||
87 | |||
88 | static struct mtd_partition h2_nor_partitions[] = { | ||
44 | /* bootloader (U-Boot, etc) in first sector */ | 89 | /* bootloader (U-Boot, etc) in first sector */ |
45 | { | 90 | { |
46 | .name = "bootloader", | 91 | .name = "bootloader", |
@@ -71,26 +116,26 @@ static struct mtd_partition h2_partitions[] = { | |||
71 | } | 116 | } |
72 | }; | 117 | }; |
73 | 118 | ||
74 | static struct flash_platform_data h2_flash_data = { | 119 | static struct flash_platform_data h2_nor_data = { |
75 | .map_name = "cfi_probe", | 120 | .map_name = "cfi_probe", |
76 | .width = 2, | 121 | .width = 2, |
77 | .parts = h2_partitions, | 122 | .parts = h2_nor_partitions, |
78 | .nr_parts = ARRAY_SIZE(h2_partitions), | 123 | .nr_parts = ARRAY_SIZE(h2_nor_partitions), |
79 | }; | 124 | }; |
80 | 125 | ||
81 | static struct resource h2_flash_resource = { | 126 | static struct resource h2_nor_resource = { |
82 | /* This is on CS3, wherever it's mapped */ | 127 | /* This is on CS3, wherever it's mapped */ |
83 | .flags = IORESOURCE_MEM, | 128 | .flags = IORESOURCE_MEM, |
84 | }; | 129 | }; |
85 | 130 | ||
86 | static struct platform_device h2_flash_device = { | 131 | static struct platform_device h2_nor_device = { |
87 | .name = "omapflash", | 132 | .name = "omapflash", |
88 | .id = 0, | 133 | .id = 0, |
89 | .dev = { | 134 | .dev = { |
90 | .platform_data = &h2_flash_data, | 135 | .platform_data = &h2_nor_data, |
91 | }, | 136 | }, |
92 | .num_resources = 1, | 137 | .num_resources = 1, |
93 | .resource = &h2_flash_resource, | 138 | .resource = &h2_nor_resource, |
94 | }; | 139 | }; |
95 | 140 | ||
96 | static struct resource h2_smc91x_resources[] = { | 141 | static struct resource h2_smc91x_resources[] = { |
@@ -113,9 +158,119 @@ static struct platform_device h2_smc91x_device = { | |||
113 | .resource = h2_smc91x_resources, | 158 | .resource = h2_smc91x_resources, |
114 | }; | 159 | }; |
115 | 160 | ||
161 | static struct resource h2_kp_resources[] = { | ||
162 | [0] = { | ||
163 | .start = INT_KEYBOARD, | ||
164 | .end = INT_KEYBOARD, | ||
165 | .flags = IORESOURCE_IRQ, | ||
166 | }, | ||
167 | }; | ||
168 | |||
169 | static struct omap_kp_platform_data h2_kp_data = { | ||
170 | .rows = 8, | ||
171 | .cols = 8, | ||
172 | .keymap = h2_keymap, | ||
173 | .rep = 1, | ||
174 | }; | ||
175 | |||
176 | static struct platform_device h2_kp_device = { | ||
177 | .name = "omap-keypad", | ||
178 | .id = -1, | ||
179 | .dev = { | ||
180 | .platform_data = &h2_kp_data, | ||
181 | }, | ||
182 | .num_resources = ARRAY_SIZE(h2_kp_resources), | ||
183 | .resource = h2_kp_resources, | ||
184 | }; | ||
185 | |||
186 | #define H2_IRDA_FIRSEL_GPIO_PIN 17 | ||
187 | |||
188 | #if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) | ||
189 | static int h2_transceiver_mode(struct device *dev, int state) | ||
190 | { | ||
191 | if (state & IR_SIRMODE) | ||
192 | omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0); | ||
193 | else /* MIR/FIR */ | ||
194 | omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | #endif | ||
199 | |||
200 | static struct omap_irda_config h2_irda_data = { | ||
201 | .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, | ||
202 | .rx_channel = OMAP_DMA_UART3_RX, | ||
203 | .tx_channel = OMAP_DMA_UART3_TX, | ||
204 | .dest_start = UART3_THR, | ||
205 | .src_start = UART3_RHR, | ||
206 | .tx_trigger = 0, | ||
207 | .rx_trigger = 0, | ||
208 | }; | ||
209 | |||
210 | static struct resource h2_irda_resources[] = { | ||
211 | [0] = { | ||
212 | .start = INT_UART3, | ||
213 | .end = INT_UART3, | ||
214 | .flags = IORESOURCE_IRQ, | ||
215 | }, | ||
216 | }; | ||
217 | static struct platform_device h2_irda_device = { | ||
218 | .name = "omapirda", | ||
219 | .id = 0, | ||
220 | .dev = { | ||
221 | .platform_data = &h2_irda_data, | ||
222 | }, | ||
223 | .num_resources = ARRAY_SIZE(h2_irda_resources), | ||
224 | .resource = h2_irda_resources, | ||
225 | }; | ||
226 | |||
227 | static struct platform_device h2_lcd_device = { | ||
228 | .name = "lcd_h2", | ||
229 | .id = -1, | ||
230 | }; | ||
231 | |||
232 | static struct omap_mcbsp_reg_cfg mcbsp_regs = { | ||
233 | .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), | ||
234 | .spcr1 = RINTM(3) | RRST, | ||
235 | .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | | ||
236 | RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1), | ||
237 | .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), | ||
238 | .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | | ||
239 | XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG, | ||
240 | .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), | ||
241 | .srgr1 = FWID(15), | ||
242 | .srgr2 = GSYNC | CLKSP | FSGM | FPER(31), | ||
243 | |||
244 | .pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, | ||
245 | //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ | ||
246 | }; | ||
247 | |||
248 | static struct omap_alsa_codec_config alsa_config = { | ||
249 | .name = "H2 TSC2101", | ||
250 | .mcbsp_regs_alsa = &mcbsp_regs, | ||
251 | .codec_configure_dev = NULL, // tsc2101_configure, | ||
252 | .codec_set_samplerate = NULL, // tsc2101_set_samplerate, | ||
253 | .codec_clock_setup = NULL, // tsc2101_clock_setup, | ||
254 | .codec_clock_on = NULL, // tsc2101_clock_on, | ||
255 | .codec_clock_off = NULL, // tsc2101_clock_off, | ||
256 | .get_default_samplerate = NULL, // tsc2101_get_default_samplerate, | ||
257 | }; | ||
258 | |||
259 | static struct platform_device h2_mcbsp1_device = { | ||
260 | .name = "omap_alsa_mcbsp", | ||
261 | .id = 1, | ||
262 | .dev = { | ||
263 | .platform_data = &alsa_config, | ||
264 | }, | ||
265 | }; | ||
266 | |||
116 | static struct platform_device *h2_devices[] __initdata = { | 267 | static struct platform_device *h2_devices[] __initdata = { |
117 | &h2_flash_device, | 268 | &h2_nor_device, |
118 | &h2_smc91x_device, | 269 | &h2_smc91x_device, |
270 | &h2_irda_device, | ||
271 | &h2_kp_device, | ||
272 | &h2_lcd_device, | ||
273 | &h2_mcbsp1_device, | ||
119 | }; | 274 | }; |
120 | 275 | ||
121 | static void __init h2_init_smc91x(void) | 276 | static void __init h2_init_smc91x(void) |
@@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = { | |||
164 | }; | 319 | }; |
165 | 320 | ||
166 | static struct omap_lcd_config h2_lcd_config __initdata = { | 321 | static struct omap_lcd_config h2_lcd_config __initdata = { |
167 | .panel_name = "h2", | ||
168 | .ctrl_name = "internal", | 322 | .ctrl_name = "internal", |
169 | }; | 323 | }; |
170 | 324 | ||
@@ -177,16 +331,34 @@ static struct omap_board_config_kernel h2_config[] = { | |||
177 | 331 | ||
178 | static void __init h2_init(void) | 332 | static void __init h2_init(void) |
179 | { | 333 | { |
180 | /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B | 334 | /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped |
181 | * and NAND (either 16bit or 8bit) on CS3. | 335 | * to address 0 by a dip switch), NAND on CS2B. The NAND driver will |
336 | * notice whether a NAND chip is enabled at probe time. | ||
337 | * | ||
338 | * FIXME revC boards (and H3) support NAND-boot, with a dip switch to | ||
339 | * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try | ||
340 | * detecting that in code here, to avoid probing every possible flash | ||
341 | * configuration... | ||
182 | */ | 342 | */ |
183 | h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys(); | 343 | h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys(); |
184 | h2_flash_resource.end += SZ_32M - 1; | 344 | h2_nor_resource.end += SZ_32M - 1; |
345 | |||
346 | omap_cfg_reg(L3_1610_FLASH_CS2B_OE); | ||
347 | omap_cfg_reg(M8_1610_FLASH_CS2B_WE); | ||
185 | 348 | ||
186 | /* MMC: card detect and WP */ | 349 | /* MMC: card detect and WP */ |
187 | // omap_cfg_reg(U19_ARMIO1); /* CD */ | 350 | // omap_cfg_reg(U19_ARMIO1); /* CD */ |
188 | omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */ | 351 | omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */ |
189 | 352 | ||
353 | /* Irda */ | ||
354 | #if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) | ||
355 | omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A); | ||
356 | if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) { | ||
357 | omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0); | ||
358 | h2_irda_data.transceiver_mode = h2_transceiver_mode; | ||
359 | } | ||
360 | #endif | ||
361 | |||
190 | platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); | 362 | platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); |
191 | omap_board_config = h2_config; | 363 | omap_board_config = h2_config; |
192 | omap_board_config_size = ARRAY_SIZE(h2_config); | 364 | omap_board_config_size = ARRAY_SIZE(h2_config); |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index d9f386265996..4b8d0ec73cb7 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
@@ -21,8 +21,11 @@ | |||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/workqueue.h> | ||
24 | #include <linux/mtd/mtd.h> | 25 | #include <linux/mtd/mtd.h> |
26 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
28 | #include <linux/input.h> | ||
26 | 29 | ||
27 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
28 | #include <asm/page.h> | 31 | #include <asm/page.h> |
@@ -33,15 +36,59 @@ | |||
33 | #include <asm/mach/map.h> | 36 | #include <asm/mach/map.h> |
34 | 37 | ||
35 | #include <asm/arch/gpio.h> | 38 | #include <asm/arch/gpio.h> |
39 | #include <asm/arch/gpioexpander.h> | ||
36 | #include <asm/arch/irqs.h> | 40 | #include <asm/arch/irqs.h> |
37 | #include <asm/arch/mux.h> | 41 | #include <asm/arch/mux.h> |
38 | #include <asm/arch/tc.h> | 42 | #include <asm/arch/tc.h> |
43 | #include <asm/arch/irda.h> | ||
39 | #include <asm/arch/usb.h> | 44 | #include <asm/arch/usb.h> |
45 | #include <asm/arch/keypad.h> | ||
46 | #include <asm/arch/dma.h> | ||
40 | #include <asm/arch/common.h> | 47 | #include <asm/arch/common.h> |
41 | 48 | ||
42 | extern int omap_gpio_init(void); | 49 | extern int omap_gpio_init(void); |
43 | 50 | ||
44 | static struct mtd_partition h3_partitions[] = { | 51 | static int h3_keymap[] = { |
52 | KEY(0, 0, KEY_LEFT), | ||
53 | KEY(0, 1, KEY_RIGHT), | ||
54 | KEY(0, 2, KEY_3), | ||
55 | KEY(0, 3, KEY_F10), | ||
56 | KEY(0, 4, KEY_F5), | ||
57 | KEY(0, 5, KEY_9), | ||
58 | KEY(1, 0, KEY_DOWN), | ||
59 | KEY(1, 1, KEY_UP), | ||
60 | KEY(1, 2, KEY_2), | ||
61 | KEY(1, 3, KEY_F9), | ||
62 | KEY(1, 4, KEY_F7), | ||
63 | KEY(1, 5, KEY_0), | ||
64 | KEY(2, 0, KEY_ENTER), | ||
65 | KEY(2, 1, KEY_6), | ||
66 | KEY(2, 2, KEY_1), | ||
67 | KEY(2, 3, KEY_F2), | ||
68 | KEY(2, 4, KEY_F6), | ||
69 | KEY(2, 5, KEY_HOME), | ||
70 | KEY(3, 0, KEY_8), | ||
71 | KEY(3, 1, KEY_5), | ||
72 | KEY(3, 2, KEY_F12), | ||
73 | KEY(3, 3, KEY_F3), | ||
74 | KEY(3, 4, KEY_F8), | ||
75 | KEY(3, 5, KEY_END), | ||
76 | KEY(4, 0, KEY_7), | ||
77 | KEY(4, 1, KEY_4), | ||
78 | KEY(4, 2, KEY_F11), | ||
79 | KEY(4, 3, KEY_F1), | ||
80 | KEY(4, 4, KEY_F4), | ||
81 | KEY(4, 5, KEY_ESC), | ||
82 | KEY(5, 0, KEY_F13), | ||
83 | KEY(5, 1, KEY_F14), | ||
84 | KEY(5, 2, KEY_F15), | ||
85 | KEY(5, 3, KEY_F16), | ||
86 | KEY(5, 4, KEY_SLEEP), | ||
87 | 0 | ||
88 | }; | ||
89 | |||
90 | |||
91 | static struct mtd_partition nor_partitions[] = { | ||
45 | /* bootloader (U-Boot, etc) in first sector */ | 92 | /* bootloader (U-Boot, etc) in first sector */ |
46 | { | 93 | { |
47 | .name = "bootloader", | 94 | .name = "bootloader", |
@@ -72,26 +119,80 @@ static struct mtd_partition h3_partitions[] = { | |||
72 | } | 119 | } |
73 | }; | 120 | }; |
74 | 121 | ||
75 | static struct flash_platform_data h3_flash_data = { | 122 | static struct flash_platform_data nor_data = { |
76 | .map_name = "cfi_probe", | 123 | .map_name = "cfi_probe", |
77 | .width = 2, | 124 | .width = 2, |
78 | .parts = h3_partitions, | 125 | .parts = nor_partitions, |
79 | .nr_parts = ARRAY_SIZE(h3_partitions), | 126 | .nr_parts = ARRAY_SIZE(nor_partitions), |
80 | }; | 127 | }; |
81 | 128 | ||
82 | static struct resource h3_flash_resource = { | 129 | static struct resource nor_resource = { |
83 | /* This is on CS3, wherever it's mapped */ | 130 | /* This is on CS3, wherever it's mapped */ |
84 | .flags = IORESOURCE_MEM, | 131 | .flags = IORESOURCE_MEM, |
85 | }; | 132 | }; |
86 | 133 | ||
87 | static struct platform_device flash_device = { | 134 | static struct platform_device nor_device = { |
88 | .name = "omapflash", | 135 | .name = "omapflash", |
89 | .id = 0, | 136 | .id = 0, |
90 | .dev = { | 137 | .dev = { |
91 | .platform_data = &h3_flash_data, | 138 | .platform_data = &nor_data, |
139 | }, | ||
140 | .num_resources = 1, | ||
141 | .resource = &nor_resource, | ||
142 | }; | ||
143 | |||
144 | static struct mtd_partition nand_partitions[] = { | ||
145 | #if 0 | ||
146 | /* REVISIT: enable these partitions if you make NAND BOOT work */ | ||
147 | { | ||
148 | .name = "xloader", | ||
149 | .offset = 0, | ||
150 | .size = 64 * 1024, | ||
151 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
152 | }, | ||
153 | { | ||
154 | .name = "bootloader", | ||
155 | .offset = MTDPART_OFS_APPEND, | ||
156 | .size = 256 * 1024, | ||
157 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
158 | }, | ||
159 | { | ||
160 | .name = "params", | ||
161 | .offset = MTDPART_OFS_APPEND, | ||
162 | .size = 192 * 1024, | ||
163 | }, | ||
164 | { | ||
165 | .name = "kernel", | ||
166 | .offset = MTDPART_OFS_APPEND, | ||
167 | .size = 2 * SZ_1M, | ||
168 | }, | ||
169 | #endif | ||
170 | { | ||
171 | .name = "filesystem", | ||
172 | .size = MTDPART_SIZ_FULL, | ||
173 | .offset = MTDPART_OFS_APPEND, | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | /* dip switches control NAND chip access: 8 bit, 16 bit, or neither */ | ||
178 | static struct nand_platform_data nand_data = { | ||
179 | .options = NAND_SAMSUNG_LP_OPTIONS, | ||
180 | .parts = nand_partitions, | ||
181 | .nr_parts = ARRAY_SIZE(nand_partitions), | ||
182 | }; | ||
183 | |||
184 | static struct resource nand_resource = { | ||
185 | .flags = IORESOURCE_MEM, | ||
186 | }; | ||
187 | |||
188 | static struct platform_device nand_device = { | ||
189 | .name = "omapnand", | ||
190 | .id = 0, | ||
191 | .dev = { | ||
192 | .platform_data = &nand_data, | ||
92 | }, | 193 | }, |
93 | .num_resources = 1, | 194 | .num_resources = 1, |
94 | .resource = &h3_flash_resource, | 195 | .resource = &nand_resource, |
95 | }; | 196 | }; |
96 | 197 | ||
97 | static struct resource smc91x_resources[] = { | 198 | static struct resource smc91x_resources[] = { |
@@ -138,10 +239,136 @@ static struct platform_device intlat_device = { | |||
138 | .resource = intlat_resources, | 239 | .resource = intlat_resources, |
139 | }; | 240 | }; |
140 | 241 | ||
242 | static struct resource h3_kp_resources[] = { | ||
243 | [0] = { | ||
244 | .start = INT_KEYBOARD, | ||
245 | .end = INT_KEYBOARD, | ||
246 | .flags = IORESOURCE_IRQ, | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | static struct omap_kp_platform_data h3_kp_data = { | ||
251 | .rows = 8, | ||
252 | .cols = 8, | ||
253 | .keymap = h3_keymap, | ||
254 | .rep = 1, | ||
255 | }; | ||
256 | |||
257 | static struct platform_device h3_kp_device = { | ||
258 | .name = "omap-keypad", | ||
259 | .id = -1, | ||
260 | .dev = { | ||
261 | .platform_data = &h3_kp_data, | ||
262 | }, | ||
263 | .num_resources = ARRAY_SIZE(h3_kp_resources), | ||
264 | .resource = h3_kp_resources, | ||
265 | }; | ||
266 | |||
267 | |||
268 | /* Select between the IrDA and aGPS module | ||
269 | */ | ||
270 | static int h3_select_irda(struct device *dev, int state) | ||
271 | { | ||
272 | unsigned char expa; | ||
273 | int err = 0; | ||
274 | |||
275 | if ((err = read_gpio_expa(&expa, 0x26))) { | ||
276 | printk(KERN_ERR "Error reading from I/O EXPANDER \n"); | ||
277 | return err; | ||
278 | } | ||
279 | |||
280 | /* 'P6' enable/disable IRDA_TX and IRDA_RX */ | ||
281 | if (state & IR_SEL) { /* IrDA */ | ||
282 | if ((err = write_gpio_expa(expa | 0x40, 0x26))) { | ||
283 | printk(KERN_ERR "Error writing to I/O EXPANDER \n"); | ||
284 | return err; | ||
285 | } | ||
286 | } else { | ||
287 | if ((err = write_gpio_expa(expa & ~0x40, 0x26))) { | ||
288 | printk(KERN_ERR "Error writing to I/O EXPANDER \n"); | ||
289 | return err; | ||
290 | } | ||
291 | } | ||
292 | return err; | ||
293 | } | ||
294 | |||
295 | static void set_trans_mode(void *data) | ||
296 | { | ||
297 | int *mode = data; | ||
298 | unsigned char expa; | ||
299 | int err = 0; | ||
300 | |||
301 | if ((err = read_gpio_expa(&expa, 0x27)) != 0) { | ||
302 | printk(KERN_ERR "Error reading from I/O expander\n"); | ||
303 | } | ||
304 | |||
305 | expa &= ~0x03; | ||
306 | |||
307 | if (*mode & IR_SIRMODE) { | ||
308 | expa |= 0x01; | ||
309 | } else { /* MIR/FIR */ | ||
310 | expa |= 0x03; | ||
311 | } | ||
312 | |||
313 | if ((err = write_gpio_expa(expa, 0x27)) != 0) { | ||
314 | printk(KERN_ERR "Error writing to I/O expander\n"); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | static int h3_transceiver_mode(struct device *dev, int mode) | ||
319 | { | ||
320 | struct omap_irda_config *irda_config = dev->platform_data; | ||
321 | |||
322 | cancel_delayed_work(&irda_config->gpio_expa); | ||
323 | PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); | ||
324 | schedule_work(&irda_config->gpio_expa); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct omap_irda_config h3_irda_data = { | ||
330 | .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, | ||
331 | .transceiver_mode = h3_transceiver_mode, | ||
332 | .select_irda = h3_select_irda, | ||
333 | .rx_channel = OMAP_DMA_UART3_RX, | ||
334 | .tx_channel = OMAP_DMA_UART3_TX, | ||
335 | .dest_start = UART3_THR, | ||
336 | .src_start = UART3_RHR, | ||
337 | .tx_trigger = 0, | ||
338 | .rx_trigger = 0, | ||
339 | }; | ||
340 | |||
341 | static struct resource h3_irda_resources[] = { | ||
342 | [0] = { | ||
343 | .start = INT_UART3, | ||
344 | .end = INT_UART3, | ||
345 | .flags = IORESOURCE_IRQ, | ||
346 | }, | ||
347 | }; | ||
348 | |||
349 | static struct platform_device h3_irda_device = { | ||
350 | .name = "omapirda", | ||
351 | .id = 0, | ||
352 | .dev = { | ||
353 | .platform_data = &h3_irda_data, | ||
354 | }, | ||
355 | .num_resources = ARRAY_SIZE(h3_irda_resources), | ||
356 | .resource = h3_irda_resources, | ||
357 | }; | ||
358 | |||
359 | static struct platform_device h3_lcd_device = { | ||
360 | .name = "lcd_h3", | ||
361 | .id = -1, | ||
362 | }; | ||
363 | |||
141 | static struct platform_device *devices[] __initdata = { | 364 | static struct platform_device *devices[] __initdata = { |
142 | &flash_device, | 365 | &nor_device, |
366 | &nand_device, | ||
143 | &smc91x_device, | 367 | &smc91x_device, |
144 | &intlat_device, | 368 | &intlat_device, |
369 | &h3_irda_device, | ||
370 | &h3_kp_device, | ||
371 | &h3_lcd_device, | ||
145 | }; | 372 | }; |
146 | 373 | ||
147 | static struct omap_usb_config h3_usb_config __initdata = { | 374 | static struct omap_usb_config h3_usb_config __initdata = { |
@@ -171,7 +398,6 @@ static struct omap_uart_config h3_uart_config __initdata = { | |||
171 | }; | 398 | }; |
172 | 399 | ||
173 | static struct omap_lcd_config h3_lcd_config __initdata = { | 400 | static struct omap_lcd_config h3_lcd_config __initdata = { |
174 | .panel_name = "h3", | ||
175 | .ctrl_name = "internal", | 401 | .ctrl_name = "internal", |
176 | }; | 402 | }; |
177 | 403 | ||
@@ -182,11 +408,36 @@ static struct omap_board_config_kernel h3_config[] = { | |||
182 | { OMAP_TAG_LCD, &h3_lcd_config }, | 408 | { OMAP_TAG_LCD, &h3_lcd_config }, |
183 | }; | 409 | }; |
184 | 410 | ||
411 | #define H3_NAND_RB_GPIO_PIN 10 | ||
412 | |||
413 | static int nand_dev_ready(struct nand_platform_data *data) | ||
414 | { | ||
415 | return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN); | ||
416 | } | ||
417 | |||
185 | static void __init h3_init(void) | 418 | static void __init h3_init(void) |
186 | { | 419 | { |
187 | h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys(); | 420 | /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped |
188 | h3_flash_resource.end += OMAP_CS3_SIZE - 1; | 421 | * to address 0 by a dip switch), NAND on CS2B. The NAND driver will |
189 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 422 | * notice whether a NAND chip is enabled at probe time. |
423 | * | ||
424 | * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND | ||
425 | * (which on H2 may be 16bit) on CS3. Try detecting that in code here, | ||
426 | * to avoid probing every possible flash configuration... | ||
427 | */ | ||
428 | nor_resource.end = nor_resource.start = omap_cs3_phys(); | ||
429 | nor_resource.end += SZ_32M - 1; | ||
430 | |||
431 | nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS; | ||
432 | nand_resource.end += SZ_4K - 1; | ||
433 | if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN))) | ||
434 | nand_data.dev_ready = nand_dev_ready; | ||
435 | |||
436 | /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */ | ||
437 | /* GPIO10 pullup/down register, Enable pullup on GPIO10 */ | ||
438 | omap_cfg_reg(V2_1710_GPIO10); | ||
439 | |||
440 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
190 | omap_board_config = h3_config; | 441 | omap_board_config = h3_config; |
191 | omap_board_config_size = ARRAY_SIZE(h3_config); | 442 | omap_board_config_size = ARRAY_SIZE(h3_config); |
192 | omap_serial_init(); | 443 | omap_serial_init(); |
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index a04e4332915e..e90c137a4cf3 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/mtd/mtd.h> | 23 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/partitions.h> | 24 | #include <linux/mtd/partitions.h> |
25 | #include <linux/input.h> | ||
25 | 26 | ||
26 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
27 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
@@ -34,8 +35,22 @@ | |||
34 | #include <asm/arch/gpio.h> | 35 | #include <asm/arch/gpio.h> |
35 | #include <asm/arch/tc.h> | 36 | #include <asm/arch/tc.h> |
36 | #include <asm/arch/usb.h> | 37 | #include <asm/arch/usb.h> |
38 | #include <asm/arch/keypad.h> | ||
37 | #include <asm/arch/common.h> | 39 | #include <asm/arch/common.h> |
38 | 40 | ||
41 | static int innovator_keymap[] = { | ||
42 | KEY(0, 0, KEY_F1), | ||
43 | KEY(0, 3, KEY_DOWN), | ||
44 | KEY(1, 1, KEY_F2), | ||
45 | KEY(1, 2, KEY_RIGHT), | ||
46 | KEY(2, 0, KEY_F3), | ||
47 | KEY(2, 1, KEY_F4), | ||
48 | KEY(2, 2, KEY_UP), | ||
49 | KEY(3, 2, KEY_ENTER), | ||
50 | KEY(3, 3, KEY_LEFT), | ||
51 | 0 | ||
52 | }; | ||
53 | |||
39 | static struct mtd_partition innovator_partitions[] = { | 54 | static struct mtd_partition innovator_partitions[] = { |
40 | /* bootloader (U-Boot, etc) in first sector */ | 55 | /* bootloader (U-Boot, etc) in first sector */ |
41 | { | 56 | { |
@@ -97,6 +112,31 @@ static struct platform_device innovator_flash_device = { | |||
97 | .resource = &innovator_flash_resource, | 112 | .resource = &innovator_flash_resource, |
98 | }; | 113 | }; |
99 | 114 | ||
115 | static struct resource innovator_kp_resources[] = { | ||
116 | [0] = { | ||
117 | .start = INT_KEYBOARD, | ||
118 | .end = INT_KEYBOARD, | ||
119 | .flags = IORESOURCE_IRQ, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | static struct omap_kp_platform_data innovator_kp_data = { | ||
124 | .rows = 8, | ||
125 | .cols = 8, | ||
126 | .keymap = innovator_keymap, | ||
127 | }; | ||
128 | |||
129 | static struct platform_device innovator_kp_device = { | ||
130 | .name = "omap-keypad", | ||
131 | .id = -1, | ||
132 | .dev = { | ||
133 | .platform_data = &innovator_kp_data, | ||
134 | }, | ||
135 | .num_resources = ARRAY_SIZE(innovator_kp_resources), | ||
136 | .resource = innovator_kp_resources, | ||
137 | }; | ||
138 | |||
139 | |||
100 | #ifdef CONFIG_ARCH_OMAP15XX | 140 | #ifdef CONFIG_ARCH_OMAP15XX |
101 | 141 | ||
102 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ | 142 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ |
@@ -129,9 +169,16 @@ static struct platform_device innovator1510_smc91x_device = { | |||
129 | .resource = innovator1510_smc91x_resources, | 169 | .resource = innovator1510_smc91x_resources, |
130 | }; | 170 | }; |
131 | 171 | ||
172 | static struct platform_device innovator1510_lcd_device = { | ||
173 | .name = "lcd_inn1510", | ||
174 | .id = -1, | ||
175 | }; | ||
176 | |||
132 | static struct platform_device *innovator1510_devices[] __initdata = { | 177 | static struct platform_device *innovator1510_devices[] __initdata = { |
133 | &innovator_flash_device, | 178 | &innovator_flash_device, |
134 | &innovator1510_smc91x_device, | 179 | &innovator1510_smc91x_device, |
180 | &innovator_kp_device, | ||
181 | &innovator1510_lcd_device, | ||
135 | }; | 182 | }; |
136 | 183 | ||
137 | #endif /* CONFIG_ARCH_OMAP15XX */ | 184 | #endif /* CONFIG_ARCH_OMAP15XX */ |
@@ -158,9 +205,16 @@ static struct platform_device innovator1610_smc91x_device = { | |||
158 | .resource = innovator1610_smc91x_resources, | 205 | .resource = innovator1610_smc91x_resources, |
159 | }; | 206 | }; |
160 | 207 | ||
208 | static struct platform_device innovator1610_lcd_device = { | ||
209 | .name = "inn1610_lcd", | ||
210 | .id = -1, | ||
211 | }; | ||
212 | |||
161 | static struct platform_device *innovator1610_devices[] __initdata = { | 213 | static struct platform_device *innovator1610_devices[] __initdata = { |
162 | &innovator_flash_device, | 214 | &innovator_flash_device, |
163 | &innovator1610_smc91x_device, | 215 | &innovator1610_smc91x_device, |
216 | &innovator_kp_device, | ||
217 | &innovator1610_lcd_device, | ||
164 | }; | 218 | }; |
165 | 219 | ||
166 | #endif /* CONFIG_ARCH_OMAP16XX */ | 220 | #endif /* CONFIG_ARCH_OMAP16XX */ |
@@ -206,7 +260,6 @@ static struct omap_usb_config innovator1510_usb_config __initdata = { | |||
206 | }; | 260 | }; |
207 | 261 | ||
208 | static struct omap_lcd_config innovator1510_lcd_config __initdata = { | 262 | static struct omap_lcd_config innovator1510_lcd_config __initdata = { |
209 | .panel_name = "inn1510", | ||
210 | .ctrl_name = "internal", | 263 | .ctrl_name = "internal", |
211 | }; | 264 | }; |
212 | #endif | 265 | #endif |
@@ -228,7 +281,6 @@ static struct omap_usb_config h2_usb_config __initdata = { | |||
228 | }; | 281 | }; |
229 | 282 | ||
230 | static struct omap_lcd_config innovator1610_lcd_config __initdata = { | 283 | static struct omap_lcd_config innovator1610_lcd_config __initdata = { |
231 | .panel_name = "inn1610", | ||
232 | .ctrl_name = "internal", | 284 | .ctrl_name = "internal", |
233 | }; | 285 | }; |
234 | #endif | 286 | #endif |
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c deleted file mode 100644 index 7520e602d7a2..000000000000 --- a/arch/arm/mach-omap1/board-netstar.c +++ /dev/null | |||
@@ -1,160 +0,0 @@ | |||
1 | /* | ||
2 | * Modified from board-generic.c | ||
3 | * | ||
4 | * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz> | ||
5 | * | ||
6 | * Code for Netstar OMAP board. | ||
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/delay.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/notifier.h> | ||
19 | #include <linux/reboot.h> | ||
20 | |||
21 | #include <asm/hardware.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/mach/arch.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | |||
26 | #include <asm/arch/gpio.h> | ||
27 | #include <asm/arch/mux.h> | ||
28 | #include <asm/arch/usb.h> | ||
29 | #include <asm/arch/common.h> | ||
30 | |||
31 | extern void __init omap_init_time(void); | ||
32 | extern int omap_gpio_init(void); | ||
33 | |||
34 | static struct resource netstar_smc91x_resources[] = { | ||
35 | [0] = { | ||
36 | .start = OMAP_CS1_PHYS + 0x300, | ||
37 | .end = OMAP_CS1_PHYS + 0x300 + 16, | ||
38 | .flags = IORESOURCE_MEM, | ||
39 | }, | ||
40 | [1] = { | ||
41 | .start = OMAP_GPIO_IRQ(8), | ||
42 | .end = OMAP_GPIO_IRQ(8), | ||
43 | .flags = IORESOURCE_IRQ, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static struct platform_device netstar_smc91x_device = { | ||
48 | .name = "smc91x", | ||
49 | .id = 0, | ||
50 | .num_resources = ARRAY_SIZE(netstar_smc91x_resources), | ||
51 | .resource = netstar_smc91x_resources, | ||
52 | }; | ||
53 | |||
54 | static struct platform_device *netstar_devices[] __initdata = { | ||
55 | &netstar_smc91x_device, | ||
56 | }; | ||
57 | |||
58 | static struct omap_uart_config netstar_uart_config __initdata = { | ||
59 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
60 | }; | ||
61 | |||
62 | static struct omap_board_config_kernel netstar_config[] = { | ||
63 | { OMAP_TAG_UART, &netstar_uart_config }, | ||
64 | }; | ||
65 | |||
66 | static void __init netstar_init_irq(void) | ||
67 | { | ||
68 | omap1_init_common_hw(); | ||
69 | omap_init_irq(); | ||
70 | omap_gpio_init(); | ||
71 | } | ||
72 | |||
73 | static void __init netstar_init(void) | ||
74 | { | ||
75 | /* green LED */ | ||
76 | omap_request_gpio(4); | ||
77 | omap_set_gpio_direction(4, 0); | ||
78 | /* smc91x reset */ | ||
79 | omap_request_gpio(7); | ||
80 | omap_set_gpio_direction(7, 0); | ||
81 | omap_set_gpio_dataout(7, 1); | ||
82 | udelay(2); /* wait at least 100ns */ | ||
83 | omap_set_gpio_dataout(7, 0); | ||
84 | mdelay(50); /* 50ms until PHY ready */ | ||
85 | /* smc91x interrupt pin */ | ||
86 | omap_request_gpio(8); | ||
87 | |||
88 | omap_request_gpio(12); | ||
89 | omap_request_gpio(13); | ||
90 | omap_request_gpio(14); | ||
91 | omap_request_gpio(15); | ||
92 | set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING); | ||
93 | set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING); | ||
94 | set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING); | ||
95 | set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING); | ||
96 | |||
97 | platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices)); | ||
98 | |||
99 | /* Switch on green LED */ | ||
100 | omap_set_gpio_dataout(4, 0); | ||
101 | /* Switch off red LED */ | ||
102 | omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ | ||
103 | omap_writeb(0x80, OMAP_LPG1_LCR); | ||
104 | |||
105 | omap_board_config = netstar_config; | ||
106 | omap_board_config_size = ARRAY_SIZE(netstar_config); | ||
107 | omap_serial_init(); | ||
108 | } | ||
109 | |||
110 | static void __init netstar_map_io(void) | ||
111 | { | ||
112 | omap1_map_common_io(); | ||
113 | } | ||
114 | |||
115 | #define MACHINE_PANICED 1 | ||
116 | #define MACHINE_REBOOTING 2 | ||
117 | #define MACHINE_REBOOT 4 | ||
118 | static unsigned long machine_state; | ||
119 | |||
120 | static int panic_event(struct notifier_block *this, unsigned long event, | ||
121 | void *ptr) | ||
122 | { | ||
123 | if (test_and_set_bit(MACHINE_PANICED, &machine_state)) | ||
124 | return NOTIFY_DONE; | ||
125 | |||
126 | /* Switch off green LED */ | ||
127 | omap_set_gpio_dataout(4, 1); | ||
128 | /* Flash red LED */ | ||
129 | omap_writeb(0x78, OMAP_LPG1_LCR); | ||
130 | omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */ | ||
131 | |||
132 | return NOTIFY_DONE; | ||
133 | } | ||
134 | |||
135 | static struct notifier_block panic_block = { | ||
136 | .notifier_call = panic_event, | ||
137 | }; | ||
138 | |||
139 | static int __init netstar_late_init(void) | ||
140 | { | ||
141 | /* TODO: Setup front panel switch here */ | ||
142 | |||
143 | /* Setup panic notifier */ | ||
144 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | postcore_initcall(netstar_late_init); | ||
150 | |||
151 | MACHINE_START(NETSTAR, "NetStar OMAP5910") | ||
152 | /* Maintainer: Ladislav Michl <michl@2n.cz> */ | ||
153 | .phys_io = 0xfff00000, | ||
154 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | ||
155 | .boot_params = 0x10000100, | ||
156 | .map_io = netstar_map_io, | ||
157 | .init_irq = netstar_init_irq, | ||
158 | .init_machine = netstar_init, | ||
159 | .timer = &omap_timer, | ||
160 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c new file mode 100644 index 000000000000..02b980d77b12 --- /dev/null +++ b/arch/arm/mach-omap1/board-nokia770.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/board-nokia770.c | ||
3 | * | ||
4 | * Modified from board-generic.c | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/clk.h> | ||
16 | |||
17 | #include <linux/spi/spi.h> | ||
18 | #include <linux/spi/ads7846.h> | ||
19 | |||
20 | #include <asm/hardware.h> | ||
21 | #include <asm/mach-types.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include <asm/mach/map.h> | ||
24 | |||
25 | #include <asm/arch/gpio.h> | ||
26 | #include <asm/arch/mux.h> | ||
27 | #include <asm/arch/usb.h> | ||
28 | #include <asm/arch/board.h> | ||
29 | #include <asm/arch/keypad.h> | ||
30 | #include <asm/arch/common.h> | ||
31 | #include <asm/arch/dsp_common.h> | ||
32 | #include <asm/arch/aic23.h> | ||
33 | #include <asm/arch/gpio.h> | ||
34 | |||
35 | static void __init omap_nokia770_init_irq(void) | ||
36 | { | ||
37 | /* On Nokia 770, the SleepX signal is masked with an | ||
38 | * MPUIO line by default. It has to be unmasked for it | ||
39 | * to become functional */ | ||
40 | |||
41 | /* SleepX mask direction */ | ||
42 | omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); | ||
43 | /* Unmask SleepX signal */ | ||
44 | omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); | ||
45 | |||
46 | omap1_init_common_hw(); | ||
47 | omap_init_irq(); | ||
48 | } | ||
49 | |||
50 | static int nokia770_keymap[] = { | ||
51 | KEY(0, 1, GROUP_0 | KEY_UP), | ||
52 | KEY(0, 2, GROUP_1 | KEY_F5), | ||
53 | KEY(1, 0, GROUP_0 | KEY_LEFT), | ||
54 | KEY(1, 1, GROUP_0 | KEY_ENTER), | ||
55 | KEY(1, 2, GROUP_0 | KEY_RIGHT), | ||
56 | KEY(2, 0, GROUP_1 | KEY_ESC), | ||
57 | KEY(2, 1, GROUP_0 | KEY_DOWN), | ||
58 | KEY(2, 2, GROUP_1 | KEY_F4), | ||
59 | KEY(3, 0, GROUP_2 | KEY_F7), | ||
60 | KEY(3, 1, GROUP_2 | KEY_F8), | ||
61 | KEY(3, 2, GROUP_2 | KEY_F6), | ||
62 | 0 | ||
63 | }; | ||
64 | |||
65 | static struct resource nokia770_kp_resources[] = { | ||
66 | [0] = { | ||
67 | .start = INT_KEYBOARD, | ||
68 | .end = INT_KEYBOARD, | ||
69 | .flags = IORESOURCE_IRQ, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static struct omap_kp_platform_data nokia770_kp_data = { | ||
74 | .rows = 8, | ||
75 | .cols = 8, | ||
76 | .keymap = nokia770_keymap | ||
77 | }; | ||
78 | |||
79 | static struct platform_device nokia770_kp_device = { | ||
80 | .name = "omap-keypad", | ||
81 | .id = -1, | ||
82 | .dev = { | ||
83 | .platform_data = &nokia770_kp_data, | ||
84 | }, | ||
85 | .num_resources = ARRAY_SIZE(nokia770_kp_resources), | ||
86 | .resource = nokia770_kp_resources, | ||
87 | }; | ||
88 | |||
89 | static struct platform_device *nokia770_devices[] __initdata = { | ||
90 | &nokia770_kp_device, | ||
91 | }; | ||
92 | |||
93 | static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { | ||
94 | .x_max = 0x0fff, | ||
95 | .y_max = 0x0fff, | ||
96 | .x_plate_ohms = 180, | ||
97 | .pressure_max = 255, | ||
98 | .debounce_max = 10, | ||
99 | .debounce_tol = 3, | ||
100 | }; | ||
101 | |||
102 | static struct spi_board_info nokia770_spi_board_info[] __initdata = { | ||
103 | [0] = { | ||
104 | .modalias = "lcd_lph8923", | ||
105 | .bus_num = 2, | ||
106 | .chip_select = 3, | ||
107 | .max_speed_hz = 12000000, | ||
108 | }, | ||
109 | [1] = { | ||
110 | .modalias = "ads7846", | ||
111 | .bus_num = 2, | ||
112 | .chip_select = 0, | ||
113 | .max_speed_hz = 2500000, | ||
114 | .irq = OMAP_GPIO_IRQ(15), | ||
115 | .platform_data = &nokia770_ads7846_platform_data, | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | |||
120 | /* assume no Mini-AB port */ | ||
121 | |||
122 | static struct omap_usb_config nokia770_usb_config __initdata = { | ||
123 | .otg = 1, | ||
124 | .register_host = 1, | ||
125 | .register_dev = 1, | ||
126 | .hmc_mode = 16, | ||
127 | .pins[0] = 6, | ||
128 | }; | ||
129 | |||
130 | static struct omap_mmc_config nokia770_mmc_config __initdata = { | ||
131 | .mmc[0] = { | ||
132 | .enabled = 0, | ||
133 | .wire4 = 0, | ||
134 | .wp_pin = -1, | ||
135 | .power_pin = -1, | ||
136 | .switch_pin = -1, | ||
137 | }, | ||
138 | .mmc[1] = { | ||
139 | .enabled = 0, | ||
140 | .wire4 = 0, | ||
141 | .wp_pin = -1, | ||
142 | .power_pin = -1, | ||
143 | .switch_pin = -1, | ||
144 | }, | ||
145 | }; | ||
146 | |||
147 | static struct omap_board_config_kernel nokia770_config[] = { | ||
148 | { OMAP_TAG_USB, NULL }, | ||
149 | { OMAP_TAG_MMC, &nokia770_mmc_config }, | ||
150 | }; | ||
151 | |||
152 | /* | ||
153 | * audio power control | ||
154 | */ | ||
155 | #define HEADPHONE_GPIO 14 | ||
156 | #define AMPLIFIER_CTRL_GPIO 58 | ||
157 | |||
158 | static struct clk *dspxor_ck; | ||
159 | static DECLARE_MUTEX(audio_pwr_sem); | ||
160 | /* | ||
161 | * audio_pwr_state | ||
162 | * +--+-------------------------+---------------------------------------+ | ||
163 | * |-1|down |power-up request -> 0 | | ||
164 | * +--+-------------------------+---------------------------------------+ | ||
165 | * | 0|up |power-down(1) request -> 1 | | ||
166 | * | | |power-down(2) request -> (ignore) | | ||
167 | * +--+-------------------------+---------------------------------------+ | ||
168 | * | 1|up, |power-up request -> 0 | | ||
169 | * | |received down(1) request |power-down(2) request -> -1 | | ||
170 | * +--+-------------------------+---------------------------------------+ | ||
171 | */ | ||
172 | static int audio_pwr_state = -1; | ||
173 | |||
174 | /* | ||
175 | * audio_pwr_up / down should be called under audio_pwr_sem | ||
176 | */ | ||
177 | static void nokia770_audio_pwr_up(void) | ||
178 | { | ||
179 | clk_enable(dspxor_ck); | ||
180 | |||
181 | /* Turn on codec */ | ||
182 | tlv320aic23_power_up(); | ||
183 | |||
184 | if (omap_get_gpio_datain(HEADPHONE_GPIO)) | ||
185 | /* HP not connected, turn on amplifier */ | ||
186 | omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1); | ||
187 | else | ||
188 | /* HP connected, do not turn on amplifier */ | ||
189 | printk("HP connected\n"); | ||
190 | } | ||
191 | |||
192 | static void codec_delayed_power_down(void *arg) | ||
193 | { | ||
194 | down(&audio_pwr_sem); | ||
195 | if (audio_pwr_state == -1) | ||
196 | tlv320aic23_power_down(); | ||
197 | clk_disable(dspxor_ck); | ||
198 | up(&audio_pwr_sem); | ||
199 | } | ||
200 | |||
201 | static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); | ||
202 | |||
203 | static void nokia770_audio_pwr_down(void) | ||
204 | { | ||
205 | /* Turn off amplifier */ | ||
206 | omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0); | ||
207 | |||
208 | /* Turn off codec: schedule delayed work */ | ||
209 | schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ | ||
210 | } | ||
211 | |||
212 | void nokia770_audio_pwr_up_request(int stage) | ||
213 | { | ||
214 | down(&audio_pwr_sem); | ||
215 | if (audio_pwr_state == -1) | ||
216 | nokia770_audio_pwr_up(); | ||
217 | /* force audio_pwr_state = 0, even if it was 1. */ | ||
218 | audio_pwr_state = 0; | ||
219 | up(&audio_pwr_sem); | ||
220 | } | ||
221 | |||
222 | void nokia770_audio_pwr_down_request(int stage) | ||
223 | { | ||
224 | down(&audio_pwr_sem); | ||
225 | switch (stage) { | ||
226 | case 1: | ||
227 | if (audio_pwr_state == 0) | ||
228 | audio_pwr_state = 1; | ||
229 | break; | ||
230 | case 2: | ||
231 | if (audio_pwr_state == 1) { | ||
232 | nokia770_audio_pwr_down(); | ||
233 | audio_pwr_state = -1; | ||
234 | } | ||
235 | break; | ||
236 | } | ||
237 | up(&audio_pwr_sem); | ||
238 | } | ||
239 | |||
240 | static void __init omap_nokia770_init(void) | ||
241 | { | ||
242 | nokia770_config[0].data = &nokia770_usb_config; | ||
243 | |||
244 | platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); | ||
245 | spi_register_board_info(nokia770_spi_board_info, | ||
246 | ARRAY_SIZE(nokia770_spi_board_info)); | ||
247 | omap_board_config = nokia770_config; | ||
248 | omap_board_config_size = ARRAY_SIZE(nokia770_config); | ||
249 | omap_serial_init(); | ||
250 | omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request; | ||
251 | omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request; | ||
252 | dspxor_ck = clk_get(0, "dspxor_ck"); | ||
253 | } | ||
254 | |||
255 | static void __init omap_nokia770_map_io(void) | ||
256 | { | ||
257 | omap1_map_common_io(); | ||
258 | } | ||
259 | |||
260 | MACHINE_START(NOKIA770, "Nokia 770") | ||
261 | .phys_io = 0xfff00000, | ||
262 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | ||
263 | .boot_params = 0x10000100, | ||
264 | .map_io = omap_nokia770_map_io, | ||
265 | .init_irq = omap_nokia770_init_irq, | ||
266 | .init_machine = omap_nokia770_init, | ||
267 | .timer = &omap_timer, | ||
268 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 543fa136106d..1160093e8ef6 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
35 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
36 | #include <linux/input.h> | ||
36 | 37 | ||
37 | #include <asm/hardware.h> | 38 | #include <asm/hardware.h> |
38 | #include <asm/mach-types.h> | 39 | #include <asm/mach-types.h> |
@@ -44,7 +45,24 @@ | |||
44 | #include <asm/arch/usb.h> | 45 | #include <asm/arch/usb.h> |
45 | #include <asm/arch/mux.h> | 46 | #include <asm/arch/mux.h> |
46 | #include <asm/arch/tc.h> | 47 | #include <asm/arch/tc.h> |
48 | #include <asm/arch/keypad.h> | ||
47 | #include <asm/arch/common.h> | 49 | #include <asm/arch/common.h> |
50 | #include <asm/arch/mcbsp.h> | ||
51 | #include <asm/arch/omap-alsa.h> | ||
52 | |||
53 | static int osk_keymap[] = { | ||
54 | KEY(0, 0, KEY_F1), | ||
55 | KEY(0, 3, KEY_UP), | ||
56 | KEY(1, 1, KEY_LEFTCTRL), | ||
57 | KEY(1, 2, KEY_LEFT), | ||
58 | KEY(2, 0, KEY_SPACE), | ||
59 | KEY(2, 1, KEY_ESC), | ||
60 | KEY(2, 2, KEY_DOWN), | ||
61 | KEY(3, 2, KEY_ENTER), | ||
62 | KEY(3, 3, KEY_RIGHT), | ||
63 | 0 | ||
64 | }; | ||
65 | |||
48 | 66 | ||
49 | static struct mtd_partition osk_partitions[] = { | 67 | static struct mtd_partition osk_partitions[] = { |
50 | /* bootloader (U-Boot, etc) in first sector */ | 68 | /* bootloader (U-Boot, etc) in first sector */ |
@@ -133,9 +151,69 @@ static struct platform_device osk5912_cf_device = { | |||
133 | .resource = osk5912_cf_resources, | 151 | .resource = osk5912_cf_resources, |
134 | }; | 152 | }; |
135 | 153 | ||
154 | #define DEFAULT_BITPERSAMPLE 16 | ||
155 | |||
156 | static struct omap_mcbsp_reg_cfg mcbsp_regs = { | ||
157 | .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), | ||
158 | .spcr1 = RINTM(3) | RRST, | ||
159 | .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | | ||
160 | RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), | ||
161 | .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), | ||
162 | .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | | ||
163 | XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, | ||
164 | .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), | ||
165 | .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), | ||
166 | .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), | ||
167 | /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ | ||
168 | .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ | ||
169 | }; | ||
170 | |||
171 | static struct omap_alsa_codec_config alsa_config = { | ||
172 | .name = "OSK AIC23", | ||
173 | .mcbsp_regs_alsa = &mcbsp_regs, | ||
174 | .codec_configure_dev = NULL, // aic23_configure, | ||
175 | .codec_set_samplerate = NULL, // aic23_set_samplerate, | ||
176 | .codec_clock_setup = NULL, // aic23_clock_setup, | ||
177 | .codec_clock_on = NULL, // aic23_clock_on, | ||
178 | .codec_clock_off = NULL, // aic23_clock_off, | ||
179 | .get_default_samplerate = NULL, // aic23_get_default_samplerate, | ||
180 | }; | ||
181 | |||
136 | static struct platform_device osk5912_mcbsp1_device = { | 182 | static struct platform_device osk5912_mcbsp1_device = { |
137 | .name = "omap_mcbsp", | 183 | .name = "omap_alsa_mcbsp", |
138 | .id = 1, | 184 | .id = 1, |
185 | .dev = { | ||
186 | .platform_data = &alsa_config, | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | static struct resource osk5912_kp_resources[] = { | ||
191 | [0] = { | ||
192 | .start = INT_KEYBOARD, | ||
193 | .end = INT_KEYBOARD, | ||
194 | .flags = IORESOURCE_IRQ, | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static struct omap_kp_platform_data osk_kp_data = { | ||
199 | .rows = 8, | ||
200 | .cols = 8, | ||
201 | .keymap = osk_keymap, | ||
202 | }; | ||
203 | |||
204 | static struct platform_device osk5912_kp_device = { | ||
205 | .name = "omap-keypad", | ||
206 | .id = -1, | ||
207 | .dev = { | ||
208 | .platform_data = &osk_kp_data, | ||
209 | }, | ||
210 | .num_resources = ARRAY_SIZE(osk5912_kp_resources), | ||
211 | .resource = osk5912_kp_resources, | ||
212 | }; | ||
213 | |||
214 | static struct platform_device osk5912_lcd_device = { | ||
215 | .name = "lcd_osk", | ||
216 | .id = -1, | ||
139 | }; | 217 | }; |
140 | 218 | ||
141 | static struct platform_device *osk5912_devices[] __initdata = { | 219 | static struct platform_device *osk5912_devices[] __initdata = { |
@@ -143,6 +221,8 @@ static struct platform_device *osk5912_devices[] __initdata = { | |||
143 | &osk5912_smc91x_device, | 221 | &osk5912_smc91x_device, |
144 | &osk5912_cf_device, | 222 | &osk5912_cf_device, |
145 | &osk5912_mcbsp1_device, | 223 | &osk5912_mcbsp1_device, |
224 | &osk5912_kp_device, | ||
225 | &osk5912_lcd_device, | ||
146 | }; | 226 | }; |
147 | 227 | ||
148 | static void __init osk_init_smc91x(void) | 228 | static void __init osk_init_smc91x(void) |
@@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = { | |||
197 | }; | 277 | }; |
198 | 278 | ||
199 | static struct omap_lcd_config osk_lcd_config __initdata = { | 279 | static struct omap_lcd_config osk_lcd_config __initdata = { |
200 | .panel_name = "osk", | ||
201 | .ctrl_name = "internal", | 280 | .ctrl_name = "internal", |
202 | }; | 281 | }; |
203 | 282 | ||
@@ -255,8 +334,18 @@ static void __init osk_mistral_init(void) | |||
255 | static void __init osk_mistral_init(void) { } | 334 | static void __init osk_mistral_init(void) { } |
256 | #endif | 335 | #endif |
257 | 336 | ||
337 | #define EMIFS_CS3_VAL (0x88013141) | ||
338 | |||
258 | static void __init osk_init(void) | 339 | static void __init osk_init(void) |
259 | { | 340 | { |
341 | /* Workaround for wrong CS3 (NOR flash) timing | ||
342 | * There are some U-Boot versions out there which configure | ||
343 | * wrong CS3 memory timings. This mainly leads to CRC | ||
344 | * or similiar errors if you use NOR flash (e.g. with JFFS2) | ||
345 | */ | ||
346 | if (EMIFS_CCS(3) != EMIFS_CS3_VAL) | ||
347 | EMIFS_CCS(3) = EMIFS_CS3_VAL; | ||
348 | |||
260 | osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); | 349 | osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); |
261 | osk_flash_resource.end += SZ_32M - 1; | 350 | osk_flash_resource.end += SZ_32M - 1; |
262 | platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); | 351 | platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index e488f7236775..4bc8a62909b9 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
@@ -38,6 +38,15 @@ static void __init omap_generic_init_irq(void) | |||
38 | omap_init_irq(); | 38 | omap_init_irq(); |
39 | } | 39 | } |
40 | 40 | ||
41 | static struct platform_device palmte_lcd_device = { | ||
42 | .name = "lcd_palmte", | ||
43 | .id = -1, | ||
44 | }; | ||
45 | |||
46 | static struct platform_device *devices[] __initdata = { | ||
47 | &palmte_lcd_device, | ||
48 | }; | ||
49 | |||
41 | static struct omap_usb_config palmte_usb_config __initdata = { | 50 | static struct omap_usb_config palmte_usb_config __initdata = { |
42 | .register_dev = 1, | 51 | .register_dev = 1, |
43 | .hmc_mode = 0, | 52 | .hmc_mode = 0, |
@@ -55,7 +64,6 @@ static struct omap_mmc_config palmte_mmc_config __initdata = { | |||
55 | }; | 64 | }; |
56 | 65 | ||
57 | static struct omap_lcd_config palmte_lcd_config __initdata = { | 66 | static struct omap_lcd_config palmte_lcd_config __initdata = { |
58 | .panel_name = "palmte", | ||
59 | .ctrl_name = "internal", | 67 | .ctrl_name = "internal", |
60 | }; | 68 | }; |
61 | 69 | ||
@@ -69,6 +77,8 @@ static void __init omap_generic_init(void) | |||
69 | { | 77 | { |
70 | omap_board_config = palmte_config; | 78 | omap_board_config = palmte_config; |
71 | omap_board_config_size = ARRAY_SIZE(palmte_config); | 79 | omap_board_config_size = ARRAY_SIZE(palmte_config); |
80 | |||
81 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
72 | } | 82 | } |
73 | 83 | ||
74 | static void __init omap_generic_map_io(void) | 84 | static void __init omap_generic_map_io(void) |
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 3913a3cc0ce6..64b45d8ae357 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c | |||
@@ -16,7 +16,9 @@ | |||
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/mtd/mtd.h> | 18 | #include <linux/mtd/mtd.h> |
19 | #include <linux/mtd/nand.h> | ||
19 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
21 | #include <linux/input.h> | ||
20 | 22 | ||
21 | #include <asm/hardware.h> | 23 | #include <asm/hardware.h> |
22 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
@@ -28,9 +30,44 @@ | |||
28 | #include <asm/arch/gpio.h> | 30 | #include <asm/arch/gpio.h> |
29 | #include <asm/arch/mux.h> | 31 | #include <asm/arch/mux.h> |
30 | #include <asm/arch/fpga.h> | 32 | #include <asm/arch/fpga.h> |
33 | #include <asm/arch/keypad.h> | ||
31 | #include <asm/arch/common.h> | 34 | #include <asm/arch/common.h> |
32 | #include <asm/arch/board.h> | 35 | #include <asm/arch/board.h> |
33 | 36 | ||
37 | static int p2_keymap[] = { | ||
38 | KEY(0,0,KEY_UP), | ||
39 | KEY(0,1,KEY_RIGHT), | ||
40 | KEY(0,2,KEY_LEFT), | ||
41 | KEY(0,3,KEY_DOWN), | ||
42 | KEY(0,4,KEY_CENTER), | ||
43 | KEY(0,5,KEY_0_5), | ||
44 | KEY(1,0,KEY_SOFT2), | ||
45 | KEY(1,1,KEY_SEND), | ||
46 | KEY(1,2,KEY_END), | ||
47 | KEY(1,3,KEY_VOLUMEDOWN), | ||
48 | KEY(1,4,KEY_VOLUMEUP), | ||
49 | KEY(1,5,KEY_RECORD), | ||
50 | KEY(2,0,KEY_SOFT1), | ||
51 | KEY(2,1,KEY_3), | ||
52 | KEY(2,2,KEY_6), | ||
53 | KEY(2,3,KEY_9), | ||
54 | KEY(2,4,KEY_SHARP), | ||
55 | KEY(2,5,KEY_2_5), | ||
56 | KEY(3,0,KEY_BACK), | ||
57 | KEY(3,1,KEY_2), | ||
58 | KEY(3,2,KEY_5), | ||
59 | KEY(3,3,KEY_8), | ||
60 | KEY(3,4,KEY_0), | ||
61 | KEY(3,5,KEY_HEADSETHOOK), | ||
62 | KEY(4,0,KEY_HOME), | ||
63 | KEY(4,1,KEY_1), | ||
64 | KEY(4,2,KEY_4), | ||
65 | KEY(4,3,KEY_7), | ||
66 | KEY(4,4,KEY_STAR), | ||
67 | KEY(4,5,KEY_POWER), | ||
68 | 0 | ||
69 | }; | ||
70 | |||
34 | static struct resource smc91x_resources[] = { | 71 | static struct resource smc91x_resources[] = { |
35 | [0] = { | 72 | [0] = { |
36 | .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ | 73 | .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ |
@@ -44,7 +81,7 @@ static struct resource smc91x_resources[] = { | |||
44 | }, | 81 | }, |
45 | }; | 82 | }; |
46 | 83 | ||
47 | static struct mtd_partition p2_partitions[] = { | 84 | static struct mtd_partition nor_partitions[] = { |
48 | /* bootloader (U-Boot, etc) in first sector */ | 85 | /* bootloader (U-Boot, etc) in first sector */ |
49 | { | 86 | { |
50 | .name = "bootloader", | 87 | .name = "bootloader", |
@@ -75,27 +112,47 @@ static struct mtd_partition p2_partitions[] = { | |||
75 | }, | 112 | }, |
76 | }; | 113 | }; |
77 | 114 | ||
78 | static struct flash_platform_data p2_flash_data = { | 115 | static struct flash_platform_data nor_data = { |
79 | .map_name = "cfi_probe", | 116 | .map_name = "cfi_probe", |
80 | .width = 2, | 117 | .width = 2, |
81 | .parts = p2_partitions, | 118 | .parts = nor_partitions, |
82 | .nr_parts = ARRAY_SIZE(p2_partitions), | 119 | .nr_parts = ARRAY_SIZE(nor_partitions), |
83 | }; | 120 | }; |
84 | 121 | ||
85 | static struct resource p2_flash_resource = { | 122 | static struct resource nor_resource = { |
86 | .start = OMAP_CS0_PHYS, | 123 | .start = OMAP_CS0_PHYS, |
87 | .end = OMAP_CS0_PHYS + SZ_32M - 1, | 124 | .end = OMAP_CS0_PHYS + SZ_32M - 1, |
88 | .flags = IORESOURCE_MEM, | 125 | .flags = IORESOURCE_MEM, |
89 | }; | 126 | }; |
90 | 127 | ||
91 | static struct platform_device p2_flash_device = { | 128 | static struct platform_device nor_device = { |
92 | .name = "omapflash", | 129 | .name = "omapflash", |
93 | .id = 0, | 130 | .id = 0, |
94 | .dev = { | 131 | .dev = { |
95 | .platform_data = &p2_flash_data, | 132 | .platform_data = &nor_data, |
133 | }, | ||
134 | .num_resources = 1, | ||
135 | .resource = &nor_resource, | ||
136 | }; | ||
137 | |||
138 | static struct nand_platform_data nand_data = { | ||
139 | .options = NAND_SAMSUNG_LP_OPTIONS, | ||
140 | }; | ||
141 | |||
142 | static struct resource nand_resource = { | ||
143 | .start = OMAP_CS3_PHYS, | ||
144 | .end = OMAP_CS3_PHYS + SZ_4K - 1, | ||
145 | .flags = IORESOURCE_MEM, | ||
146 | }; | ||
147 | |||
148 | static struct platform_device nand_device = { | ||
149 | .name = "omapnand", | ||
150 | .id = 0, | ||
151 | .dev = { | ||
152 | .platform_data = &nand_data, | ||
96 | }, | 153 | }, |
97 | .num_resources = 1, | 154 | .num_resources = 1, |
98 | .resource = &p2_flash_resource, | 155 | .resource = &nand_resource, |
99 | }; | 156 | }; |
100 | 157 | ||
101 | static struct platform_device smc91x_device = { | 158 | static struct platform_device smc91x_device = { |
@@ -105,17 +162,55 @@ static struct platform_device smc91x_device = { | |||
105 | .resource = smc91x_resources, | 162 | .resource = smc91x_resources, |
106 | }; | 163 | }; |
107 | 164 | ||
165 | static struct resource kp_resources[] = { | ||
166 | [0] = { | ||
167 | .start = INT_730_MPUIO_KEYPAD, | ||
168 | .end = INT_730_MPUIO_KEYPAD, | ||
169 | .flags = IORESOURCE_IRQ, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static struct omap_kp_platform_data kp_data = { | ||
174 | .rows = 8, | ||
175 | .cols = 8, | ||
176 | .keymap = p2_keymap, | ||
177 | }; | ||
178 | |||
179 | static struct platform_device kp_device = { | ||
180 | .name = "omap-keypad", | ||
181 | .id = -1, | ||
182 | .dev = { | ||
183 | .platform_data = &kp_data, | ||
184 | }, | ||
185 | .num_resources = ARRAY_SIZE(kp_resources), | ||
186 | .resource = kp_resources, | ||
187 | }; | ||
188 | |||
189 | static struct platform_device lcd_device = { | ||
190 | .name = "lcd_p2", | ||
191 | .id = -1, | ||
192 | }; | ||
193 | |||
108 | static struct platform_device *devices[] __initdata = { | 194 | static struct platform_device *devices[] __initdata = { |
109 | &p2_flash_device, | 195 | &nor_device, |
196 | &nand_device, | ||
110 | &smc91x_device, | 197 | &smc91x_device, |
198 | &kp_device, | ||
199 | &lcd_device, | ||
111 | }; | 200 | }; |
112 | 201 | ||
202 | #define P2_NAND_RB_GPIO_PIN 62 | ||
203 | |||
204 | static int nand_dev_ready(struct nand_platform_data *data) | ||
205 | { | ||
206 | return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN); | ||
207 | } | ||
208 | |||
113 | static struct omap_uart_config perseus2_uart_config __initdata = { | 209 | static struct omap_uart_config perseus2_uart_config __initdata = { |
114 | .enabled_uarts = ((1 << 0) | (1 << 1)), | 210 | .enabled_uarts = ((1 << 0) | (1 << 1)), |
115 | }; | 211 | }; |
116 | 212 | ||
117 | static struct omap_lcd_config perseus2_lcd_config __initdata = { | 213 | static struct omap_lcd_config perseus2_lcd_config __initdata = { |
118 | .panel_name = "p2", | ||
119 | .ctrl_name = "internal", | 214 | .ctrl_name = "internal", |
120 | }; | 215 | }; |
121 | 216 | ||
@@ -126,7 +221,13 @@ static struct omap_board_config_kernel perseus2_config[] = { | |||
126 | 221 | ||
127 | static void __init omap_perseus2_init(void) | 222 | static void __init omap_perseus2_init(void) |
128 | { | 223 | { |
129 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 224 | if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN))) |
225 | nand_data.dev_ready = nand_dev_ready; | ||
226 | |||
227 | omap_cfg_reg(L3_1610_FLASH_CS2B_OE); | ||
228 | omap_cfg_reg(M8_1610_FLASH_CS2B_WE); | ||
229 | |||
230 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
130 | 231 | ||
131 | omap_board_config = perseus2_config; | 232 | omap_board_config = perseus2_config; |
132 | omap_board_config_size = ARRAY_SIZE(perseus2_config); | 233 | omap_board_config_size = ARRAY_SIZE(perseus2_config); |
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 52e4a9d69642..447a586eb334 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
@@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | static struct omap_board_config_kernel voiceblue_config[] = { | 157 | static struct omap_board_config_kernel voiceblue_config[] = { |
158 | { OMAP_TAG_USB, &voiceblue_usb_config }, | 158 | { OMAP_TAG_USB, &voiceblue_usb_config }, |
159 | { OMAP_TAG_MMC, &voiceblue_mmc_config }, | 159 | { OMAP_TAG_MMC, &voiceblue_mmc_config }, |
160 | { OMAP_TAG_UART, &voiceblue_uart_config }, | 160 | { OMAP_TAG_UART, &voiceblue_uart_config }, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static void __init voiceblue_init_irq(void) | 163 | static void __init voiceblue_init_irq(void) |
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = { | |||
235 | static int __init voiceblue_setup(void) | 235 | static int __init voiceblue_setup(void) |
236 | { | 236 | { |
237 | /* Setup panic notifier */ | 237 | /* Setup panic notifier */ |
238 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 238 | notifier_chain_register(&panic_notifier_list, &panic_block); |
239 | 239 | ||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 75110ba10424..619db18144ea 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c | |||
@@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate) | |||
345 | */ | 345 | */ |
346 | for (dsor = 2; dsor < 96; ++dsor) { | 346 | for (dsor = 2; dsor < 96; ++dsor) { |
347 | if ((dsor & 1) && dsor > 8) | 347 | if ((dsor & 1) && dsor > 8) |
348 | continue; | 348 | continue; |
349 | if (rate >= 96000000 / dsor) | 349 | if (rate >= 96000000 / dsor) |
350 | break; | 350 | break; |
351 | } | 351 | } |
@@ -687,6 +687,11 @@ int __init omap1_clk_init(void) | |||
687 | clk_register(*clkp); | 687 | clk_register(*clkp); |
688 | continue; | 688 | continue; |
689 | } | 689 | } |
690 | |||
691 | if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) { | ||
692 | clk_register(*clkp); | ||
693 | continue; | ||
694 | } | ||
690 | } | 695 | } |
691 | 696 | ||
692 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); | 697 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); |
@@ -784,7 +789,7 @@ int __init omap1_clk_init(void) | |||
784 | clk_enable(&armxor_ck.clk); | 789 | clk_enable(&armxor_ck.clk); |
785 | clk_enable(&armtim_ck.clk); /* This should be done by timer code */ | 790 | clk_enable(&armtim_ck.clk); /* This should be done by timer code */ |
786 | 791 | ||
787 | if (cpu_is_omap1510()) | 792 | if (cpu_is_omap15xx()) |
788 | clk_enable(&arm_gpio_ck); | 793 | clk_enable(&arm_gpio_ck); |
789 | 794 | ||
790 | return 0; | 795 | return 0; |
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 4f18d1b94449..b7c68819c4e7 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h | |||
@@ -151,7 +151,7 @@ static struct clk ck_ref = { | |||
151 | .name = "ck_ref", | 151 | .name = "ck_ref", |
152 | .rate = 12000000, | 152 | .rate = 12000000, |
153 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 153 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
154 | ALWAYS_ENABLED, | 154 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, |
155 | .enable = &omap1_clk_enable_generic, | 155 | .enable = &omap1_clk_enable_generic, |
156 | .disable = &omap1_clk_disable_generic, | 156 | .disable = &omap1_clk_disable_generic, |
157 | }; | 157 | }; |
@@ -160,7 +160,7 @@ static struct clk ck_dpll1 = { | |||
160 | .name = "ck_dpll1", | 160 | .name = "ck_dpll1", |
161 | .parent = &ck_ref, | 161 | .parent = &ck_ref, |
162 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 162 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
163 | RATE_PROPAGATES | ALWAYS_ENABLED, | 163 | CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED, |
164 | .enable = &omap1_clk_enable_generic, | 164 | .enable = &omap1_clk_enable_generic, |
165 | .disable = &omap1_clk_disable_generic, | 165 | .disable = &omap1_clk_disable_generic, |
166 | }; | 166 | }; |
@@ -183,7 +183,8 @@ static struct clk arm_ck = { | |||
183 | .name = "arm_ck", | 183 | .name = "arm_ck", |
184 | .parent = &ck_dpll1, | 184 | .parent = &ck_dpll1, |
185 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 185 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
186 | RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, | 186 | CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES | |
187 | ALWAYS_ENABLED, | ||
187 | .rate_offset = CKCTL_ARMDIV_OFFSET, | 188 | .rate_offset = CKCTL_ARMDIV_OFFSET, |
188 | .recalc = &omap1_ckctl_recalc, | 189 | .recalc = &omap1_ckctl_recalc, |
189 | .enable = &omap1_clk_enable_generic, | 190 | .enable = &omap1_clk_enable_generic, |
@@ -195,7 +196,8 @@ static struct arm_idlect1_clk armper_ck = { | |||
195 | .name = "armper_ck", | 196 | .name = "armper_ck", |
196 | .parent = &ck_dpll1, | 197 | .parent = &ck_dpll1, |
197 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 198 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
198 | RATE_CKCTL | CLOCK_IDLE_CONTROL, | 199 | CLOCK_IN_OMAP310 | RATE_CKCTL | |
200 | CLOCK_IDLE_CONTROL, | ||
199 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 201 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
200 | .enable_bit = EN_PERCK, | 202 | .enable_bit = EN_PERCK, |
201 | .rate_offset = CKCTL_PERDIV_OFFSET, | 203 | .rate_offset = CKCTL_PERDIV_OFFSET, |
@@ -209,7 +211,7 @@ static struct arm_idlect1_clk armper_ck = { | |||
209 | static struct clk arm_gpio_ck = { | 211 | static struct clk arm_gpio_ck = { |
210 | .name = "arm_gpio_ck", | 212 | .name = "arm_gpio_ck", |
211 | .parent = &ck_dpll1, | 213 | .parent = &ck_dpll1, |
212 | .flags = CLOCK_IN_OMAP1510, | 214 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, |
213 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 215 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
214 | .enable_bit = EN_GPIOCK, | 216 | .enable_bit = EN_GPIOCK, |
215 | .recalc = &followparent_recalc, | 217 | .recalc = &followparent_recalc, |
@@ -222,7 +224,7 @@ static struct arm_idlect1_clk armxor_ck = { | |||
222 | .name = "armxor_ck", | 224 | .name = "armxor_ck", |
223 | .parent = &ck_ref, | 225 | .parent = &ck_ref, |
224 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 226 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
225 | CLOCK_IDLE_CONTROL, | 227 | CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, |
226 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 228 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
227 | .enable_bit = EN_XORPCK, | 229 | .enable_bit = EN_XORPCK, |
228 | .recalc = &followparent_recalc, | 230 | .recalc = &followparent_recalc, |
@@ -237,7 +239,7 @@ static struct arm_idlect1_clk armtim_ck = { | |||
237 | .name = "armtim_ck", | 239 | .name = "armtim_ck", |
238 | .parent = &ck_ref, | 240 | .parent = &ck_ref, |
239 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 241 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
240 | CLOCK_IDLE_CONTROL, | 242 | CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, |
241 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 243 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
242 | .enable_bit = EN_TIMCK, | 244 | .enable_bit = EN_TIMCK, |
243 | .recalc = &followparent_recalc, | 245 | .recalc = &followparent_recalc, |
@@ -252,7 +254,7 @@ static struct arm_idlect1_clk armwdt_ck = { | |||
252 | .name = "armwdt_ck", | 254 | .name = "armwdt_ck", |
253 | .parent = &ck_ref, | 255 | .parent = &ck_ref, |
254 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 256 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
255 | CLOCK_IDLE_CONTROL, | 257 | CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, |
256 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 258 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
257 | .enable_bit = EN_WDTCK, | 259 | .enable_bit = EN_WDTCK, |
258 | .recalc = &omap1_watchdog_recalc, | 260 | .recalc = &omap1_watchdog_recalc, |
@@ -344,9 +346,9 @@ static struct arm_idlect1_clk tc_ck = { | |||
344 | .name = "tc_ck", | 346 | .name = "tc_ck", |
345 | .parent = &ck_dpll1, | 347 | .parent = &ck_dpll1, |
346 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 348 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
347 | CLOCK_IN_OMAP730 | RATE_CKCTL | | 349 | CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | |
348 | RATE_PROPAGATES | ALWAYS_ENABLED | | 350 | RATE_CKCTL | RATE_PROPAGATES | |
349 | CLOCK_IDLE_CONTROL, | 351 | ALWAYS_ENABLED | CLOCK_IDLE_CONTROL, |
350 | .rate_offset = CKCTL_TCDIV_OFFSET, | 352 | .rate_offset = CKCTL_TCDIV_OFFSET, |
351 | .recalc = &omap1_ckctl_recalc, | 353 | .recalc = &omap1_ckctl_recalc, |
352 | .enable = &omap1_clk_enable_generic, | 354 | .enable = &omap1_clk_enable_generic, |
@@ -358,7 +360,8 @@ static struct arm_idlect1_clk tc_ck = { | |||
358 | static struct clk arminth_ck1510 = { | 360 | static struct clk arminth_ck1510 = { |
359 | .name = "arminth_ck", | 361 | .name = "arminth_ck", |
360 | .parent = &tc_ck.clk, | 362 | .parent = &tc_ck.clk, |
361 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | 363 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
364 | ALWAYS_ENABLED, | ||
362 | .recalc = &followparent_recalc, | 365 | .recalc = &followparent_recalc, |
363 | /* Note: On 1510 the frequency follows TC_CK | 366 | /* Note: On 1510 the frequency follows TC_CK |
364 | * | 367 | * |
@@ -372,7 +375,8 @@ static struct clk tipb_ck = { | |||
372 | /* No-idle controlled by "tc_ck" */ | 375 | /* No-idle controlled by "tc_ck" */ |
373 | .name = "tibp_ck", | 376 | .name = "tibp_ck", |
374 | .parent = &tc_ck.clk, | 377 | .parent = &tc_ck.clk, |
375 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | 378 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
379 | ALWAYS_ENABLED, | ||
376 | .recalc = &followparent_recalc, | 380 | .recalc = &followparent_recalc, |
377 | .enable = &omap1_clk_enable_generic, | 381 | .enable = &omap1_clk_enable_generic, |
378 | .disable = &omap1_clk_disable_generic, | 382 | .disable = &omap1_clk_disable_generic, |
@@ -417,7 +421,7 @@ static struct clk dma_ck = { | |||
417 | .name = "dma_ck", | 421 | .name = "dma_ck", |
418 | .parent = &tc_ck.clk, | 422 | .parent = &tc_ck.clk, |
419 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 423 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
420 | ALWAYS_ENABLED, | 424 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, |
421 | .recalc = &followparent_recalc, | 425 | .recalc = &followparent_recalc, |
422 | .enable = &omap1_clk_enable_generic, | 426 | .enable = &omap1_clk_enable_generic, |
423 | .disable = &omap1_clk_disable_generic, | 427 | .disable = &omap1_clk_disable_generic, |
@@ -437,7 +441,7 @@ static struct arm_idlect1_clk api_ck = { | |||
437 | .name = "api_ck", | 441 | .name = "api_ck", |
438 | .parent = &tc_ck.clk, | 442 | .parent = &tc_ck.clk, |
439 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 443 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
440 | CLOCK_IDLE_CONTROL, | 444 | CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, |
441 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 445 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
442 | .enable_bit = EN_APICK, | 446 | .enable_bit = EN_APICK, |
443 | .recalc = &followparent_recalc, | 447 | .recalc = &followparent_recalc, |
@@ -451,7 +455,8 @@ static struct arm_idlect1_clk lb_ck = { | |||
451 | .clk = { | 455 | .clk = { |
452 | .name = "lb_ck", | 456 | .name = "lb_ck", |
453 | .parent = &tc_ck.clk, | 457 | .parent = &tc_ck.clk, |
454 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, | 458 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
459 | CLOCK_IDLE_CONTROL, | ||
455 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 460 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
456 | .enable_bit = EN_LBCK, | 461 | .enable_bit = EN_LBCK, |
457 | .recalc = &followparent_recalc, | 462 | .recalc = &followparent_recalc, |
@@ -495,8 +500,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = { | |||
495 | .clk = { | 500 | .clk = { |
496 | .name = "lcd_ck", | 501 | .name = "lcd_ck", |
497 | .parent = &ck_dpll1, | 502 | .parent = &ck_dpll1, |
498 | .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | | 503 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
499 | CLOCK_IDLE_CONTROL, | 504 | RATE_CKCTL | CLOCK_IDLE_CONTROL, |
500 | .enable_reg = (void __iomem *)ARM_IDLECT2, | 505 | .enable_reg = (void __iomem *)ARM_IDLECT2, |
501 | .enable_bit = EN_LCDCK, | 506 | .enable_bit = EN_LCDCK, |
502 | .rate_offset = CKCTL_LCDDIV_OFFSET, | 507 | .rate_offset = CKCTL_LCDDIV_OFFSET, |
@@ -512,8 +517,9 @@ static struct clk uart1_1510 = { | |||
512 | /* Direct from ULPD, no real parent */ | 517 | /* Direct from ULPD, no real parent */ |
513 | .parent = &armper_ck.clk, | 518 | .parent = &armper_ck.clk, |
514 | .rate = 12000000, | 519 | .rate = 12000000, |
515 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | | 520 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
516 | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, | 521 | ENABLE_REG_32BIT | ALWAYS_ENABLED | |
522 | CLOCK_NO_IDLE_PARENT, | ||
517 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | 523 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, |
518 | .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ | 524 | .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ |
519 | .set_rate = &omap1_set_uart_rate, | 525 | .set_rate = &omap1_set_uart_rate, |
@@ -544,8 +550,8 @@ static struct clk uart2_ck = { | |||
544 | .parent = &armper_ck.clk, | 550 | .parent = &armper_ck.clk, |
545 | .rate = 12000000, | 551 | .rate = 12000000, |
546 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 552 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
547 | ENABLE_REG_32BIT | ALWAYS_ENABLED | | 553 | CLOCK_IN_OMAP310 | ENABLE_REG_32BIT | |
548 | CLOCK_NO_IDLE_PARENT, | 554 | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, |
549 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | 555 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, |
550 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ | 556 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ |
551 | .set_rate = &omap1_set_uart_rate, | 557 | .set_rate = &omap1_set_uart_rate, |
@@ -559,8 +565,9 @@ static struct clk uart3_1510 = { | |||
559 | /* Direct from ULPD, no real parent */ | 565 | /* Direct from ULPD, no real parent */ |
560 | .parent = &armper_ck.clk, | 566 | .parent = &armper_ck.clk, |
561 | .rate = 12000000, | 567 | .rate = 12000000, |
562 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | | 568 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
563 | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, | 569 | ENABLE_REG_32BIT | ALWAYS_ENABLED | |
570 | CLOCK_NO_IDLE_PARENT, | ||
564 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | 571 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, |
565 | .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ | 572 | .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ |
566 | .set_rate = &omap1_set_uart_rate, | 573 | .set_rate = &omap1_set_uart_rate, |
@@ -590,7 +597,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ | |||
590 | /* Direct from ULPD, no parent */ | 597 | /* Direct from ULPD, no parent */ |
591 | .rate = 6000000, | 598 | .rate = 6000000, |
592 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 599 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
593 | RATE_FIXED | ENABLE_REG_32BIT, | 600 | CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT, |
594 | .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, | 601 | .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, |
595 | .enable_bit = USB_MCLK_EN_BIT, | 602 | .enable_bit = USB_MCLK_EN_BIT, |
596 | .enable = &omap1_clk_enable_generic, | 603 | .enable = &omap1_clk_enable_generic, |
@@ -601,7 +608,7 @@ static struct clk usb_hhc_ck1510 = { | |||
601 | .name = "usb_hhc_ck", | 608 | .name = "usb_hhc_ck", |
602 | /* Direct from ULPD, no parent */ | 609 | /* Direct from ULPD, no parent */ |
603 | .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ | 610 | .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ |
604 | .flags = CLOCK_IN_OMAP1510 | | 611 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | |
605 | RATE_FIXED | ENABLE_REG_32BIT, | 612 | RATE_FIXED | ENABLE_REG_32BIT, |
606 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | 613 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, |
607 | .enable_bit = USB_HOST_HHC_UHOST_EN, | 614 | .enable_bit = USB_HOST_HHC_UHOST_EN, |
@@ -637,7 +644,9 @@ static struct clk mclk_1510 = { | |||
637 | .name = "mclk", | 644 | .name = "mclk", |
638 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | 645 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ |
639 | .rate = 12000000, | 646 | .rate = 12000000, |
640 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | 647 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED, |
648 | .enable_reg = (void __iomem *)SOFT_REQ_REG, | ||
649 | .enable_bit = 6, | ||
641 | .enable = &omap1_clk_enable_generic, | 650 | .enable = &omap1_clk_enable_generic, |
642 | .disable = &omap1_clk_disable_generic, | 651 | .disable = &omap1_clk_disable_generic, |
643 | }; | 652 | }; |
@@ -659,7 +668,7 @@ static struct clk bclk_1510 = { | |||
659 | .name = "bclk", | 668 | .name = "bclk", |
660 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | 669 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ |
661 | .rate = 12000000, | 670 | .rate = 12000000, |
662 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | 671 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED, |
663 | .enable = &omap1_clk_enable_generic, | 672 | .enable = &omap1_clk_enable_generic, |
664 | .disable = &omap1_clk_disable_generic, | 673 | .disable = &omap1_clk_disable_generic, |
665 | }; | 674 | }; |
@@ -678,12 +687,14 @@ static struct clk bclk_16xx = { | |||
678 | }; | 687 | }; |
679 | 688 | ||
680 | static struct clk mmc1_ck = { | 689 | static struct clk mmc1_ck = { |
681 | .name = "mmc1_ck", | 690 | .name = "mmc_ck", |
691 | .id = 1, | ||
682 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | 692 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ |
683 | .parent = &armper_ck.clk, | 693 | .parent = &armper_ck.clk, |
684 | .rate = 48000000, | 694 | .rate = 48000000, |
685 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 695 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
686 | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, | 696 | CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT | |
697 | CLOCK_NO_IDLE_PARENT, | ||
687 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | 698 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, |
688 | .enable_bit = 23, | 699 | .enable_bit = 23, |
689 | .enable = &omap1_clk_enable_generic, | 700 | .enable = &omap1_clk_enable_generic, |
@@ -691,7 +702,8 @@ static struct clk mmc1_ck = { | |||
691 | }; | 702 | }; |
692 | 703 | ||
693 | static struct clk mmc2_ck = { | 704 | static struct clk mmc2_ck = { |
694 | .name = "mmc2_ck", | 705 | .name = "mmc_ck", |
706 | .id = 2, | ||
695 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | 707 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ |
696 | .parent = &armper_ck.clk, | 708 | .parent = &armper_ck.clk, |
697 | .rate = 48000000, | 709 | .rate = 48000000, |
@@ -706,7 +718,7 @@ static struct clk mmc2_ck = { | |||
706 | static struct clk virtual_ck_mpu = { | 718 | static struct clk virtual_ck_mpu = { |
707 | .name = "mpu", | 719 | .name = "mpu", |
708 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 720 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
709 | VIRTUAL_CLOCK | ALWAYS_ENABLED, | 721 | CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED, |
710 | .parent = &arm_ck, /* Is smarter alias for */ | 722 | .parent = &arm_ck, /* Is smarter alias for */ |
711 | .recalc = &followparent_recalc, | 723 | .recalc = &followparent_recalc, |
712 | .set_rate = &omap1_select_table_rate, | 724 | .set_rate = &omap1_select_table_rate, |
@@ -715,6 +727,20 @@ static struct clk virtual_ck_mpu = { | |||
715 | .disable = &omap1_clk_disable_generic, | 727 | .disable = &omap1_clk_disable_generic, |
716 | }; | 728 | }; |
717 | 729 | ||
730 | /* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK | ||
731 | remains active during MPU idle whenever this is enabled */ | ||
732 | static struct clk i2c_fck = { | ||
733 | .name = "i2c_fck", | ||
734 | .id = 1, | ||
735 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
736 | VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | | ||
737 | ALWAYS_ENABLED, | ||
738 | .parent = &armxor_ck.clk, | ||
739 | .recalc = &followparent_recalc, | ||
740 | .enable = &omap1_clk_enable_generic, | ||
741 | .disable = &omap1_clk_disable_generic, | ||
742 | }; | ||
743 | |||
718 | static struct clk * onchip_clks[] = { | 744 | static struct clk * onchip_clks[] = { |
719 | /* non-ULPD clocks */ | 745 | /* non-ULPD clocks */ |
720 | &ck_ref, | 746 | &ck_ref, |
@@ -763,6 +789,7 @@ static struct clk * onchip_clks[] = { | |||
763 | &mmc2_ck, | 789 | &mmc2_ck, |
764 | /* Virtual clocks */ | 790 | /* Virtual clocks */ |
765 | &virtual_ck_mpu, | 791 | &virtual_ck_mpu, |
792 | &i2c_fck, | ||
766 | }; | 793 | }; |
767 | 794 | ||
768 | #endif | 795 | #endif |
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index ecbc47514adc..876c38da14f7 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
@@ -99,6 +99,45 @@ static void omap_init_rtc(void) | |||
99 | static inline void omap_init_rtc(void) {} | 99 | static inline void omap_init_rtc(void) {} |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | #if defined(CONFIG_OMAP_STI) | ||
103 | |||
104 | #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) | ||
105 | #define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400) | ||
106 | |||
107 | static struct resource sti_resources[] = { | ||
108 | { | ||
109 | .start = OMAP1_STI_BASE, | ||
110 | .end = OMAP1_STI_BASE + SZ_1K - 1, | ||
111 | .flags = IORESOURCE_MEM, | ||
112 | }, | ||
113 | { | ||
114 | .start = OMAP1_STI_CHANNEL_BASE, | ||
115 | .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1, | ||
116 | .flags = IORESOURCE_MEM, | ||
117 | }, | ||
118 | { | ||
119 | .start = INT_1610_STI, | ||
120 | .flags = IORESOURCE_IRQ, | ||
121 | } | ||
122 | }; | ||
123 | |||
124 | static struct platform_device sti_device = { | ||
125 | .name = "sti", | ||
126 | .id = -1, | ||
127 | .dev = { | ||
128 | .release = omap_nop_release, | ||
129 | }, | ||
130 | .num_resources = ARRAY_SIZE(sti_resources), | ||
131 | .resource = sti_resources, | ||
132 | }; | ||
133 | |||
134 | static inline void omap_init_sti(void) | ||
135 | { | ||
136 | platform_device_register(&sti_device); | ||
137 | } | ||
138 | #else | ||
139 | static inline void omap_init_sti(void) {} | ||
140 | #endif | ||
102 | 141 | ||
103 | /*-------------------------------------------------------------------------*/ | 142 | /*-------------------------------------------------------------------------*/ |
104 | 143 | ||
@@ -129,6 +168,7 @@ static int __init omap1_init_devices(void) | |||
129 | */ | 168 | */ |
130 | omap_init_irda(); | 169 | omap_init_irda(); |
131 | omap_init_rtc(); | 170 | omap_init_rtc(); |
171 | omap_init_sti(); | ||
132 | 172 | ||
133 | return 0; | 173 | return 0; |
134 | } | 174 | } |
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 82d556be79c5..be3a2a4ee2b8 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/arch/mux.h> | 19 | #include <asm/arch/mux.h> |
20 | #include <asm/arch/tc.h> | 20 | #include <asm/arch/tc.h> |
21 | #include <asm/arch/omapfb.h> | ||
21 | 22 | ||
22 | extern int omap1_clk_init(void); | 23 | extern int omap1_clk_init(void); |
23 | extern void omap_check_revision(void); | 24 | extern void omap_check_revision(void); |
@@ -110,7 +111,7 @@ void __init omap1_map_common_io(void) | |||
110 | } | 111 | } |
111 | #endif | 112 | #endif |
112 | #ifdef CONFIG_ARCH_OMAP15XX | 113 | #ifdef CONFIG_ARCH_OMAP15XX |
113 | if (cpu_is_omap1510()) { | 114 | if (cpu_is_omap15xx()) { |
114 | iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); | 115 | iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); |
115 | } | 116 | } |
116 | #endif | 117 | #endif |
@@ -121,6 +122,7 @@ void __init omap1_map_common_io(void) | |||
121 | #endif | 122 | #endif |
122 | 123 | ||
123 | omap_sram_init(); | 124 | omap_sram_init(); |
125 | omapfb_reserve_mem(); | ||
124 | } | 126 | } |
125 | 127 | ||
126 | /* | 128 | /* |
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index ed65a7d2e941..a0431c00fa81 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c | |||
@@ -60,7 +60,7 @@ struct omap_irq_bank { | |||
60 | unsigned long wake_enable; | 60 | unsigned long wake_enable; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static unsigned int irq_bank_count = 0; | 63 | static unsigned int irq_bank_count; |
64 | static struct omap_irq_bank *irq_banks; | 64 | static struct omap_irq_bank *irq_banks; |
65 | 65 | ||
66 | static inline unsigned int irq_bank_readl(int bank, int offset) | 66 | static inline unsigned int irq_bank_readl(int bank, int offset) |
@@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger) | |||
142 | 142 | ||
143 | #ifdef CONFIG_ARCH_OMAP730 | 143 | #ifdef CONFIG_ARCH_OMAP730 |
144 | static struct omap_irq_bank omap730_irq_banks[] = { | 144 | static struct omap_irq_bank omap730_irq_banks[] = { |
145 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, | 145 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, |
146 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, | 146 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, |
147 | { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, | 147 | { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, |
148 | }; | 148 | }; |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | #ifdef CONFIG_ARCH_OMAP15XX | 151 | #ifdef CONFIG_ARCH_OMAP15XX |
152 | static struct omap_irq_bank omap1510_irq_banks[] = { | 152 | static struct omap_irq_bank omap1510_irq_banks[] = { |
153 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, | 153 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, |
154 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, | 154 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, |
155 | }; | 155 | }; |
156 | static struct omap_irq_bank omap310_irq_banks[] = { | 156 | static struct omap_irq_bank omap310_irq_banks[] = { |
157 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, | 157 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, |
158 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, | 158 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, |
159 | }; | 159 | }; |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | #if defined(CONFIG_ARCH_OMAP16XX) | 162 | #if defined(CONFIG_ARCH_OMAP16XX) |
163 | 163 | ||
164 | static struct omap_irq_bank omap1610_irq_banks[] = { | 164 | static struct omap_irq_bank omap1610_irq_banks[] = { |
165 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, | 165 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, |
166 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, | 166 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, |
167 | { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, | 167 | { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, |
168 | { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, | 168 | { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, |
169 | }; | 169 | }; |
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index d4b8d624e742..10fe0b3efcac 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c | |||
@@ -35,16 +35,20 @@ | |||
35 | 35 | ||
36 | #ifdef CONFIG_ARCH_OMAP730 | 36 | #ifdef CONFIG_ARCH_OMAP730 |
37 | struct pin_config __initdata_or_module omap730_pins[] = { | 37 | struct pin_config __initdata_or_module omap730_pins[] = { |
38 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) | 38 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) |
39 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) | 39 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) |
40 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) | 40 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) |
41 | MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) | 41 | MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0) |
42 | MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) | 42 | MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0) |
43 | MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) | 43 | MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0) |
44 | MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) | 44 | MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0) |
45 | MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) | 45 | MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0) |
46 | MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) | 46 | MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0) |
47 | MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) | 47 | MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0) |
48 | |||
49 | MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0) | ||
50 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) | ||
51 | MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) | ||
48 | }; | 52 | }; |
49 | #endif | 53 | #endif |
50 | 54 | ||
@@ -73,8 +77,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0) | |||
73 | MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) | 77 | MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) |
74 | 78 | ||
75 | /* PWT & PWL, conflicts with UART3 */ | 79 | /* PWT & PWL, conflicts with UART3 */ |
76 | MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) | 80 | MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) |
77 | MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) | 81 | MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) |
78 | 82 | ||
79 | /* USB internal master generic */ | 83 | /* USB internal master generic */ |
80 | MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) | 84 | MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) |
@@ -151,7 +155,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1) | |||
151 | 155 | ||
152 | /* Misc ballouts */ | 156 | /* Misc ballouts */ |
153 | MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) | 157 | MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) |
154 | MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) | 158 | MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) |
155 | 159 | ||
156 | /* OMAP-1610 MMC2 */ | 160 | /* OMAP-1610 MMC2 */ |
157 | MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) | 161 | MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) |
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c new file mode 100644 index 000000000000..ddf6b07dc9c7 --- /dev/null +++ b/arch/arm/mach-omap1/pm.c | |||
@@ -0,0 +1,770 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/pm.c | ||
3 | * | ||
4 | * OMAP Power Management Routines | ||
5 | * | ||
6 | * Original code for the SA11x0: | ||
7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> | ||
8 | * | ||
9 | * Modified for the PXA250 by Nicolas Pitre: | ||
10 | * Copyright (c) 2002 Monta Vista Software, Inc. | ||
11 | * | ||
12 | * Modified for the OMAP1510 by David Singleton: | ||
13 | * Copyright (c) 2002 Monta Vista Software, Inc. | ||
14 | * | ||
15 | * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify it | ||
18 | * under the terms of the GNU General Public License as published by the | ||
19 | * Free Software Foundation; either version 2 of the License, or (at your | ||
20 | * option) any later version. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
25 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
28 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
29 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | ||
33 | * You should have received a copy of the GNU General Public License along | ||
34 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
35 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
36 | */ | ||
37 | |||
38 | #include <linux/pm.h> | ||
39 | #include <linux/sched.h> | ||
40 | #include <linux/proc_fs.h> | ||
41 | #include <linux/pm.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/sysfs.h> | ||
44 | #include <linux/module.h> | ||
45 | |||
46 | #include <asm/io.h> | ||
47 | #include <asm/irq.h> | ||
48 | #include <asm/atomic.h> | ||
49 | #include <asm/mach/time.h> | ||
50 | #include <asm/mach/irq.h> | ||
51 | #include <asm/mach-types.h> | ||
52 | |||
53 | #include <asm/arch/irqs.h> | ||
54 | #include <asm/arch/clock.h> | ||
55 | #include <asm/arch/sram.h> | ||
56 | #include <asm/arch/tc.h> | ||
57 | #include <asm/arch/pm.h> | ||
58 | #include <asm/arch/mux.h> | ||
59 | #include <asm/arch/tps65010.h> | ||
60 | #include <asm/arch/dma.h> | ||
61 | #include <asm/arch/dsp_common.h> | ||
62 | #include <asm/arch/dmtimer.h> | ||
63 | |||
64 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; | ||
65 | static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE]; | ||
66 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; | ||
67 | static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; | ||
68 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; | ||
69 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | ||
70 | |||
71 | static unsigned short enable_dyn_sleep = 1; | ||
72 | |||
73 | static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf) | ||
74 | { | ||
75 | return sprintf(buf, "%hu\n", enable_dyn_sleep); | ||
76 | } | ||
77 | |||
78 | static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys, | ||
79 | const char * buf, | ||
80 | size_t n) | ||
81 | { | ||
82 | unsigned short value; | ||
83 | if (sscanf(buf, "%hu", &value) != 1 || | ||
84 | (value != 0 && value != 1)) { | ||
85 | printk(KERN_ERR "idle_sleep_store: Invalid value\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | enable_dyn_sleep = value; | ||
89 | return n; | ||
90 | } | ||
91 | |||
92 | static struct subsys_attribute sleep_while_idle_attr = { | ||
93 | .attr = { | ||
94 | .name = __stringify(sleep_while_idle), | ||
95 | .mode = 0644, | ||
96 | }, | ||
97 | .show = omap_pm_sleep_while_idle_show, | ||
98 | .store = omap_pm_sleep_while_idle_store, | ||
99 | }; | ||
100 | |||
101 | extern struct subsystem power_subsys; | ||
102 | static void (*omap_sram_idle)(void) = NULL; | ||
103 | static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; | ||
104 | |||
105 | /* | ||
106 | * Let's power down on idle, but only if we are really | ||
107 | * idle, because once we start down the path of | ||
108 | * going idle we continue to do idle even if we get | ||
109 | * a clock tick interrupt . . | ||
110 | */ | ||
111 | void omap_pm_idle(void) | ||
112 | { | ||
113 | extern __u32 arm_idlect1_mask; | ||
114 | __u32 use_idlect1 = arm_idlect1_mask; | ||
115 | #ifndef CONFIG_OMAP_MPU_TIMER | ||
116 | int do_sleep; | ||
117 | #endif | ||
118 | |||
119 | local_irq_disable(); | ||
120 | local_fiq_disable(); | ||
121 | if (need_resched()) { | ||
122 | local_fiq_enable(); | ||
123 | local_irq_enable(); | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Since an interrupt may set up a timer, we don't want to | ||
129 | * reprogram the hardware timer with interrupts enabled. | ||
130 | * Re-enable interrupts only after returning from idle. | ||
131 | */ | ||
132 | timer_dyn_reprogram(); | ||
133 | |||
134 | #ifdef CONFIG_OMAP_MPU_TIMER | ||
135 | #warning Enable 32kHz OS timer in order to allow sleep states in idle | ||
136 | use_idlect1 = use_idlect1 & ~(1 << 9); | ||
137 | #else | ||
138 | |||
139 | do_sleep = 0; | ||
140 | while (enable_dyn_sleep) { | ||
141 | |||
142 | #ifdef CONFIG_CBUS_TAHVO_USB | ||
143 | extern int vbus_active; | ||
144 | /* Clock requirements? */ | ||
145 | if (vbus_active) | ||
146 | break; | ||
147 | #endif | ||
148 | do_sleep = 1; | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | #ifdef CONFIG_OMAP_DM_TIMER | ||
153 | use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1); | ||
154 | #endif | ||
155 | |||
156 | if (omap_dma_running()) { | ||
157 | use_idlect1 &= ~(1 << 6); | ||
158 | if (omap_lcd_dma_ext_running()) | ||
159 | use_idlect1 &= ~(1 << 12); | ||
160 | } | ||
161 | |||
162 | /* We should be able to remove the do_sleep variable and multiple | ||
163 | * tests above as soon as drivers, timer and DMA code have been fixed. | ||
164 | * Even the sleep block count should become obsolete. */ | ||
165 | if ((use_idlect1 != ~0) || !do_sleep) { | ||
166 | |||
167 | __u32 saved_idlect1 = omap_readl(ARM_IDLECT1); | ||
168 | if (cpu_is_omap15xx()) | ||
169 | use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST; | ||
170 | else | ||
171 | use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL; | ||
172 | omap_writel(use_idlect1, ARM_IDLECT1); | ||
173 | __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); | ||
174 | omap_writel(saved_idlect1, ARM_IDLECT1); | ||
175 | |||
176 | local_fiq_enable(); | ||
177 | local_irq_enable(); | ||
178 | return; | ||
179 | } | ||
180 | omap_sram_suspend(omap_readl(ARM_IDLECT1), | ||
181 | omap_readl(ARM_IDLECT2)); | ||
182 | #endif | ||
183 | |||
184 | local_fiq_enable(); | ||
185 | local_irq_enable(); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Configuration of the wakeup event is board specific. For the | ||
190 | * moment we put it into this helper function. Later it may move | ||
191 | * to board specific files. | ||
192 | */ | ||
193 | static void omap_pm_wakeup_setup(void) | ||
194 | { | ||
195 | u32 level1_wake = 0; | ||
196 | u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); | ||
197 | |||
198 | /* | ||
199 | * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, | ||
200 | * and the L2 wakeup interrupts: keypad and UART2. Note that the | ||
201 | * drivers must still separately call omap_set_gpio_wakeup() to | ||
202 | * wake up to a GPIO interrupt. | ||
203 | */ | ||
204 | if (cpu_is_omap730()) | ||
205 | level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | | ||
206 | OMAP_IRQ_BIT(INT_730_IH2_IRQ); | ||
207 | else if (cpu_is_omap15xx()) | ||
208 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
209 | OMAP_IRQ_BIT(INT_1510_IH2_IRQ); | ||
210 | else if (cpu_is_omap16xx()) | ||
211 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
212 | OMAP_IRQ_BIT(INT_1610_IH2_IRQ); | ||
213 | |||
214 | omap_writel(~level1_wake, OMAP_IH1_MIR); | ||
215 | |||
216 | if (cpu_is_omap730()) { | ||
217 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | ||
218 | omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | | ||
219 | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), | ||
220 | OMAP_IH2_1_MIR); | ||
221 | } else if (cpu_is_omap15xx()) { | ||
222 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); | ||
223 | omap_writel(~level2_wake, OMAP_IH2_MIR); | ||
224 | } else if (cpu_is_omap16xx()) { | ||
225 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); | ||
226 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | ||
227 | |||
228 | /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ | ||
229 | omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), | ||
230 | OMAP_IH2_1_MIR); | ||
231 | omap_writel(~0x0, OMAP_IH2_2_MIR); | ||
232 | omap_writel(~0x0, OMAP_IH2_3_MIR); | ||
233 | } | ||
234 | |||
235 | /* New IRQ agreement, recalculate in cascade order */ | ||
236 | omap_writel(1, OMAP_IH2_CONTROL); | ||
237 | omap_writel(1, OMAP_IH1_CONTROL); | ||
238 | } | ||
239 | |||
240 | #define EN_DSPCK 13 /* ARM_CKCTL */ | ||
241 | #define EN_APICK 6 /* ARM_IDLECT2 */ | ||
242 | #define DSP_EN 1 /* ARM_RSTCT1 */ | ||
243 | |||
244 | void omap_pm_suspend(void) | ||
245 | { | ||
246 | unsigned long arg0 = 0, arg1 = 0; | ||
247 | |||
248 | printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); | ||
249 | |||
250 | omap_serial_wake_trigger(1); | ||
251 | |||
252 | if (machine_is_omap_osk()) { | ||
253 | /* Stop LED1 (D9) blink */ | ||
254 | tps65010_set_led(LED1, OFF); | ||
255 | } | ||
256 | |||
257 | omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); | ||
258 | |||
259 | /* | ||
260 | * Step 1: turn off interrupts (FIXME: NOTE: already disabled) | ||
261 | */ | ||
262 | |||
263 | local_irq_disable(); | ||
264 | local_fiq_disable(); | ||
265 | |||
266 | /* | ||
267 | * Step 2: save registers | ||
268 | * | ||
269 | * The omap is a strange/beautiful device. The caches, memory | ||
270 | * and register state are preserved across power saves. | ||
271 | * We have to save and restore very little register state to | ||
272 | * idle the omap. | ||
273 | * | ||
274 | * Save interrupt, MPUI, ARM and UPLD control registers. | ||
275 | */ | ||
276 | |||
277 | if (cpu_is_omap730()) { | ||
278 | MPUI730_SAVE(OMAP_IH1_MIR); | ||
279 | MPUI730_SAVE(OMAP_IH2_0_MIR); | ||
280 | MPUI730_SAVE(OMAP_IH2_1_MIR); | ||
281 | MPUI730_SAVE(MPUI_CTRL); | ||
282 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
283 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
284 | MPUI730_SAVE(EMIFS_CONFIG); | ||
285 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
286 | |||
287 | } else if (cpu_is_omap15xx()) { | ||
288 | MPUI1510_SAVE(OMAP_IH1_MIR); | ||
289 | MPUI1510_SAVE(OMAP_IH2_MIR); | ||
290 | MPUI1510_SAVE(MPUI_CTRL); | ||
291 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
292 | MPUI1510_SAVE(MPUI_DSP_API_CONFIG); | ||
293 | MPUI1510_SAVE(EMIFS_CONFIG); | ||
294 | MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); | ||
295 | } else if (cpu_is_omap16xx()) { | ||
296 | MPUI1610_SAVE(OMAP_IH1_MIR); | ||
297 | MPUI1610_SAVE(OMAP_IH2_0_MIR); | ||
298 | MPUI1610_SAVE(OMAP_IH2_1_MIR); | ||
299 | MPUI1610_SAVE(OMAP_IH2_2_MIR); | ||
300 | MPUI1610_SAVE(OMAP_IH2_3_MIR); | ||
301 | MPUI1610_SAVE(MPUI_CTRL); | ||
302 | MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
303 | MPUI1610_SAVE(MPUI_DSP_API_CONFIG); | ||
304 | MPUI1610_SAVE(EMIFS_CONFIG); | ||
305 | MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); | ||
306 | } | ||
307 | |||
308 | ARM_SAVE(ARM_CKCTL); | ||
309 | ARM_SAVE(ARM_IDLECT1); | ||
310 | ARM_SAVE(ARM_IDLECT2); | ||
311 | if (!(cpu_is_omap15xx())) | ||
312 | ARM_SAVE(ARM_IDLECT3); | ||
313 | ARM_SAVE(ARM_EWUPCT); | ||
314 | ARM_SAVE(ARM_RSTCT1); | ||
315 | ARM_SAVE(ARM_RSTCT2); | ||
316 | ARM_SAVE(ARM_SYSST); | ||
317 | ULPD_SAVE(ULPD_CLOCK_CTRL); | ||
318 | ULPD_SAVE(ULPD_STATUS_REQ); | ||
319 | |||
320 | /* (Step 3 removed - we now allow deep sleep by default) */ | ||
321 | |||
322 | /* | ||
323 | * Step 4: OMAP DSP Shutdown | ||
324 | */ | ||
325 | |||
326 | /* stop DSP */ | ||
327 | omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1); | ||
328 | |||
329 | /* shut down dsp_ck */ | ||
330 | omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL); | ||
331 | |||
332 | /* temporarily enabling api_ck to access DSP registers */ | ||
333 | omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2); | ||
334 | |||
335 | /* save DSP registers */ | ||
336 | DSP_SAVE(DSP_IDLECT2); | ||
337 | |||
338 | /* Stop all DSP domain clocks */ | ||
339 | __raw_writew(0, DSP_IDLECT2); | ||
340 | |||
341 | /* | ||
342 | * Step 5: Wakeup Event Setup | ||
343 | */ | ||
344 | |||
345 | omap_pm_wakeup_setup(); | ||
346 | |||
347 | /* | ||
348 | * Step 6: ARM and Traffic controller shutdown | ||
349 | */ | ||
350 | |||
351 | /* disable ARM watchdog */ | ||
352 | omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); | ||
353 | omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); | ||
354 | |||
355 | /* | ||
356 | * Step 6b: ARM and Traffic controller shutdown | ||
357 | * | ||
358 | * Step 6 continues here. Prepare jump to power management | ||
359 | * assembly code in internal SRAM. | ||
360 | * | ||
361 | * Since the omap_cpu_suspend routine has been copied to | ||
362 | * SRAM, we'll do an indirect procedure call to it and pass the | ||
363 | * contents of arm_idlect1 and arm_idlect2 so it can restore | ||
364 | * them when it wakes up and it will return. | ||
365 | */ | ||
366 | |||
367 | arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; | ||
368 | arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; | ||
369 | |||
370 | /* | ||
371 | * Step 6c: ARM and Traffic controller shutdown | ||
372 | * | ||
373 | * Jump to assembly code. The processor will stay there | ||
374 | * until wake up. | ||
375 | */ | ||
376 | omap_sram_suspend(arg0, arg1); | ||
377 | |||
378 | /* | ||
379 | * If we are here, processor is woken up! | ||
380 | */ | ||
381 | |||
382 | /* | ||
383 | * Restore DSP clocks | ||
384 | */ | ||
385 | |||
386 | /* again temporarily enabling api_ck to access DSP registers */ | ||
387 | omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2); | ||
388 | |||
389 | /* Restore DSP domain clocks */ | ||
390 | DSP_RESTORE(DSP_IDLECT2); | ||
391 | |||
392 | /* | ||
393 | * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did | ||
394 | */ | ||
395 | |||
396 | if (!(cpu_is_omap15xx())) | ||
397 | ARM_RESTORE(ARM_IDLECT3); | ||
398 | ARM_RESTORE(ARM_CKCTL); | ||
399 | ARM_RESTORE(ARM_EWUPCT); | ||
400 | ARM_RESTORE(ARM_RSTCT1); | ||
401 | ARM_RESTORE(ARM_RSTCT2); | ||
402 | ARM_RESTORE(ARM_SYSST); | ||
403 | ULPD_RESTORE(ULPD_CLOCK_CTRL); | ||
404 | ULPD_RESTORE(ULPD_STATUS_REQ); | ||
405 | |||
406 | if (cpu_is_omap730()) { | ||
407 | MPUI730_RESTORE(EMIFS_CONFIG); | ||
408 | MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); | ||
409 | MPUI730_RESTORE(OMAP_IH1_MIR); | ||
410 | MPUI730_RESTORE(OMAP_IH2_0_MIR); | ||
411 | MPUI730_RESTORE(OMAP_IH2_1_MIR); | ||
412 | } else if (cpu_is_omap15xx()) { | ||
413 | MPUI1510_RESTORE(MPUI_CTRL); | ||
414 | MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); | ||
415 | MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); | ||
416 | MPUI1510_RESTORE(EMIFS_CONFIG); | ||
417 | MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); | ||
418 | MPUI1510_RESTORE(OMAP_IH1_MIR); | ||
419 | MPUI1510_RESTORE(OMAP_IH2_MIR); | ||
420 | } else if (cpu_is_omap16xx()) { | ||
421 | MPUI1610_RESTORE(MPUI_CTRL); | ||
422 | MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); | ||
423 | MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); | ||
424 | MPUI1610_RESTORE(EMIFS_CONFIG); | ||
425 | MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); | ||
426 | |||
427 | MPUI1610_RESTORE(OMAP_IH1_MIR); | ||
428 | MPUI1610_RESTORE(OMAP_IH2_0_MIR); | ||
429 | MPUI1610_RESTORE(OMAP_IH2_1_MIR); | ||
430 | MPUI1610_RESTORE(OMAP_IH2_2_MIR); | ||
431 | MPUI1610_RESTORE(OMAP_IH2_3_MIR); | ||
432 | } | ||
433 | |||
434 | omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); | ||
435 | |||
436 | /* | ||
437 | * Reenable interrupts | ||
438 | */ | ||
439 | |||
440 | local_irq_enable(); | ||
441 | local_fiq_enable(); | ||
442 | |||
443 | omap_serial_wake_trigger(0); | ||
444 | |||
445 | printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); | ||
446 | |||
447 | if (machine_is_omap_osk()) { | ||
448 | /* Let LED1 (D9) blink again */ | ||
449 | tps65010_set_led(LED1, BLINK); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | ||
454 | static int g_read_completed; | ||
455 | |||
456 | /* | ||
457 | * Read system PM registers for debugging | ||
458 | */ | ||
459 | static int omap_pm_read_proc( | ||
460 | char *page_buffer, | ||
461 | char **my_first_byte, | ||
462 | off_t virtual_start, | ||
463 | int length, | ||
464 | int *eof, | ||
465 | void *data) | ||
466 | { | ||
467 | int my_buffer_offset = 0; | ||
468 | char * const my_base = page_buffer; | ||
469 | |||
470 | ARM_SAVE(ARM_CKCTL); | ||
471 | ARM_SAVE(ARM_IDLECT1); | ||
472 | ARM_SAVE(ARM_IDLECT2); | ||
473 | if (!(cpu_is_omap15xx())) | ||
474 | ARM_SAVE(ARM_IDLECT3); | ||
475 | ARM_SAVE(ARM_EWUPCT); | ||
476 | ARM_SAVE(ARM_RSTCT1); | ||
477 | ARM_SAVE(ARM_RSTCT2); | ||
478 | ARM_SAVE(ARM_SYSST); | ||
479 | |||
480 | ULPD_SAVE(ULPD_IT_STATUS); | ||
481 | ULPD_SAVE(ULPD_CLOCK_CTRL); | ||
482 | ULPD_SAVE(ULPD_SOFT_REQ); | ||
483 | ULPD_SAVE(ULPD_STATUS_REQ); | ||
484 | ULPD_SAVE(ULPD_DPLL_CTRL); | ||
485 | ULPD_SAVE(ULPD_POWER_CTRL); | ||
486 | |||
487 | if (cpu_is_omap730()) { | ||
488 | MPUI730_SAVE(MPUI_CTRL); | ||
489 | MPUI730_SAVE(MPUI_DSP_STATUS); | ||
490 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
491 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
492 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
493 | MPUI730_SAVE(EMIFS_CONFIG); | ||
494 | } else if (cpu_is_omap15xx()) { | ||
495 | MPUI1510_SAVE(MPUI_CTRL); | ||
496 | MPUI1510_SAVE(MPUI_DSP_STATUS); | ||
497 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
498 | MPUI1510_SAVE(MPUI_DSP_API_CONFIG); | ||
499 | MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); | ||
500 | MPUI1510_SAVE(EMIFS_CONFIG); | ||
501 | } else if (cpu_is_omap16xx()) { | ||
502 | MPUI1610_SAVE(MPUI_CTRL); | ||
503 | MPUI1610_SAVE(MPUI_DSP_STATUS); | ||
504 | MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
505 | MPUI1610_SAVE(MPUI_DSP_API_CONFIG); | ||
506 | MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); | ||
507 | MPUI1610_SAVE(EMIFS_CONFIG); | ||
508 | } | ||
509 | |||
510 | if (virtual_start == 0) { | ||
511 | g_read_completed = 0; | ||
512 | |||
513 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
514 | "ARM_CKCTL_REG: 0x%-8x \n" | ||
515 | "ARM_IDLECT1_REG: 0x%-8x \n" | ||
516 | "ARM_IDLECT2_REG: 0x%-8x \n" | ||
517 | "ARM_IDLECT3_REG: 0x%-8x \n" | ||
518 | "ARM_EWUPCT_REG: 0x%-8x \n" | ||
519 | "ARM_RSTCT1_REG: 0x%-8x \n" | ||
520 | "ARM_RSTCT2_REG: 0x%-8x \n" | ||
521 | "ARM_SYSST_REG: 0x%-8x \n" | ||
522 | "ULPD_IT_STATUS_REG: 0x%-4x \n" | ||
523 | "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" | ||
524 | "ULPD_SOFT_REQ_REG: 0x%-4x \n" | ||
525 | "ULPD_DPLL_CTRL_REG: 0x%-4x \n" | ||
526 | "ULPD_STATUS_REQ_REG: 0x%-4x \n" | ||
527 | "ULPD_POWER_CTRL_REG: 0x%-4x \n", | ||
528 | ARM_SHOW(ARM_CKCTL), | ||
529 | ARM_SHOW(ARM_IDLECT1), | ||
530 | ARM_SHOW(ARM_IDLECT2), | ||
531 | ARM_SHOW(ARM_IDLECT3), | ||
532 | ARM_SHOW(ARM_EWUPCT), | ||
533 | ARM_SHOW(ARM_RSTCT1), | ||
534 | ARM_SHOW(ARM_RSTCT2), | ||
535 | ARM_SHOW(ARM_SYSST), | ||
536 | ULPD_SHOW(ULPD_IT_STATUS), | ||
537 | ULPD_SHOW(ULPD_CLOCK_CTRL), | ||
538 | ULPD_SHOW(ULPD_SOFT_REQ), | ||
539 | ULPD_SHOW(ULPD_DPLL_CTRL), | ||
540 | ULPD_SHOW(ULPD_STATUS_REQ), | ||
541 | ULPD_SHOW(ULPD_POWER_CTRL)); | ||
542 | |||
543 | if (cpu_is_omap730()) { | ||
544 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
545 | "MPUI730_CTRL_REG 0x%-8x \n" | ||
546 | "MPUI730_DSP_STATUS_REG: 0x%-8x \n" | ||
547 | "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
548 | "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
549 | "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
550 | "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
551 | MPUI730_SHOW(MPUI_CTRL), | ||
552 | MPUI730_SHOW(MPUI_DSP_STATUS), | ||
553 | MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
554 | MPUI730_SHOW(MPUI_DSP_API_CONFIG), | ||
555 | MPUI730_SHOW(EMIFF_SDRAM_CONFIG), | ||
556 | MPUI730_SHOW(EMIFS_CONFIG)); | ||
557 | } else if (cpu_is_omap15xx()) { | ||
558 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
559 | "MPUI1510_CTRL_REG 0x%-8x \n" | ||
560 | "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" | ||
561 | "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
562 | "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
563 | "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
564 | "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
565 | MPUI1510_SHOW(MPUI_CTRL), | ||
566 | MPUI1510_SHOW(MPUI_DSP_STATUS), | ||
567 | MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
568 | MPUI1510_SHOW(MPUI_DSP_API_CONFIG), | ||
569 | MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), | ||
570 | MPUI1510_SHOW(EMIFS_CONFIG)); | ||
571 | } else if (cpu_is_omap16xx()) { | ||
572 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
573 | "MPUI1610_CTRL_REG 0x%-8x \n" | ||
574 | "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" | ||
575 | "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
576 | "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
577 | "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
578 | "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
579 | MPUI1610_SHOW(MPUI_CTRL), | ||
580 | MPUI1610_SHOW(MPUI_DSP_STATUS), | ||
581 | MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
582 | MPUI1610_SHOW(MPUI_DSP_API_CONFIG), | ||
583 | MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), | ||
584 | MPUI1610_SHOW(EMIFS_CONFIG)); | ||
585 | } | ||
586 | |||
587 | g_read_completed++; | ||
588 | } else if (g_read_completed >= 1) { | ||
589 | *eof = 1; | ||
590 | return 0; | ||
591 | } | ||
592 | g_read_completed++; | ||
593 | |||
594 | *my_first_byte = page_buffer; | ||
595 | return my_buffer_offset; | ||
596 | } | ||
597 | |||
598 | static void omap_pm_init_proc(void) | ||
599 | { | ||
600 | struct proc_dir_entry *entry; | ||
601 | |||
602 | entry = create_proc_read_entry("driver/omap_pm", | ||
603 | S_IWUSR | S_IRUGO, NULL, | ||
604 | omap_pm_read_proc, NULL); | ||
605 | } | ||
606 | |||
607 | #endif /* DEBUG && CONFIG_PROC_FS */ | ||
608 | |||
609 | static void (*saved_idle)(void) = NULL; | ||
610 | |||
611 | /* | ||
612 | * omap_pm_prepare - Do preliminary suspend work. | ||
613 | * @state: suspend state we're entering. | ||
614 | * | ||
615 | */ | ||
616 | static int omap_pm_prepare(suspend_state_t state) | ||
617 | { | ||
618 | int error = 0; | ||
619 | |||
620 | /* We cannot sleep in idle until we have resumed */ | ||
621 | saved_idle = pm_idle; | ||
622 | pm_idle = NULL; | ||
623 | |||
624 | switch (state) | ||
625 | { | ||
626 | case PM_SUSPEND_STANDBY: | ||
627 | case PM_SUSPEND_MEM: | ||
628 | break; | ||
629 | |||
630 | case PM_SUSPEND_DISK: | ||
631 | return -ENOTSUPP; | ||
632 | |||
633 | default: | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | return error; | ||
638 | } | ||
639 | |||
640 | |||
641 | /* | ||
642 | * omap_pm_enter - Actually enter a sleep state. | ||
643 | * @state: State we're entering. | ||
644 | * | ||
645 | */ | ||
646 | |||
647 | static int omap_pm_enter(suspend_state_t state) | ||
648 | { | ||
649 | switch (state) | ||
650 | { | ||
651 | case PM_SUSPEND_STANDBY: | ||
652 | case PM_SUSPEND_MEM: | ||
653 | omap_pm_suspend(); | ||
654 | break; | ||
655 | |||
656 | case PM_SUSPEND_DISK: | ||
657 | return -ENOTSUPP; | ||
658 | |||
659 | default: | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | |||
667 | /** | ||
668 | * omap_pm_finish - Finish up suspend sequence. | ||
669 | * @state: State we're coming out of. | ||
670 | * | ||
671 | * This is called after we wake back up (or if entering the sleep state | ||
672 | * failed). | ||
673 | */ | ||
674 | |||
675 | static int omap_pm_finish(suspend_state_t state) | ||
676 | { | ||
677 | pm_idle = saved_idle; | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | |||
682 | static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, | ||
683 | struct pt_regs * regs) | ||
684 | { | ||
685 | return IRQ_HANDLED; | ||
686 | } | ||
687 | |||
688 | static struct irqaction omap_wakeup_irq = { | ||
689 | .name = "peripheral wakeup", | ||
690 | .flags = SA_INTERRUPT, | ||
691 | .handler = omap_wakeup_interrupt | ||
692 | }; | ||
693 | |||
694 | |||
695 | |||
696 | static struct pm_ops omap_pm_ops ={ | ||
697 | .pm_disk_mode = 0, | ||
698 | .prepare = omap_pm_prepare, | ||
699 | .enter = omap_pm_enter, | ||
700 | .finish = omap_pm_finish, | ||
701 | }; | ||
702 | |||
703 | static int __init omap_pm_init(void) | ||
704 | { | ||
705 | printk("Power Management for TI OMAP.\n"); | ||
706 | |||
707 | /* | ||
708 | * We copy the assembler sleep/wakeup routines to SRAM. | ||
709 | * These routines need to be in SRAM as that's the only | ||
710 | * memory the MPU can see when it wakes up. | ||
711 | */ | ||
712 | if (cpu_is_omap730()) { | ||
713 | omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, | ||
714 | omap730_idle_loop_suspend_sz); | ||
715 | omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, | ||
716 | omap730_cpu_suspend_sz); | ||
717 | } else if (cpu_is_omap15xx()) { | ||
718 | omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, | ||
719 | omap1510_idle_loop_suspend_sz); | ||
720 | omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, | ||
721 | omap1510_cpu_suspend_sz); | ||
722 | } else if (cpu_is_omap16xx()) { | ||
723 | omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, | ||
724 | omap1610_idle_loop_suspend_sz); | ||
725 | omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, | ||
726 | omap1610_cpu_suspend_sz); | ||
727 | } | ||
728 | |||
729 | if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { | ||
730 | printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); | ||
731 | return -ENODEV; | ||
732 | } | ||
733 | |||
734 | pm_idle = omap_pm_idle; | ||
735 | |||
736 | if (cpu_is_omap730()) | ||
737 | setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); | ||
738 | else if (cpu_is_omap16xx()) | ||
739 | setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); | ||
740 | |||
741 | /* Program new power ramp-up time | ||
742 | * (0 for most boards since we don't lower voltage when in deep sleep) | ||
743 | */ | ||
744 | omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); | ||
745 | |||
746 | /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ | ||
747 | omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); | ||
748 | |||
749 | /* Configure IDLECT3 */ | ||
750 | if (cpu_is_omap730()) | ||
751 | omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); | ||
752 | else if (cpu_is_omap16xx()) | ||
753 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); | ||
754 | |||
755 | pm_set_ops(&omap_pm_ops); | ||
756 | |||
757 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | ||
758 | omap_pm_init_proc(); | ||
759 | #endif | ||
760 | |||
761 | subsys_create_file(&power_subsys, &sleep_while_idle_attr); | ||
762 | |||
763 | if (cpu_is_omap16xx()) { | ||
764 | /* configure LOW_PWR pin */ | ||
765 | omap_cfg_reg(T20_1610_LOW_PWR); | ||
766 | } | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | __initcall(omap_pm_init); | ||
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index e924e0c6a4ce..9b4cd698bec8 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c | |||
@@ -30,9 +30,9 @@ | |||
30 | #include <asm/arch/pm.h> | 30 | #include <asm/arch/pm.h> |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | static struct clk * uart1_ck = NULL; | 33 | static struct clk * uart1_ck; |
34 | static struct clk * uart2_ck = NULL; | 34 | static struct clk * uart2_ck; |
35 | static struct clk * uart3_ck = NULL; | 35 | static struct clk * uart3_ck; |
36 | 36 | ||
37 | static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, | 37 | static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, |
38 | int offset) | 38 | int offset) |
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/mach-omap1/sleep.S index 4cd7d292f854..e58295e2d3b2 100644 --- a/arch/arm/plat-omap/sleep.S +++ b/arch/arm/mach-omap1/sleep.S | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/sleep.S | 2 | * linux/arch/arm/mach-omap1/sleep.S |
3 | * | 3 | * |
4 | * Low-level OMAP730/1510/1610 sleep/wakeUp support | 4 | * Low-level OMAP730/1510/1610 sleep/wakeUp support |
5 | * | 5 | * |
@@ -383,60 +383,133 @@ ENTRY(omap1610_cpu_suspend) | |||
383 | mcr p15, 0, r0, c7, c10, 4 | 383 | mcr p15, 0, r0, c7, c10, 4 |
384 | nop | 384 | nop |
385 | 385 | ||
386 | @ load base address of Traffic Controller | 386 | @ Load base address of Traffic Controller |
387 | mov r6, #TCMIF_ASM_BASE & 0xff000000 | 387 | mov r6, #TCMIF_ASM_BASE & 0xff000000 |
388 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 | 388 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 |
389 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 | 389 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 |
390 | 390 | ||
391 | @ prepare to put SDRAM into self-refresh manually | 391 | @ Prepare to put SDRAM into self-refresh manually |
392 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 392 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
393 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 | 393 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 |
394 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff | 394 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff |
395 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 395 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
396 | 396 | ||
397 | @ prepare to put EMIFS to Sleep | 397 | @ Prepare to put EMIFS to Sleep |
398 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 398 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
399 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff | 399 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff |
400 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 400 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
401 | 401 | ||
402 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | 402 | @ Load base address of ARM_IDLECT1 and ARM_IDLECT2 |
403 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | 403 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 |
404 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | 404 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 |
405 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | 405 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 |
406 | 406 | ||
407 | @ turn off clock domains | 407 | @ Turn off clock domains |
408 | @ do not disable PERCK (0x04) | 408 | @ Do not disable PERCK (0x04) |
409 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff | 409 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff |
410 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 | 410 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 |
411 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 411 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
412 | 412 | ||
413 | @ request ARM idle | 413 | @ Request ARM idle |
414 | mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff | 414 | mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff |
415 | orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 | 415 | orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 |
416 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 416 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
417 | 417 | ||
418 | @ disable instruction cache | ||
419 | mrc p15, 0, r9, c1, c0, 0 | ||
420 | bic r2, r9, #0x1000 | ||
421 | mcr p15, 0, r2, c1, c0, 0 | ||
422 | nop | ||
423 | |||
424 | /* | 418 | /* |
425 | * Let's wait for the next wake up event to wake us up. r0 can't be | 419 | * Let's wait for the next wake up event to wake us up. r0 can't be |
426 | * used here because r0 holds ARM_IDLECT1 | 420 | * used here because r0 holds ARM_IDLECT1 |
427 | */ | 421 | */ |
428 | mov r2, #0 | 422 | mov r2, #0 |
429 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | 423 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt |
424 | |||
425 | @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions | ||
426 | @ according to this formula: | ||
427 | @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV | ||
428 | @ Max DPLL_MULT = 18 | ||
429 | @ DPLL_DIV = 1 | ||
430 | @ ARMDIV = 1 | ||
431 | @ => 74 nop-instructions | ||
432 | nop | ||
433 | nop | ||
434 | nop | ||
435 | nop | ||
436 | nop | ||
437 | nop | ||
438 | nop | ||
439 | nop | ||
440 | nop | ||
441 | nop @10 | ||
442 | nop | ||
443 | nop | ||
444 | nop | ||
445 | nop | ||
446 | nop | ||
447 | nop | ||
448 | nop | ||
449 | nop | ||
450 | nop | ||
451 | nop @20 | ||
452 | nop | ||
453 | nop | ||
454 | nop | ||
455 | nop | ||
456 | nop | ||
457 | nop | ||
458 | nop | ||
459 | nop | ||
460 | nop | ||
461 | nop @30 | ||
462 | nop | ||
463 | nop | ||
464 | nop | ||
465 | nop | ||
466 | nop | ||
467 | nop | ||
468 | nop | ||
469 | nop | ||
470 | nop | ||
471 | nop @40 | ||
472 | nop | ||
473 | nop | ||
474 | nop | ||
475 | nop | ||
476 | nop | ||
477 | nop | ||
478 | nop | ||
479 | nop | ||
480 | nop | ||
481 | nop @50 | ||
482 | nop | ||
483 | nop | ||
484 | nop | ||
485 | nop | ||
486 | nop | ||
487 | nop | ||
488 | nop | ||
489 | nop | ||
490 | nop | ||
491 | nop @60 | ||
492 | nop | ||
493 | nop | ||
494 | nop | ||
495 | nop | ||
496 | nop | ||
497 | nop | ||
498 | nop | ||
499 | nop | ||
500 | nop | ||
501 | nop @70 | ||
502 | nop | ||
503 | nop | ||
504 | nop | ||
505 | nop @74 | ||
430 | /* | 506 | /* |
431 | * omap1610_cpu_suspend()'s resume point. | 507 | * omap1610_cpu_suspend()'s resume point. |
432 | * | 508 | * |
433 | * It will just start executing here, so we'll restore stuff from the | 509 | * It will just start executing here, so we'll restore stuff from the |
434 | * stack. | 510 | * stack. |
435 | */ | 511 | */ |
436 | @ re-enable Icache | 512 | @ Restore the ARM_IDLECT1 and ARM_IDLECT2. |
437 | mcr p15, 0, r9, c1, c0, 0 | ||
438 | |||
439 | @ reset the ARM_IDLECT1 and ARM_IDLECT2. | ||
440 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 513 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
441 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 514 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
442 | 515 | ||
@@ -444,7 +517,7 @@ ENTRY(omap1610_cpu_suspend) | |||
444 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 517 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
445 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 518 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
446 | 519 | ||
447 | @ restore regs and return | 520 | @ Restore regs and return |
448 | ldmfd sp!, {r0 - r12, pc} | 521 | ldmfd sp!, {r0 - r12, pc} |
449 | 522 | ||
450 | ENTRY(omap1610_cpu_suspend_sz) | 523 | ENTRY(omap1610_cpu_suspend_sz) |
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index cdbf4d7620c6..a85fe6066bc4 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
@@ -51,8 +51,6 @@ | |||
51 | 51 | ||
52 | struct sys_timer omap_timer; | 52 | struct sys_timer omap_timer; |
53 | 53 | ||
54 | #ifdef CONFIG_OMAP_MPU_TIMER | ||
55 | |||
56 | /* | 54 | /* |
57 | * --------------------------------------------------------------------------- | 55 | * --------------------------------------------------------------------------- |
58 | * MPU timer | 56 | * MPU timer |
@@ -222,195 +220,6 @@ unsigned long long sched_clock(void) | |||
222 | 220 | ||
223 | return cycles_2_ns(ticks64); | 221 | return cycles_2_ns(ticks64); |
224 | } | 222 | } |
225 | #endif /* CONFIG_OMAP_MPU_TIMER */ | ||
226 | |||
227 | #ifdef CONFIG_OMAP_32K_TIMER | ||
228 | |||
229 | #ifdef CONFIG_ARCH_OMAP15XX | ||
230 | #error OMAP 32KHz timer does not currently work on 15XX! | ||
231 | #endif | ||
232 | |||
233 | /* | ||
234 | * --------------------------------------------------------------------------- | ||
235 | * 32KHz OS timer | ||
236 | * | ||
237 | * This currently works only on 16xx, as 1510 does not have the continuous | ||
238 | * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track | ||
239 | * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer | ||
240 | * on 1510 would be possible, but the timer would not be as accurate as | ||
241 | * with the 32KHz synchronized timer. | ||
242 | * --------------------------------------------------------------------------- | ||
243 | */ | ||
244 | #define OMAP_32K_TIMER_BASE 0xfffb9000 | ||
245 | #define OMAP_32K_TIMER_CR 0x08 | ||
246 | #define OMAP_32K_TIMER_TVR 0x00 | ||
247 | #define OMAP_32K_TIMER_TCR 0x04 | ||
248 | |||
249 | #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) | ||
250 | |||
251 | /* | ||
252 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 | ||
253 | * so with HZ = 100, TVR = 327.68. | ||
254 | */ | ||
255 | #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) | ||
256 | #define TIMER_32K_SYNCHRONIZED 0xfffbc410 | ||
257 | |||
258 | #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ | ||
259 | (((nr_jiffies) * (clock_rate)) / HZ) | ||
260 | |||
261 | static inline void omap_32k_timer_write(int val, int reg) | ||
262 | { | ||
263 | omap_writew(val, reg + OMAP_32K_TIMER_BASE); | ||
264 | } | ||
265 | |||
266 | static inline unsigned long omap_32k_timer_read(int reg) | ||
267 | { | ||
268 | return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * The 32KHz synchronized timer is an additional timer on 16xx. | ||
273 | * It is always running. | ||
274 | */ | ||
275 | static inline unsigned long omap_32k_sync_timer_read(void) | ||
276 | { | ||
277 | return omap_readl(TIMER_32K_SYNCHRONIZED); | ||
278 | } | ||
279 | |||
280 | static inline void omap_32k_timer_start(unsigned long load_val) | ||
281 | { | ||
282 | omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR); | ||
283 | omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR); | ||
284 | } | ||
285 | |||
286 | static inline void omap_32k_timer_stop(void) | ||
287 | { | ||
288 | omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Rounds down to nearest usec. Note that this will overflow for larger values. | ||
293 | */ | ||
294 | static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) | ||
295 | { | ||
296 | return (ticks_32k * 5*5*5*5*5*5) >> 9; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * Rounds down to nearest nsec. | ||
301 | */ | ||
302 | static inline unsigned long long | ||
303 | omap_32k_ticks_to_nsecs(unsigned long ticks_32k) | ||
304 | { | ||
305 | return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; | ||
306 | } | ||
307 | |||
308 | static unsigned long omap_32k_last_tick = 0; | ||
309 | |||
310 | /* | ||
311 | * Returns elapsed usecs since last 32k timer interrupt | ||
312 | */ | ||
313 | static unsigned long omap_32k_timer_gettimeoffset(void) | ||
314 | { | ||
315 | unsigned long now = omap_32k_sync_timer_read(); | ||
316 | return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Returns current time from boot in nsecs. It's OK for this to wrap | ||
321 | * around for now, as it's just a relative time stamp. | ||
322 | */ | ||
323 | unsigned long long sched_clock(void) | ||
324 | { | ||
325 | return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this | ||
330 | * function is also called from other interrupts to remove latency | ||
331 | * issues with dynamic tick. In the dynamic tick case, we need to lock | ||
332 | * with irqsave. | ||
333 | */ | ||
334 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | ||
335 | struct pt_regs *regs) | ||
336 | { | ||
337 | unsigned long flags; | ||
338 | unsigned long now; | ||
339 | |||
340 | write_seqlock_irqsave(&xtime_lock, flags); | ||
341 | now = omap_32k_sync_timer_read(); | ||
342 | |||
343 | while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { | ||
344 | omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; | ||
345 | timer_tick(regs); | ||
346 | } | ||
347 | |||
348 | /* Restart timer so we don't drift off due to modulo or dynamic tick. | ||
349 | * By default we program the next timer to be continuous to avoid | ||
350 | * latencies during high system load. During dynamic tick operation the | ||
351 | * continuous timer can be overridden from pm_idle to be longer. | ||
352 | */ | ||
353 | omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); | ||
354 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
355 | |||
356 | return IRQ_HANDLED; | ||
357 | } | ||
358 | |||
359 | #ifdef CONFIG_NO_IDLE_HZ | ||
360 | /* | ||
361 | * Programs the next timer interrupt needed. Called when dynamic tick is | ||
362 | * enabled, and to reprogram the ticks to skip from pm_idle. Note that | ||
363 | * we can keep the timer continuous, and don't need to set it to run in | ||
364 | * one-shot mode. This is because the timer will get reprogrammed again | ||
365 | * after next interrupt. | ||
366 | */ | ||
367 | void omap_32k_timer_reprogram(unsigned long next_tick) | ||
368 | { | ||
369 | omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); | ||
370 | } | ||
371 | |||
372 | static struct irqaction omap_32k_timer_irq; | ||
373 | extern struct timer_update_handler timer_update; | ||
374 | |||
375 | static int omap_32k_timer_enable_dyn_tick(void) | ||
376 | { | ||
377 | /* No need to reprogram timer, just use the next interrupt */ | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int omap_32k_timer_disable_dyn_tick(void) | ||
382 | { | ||
383 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static struct dyn_tick_timer omap_dyn_tick_timer = { | ||
388 | .enable = omap_32k_timer_enable_dyn_tick, | ||
389 | .disable = omap_32k_timer_disable_dyn_tick, | ||
390 | .reprogram = omap_32k_timer_reprogram, | ||
391 | .handler = omap_32k_timer_interrupt, | ||
392 | }; | ||
393 | #endif /* CONFIG_NO_IDLE_HZ */ | ||
394 | |||
395 | static struct irqaction omap_32k_timer_irq = { | ||
396 | .name = "32KHz timer", | ||
397 | .flags = SA_INTERRUPT | SA_TIMER, | ||
398 | .handler = omap_32k_timer_interrupt, | ||
399 | }; | ||
400 | |||
401 | static __init void omap_init_32k_timer(void) | ||
402 | { | ||
403 | |||
404 | #ifdef CONFIG_NO_IDLE_HZ | ||
405 | omap_timer.dyn_tick = &omap_dyn_tick_timer; | ||
406 | #endif | ||
407 | |||
408 | setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); | ||
409 | omap_timer.offset = omap_32k_timer_gettimeoffset; | ||
410 | omap_32k_last_tick = omap_32k_sync_timer_read(); | ||
411 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
412 | } | ||
413 | #endif /* CONFIG_OMAP_32K_TIMER */ | ||
414 | 223 | ||
415 | /* | 224 | /* |
416 | * --------------------------------------------------------------------------- | 225 | * --------------------------------------------------------------------------- |
@@ -419,13 +228,7 @@ static __init void omap_init_32k_timer(void) | |||
419 | */ | 228 | */ |
420 | static void __init omap_timer_init(void) | 229 | static void __init omap_timer_init(void) |
421 | { | 230 | { |
422 | #if defined(CONFIG_OMAP_MPU_TIMER) | ||
423 | omap_init_mpu_timer(); | 231 | omap_init_mpu_timer(); |
424 | #elif defined(CONFIG_OMAP_32K_TIMER) | ||
425 | omap_init_32k_timer(); | ||
426 | #else | ||
427 | #error No system timer selected in Kconfig! | ||
428 | #endif | ||
429 | } | 232 | } |
430 | 233 | ||
431 | struct sys_timer omap_timer = { | 234 | struct sys_timer omap_timer = { |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 578880943cf2..537dd2e6d380 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -20,3 +20,6 @@ config MACH_OMAP_H4 | |||
20 | bool "OMAP 2420 H4 board" | 20 | bool "OMAP 2420 H4 board" |
21 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | 21 | depends on ARCH_OMAP2 && ARCH_OMAP24XX |
22 | 22 | ||
23 | config MACH_OMAP_APOLLON | ||
24 | bool "OMAP 2420 Apollon board" | ||
25 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | ||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 42041166435c..111eaa64258f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -3,11 +3,15 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o | 6 | obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o |
7 | 7 | ||
8 | obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o | 8 | obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o |
9 | 9 | ||
10 | # Power Management | ||
11 | obj-$(CONFIG_PM) += pm.o sleep.o | ||
12 | |||
10 | # Specific board support | 13 | # Specific board support |
11 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o | 14 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o |
12 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o | 15 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o |
16 | obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o | ||
13 | 17 | ||
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c new file mode 100644 index 000000000000..6c6ba172cdf6 --- /dev/null +++ b/arch/arm/mach-omap2/board-apollon.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap/omap2/board-apollon.c | ||
3 | * | ||
4 | * Copyright (C) 2005,2006 Samsung Electronics | ||
5 | * Author: Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * | ||
7 | * Modified from mach-omap/omap2/board-h4.c | ||
8 | * | ||
9 | * Code for apollon OMAP2 board. Should work on many OMAP2 systems where | ||
10 | * the bootloader passes the board-specific data to the kernel. | ||
11 | * Do not put any board specific code to this file; create a new machine | ||
12 | * type if you need custom low-level initializations. | ||
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/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/mtd/mtd.h> | ||
23 | #include <linux/mtd/partitions.h> | ||
24 | #include <linux/mtd/onenand.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/mach/arch.h> | ||
31 | #include <asm/mach/flash.h> | ||
32 | |||
33 | #include <asm/arch/gpio.h> | ||
34 | #include <asm/arch/mux.h> | ||
35 | #include <asm/arch/usb.h> | ||
36 | #include <asm/arch/board.h> | ||
37 | #include <asm/arch/common.h> | ||
38 | #include "prcm-regs.h" | ||
39 | |||
40 | /* LED & Switch macros */ | ||
41 | #define LED0_GPIO13 13 | ||
42 | #define LED1_GPIO14 14 | ||
43 | #define LED2_GPIO15 15 | ||
44 | #define SW_ENTER_GPIO16 16 | ||
45 | #define SW_UP_GPIO17 17 | ||
46 | #define SW_DOWN_GPIO58 58 | ||
47 | |||
48 | static struct mtd_partition apollon_partitions[] = { | ||
49 | { | ||
50 | .name = "X-Loader + U-Boot", | ||
51 | .offset = 0, | ||
52 | .size = SZ_128K, | ||
53 | .mask_flags = MTD_WRITEABLE, | ||
54 | }, | ||
55 | { | ||
56 | .name = "params", | ||
57 | .offset = MTDPART_OFS_APPEND, | ||
58 | .size = SZ_128K, | ||
59 | }, | ||
60 | { | ||
61 | .name = "kernel", | ||
62 | .offset = MTDPART_OFS_APPEND, | ||
63 | .size = SZ_2M, | ||
64 | }, | ||
65 | { | ||
66 | .name = "rootfs", | ||
67 | .offset = MTDPART_OFS_APPEND, | ||
68 | .size = SZ_16M, | ||
69 | }, | ||
70 | { | ||
71 | .name = "filesystem00", | ||
72 | .offset = MTDPART_OFS_APPEND, | ||
73 | .size = SZ_32M, | ||
74 | }, | ||
75 | { | ||
76 | .name = "filesystem01", | ||
77 | .offset = MTDPART_OFS_APPEND, | ||
78 | .size = MTDPART_SIZ_FULL, | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | static struct flash_platform_data apollon_flash_data = { | ||
83 | .parts = apollon_partitions, | ||
84 | .nr_parts = ARRAY_SIZE(apollon_partitions), | ||
85 | }; | ||
86 | |||
87 | static struct resource apollon_flash_resource = { | ||
88 | .start = APOLLON_CS0_BASE, | ||
89 | .end = APOLLON_CS0_BASE + SZ_128K, | ||
90 | .flags = IORESOURCE_MEM, | ||
91 | }; | ||
92 | |||
93 | static struct platform_device apollon_onenand_device = { | ||
94 | .name = "onenand", | ||
95 | .id = -1, | ||
96 | .dev = { | ||
97 | .platform_data = &apollon_flash_data, | ||
98 | }, | ||
99 | .num_resources = ARRAY_SIZE(&apollon_flash_resource), | ||
100 | .resource = &apollon_flash_resource, | ||
101 | }; | ||
102 | |||
103 | static struct resource apollon_smc91x_resources[] = { | ||
104 | [0] = { | ||
105 | .start = APOLLON_ETHR_START, /* Physical */ | ||
106 | .end = APOLLON_ETHR_START + 0xf, | ||
107 | .flags = IORESOURCE_MEM, | ||
108 | }, | ||
109 | [1] = { | ||
110 | .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), | ||
111 | .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), | ||
112 | .flags = IORESOURCE_IRQ, | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | static struct platform_device apollon_smc91x_device = { | ||
117 | .name = "smc91x", | ||
118 | .id = -1, | ||
119 | .num_resources = ARRAY_SIZE(apollon_smc91x_resources), | ||
120 | .resource = apollon_smc91x_resources, | ||
121 | }; | ||
122 | |||
123 | static struct platform_device apollon_lcd_device = { | ||
124 | .name = "apollon_lcd", | ||
125 | .id = -1, | ||
126 | }; | ||
127 | |||
128 | static struct platform_device *apollon_devices[] __initdata = { | ||
129 | &apollon_onenand_device, | ||
130 | &apollon_smc91x_device, | ||
131 | &apollon_lcd_device, | ||
132 | }; | ||
133 | |||
134 | static inline void __init apollon_init_smc91x(void) | ||
135 | { | ||
136 | /* Make sure CS1 timings are correct */ | ||
137 | GPMC_CONFIG1_1 = 0x00011203; | ||
138 | GPMC_CONFIG2_1 = 0x001f1f01; | ||
139 | GPMC_CONFIG3_1 = 0x00080803; | ||
140 | GPMC_CONFIG4_1 = 0x1c091c09; | ||
141 | GPMC_CONFIG5_1 = 0x041f1f1f; | ||
142 | GPMC_CONFIG6_1 = 0x000004c4; | ||
143 | GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); | ||
144 | udelay(100); | ||
145 | |||
146 | omap_cfg_reg(W4__24XX_GPIO74); | ||
147 | if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { | ||
148 | printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", | ||
149 | APOLLON_ETHR_GPIO_IRQ); | ||
150 | return; | ||
151 | } | ||
152 | omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); | ||
153 | } | ||
154 | |||
155 | static void __init omap_apollon_init_irq(void) | ||
156 | { | ||
157 | omap2_init_common_hw(); | ||
158 | omap_init_irq(); | ||
159 | omap_gpio_init(); | ||
160 | apollon_init_smc91x(); | ||
161 | } | ||
162 | |||
163 | static struct omap_uart_config apollon_uart_config __initdata = { | ||
164 | .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), | ||
165 | }; | ||
166 | |||
167 | static struct omap_mmc_config apollon_mmc_config __initdata = { | ||
168 | .mmc [0] = { | ||
169 | .enabled = 0, | ||
170 | .wire4 = 0, | ||
171 | .wp_pin = -1, | ||
172 | .power_pin = -1, | ||
173 | .switch_pin = -1, | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | static struct omap_lcd_config apollon_lcd_config __initdata = { | ||
178 | .ctrl_name = "internal", | ||
179 | }; | ||
180 | |||
181 | static struct omap_board_config_kernel apollon_config[] = { | ||
182 | { OMAP_TAG_UART, &apollon_uart_config }, | ||
183 | { OMAP_TAG_MMC, &apollon_mmc_config }, | ||
184 | { OMAP_TAG_LCD, &apollon_lcd_config }, | ||
185 | }; | ||
186 | |||
187 | static void __init apollon_led_init(void) | ||
188 | { | ||
189 | /* LED0 - AA10 */ | ||
190 | omap_cfg_reg(AA10_242X_GPIO13); | ||
191 | omap_request_gpio(LED0_GPIO13); | ||
192 | omap_set_gpio_direction(LED0_GPIO13, 0); | ||
193 | omap_set_gpio_dataout(LED0_GPIO13, 0); | ||
194 | /* LED1 - AA6 */ | ||
195 | omap_cfg_reg(AA6_242X_GPIO14); | ||
196 | omap_request_gpio(LED1_GPIO14); | ||
197 | omap_set_gpio_direction(LED1_GPIO14, 0); | ||
198 | omap_set_gpio_dataout(LED1_GPIO14, 0); | ||
199 | /* LED2 - AA4 */ | ||
200 | omap_cfg_reg(AA4_242X_GPIO15); | ||
201 | omap_request_gpio(LED2_GPIO15); | ||
202 | omap_set_gpio_direction(LED2_GPIO15, 0); | ||
203 | omap_set_gpio_dataout(LED2_GPIO15, 0); | ||
204 | } | ||
205 | |||
206 | static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs) | ||
207 | { | ||
208 | static unsigned int led0, led1, led2; | ||
209 | |||
210 | if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16)) | ||
211 | omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1); | ||
212 | else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17)) | ||
213 | omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1); | ||
214 | else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58)) | ||
215 | omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1); | ||
216 | |||
217 | return IRQ_HANDLED; | ||
218 | } | ||
219 | |||
220 | static void __init apollon_sw_init(void) | ||
221 | { | ||
222 | /* Enter SW - Y11 */ | ||
223 | omap_cfg_reg(Y11_242X_GPIO16); | ||
224 | omap_request_gpio(SW_ENTER_GPIO16); | ||
225 | omap_set_gpio_direction(SW_ENTER_GPIO16, 1); | ||
226 | /* Up SW - AA12 */ | ||
227 | omap_cfg_reg(AA12_242X_GPIO17); | ||
228 | omap_request_gpio(SW_UP_GPIO17); | ||
229 | omap_set_gpio_direction(SW_UP_GPIO17, 1); | ||
230 | /* Down SW - AA8 */ | ||
231 | omap_cfg_reg(AA8_242X_GPIO58); | ||
232 | omap_request_gpio(SW_DOWN_GPIO58); | ||
233 | omap_set_gpio_direction(SW_DOWN_GPIO58, 1); | ||
234 | |||
235 | set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING); | ||
236 | if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, | ||
237 | SA_SHIRQ, "enter sw", | ||
238 | &apollon_sw_interrupt)) | ||
239 | return; | ||
240 | set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING); | ||
241 | if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, | ||
242 | SA_SHIRQ, "up sw", | ||
243 | &apollon_sw_interrupt)) | ||
244 | return; | ||
245 | set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING); | ||
246 | if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, | ||
247 | SA_SHIRQ, "down sw", | ||
248 | &apollon_sw_interrupt)) | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | static void __init omap_apollon_init(void) | ||
253 | { | ||
254 | apollon_led_init(); | ||
255 | apollon_sw_init(); | ||
256 | |||
257 | /* REVISIT: where's the correct place */ | ||
258 | omap_cfg_reg(W19_24XX_SYS_NIRQ); | ||
259 | |||
260 | /* | ||
261 | * Make sure the serial ports are muxed on at this point. | ||
262 | * You have to mux them off in device drivers later on | ||
263 | * if not needed. | ||
264 | */ | ||
265 | platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); | ||
266 | omap_board_config = apollon_config; | ||
267 | omap_board_config_size = ARRAY_SIZE(apollon_config); | ||
268 | omap_serial_init(); | ||
269 | } | ||
270 | |||
271 | static void __init omap_apollon_map_io(void) | ||
272 | { | ||
273 | omap2_map_common_io(); | ||
274 | } | ||
275 | |||
276 | MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") | ||
277 | /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ | ||
278 | .phys_io = 0x48000000, | ||
279 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
280 | .boot_params = 0x80000100, | ||
281 | .map_io = omap_apollon_map_io, | ||
282 | .init_irq = omap_apollon_init_irq, | ||
283 | .init_machine = omap_apollon_init, | ||
284 | .timer = &omap_timer, | ||
285 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index a300d634d8a5..4933fce766c8 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
18 | #include <linux/mtd/partitions.h> | 18 | #include <linux/mtd/partitions.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/workqueue.h> | ||
21 | #include <linux/input.h> | ||
20 | 22 | ||
21 | #include <asm/hardware.h> | 23 | #include <asm/hardware.h> |
22 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
@@ -25,15 +27,57 @@ | |||
25 | #include <asm/mach/flash.h> | 27 | #include <asm/mach/flash.h> |
26 | 28 | ||
27 | #include <asm/arch/gpio.h> | 29 | #include <asm/arch/gpio.h> |
30 | #include <asm/arch/gpioexpander.h> | ||
28 | #include <asm/arch/mux.h> | 31 | #include <asm/arch/mux.h> |
29 | #include <asm/arch/usb.h> | 32 | #include <asm/arch/usb.h> |
33 | #include <asm/arch/irda.h> | ||
30 | #include <asm/arch/board.h> | 34 | #include <asm/arch/board.h> |
31 | #include <asm/arch/common.h> | 35 | #include <asm/arch/common.h> |
32 | #include <asm/arch/prcm.h> | 36 | #include <asm/arch/keypad.h> |
37 | #include <asm/arch/menelaus.h> | ||
38 | #include <asm/arch/dma.h> | ||
39 | #include "prcm-regs.h" | ||
33 | 40 | ||
34 | #include <asm/io.h> | 41 | #include <asm/io.h> |
35 | #include <asm/delay.h> | 42 | #include <asm/delay.h> |
36 | 43 | ||
44 | static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; | ||
45 | static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; | ||
46 | |||
47 | static int h4_keymap[] = { | ||
48 | KEY(0, 0, KEY_LEFT), | ||
49 | KEY(0, 1, KEY_RIGHT), | ||
50 | KEY(0, 2, KEY_A), | ||
51 | KEY(0, 3, KEY_B), | ||
52 | KEY(0, 4, KEY_C), | ||
53 | KEY(1, 0, KEY_DOWN), | ||
54 | KEY(1, 1, KEY_UP), | ||
55 | KEY(1, 2, KEY_E), | ||
56 | KEY(1, 3, KEY_F), | ||
57 | KEY(1, 4, KEY_G), | ||
58 | KEY(2, 0, KEY_ENTER), | ||
59 | KEY(2, 1, KEY_I), | ||
60 | KEY(2, 2, KEY_J), | ||
61 | KEY(2, 3, KEY_K), | ||
62 | KEY(2, 4, KEY_3), | ||
63 | KEY(3, 0, KEY_M), | ||
64 | KEY(3, 1, KEY_N), | ||
65 | KEY(3, 2, KEY_O), | ||
66 | KEY(3, 3, KEY_P), | ||
67 | KEY(3, 4, KEY_Q), | ||
68 | KEY(4, 0, KEY_R), | ||
69 | KEY(4, 1, KEY_4), | ||
70 | KEY(4, 2, KEY_T), | ||
71 | KEY(4, 3, KEY_U), | ||
72 | KEY(4, 4, KEY_ENTER), | ||
73 | KEY(5, 0, KEY_V), | ||
74 | KEY(5, 1, KEY_W), | ||
75 | KEY(5, 2, KEY_L), | ||
76 | KEY(5, 3, KEY_S), | ||
77 | KEY(5, 4, KEY_ENTER), | ||
78 | 0 | ||
79 | }; | ||
80 | |||
37 | static struct mtd_partition h4_partitions[] = { | 81 | static struct mtd_partition h4_partitions[] = { |
38 | /* bootloader (U-Boot, etc) in first sector */ | 82 | /* bootloader (U-Boot, etc) in first sector */ |
39 | { | 83 | { |
@@ -108,9 +152,123 @@ static struct platform_device h4_smc91x_device = { | |||
108 | .resource = h4_smc91x_resources, | 152 | .resource = h4_smc91x_resources, |
109 | }; | 153 | }; |
110 | 154 | ||
155 | /* Select between the IrDA and aGPS module | ||
156 | */ | ||
157 | static int h4_select_irda(struct device *dev, int state) | ||
158 | { | ||
159 | unsigned char expa; | ||
160 | int err = 0; | ||
161 | |||
162 | if ((err = read_gpio_expa(&expa, 0x21))) { | ||
163 | printk(KERN_ERR "Error reading from I/O expander\n"); | ||
164 | return err; | ||
165 | } | ||
166 | |||
167 | /* 'P6' enable/disable IRDA_TX and IRDA_RX */ | ||
168 | if (state & IR_SEL) { /* IrDa */ | ||
169 | if ((err = write_gpio_expa(expa | 0x01, 0x21))) { | ||
170 | printk(KERN_ERR "Error writing to I/O expander\n"); | ||
171 | return err; | ||
172 | } | ||
173 | } else { | ||
174 | if ((err = write_gpio_expa(expa & ~0x01, 0x21))) { | ||
175 | printk(KERN_ERR "Error writing to I/O expander\n"); | ||
176 | return err; | ||
177 | } | ||
178 | } | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | static void set_trans_mode(void *data) | ||
183 | { | ||
184 | int *mode = data; | ||
185 | unsigned char expa; | ||
186 | int err = 0; | ||
187 | |||
188 | if ((err = read_gpio_expa(&expa, 0x20)) != 0) { | ||
189 | printk(KERN_ERR "Error reading from I/O expander\n"); | ||
190 | } | ||
191 | |||
192 | expa &= ~0x01; | ||
193 | |||
194 | if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */ | ||
195 | expa |= 0x01; | ||
196 | } | ||
197 | |||
198 | if ((err = write_gpio_expa(expa, 0x20)) != 0) { | ||
199 | printk(KERN_ERR "Error writing to I/O expander\n"); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static int h4_transceiver_mode(struct device *dev, int mode) | ||
204 | { | ||
205 | struct omap_irda_config *irda_config = dev->platform_data; | ||
206 | |||
207 | cancel_delayed_work(&irda_config->gpio_expa); | ||
208 | PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); | ||
209 | schedule_work(&irda_config->gpio_expa); | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static struct omap_irda_config h4_irda_data = { | ||
215 | .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, | ||
216 | .transceiver_mode = h4_transceiver_mode, | ||
217 | .select_irda = h4_select_irda, | ||
218 | .rx_channel = OMAP24XX_DMA_UART3_RX, | ||
219 | .tx_channel = OMAP24XX_DMA_UART3_TX, | ||
220 | .dest_start = OMAP_UART3_BASE, | ||
221 | .src_start = OMAP_UART3_BASE, | ||
222 | .tx_trigger = OMAP24XX_DMA_UART3_TX, | ||
223 | .rx_trigger = OMAP24XX_DMA_UART3_RX, | ||
224 | }; | ||
225 | |||
226 | static struct resource h4_irda_resources[] = { | ||
227 | [0] = { | ||
228 | .start = INT_24XX_UART3_IRQ, | ||
229 | .end = INT_24XX_UART3_IRQ, | ||
230 | .flags = IORESOURCE_IRQ, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | static struct platform_device h4_irda_device = { | ||
235 | .name = "omapirda", | ||
236 | .id = -1, | ||
237 | .dev = { | ||
238 | .platform_data = &h4_irda_data, | ||
239 | }, | ||
240 | .num_resources = 1, | ||
241 | .resource = h4_irda_resources, | ||
242 | }; | ||
243 | |||
244 | static struct omap_kp_platform_data h4_kp_data = { | ||
245 | .rows = 6, | ||
246 | .cols = 7, | ||
247 | .keymap = h4_keymap, | ||
248 | .rep = 1, | ||
249 | .row_gpios = row_gpios, | ||
250 | .col_gpios = col_gpios, | ||
251 | }; | ||
252 | |||
253 | static struct platform_device h4_kp_device = { | ||
254 | .name = "omap-keypad", | ||
255 | .id = -1, | ||
256 | .dev = { | ||
257 | .platform_data = &h4_kp_data, | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | static struct platform_device h4_lcd_device = { | ||
262 | .name = "lcd_h4", | ||
263 | .id = -1, | ||
264 | }; | ||
265 | |||
111 | static struct platform_device *h4_devices[] __initdata = { | 266 | static struct platform_device *h4_devices[] __initdata = { |
112 | &h4_smc91x_device, | 267 | &h4_smc91x_device, |
113 | &h4_flash_device, | 268 | &h4_flash_device, |
269 | &h4_irda_device, | ||
270 | &h4_kp_device, | ||
271 | &h4_lcd_device, | ||
114 | }; | 272 | }; |
115 | 273 | ||
116 | static inline void __init h4_init_smc91x(void) | 274 | static inline void __init h4_init_smc91x(void) |
@@ -157,7 +315,6 @@ static struct omap_mmc_config h4_mmc_config __initdata = { | |||
157 | }; | 315 | }; |
158 | 316 | ||
159 | static struct omap_lcd_config h4_lcd_config __initdata = { | 317 | static struct omap_lcd_config h4_lcd_config __initdata = { |
160 | .panel_name = "h4", | ||
161 | .ctrl_name = "internal", | 318 | .ctrl_name = "internal", |
162 | }; | 319 | }; |
163 | 320 | ||
@@ -174,6 +331,19 @@ static void __init omap_h4_init(void) | |||
174 | * You have to mux them off in device drivers later on | 331 | * You have to mux them off in device drivers later on |
175 | * if not needed. | 332 | * if not needed. |
176 | */ | 333 | */ |
334 | #if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) | ||
335 | omap_cfg_reg(K15_24XX_UART3_TX); | ||
336 | omap_cfg_reg(K14_24XX_UART3_RX); | ||
337 | #endif | ||
338 | |||
339 | #if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) | ||
340 | if (omap_has_menelaus()) { | ||
341 | row_gpios[5] = 0; | ||
342 | col_gpios[2] = 15; | ||
343 | col_gpios[6] = 18; | ||
344 | } | ||
345 | #endif | ||
346 | |||
177 | platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); | 347 | platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); |
178 | omap_board_config = h4_config; | 348 | omap_board_config = h4_config; |
179 | omap_board_config_size = ARRAY_SIZE(h4_config); | 349 | omap_board_config_size = ARRAY_SIZE(h4_config); |
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 180f675c9064..72eb4bf571ac 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -28,14 +28,14 @@ | |||
28 | 28 | ||
29 | #include <asm/arch/clock.h> | 29 | #include <asm/arch/clock.h> |
30 | #include <asm/arch/sram.h> | 30 | #include <asm/arch/sram.h> |
31 | #include <asm/arch/prcm.h> | ||
32 | 31 | ||
32 | #include "prcm-regs.h" | ||
33 | #include "memory.h" | ||
33 | #include "clock.h" | 34 | #include "clock.h" |
34 | 35 | ||
35 | //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ | 36 | //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ |
36 | 37 | ||
37 | static struct prcm_config *curr_prcm_set; | 38 | static struct prcm_config *curr_prcm_set; |
38 | static struct memory_timings mem_timings; | ||
39 | static u32 curr_perf_level = PRCM_FULL_SPEED; | 39 | static u32 curr_perf_level = PRCM_FULL_SPEED; |
40 | 40 | ||
41 | /*------------------------------------------------------------------------- | 41 | /*------------------------------------------------------------------------- |
@@ -54,11 +54,13 @@ static void omap2_sys_clk_recalc(struct clk * clk) | |||
54 | 54 | ||
55 | static u32 omap2_get_dpll_rate(struct clk * tclk) | 55 | static u32 omap2_get_dpll_rate(struct clk * tclk) |
56 | { | 56 | { |
57 | int dpll_clk, dpll_mult, dpll_div, amult; | 57 | long long dpll_clk; |
58 | int dpll_mult, dpll_div, amult; | ||
58 | 59 | ||
59 | dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ | 60 | dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ |
60 | dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ | 61 | dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ |
61 | dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1); | 62 | dpll_clk = (long long)tclk->parent->rate * dpll_mult; |
63 | do_div(dpll_clk, dpll_div + 1); | ||
62 | amult = CM_CLKSEL2_PLL & 0x3; | 64 | amult = CM_CLKSEL2_PLL & 0x3; |
63 | dpll_clk *= amult; | 65 | dpll_clk *= amult; |
64 | 66 | ||
@@ -385,75 +387,23 @@ static u32 omap2_dll_force_needed(void) | |||
385 | return 0; | 387 | return 0; |
386 | } | 388 | } |
387 | 389 | ||
388 | static void omap2_init_memory_params(u32 force_lock_to_unlock_mode) | ||
389 | { | ||
390 | unsigned long dll_cnt; | ||
391 | u32 fast_dll = 0; | ||
392 | |||
393 | mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ | ||
394 | |||
395 | /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. | ||
396 | * In the case of 2422, its ok to use CS1 instead of CS0. | ||
397 | */ | ||
398 | |||
399 | #if 0 /* FIXME: Enable after 24xx cpu detection works */ | ||
400 | ctype = get_cpu_type(); | ||
401 | if (cpu_is_omap2422()) | ||
402 | mem_timings.base_cs = 1; | ||
403 | else | ||
404 | #endif | ||
405 | mem_timings.base_cs = 0; | ||
406 | |||
407 | if (mem_timings.m_type != M_DDR) | ||
408 | return; | ||
409 | |||
410 | /* With DDR we need to determine the low frequency DLL value */ | ||
411 | if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) | ||
412 | mem_timings.dll_mode = M_UNLOCK; | ||
413 | else | ||
414 | mem_timings.dll_mode = M_LOCK; | ||
415 | |||
416 | if (mem_timings.base_cs == 0) { | ||
417 | fast_dll = SDRC_DLLA_CTRL; | ||
418 | dll_cnt = SDRC_DLLA_STATUS & 0xff00; | ||
419 | } else { | ||
420 | fast_dll = SDRC_DLLB_CTRL; | ||
421 | dll_cnt = SDRC_DLLB_STATUS & 0xff00; | ||
422 | } | ||
423 | if (force_lock_to_unlock_mode) { | ||
424 | fast_dll &= ~0xff00; | ||
425 | fast_dll |= dll_cnt; /* Current lock mode */ | ||
426 | } | ||
427 | mem_timings.fast_dll_ctrl = fast_dll; | ||
428 | |||
429 | /* No disruptions, DDR will be offline & C-ABI not followed */ | ||
430 | omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, | ||
431 | mem_timings.fast_dll_ctrl, | ||
432 | mem_timings.base_cs, | ||
433 | force_lock_to_unlock_mode); | ||
434 | mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ | ||
435 | |||
436 | /* Turn status into unlock ctrl */ | ||
437 | mem_timings.slow_dll_ctrl |= | ||
438 | ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); | ||
439 | |||
440 | /* 90 degree phase for anything below 133Mhz */ | ||
441 | mem_timings.slow_dll_ctrl |= (1 << 1); | ||
442 | } | ||
443 | |||
444 | static u32 omap2_reprogram_sdrc(u32 level, u32 force) | 390 | static u32 omap2_reprogram_sdrc(u32 level, u32 force) |
445 | { | 391 | { |
392 | u32 slow_dll_ctrl, fast_dll_ctrl, m_type; | ||
446 | u32 prev = curr_perf_level, flags; | 393 | u32 prev = curr_perf_level, flags; |
447 | 394 | ||
448 | if ((curr_perf_level == level) && !force) | 395 | if ((curr_perf_level == level) && !force) |
449 | return prev; | 396 | return prev; |
450 | 397 | ||
398 | m_type = omap2_memory_get_type(); | ||
399 | slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl(); | ||
400 | fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl(); | ||
401 | |||
451 | if (level == PRCM_HALF_SPEED) { | 402 | if (level == PRCM_HALF_SPEED) { |
452 | local_irq_save(flags); | 403 | local_irq_save(flags); |
453 | PRCM_VOLTSETUP = 0xffff; | 404 | PRCM_VOLTSETUP = 0xffff; |
454 | omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, | 405 | omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, |
455 | mem_timings.slow_dll_ctrl, | 406 | slow_dll_ctrl, m_type); |
456 | mem_timings.m_type); | ||
457 | curr_perf_level = PRCM_HALF_SPEED; | 407 | curr_perf_level = PRCM_HALF_SPEED; |
458 | local_irq_restore(flags); | 408 | local_irq_restore(flags); |
459 | } | 409 | } |
@@ -461,8 +411,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force) | |||
461 | local_irq_save(flags); | 411 | local_irq_save(flags); |
462 | PRCM_VOLTSETUP = 0xffff; | 412 | PRCM_VOLTSETUP = 0xffff; |
463 | omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, | 413 | omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, |
464 | mem_timings.fast_dll_ctrl, | 414 | fast_dll_ctrl, m_type); |
465 | mem_timings.m_type); | ||
466 | curr_perf_level = PRCM_FULL_SPEED; | 415 | curr_perf_level = PRCM_FULL_SPEED; |
467 | local_irq_restore(flags); | 416 | local_irq_restore(flags); |
468 | } | 417 | } |
@@ -650,7 +599,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask, | |||
650 | case 13: /* dss2 */ | 599 | case 13: /* dss2 */ |
651 | mask = 0x1; break; | 600 | mask = 0x1; break; |
652 | case 25: /* usb */ | 601 | case 25: /* usb */ |
653 | mask = 0xf; break; | 602 | mask = 0x7; break; |
654 | } | 603 | } |
655 | } | 604 | } |
656 | 605 | ||
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 6cab20b1d3c1..6c78d471fab7 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -33,20 +33,6 @@ static u32 omap2_clksel_get_divisor(struct clk *clk); | |||
33 | #define RATE_IN_242X (1 << 0) | 33 | #define RATE_IN_242X (1 << 0) |
34 | #define RATE_IN_243X (1 << 1) | 34 | #define RATE_IN_243X (1 << 1) |
35 | 35 | ||
36 | /* Memory timings */ | ||
37 | #define M_DDR 1 | ||
38 | #define M_LOCK_CTRL (1 << 2) | ||
39 | #define M_UNLOCK 0 | ||
40 | #define M_LOCK 1 | ||
41 | |||
42 | struct memory_timings { | ||
43 | u32 m_type; /* ddr = 1, sdr = 0 */ | ||
44 | u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ | ||
45 | u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ | ||
46 | u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ | ||
47 | u32 base_cs; /* base chip select to use for calculations */ | ||
48 | }; | ||
49 | |||
50 | /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. | 36 | /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. |
51 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP | 37 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP |
52 | * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM | 38 | * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM |
@@ -731,6 +717,16 @@ static struct clk sys_clkout2 = { | |||
731 | .recalc = &omap2_clksel_recalc, | 717 | .recalc = &omap2_clksel_recalc, |
732 | }; | 718 | }; |
733 | 719 | ||
720 | static struct clk emul_ck = { | ||
721 | .name = "emul_ck", | ||
722 | .parent = &func_54m_ck, | ||
723 | .flags = CLOCK_IN_OMAP242X, | ||
724 | .enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL, | ||
725 | .enable_bit = 0, | ||
726 | .recalc = &omap2_propagate_rate, | ||
727 | |||
728 | }; | ||
729 | |||
734 | /* | 730 | /* |
735 | * MPU clock domain | 731 | * MPU clock domain |
736 | * Clocks: | 732 | * Clocks: |
@@ -1702,7 +1698,8 @@ static struct clk hdq_fck = { | |||
1702 | }; | 1698 | }; |
1703 | 1699 | ||
1704 | static struct clk i2c2_ick = { | 1700 | static struct clk i2c2_ick = { |
1705 | .name = "i2c2_ick", | 1701 | .name = "i2c_ick", |
1702 | .id = 2, | ||
1706 | .parent = &l4_ck, | 1703 | .parent = &l4_ck, |
1707 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1704 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1708 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | 1705 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, |
@@ -1711,7 +1708,8 @@ static struct clk i2c2_ick = { | |||
1711 | }; | 1708 | }; |
1712 | 1709 | ||
1713 | static struct clk i2c2_fck = { | 1710 | static struct clk i2c2_fck = { |
1714 | .name = "i2c2_fck", | 1711 | .name = "i2c_fck", |
1712 | .id = 2, | ||
1715 | .parent = &func_12m_ck, | 1713 | .parent = &func_12m_ck, |
1716 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1714 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1717 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | 1715 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, |
@@ -1729,7 +1727,8 @@ static struct clk i2chs2_fck = { | |||
1729 | }; | 1727 | }; |
1730 | 1728 | ||
1731 | static struct clk i2c1_ick = { | 1729 | static struct clk i2c1_ick = { |
1732 | .name = "i2c1_ick", | 1730 | .name = "i2c_ick", |
1731 | .id = 1, | ||
1733 | .parent = &l4_ck, | 1732 | .parent = &l4_ck, |
1734 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1733 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1735 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | 1734 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, |
@@ -1738,7 +1737,8 @@ static struct clk i2c1_ick = { | |||
1738 | }; | 1737 | }; |
1739 | 1738 | ||
1740 | static struct clk i2c1_fck = { | 1739 | static struct clk i2c1_fck = { |
1741 | .name = "i2c1_fck", | 1740 | .name = "i2c_fck", |
1741 | .id = 1, | ||
1742 | .parent = &func_12m_ck, | 1742 | .parent = &func_12m_ck, |
1743 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1743 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1744 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | 1744 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, |
@@ -1971,6 +1971,7 @@ static struct clk *onchip_clks[] = { | |||
1971 | &wdt1_osc_ck, | 1971 | &wdt1_osc_ck, |
1972 | &sys_clkout, | 1972 | &sys_clkout, |
1973 | &sys_clkout2, | 1973 | &sys_clkout2, |
1974 | &emul_ck, | ||
1974 | /* mpu domain clocks */ | 1975 | /* mpu domain clocks */ |
1975 | &mpu_ck, | 1976 | &mpu_ck, |
1976 | /* dsp domain clocks */ | 1977 | /* dsp domain clocks */ |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 7181edb89352..def9e5370edf 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -74,6 +74,47 @@ static void omap_init_i2c(void) {} | |||
74 | 74 | ||
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | #if defined(CONFIG_OMAP_STI) | ||
78 | |||
79 | #define OMAP2_STI_BASE IO_ADDRESS(0x48068000) | ||
80 | #define OMAP2_STI_CHANNEL_BASE 0x54000000 | ||
81 | #define OMAP2_STI_IRQ 4 | ||
82 | |||
83 | static struct resource sti_resources[] = { | ||
84 | { | ||
85 | .start = OMAP2_STI_BASE, | ||
86 | .end = OMAP2_STI_BASE + 0x7ff, | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | }, | ||
89 | { | ||
90 | .start = OMAP2_STI_CHANNEL_BASE, | ||
91 | .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1, | ||
92 | .flags = IORESOURCE_MEM, | ||
93 | }, | ||
94 | { | ||
95 | .start = OMAP2_STI_IRQ, | ||
96 | .flags = IORESOURCE_IRQ, | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | static struct platform_device sti_device = { | ||
101 | .name = "sti", | ||
102 | .id = -1, | ||
103 | .dev = { | ||
104 | .release = omap_nop_release, | ||
105 | }, | ||
106 | .num_resources = ARRAY_SIZE(sti_resources), | ||
107 | .resource = sti_resources, | ||
108 | }; | ||
109 | |||
110 | static inline void omap_init_sti(void) | ||
111 | { | ||
112 | platform_device_register(&sti_device); | ||
113 | } | ||
114 | #else | ||
115 | static inline void omap_init_sti(void) {} | ||
116 | #endif | ||
117 | |||
77 | /*-------------------------------------------------------------------------*/ | 118 | /*-------------------------------------------------------------------------*/ |
78 | 119 | ||
79 | static int __init omap2_init_devices(void) | 120 | static int __init omap2_init_devices(void) |
@@ -82,6 +123,7 @@ static int __init omap2_init_devices(void) | |||
82 | * in alphabetical order so they're easier to sort through. | 123 | * in alphabetical order so they're easier to sort through. |
83 | */ | 124 | */ |
84 | omap_init_i2c(); | 125 | omap_init_i2c(); |
126 | omap_init_sti(); | ||
85 | 127 | ||
86 | return 0; | 128 | return 0; |
87 | } | 129 | } |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 8ea67bf196a5..7d5711611f2f 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -16,9 +16,13 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | 18 | ||
19 | #include <asm/mach/map.h> | 19 | #include <asm/tlb.h> |
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | |||
22 | #include <asm/mach/map.h> | ||
23 | |||
21 | #include <asm/arch/mux.h> | 24 | #include <asm/arch/mux.h> |
25 | #include <asm/arch/omapfb.h> | ||
22 | 26 | ||
23 | extern void omap_sram_init(void); | 27 | extern void omap_sram_init(void); |
24 | extern int omap2_clk_init(void); | 28 | extern int omap2_clk_init(void); |
@@ -43,11 +47,24 @@ static struct map_desc omap2_io_desc[] __initdata = { | |||
43 | } | 47 | } |
44 | }; | 48 | }; |
45 | 49 | ||
46 | void __init omap_map_common_io(void) | 50 | void __init omap2_map_common_io(void) |
47 | { | 51 | { |
48 | iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); | 52 | iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); |
53 | |||
54 | /* Normally devicemaps_init() would flush caches and tlb after | ||
55 | * mdesc->map_io(), but we must also do it here because of the CPU | ||
56 | * revision check below. | ||
57 | */ | ||
58 | local_flush_tlb_all(); | ||
59 | flush_cache_all(); | ||
60 | |||
49 | omap2_check_revision(); | 61 | omap2_check_revision(); |
50 | omap_sram_init(); | 62 | omap_sram_init(); |
63 | omapfb_reserve_mem(); | ||
64 | } | ||
65 | |||
66 | void __init omap2_init_common_hw(void) | ||
67 | { | ||
51 | omap2_mux_init(); | 68 | omap2_mux_init(); |
52 | omap2_clk_init(); | 69 | omap2_clk_init(); |
53 | } | 70 | } |
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c new file mode 100644 index 000000000000..1d925d69fc35 --- /dev/null +++ b/arch/arm/mach-omap2/memory.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/memory.c | ||
3 | * | ||
4 | * Memory timing related functions for OMAP24XX | ||
5 | * | ||
6 | * Copyright (C) 2005 Texas Instruments Inc. | ||
7 | * Richard Woodruff <r-woodruff2@ti.com> | ||
8 | * | ||
9 | * Copyright (C) 2005 Nokia Corporation | ||
10 | * Tony Lindgren <tony@atomide.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include <asm/arch/clock.h> | ||
29 | #include <asm/arch/sram.h> | ||
30 | |||
31 | #include "prcm-regs.h" | ||
32 | #include "memory.h" | ||
33 | |||
34 | static struct memory_timings mem_timings; | ||
35 | |||
36 | u32 omap2_memory_get_slow_dll_ctrl(void) | ||
37 | { | ||
38 | return mem_timings.slow_dll_ctrl; | ||
39 | } | ||
40 | |||
41 | u32 omap2_memory_get_fast_dll_ctrl(void) | ||
42 | { | ||
43 | return mem_timings.fast_dll_ctrl; | ||
44 | } | ||
45 | |||
46 | u32 omap2_memory_get_type(void) | ||
47 | { | ||
48 | return mem_timings.m_type; | ||
49 | } | ||
50 | |||
51 | void omap2_init_memory_params(u32 force_lock_to_unlock_mode) | ||
52 | { | ||
53 | unsigned long dll_cnt; | ||
54 | u32 fast_dll = 0; | ||
55 | |||
56 | mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ | ||
57 | |||
58 | /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. | ||
59 | * In the case of 2422, its ok to use CS1 instead of CS0. | ||
60 | */ | ||
61 | if (cpu_is_omap2422()) | ||
62 | mem_timings.base_cs = 1; | ||
63 | else | ||
64 | mem_timings.base_cs = 0; | ||
65 | |||
66 | if (mem_timings.m_type != M_DDR) | ||
67 | return; | ||
68 | |||
69 | /* With DDR we need to determine the low frequency DLL value */ | ||
70 | if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) | ||
71 | mem_timings.dll_mode = M_UNLOCK; | ||
72 | else | ||
73 | mem_timings.dll_mode = M_LOCK; | ||
74 | |||
75 | if (mem_timings.base_cs == 0) { | ||
76 | fast_dll = SDRC_DLLA_CTRL; | ||
77 | dll_cnt = SDRC_DLLA_STATUS & 0xff00; | ||
78 | } else { | ||
79 | fast_dll = SDRC_DLLB_CTRL; | ||
80 | dll_cnt = SDRC_DLLB_STATUS & 0xff00; | ||
81 | } | ||
82 | if (force_lock_to_unlock_mode) { | ||
83 | fast_dll &= ~0xff00; | ||
84 | fast_dll |= dll_cnt; /* Current lock mode */ | ||
85 | } | ||
86 | /* set fast timings with DLL filter disabled */ | ||
87 | mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8)); | ||
88 | |||
89 | /* No disruptions, DDR will be offline & C-ABI not followed */ | ||
90 | omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, | ||
91 | mem_timings.fast_dll_ctrl, | ||
92 | mem_timings.base_cs, | ||
93 | force_lock_to_unlock_mode); | ||
94 | mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ | ||
95 | |||
96 | /* Turn status into unlock ctrl */ | ||
97 | mem_timings.slow_dll_ctrl |= | ||
98 | ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); | ||
99 | |||
100 | /* 90 degree phase for anything below 133Mhz + disable DLL filter */ | ||
101 | mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); | ||
102 | } | ||
diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h new file mode 100644 index 000000000000..d212eea83a05 --- /dev/null +++ b/arch/arm/mach-omap2/memory.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/memory.h | ||
3 | * | ||
4 | * Interface for memory timing related functions for OMAP24XX | ||
5 | * | ||
6 | * Copyright (C) 2005 Texas Instruments Inc. | ||
7 | * Richard Woodruff <r-woodruff2@ti.com> | ||
8 | * | ||
9 | * Copyright (C) 2005 Nokia Corporation | ||
10 | * Tony Lindgren <tony@atomide.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | /* Memory timings */ | ||
18 | #define M_DDR 1 | ||
19 | #define M_LOCK_CTRL (1 << 2) | ||
20 | #define M_UNLOCK 0 | ||
21 | #define M_LOCK 1 | ||
22 | |||
23 | struct memory_timings { | ||
24 | u32 m_type; /* ddr = 1, sdr = 0 */ | ||
25 | u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ | ||
26 | u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ | ||
27 | u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ | ||
28 | u32 base_cs; /* base chip select to use for calculations */ | ||
29 | }; | ||
30 | |||
31 | extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode); | ||
32 | extern u32 omap2_memory_get_slow_dll_ctrl(void); | ||
33 | extern u32 omap2_memory_get_fast_dll_ctrl(void); | ||
34 | extern u32 omap2_memory_get_type(void); | ||
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index ea4654815dd1..1197dc38c20a 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -50,9 +50,54 @@ MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1) | |||
50 | /* Menelaus interrupt */ | 50 | /* Menelaus interrupt */ |
51 | MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) | 51 | MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) |
52 | 52 | ||
53 | /* 24xx clocks */ | ||
54 | MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) | ||
55 | |||
56 | /* 24xx McBSP */ | ||
57 | MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1) | ||
58 | MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1) | ||
59 | MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1) | ||
60 | MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1) | ||
61 | |||
53 | /* 24xx GPIO */ | 62 | /* 24xx GPIO */ |
63 | MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) | ||
64 | MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) | ||
65 | MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) | ||
66 | MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) | ||
67 | MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) | ||
68 | MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) | ||
69 | MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) | ||
54 | MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) | 70 | MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) |
71 | MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) | ||
55 | MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) | 72 | MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) |
73 | MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) | ||
74 | |||
75 | /* TSC IRQ */ | ||
76 | MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) | ||
77 | |||
78 | /* UART3 */ | ||
79 | MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) | ||
80 | MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) | ||
81 | |||
82 | /* Keypad GPIO*/ | ||
83 | MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) | ||
84 | MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) | ||
85 | MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1) | ||
86 | MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1) | ||
87 | MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1) | ||
88 | MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1) | ||
89 | MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1) | ||
90 | MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1) | ||
91 | MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1) | ||
92 | MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1) | ||
93 | MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1) | ||
94 | MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1) | ||
95 | MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1) | ||
96 | |||
97 | /* 24xx Menelaus Keypad GPIO */ | ||
98 | MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1) | ||
99 | MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1) | ||
100 | MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1) | ||
56 | 101 | ||
57 | }; | 102 | }; |
58 | 103 | ||
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c new file mode 100644 index 000000000000..562168fa2b16 --- /dev/null +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -0,0 +1,149 @@ | |||
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/pm.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/proc_fs.h> | ||
22 | #include <linux/pm.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/sysfs.h> | ||
25 | #include <linux/module.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/atomic.h> | ||
30 | #include <asm/mach/time.h> | ||
31 | #include <asm/mach/irq.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | |||
34 | #include <asm/arch/irqs.h> | ||
35 | #include <asm/arch/clock.h> | ||
36 | #include <asm/arch/sram.h> | ||
37 | #include <asm/arch/pm.h> | ||
38 | |||
39 | static struct clk *vclk; | ||
40 | static void (*omap2_sram_idle)(void); | ||
41 | static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); | ||
42 | static void (*saved_idle)(void); | ||
43 | |||
44 | void omap2_pm_idle(void) | ||
45 | { | ||
46 | local_irq_disable(); | ||
47 | local_fiq_disable(); | ||
48 | if (need_resched()) { | ||
49 | local_fiq_enable(); | ||
50 | local_irq_enable(); | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Since an interrupt may set up a timer, we don't want to | ||
56 | * reprogram the hardware timer with interrupts enabled. | ||
57 | * Re-enable interrupts only after returning from idle. | ||
58 | */ | ||
59 | timer_dyn_reprogram(); | ||
60 | |||
61 | omap2_sram_idle(); | ||
62 | local_fiq_enable(); | ||
63 | local_irq_enable(); | ||
64 | } | ||
65 | |||
66 | static int omap2_pm_prepare(suspend_state_t state) | ||
67 | { | ||
68 | int error = 0; | ||
69 | |||
70 | /* We cannot sleep in idle until we have resumed */ | ||
71 | saved_idle = pm_idle; | ||
72 | pm_idle = NULL; | ||
73 | |||
74 | switch (state) | ||
75 | { | ||
76 | case PM_SUSPEND_STANDBY: | ||
77 | case PM_SUSPEND_MEM: | ||
78 | break; | ||
79 | |||
80 | case PM_SUSPEND_DISK: | ||
81 | return -ENOTSUPP; | ||
82 | |||
83 | default: | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | return error; | ||
88 | } | ||
89 | |||
90 | static int omap2_pm_enter(suspend_state_t state) | ||
91 | { | ||
92 | switch (state) | ||
93 | { | ||
94 | case PM_SUSPEND_STANDBY: | ||
95 | case PM_SUSPEND_MEM: | ||
96 | /* FIXME: Add suspend */ | ||
97 | break; | ||
98 | |||
99 | case PM_SUSPEND_DISK: | ||
100 | return -ENOTSUPP; | ||
101 | |||
102 | default: | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int omap2_pm_finish(suspend_state_t state) | ||
110 | { | ||
111 | pm_idle = saved_idle; | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct pm_ops omap_pm_ops = { | ||
116 | .pm_disk_mode = 0, | ||
117 | .prepare = omap2_pm_prepare, | ||
118 | .enter = omap2_pm_enter, | ||
119 | .finish = omap2_pm_finish, | ||
120 | }; | ||
121 | |||
122 | int __init omap2_pm_init(void) | ||
123 | { | ||
124 | printk("Power Management for TI OMAP.\n"); | ||
125 | |||
126 | vclk = clk_get(NULL, "virt_prcm_set"); | ||
127 | if (IS_ERR(vclk)) { | ||
128 | printk(KERN_ERR "Could not get PM vclk\n"); | ||
129 | return -ENODEV; | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * We copy the assembler sleep/wakeup routines to SRAM. | ||
134 | * These routines need to be in SRAM as that's the only | ||
135 | * memory the MPU can see when it wakes up. | ||
136 | */ | ||
137 | omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, | ||
138 | omap24xx_idle_loop_suspend_sz); | ||
139 | |||
140 | omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, | ||
141 | omap24xx_cpu_suspend_sz); | ||
142 | |||
143 | pm_set_ops(&omap_pm_ops); | ||
144 | pm_idle = omap2_pm_idle; | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | __initcall(omap2_pm_init); | ||
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm-regs.h index 2eb89b936c83..22ac7be4f782 100644 --- a/arch/arm/mach-omap2/prcm.h +++ b/arch/arm/mach-omap2/prcm-regs.h | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * prcm.h - Access definations for use in OMAP24XX clock and power management | 2 | * linux/arch/arm/mach-omap2/prcm-reg.h |
3 | * | ||
4 | * OMAP24XX Power Reset and Clock Management (PRCM) registers | ||
3 | * | 5 | * |
4 | * Copyright (C) 2005 Texas Instruments, Inc. | 6 | * Copyright (C) 2005 Texas Instruments, Inc. |
5 | * | 7 | * |
@@ -18,8 +20,8 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 21 | */ |
20 | 22 | ||
21 | #ifndef __ASM_ARM_ARCH_DPM_PRCM_H | 23 | #ifndef __ARCH_ARM_MACH_OMAP2_PRCM_H |
22 | #define __ASM_ARM_ARCH_DPM_PRCM_H | 24 | #define __ARCH_ARM_MACH_OMAP2_PRCM_H |
23 | 25 | ||
24 | /* SET_PERFORMANCE_LEVEL PARAMETERS */ | 26 | /* SET_PERFORMANCE_LEVEL PARAMETERS */ |
25 | #define PRCM_HALF_SPEED 1 | 27 | #define PRCM_HALF_SPEED 1 |
@@ -159,54 +161,63 @@ | |||
159 | #define CM_FCLKEN_MDM PRCM_REG32(0xC00) | 161 | #define CM_FCLKEN_MDM PRCM_REG32(0xC00) |
160 | #define CM_ICLKEN_MDM PRCM_REG32(0xC10) | 162 | #define CM_ICLKEN_MDM PRCM_REG32(0xC10) |
161 | #define CM_IDLEST_MDM PRCM_REG32(0xC20) | 163 | #define CM_IDLEST_MDM PRCM_REG32(0xC20) |
164 | #define CM_AUTOIDLE_MDM PRCM_REG32(0xC30) | ||
162 | #define CM_CLKSEL_MDM PRCM_REG32(0xC40) | 165 | #define CM_CLKSEL_MDM PRCM_REG32(0xC40) |
163 | 166 | #define CM_CLKSTCTRL_MDM PRCM_REG32(0xC48) | |
164 | /* FIXME: Move to header for 2430 */ | 167 | #define RM_RSTCTRL_MDM PRCM_REG32(0xC50) |
165 | #define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000) | 168 | #define RM_RSTST_MDM PRCM_REG32(0xC58) |
169 | #define PM_WKEN_MDM PRCM_REG32(0xCA0) | ||
170 | #define PM_WKST_MDM PRCM_REG32(0xCB0) | ||
171 | #define PM_WKDEP_MDM PRCM_REG32(0xCC8) | ||
172 | #define PM_PWSTCTRL_MDM PRCM_REG32(0xCE0) | ||
173 | #define PM_PWSTST_MDM PRCM_REG32(0xCE4) | ||
174 | |||
175 | #define OMAP24XX_L4_IO_BASE 0x48000000 | ||
176 | |||
177 | #define DISP_BASE (OMAP24XX_L4_IO_BASE + 0x50000) | ||
166 | #define DISP_REG32(offset) __REG32(DISP_BASE + (offset)) | 178 | #define DISP_REG32(offset) __REG32(DISP_BASE + (offset)) |
167 | 179 | ||
168 | #define GPMC_BASE (OMAP24XX_GPMC_BASE) | 180 | #define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000) |
169 | #define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset)) | 181 | #define GPMC_REG32(offset) __REG32(OMAP24XX_GPMC_BASE + (offset)) |
170 | 182 | ||
171 | #define GPT1_BASE (OMAP24XX_GPT1) | 183 | /* FIXME: Move these to timer code */ |
184 | #define GPT1_BASE (0x48028000) | ||
172 | #define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset)) | 185 | #define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset)) |
173 | 186 | ||
174 | /* Misc sysconfig */ | 187 | /* Misc sysconfig */ |
175 | #define DISPC_SYSCONFIG DISP_REG32(0x410) | 188 | #define DISPC_SYSCONFIG DISP_REG32(0x410) |
176 | #define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000) | 189 | #define SPI_BASE (OMAP24XX_L4_IO_BASE + 0x98000) |
177 | #define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10) | 190 | #define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10) |
178 | #define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10) | 191 | #define MCSPI2_SYSCONFIG __REG32(SPI_BASE + 0x2000 + 0x10) |
179 | 192 | #define MCSPI3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0xb8010) | |
180 | //#define DSP_MMU_SYSCONFIG 0x5A000010 | 193 | |
181 | #define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10) | 194 | #define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE + 0x2C10) |
182 | //#define IVA_MMU_SYSCONFIG 0x5D000010 | 195 | #define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE + 0x282C) |
183 | //#define DSP_DMA_SYSCONFIG 0x00FCC02C | 196 | #define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE + 0x602C) |
184 | #define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C) | ||
185 | #define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C) | ||
186 | #define GPMC_SYSCONFIG GPMC_REG32(0x010) | 197 | #define GPMC_SYSCONFIG GPMC_REG32(0x010) |
187 | #define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010) | 198 | #define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x94010) |
188 | #define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054) | 199 | #define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6A054) |
189 | #define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054) | 200 | #define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6C054) |
190 | #define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054) | 201 | #define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6E054) |
191 | //#define IVA_SYSCONFIG 0x5C060010 | 202 | #define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE + 0x10) |
192 | #define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10) | 203 | #define OMAP24XX_SMS_BASE (L3_24XX_BASE + 0x8000) |
193 | #define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10) | 204 | #define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE + 0x10) |
194 | #define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010) | 205 | #define SSI_SYSCONFIG __REG32(DISP_BASE + 0x8010) |
195 | //#define VLYNQ_SYSCONFIG 0x67FFFE10 | ||
196 | 206 | ||
197 | /* rkw - good cannidates for PM_ to start what nm was trying */ | 207 | /* rkw - good cannidates for PM_ to start what nm was trying */ |
198 | #define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000) | 208 | #define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE + 0x2A000) |
199 | #define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000) | 209 | #define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE + 0x78000) |
200 | #define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000) | 210 | #define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE + 0x7A000) |
201 | #define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000) | 211 | #define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE + 0x7C000) |
202 | #define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000) | 212 | #define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE + 0x7E000) |
203 | #define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000) | 213 | #define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE + 0x80000) |
204 | #define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000) | 214 | #define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE + 0x82000) |
205 | #define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000) | 215 | #define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE + 0x84000) |
206 | #define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000) | 216 | #define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE + 0x86000) |
207 | #define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000) | 217 | #define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE + 0x88000) |
208 | #define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000) | 218 | #define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE + 0x8A000) |
209 | 219 | ||
220 | /* FIXME: Move these to timer code */ | ||
210 | #define GPTIMER1_SYSCONFIG GPT1_REG32(0x010) | 221 | #define GPTIMER1_SYSCONFIG GPT1_REG32(0x010) |
211 | #define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10) | 222 | #define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10) |
212 | #define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10) | 223 | #define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10) |
@@ -220,12 +231,18 @@ | |||
220 | #define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10) | 231 | #define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10) |
221 | #define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10) | 232 | #define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10) |
222 | 233 | ||
223 | #define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1))) | 234 | /* FIXME: Move these to gpio code */ |
235 | #define OMAP24XX_GPIO_BASE 0x48018000 | ||
236 | #define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1))) | ||
237 | |||
238 | #define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1) + 0x10)) | ||
239 | #define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2) + 0x10)) | ||
240 | #define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3) + 0x10)) | ||
241 | #define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4) + 0x10)) | ||
224 | 242 | ||
225 | #define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10)) | 243 | #if defined(CONFIG_ARCH_OMAP243X) |
226 | #define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10)) | 244 | #define GPIO5_SYSCONFIG __REG32((OMAP24XX_GPIO5_BASE + 0x10)) |
227 | #define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10)) | 245 | #endif |
228 | #define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10)) | ||
229 | 246 | ||
230 | /* GP TIMER 1 */ | 247 | /* GP TIMER 1 */ |
231 | #define GPTIMER1_TISTAT GPT1_REG32(0x014) | 248 | #define GPTIMER1_TISTAT GPT1_REG32(0x014) |
@@ -243,15 +260,15 @@ | |||
243 | #define GPTIMER1_TCAR2 GPT1_REG32(0x044) | 260 | #define GPTIMER1_TCAR2 GPT1_REG32(0x044) |
244 | 261 | ||
245 | /* rkw -- base fix up please... */ | 262 | /* rkw -- base fix up please... */ |
246 | #define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018) | 263 | #define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE + 0x78018) |
247 | 264 | ||
248 | /* SDRC */ | 265 | /* SDRC */ |
249 | #define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060) | 266 | #define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x060) |
250 | #define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064) | 267 | #define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x064) |
251 | #define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068) | 268 | #define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x068) |
252 | #define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C) | 269 | #define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x06C) |
253 | #define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070) | 270 | #define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE + 0x070) |
254 | #define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084) | 271 | #define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE + 0x084) |
255 | 272 | ||
256 | /* GPIO 1 */ | 273 | /* GPIO 1 */ |
257 | #define GPIO1_BASE GPIOX_BASE(1) | 274 | #define GPIO1_BASE GPIOX_BASE(1) |
@@ -278,6 +295,8 @@ | |||
278 | #define GPIO2_DATAIN GPIO2_REG32(0x038) | 295 | #define GPIO2_DATAIN GPIO2_REG32(0x038) |
279 | #define GPIO2_OE GPIO2_REG32(0x034) | 296 | #define GPIO2_OE GPIO2_REG32(0x034) |
280 | #define GPIO2_DATAOUT GPIO2_REG32(0x03C) | 297 | #define GPIO2_DATAOUT GPIO2_REG32(0x03C) |
298 | #define GPIO2_DEBOUNCENABLE GPIO2_REG32(0x050) | ||
299 | #define GPIO2_DEBOUNCINGTIME GPIO2_REG32(0x054) | ||
281 | 300 | ||
282 | /* GPIO 3 */ | 301 | /* GPIO 3 */ |
283 | #define GPIO3_BASE GPIOX_BASE(3) | 302 | #define GPIO3_BASE GPIOX_BASE(3) |
@@ -294,6 +313,8 @@ | |||
294 | #define GPIO3_DATAOUT GPIO3_REG32(0x03C) | 313 | #define GPIO3_DATAOUT GPIO3_REG32(0x03C) |
295 | #define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) | 314 | #define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) |
296 | #define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) | 315 | #define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) |
316 | #define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) | ||
317 | #define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) | ||
297 | 318 | ||
298 | /* GPIO 4 */ | 319 | /* GPIO 4 */ |
299 | #define GPIO4_BASE GPIOX_BASE(4) | 320 | #define GPIO4_BASE GPIOX_BASE(4) |
@@ -311,10 +332,26 @@ | |||
311 | #define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050) | 332 | #define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050) |
312 | #define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054) | 333 | #define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054) |
313 | 334 | ||
335 | #if defined(CONFIG_ARCH_OMAP243X) | ||
336 | /* GPIO 5 */ | ||
337 | #define GPIO5_REG32(offset) __REG32((OMAP24XX_GPIO5_BASE + (offset))) | ||
338 | #define GPIO5_IRQENABLE1 GPIO5_REG32(0x01C) | ||
339 | #define GPIO5_IRQSTATUS1 GPIO5_REG32(0x018) | ||
340 | #define GPIO5_IRQENABLE2 GPIO5_REG32(0x02C) | ||
341 | #define GPIO5_IRQSTATUS2 GPIO5_REG32(0x028) | ||
342 | #define GPIO5_WAKEUPENABLE GPIO5_REG32(0x020) | ||
343 | #define GPIO5_RISINGDETECT GPIO5_REG32(0x048) | ||
344 | #define GPIO5_FALLINGDETECT GPIO5_REG32(0x04C) | ||
345 | #define GPIO5_DATAIN GPIO5_REG32(0x038) | ||
346 | #define GPIO5_OE GPIO5_REG32(0x034) | ||
347 | #define GPIO5_DATAOUT GPIO5_REG32(0x03C) | ||
348 | #define GPIO5_DEBOUNCENABLE GPIO5_REG32(0x050) | ||
349 | #define GPIO5_DEBOUNCINGTIME GPIO5_REG32(0x054) | ||
350 | #endif | ||
314 | 351 | ||
315 | /* IO CONFIG */ | 352 | /* IO CONFIG */ |
316 | #define CONTROL_BASE (OMAP24XX_CTRL_BASE) | 353 | #define OMAP24XX_CTRL_BASE (L4_24XX_BASE) |
317 | #define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset)) | 354 | #define CONTROL_REG32(offset) __REG32(OMAP24XX_CTRL_BASE + (offset)) |
318 | 355 | ||
319 | #define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104) | 356 | #define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104) |
320 | #define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134) | 357 | #define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134) |
@@ -322,15 +359,18 @@ | |||
322 | #define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C) | 359 | #define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C) |
323 | #define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090) | 360 | #define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090) |
324 | #define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8) | 361 | #define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8) |
325 | #define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) | 362 | #define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) /* 2420 */ |
326 | #define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0) | 363 | #define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0) |
327 | #define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC) | 364 | #define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC) |
365 | #define CONTROL_PADCONF_SYS_NIRQW0 CONTROL_REG32(0x0BC) /* 2430 */ | ||
366 | #define CONTROL_PADCONF_SSI1_FLAG_TX CONTROL_REG32(0x108) /* 2430 */ | ||
328 | 367 | ||
329 | /* CONTROL */ | 368 | /* CONTROL */ |
330 | #define CONTROL_DEVCONF CONTROL_REG32(0x274) | 369 | #define CONTROL_DEVCONF CONTROL_REG32(0x274) |
370 | #define CONTROL_DEVCONF1 CONTROL_REG32(0x2E8) | ||
331 | 371 | ||
332 | /* INTERRUPT CONTROLLER */ | 372 | /* INTERRUPT CONTROLLER */ |
333 | #define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000) | 373 | #define INTC_BASE ((L4_24XX_BASE) + 0xfe000) |
334 | #define INTC_REG32(offset) __REG32(INTC_BASE + (offset)) | 374 | #define INTC_REG32(offset) __REG32(INTC_BASE + (offset)) |
335 | 375 | ||
336 | #define INTC1_U_BASE INTC_REG32(0x000) | 376 | #define INTC1_U_BASE INTC_REG32(0x000) |
@@ -348,10 +388,12 @@ | |||
348 | #define INTC_ISR_CLEAR2 INTC_REG32(0x0D4) | 388 | #define INTC_ISR_CLEAR2 INTC_REG32(0x0D4) |
349 | #define INTC_SIR_IRQ INTC_REG32(0x040) | 389 | #define INTC_SIR_IRQ INTC_REG32(0x040) |
350 | #define INTC_CONTROL INTC_REG32(0x048) | 390 | #define INTC_CONTROL INTC_REG32(0x048) |
351 | #define INTC_ILR11 INTC_REG32(0x12C) | 391 | #define INTC_ILR11 INTC_REG32(0x12C) /* PRCM on MPU PIC */ |
392 | #define INTC_ILR30 INTC_REG32(0x178) | ||
393 | #define INTC_ILR31 INTC_REG32(0x17C) | ||
352 | #define INTC_ILR32 INTC_REG32(0x180) | 394 | #define INTC_ILR32 INTC_REG32(0x180) |
353 | #define INTC_ILR37 INTC_REG32(0x194) | 395 | #define INTC_ILR37 INTC_REG32(0x194) /* GPIO4 on MPU PIC */ |
354 | #define INTC_SYSCONFIG INTC_REG32(0x010) | 396 | #define INTC_SYSCONFIG INTC_REG32(0x010) /* GPT1 on MPU PIC */ |
355 | 397 | ||
356 | /* RAM FIREWALL */ | 398 | /* RAM FIREWALL */ |
357 | #define RAMFW_BASE (0x68005000) | 399 | #define RAMFW_BASE (0x68005000) |
@@ -373,6 +415,24 @@ | |||
373 | #define GPMC_CONFIG6_0 GPMC_REG32(0x074) | 415 | #define GPMC_CONFIG6_0 GPMC_REG32(0x074) |
374 | #define GPMC_CONFIG7_0 GPMC_REG32(0x078) | 416 | #define GPMC_CONFIG7_0 GPMC_REG32(0x078) |
375 | 417 | ||
418 | /* GPMC CS1 */ | ||
419 | #define GPMC_CONFIG1_1 GPMC_REG32(0x090) | ||
420 | #define GPMC_CONFIG2_1 GPMC_REG32(0x094) | ||
421 | #define GPMC_CONFIG3_1 GPMC_REG32(0x098) | ||
422 | #define GPMC_CONFIG4_1 GPMC_REG32(0x09C) | ||
423 | #define GPMC_CONFIG5_1 GPMC_REG32(0x0a0) | ||
424 | #define GPMC_CONFIG6_1 GPMC_REG32(0x0a4) | ||
425 | #define GPMC_CONFIG7_1 GPMC_REG32(0x0a8) | ||
426 | |||
427 | /* GPMC CS3 */ | ||
428 | #define GPMC_CONFIG1_3 GPMC_REG32(0x0F0) | ||
429 | #define GPMC_CONFIG2_3 GPMC_REG32(0x0F4) | ||
430 | #define GPMC_CONFIG3_3 GPMC_REG32(0x0F8) | ||
431 | #define GPMC_CONFIG4_3 GPMC_REG32(0x0FC) | ||
432 | #define GPMC_CONFIG5_3 GPMC_REG32(0x100) | ||
433 | #define GPMC_CONFIG6_3 GPMC_REG32(0x104) | ||
434 | #define GPMC_CONFIG7_3 GPMC_REG32(0x108) | ||
435 | |||
376 | /* DSS */ | 436 | /* DSS */ |
377 | #define DSS_CONTROL DISP_REG32(0x040) | 437 | #define DSS_CONTROL DISP_REG32(0x040) |
378 | #define DISPC_CONTROL DISP_REG32(0x440) | 438 | #define DISPC_CONTROL DISP_REG32(0x440) |
@@ -405,11 +465,15 @@ | |||
405 | #define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8) | 465 | #define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8) |
406 | #define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC) | 466 | #define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC) |
407 | 467 | ||
408 | /* Wake up define for board */ | 468 | /* HSUSB Suspend */ |
409 | #define GPIO97 (1 << 1) | 469 | #define HSUSB_CTRL __REG8(0x480AC001) |
410 | #define GPIO88 (1 << 24) | 470 | #define USBOTG_POWER __REG32(0x480AC000) |
471 | |||
472 | /* HS MMC */ | ||
473 | #define MMCHS1_SYSCONFIG __REG32(0x4809C010) | ||
474 | #define MMCHS2_SYSCONFIG __REG32(0x480b4010) | ||
411 | 475 | ||
412 | #endif /* __ASSEMBLER__ */ | 476 | #endif /* __ASSEMBLER__ */ |
413 | 477 | ||
414 | #endif | 478 | #endif |
415 | 479 | ||
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c new file mode 100644 index 000000000000..8893479dc7e0 --- /dev/null +++ b/arch/arm/mach-omap2/prcm.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/prcm.c | ||
3 | * | ||
4 | * OMAP 24xx Power Reset and Clock Management (PRCM) functions | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * | ||
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | ||
9 | * | ||
10 | * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/clk.h> | ||
20 | |||
21 | #include "prcm-regs.h" | ||
22 | |||
23 | u32 omap_prcm_get_reset_sources(void) | ||
24 | { | ||
25 | return RM_RSTST_WKUP & 0x7f; | ||
26 | } | ||
27 | EXPORT_SYMBOL(omap_prcm_get_reset_sources); | ||
28 | |||
29 | /* Resets clock rates and reboots the system. Only called from system.h */ | ||
30 | void omap_prcm_arch_reset(char mode) | ||
31 | { | ||
32 | u32 rate; | ||
33 | struct clk *vclk, *sclk; | ||
34 | |||
35 | vclk = clk_get(NULL, "virt_prcm_set"); | ||
36 | sclk = clk_get(NULL, "sys_ck"); | ||
37 | rate = clk_get_rate(sclk); | ||
38 | clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */ | ||
39 | RM_RSTCTRL_WKUP |= 2; | ||
40 | } | ||
diff --git a/arch/arm/mach-omap2/sleep.S b/arch/arm/mach-omap2/sleep.S new file mode 100644 index 000000000000..00299cbeb911 --- /dev/null +++ b/arch/arm/mach-omap2/sleep.S | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/sleep.S | ||
3 | * | ||
4 | * (C) Copyright 2004 | ||
5 | * Texas Instruments, <www.ti.com> | ||
6 | * Richard Woodruff <r-woodruff2@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
21 | * MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/linkage.h> | ||
26 | #include <asm/assembler.h> | ||
27 | #include <asm/arch/io.h> | ||
28 | #include <asm/arch/pm.h> | ||
29 | |||
30 | #define A_32KSYNC_CR_V IO_ADDRESS(OMAP_TIMER32K_BASE+0x10) | ||
31 | #define A_PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50) | ||
32 | #define A_PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80) | ||
33 | #define A_CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500) | ||
34 | #define A_CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520) | ||
35 | #define A_CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540) | ||
36 | #define A_CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544) | ||
37 | |||
38 | #define A_SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60) | ||
39 | #define A_SDRC_POWER_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70) | ||
40 | #define A_SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4) | ||
41 | #define A_SDRC0_V (0xC0000000) | ||
42 | #define A_SDRC_MANUAL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8) | ||
43 | |||
44 | .text | ||
45 | |||
46 | /* | ||
47 | * Forces OMAP into idle state | ||
48 | * | ||
49 | * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI | ||
50 | * for normal idles. | ||
51 | * | ||
52 | * Note: This code get's copied to internal SRAM at boot. When the OMAP | ||
53 | * wakes up it continues execution at the point it went to sleep. | ||
54 | */ | ||
55 | ENTRY(omap24xx_idle_loop_suspend) | ||
56 | stmfd sp!, {r0, lr} @ save registers on stack | ||
57 | mov r0, #0 @ clear for mcr setup | ||
58 | mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt | ||
59 | ldmfd sp!, {r0, pc} @ restore regs and return | ||
60 | |||
61 | ENTRY(omap24xx_idle_loop_suspend_sz) | ||
62 | .word . - omap24xx_idle_loop_suspend | ||
63 | |||
64 | /* | ||
65 | * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing | ||
66 | * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore | ||
67 | * SDRC. | ||
68 | * | ||
69 | * Input: | ||
70 | * R0 : DLL ctrl value pre-Sleep | ||
71 | * R1 : Processor+Revision | ||
72 | * 2420: 0x21 = 242xES1, 0x26 = 242xES2.2 | ||
73 | * 2430: 0x31 = 2430ES1, 0x32 = 2430ES2 | ||
74 | * | ||
75 | * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on | ||
76 | * when we get called, but the DLL probably isn't. We will wait a bit more in | ||
77 | * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even | ||
78 | * if in unlocked mode. | ||
79 | * | ||
80 | * For less than 242x-ES2.2 upon wake from a sleep mode where the external | ||
81 | * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz | ||
82 | * clock can pass into the PRCM can cause problems at DSP and IVA. | ||
83 | * To work around this the code will switch to the 32kHz source prior to sleep. | ||
84 | * Post sleep we will shift back to using the DPLL. Apparently, | ||
85 | * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait | ||
86 | * 3x12MHz + 3x32kHz clocks for a full switch. | ||
87 | * | ||
88 | * The DLL load value is not kept in RETENTION or OFF. It needs to be restored | ||
89 | * at wake | ||
90 | */ | ||
91 | ENTRY(omap24xx_cpu_suspend) | ||
92 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | ||
93 | mov r3, #0x0 @ clear for mrc call | ||
94 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished | ||
95 | nop | ||
96 | nop | ||
97 | ldr r3, A_SDRC_POWER @ addr of sdrc power | ||
98 | ldr r4, [r3] @ value of sdrc power | ||
99 | orr r4, r4, #0x40 @ enable self refresh on idle req | ||
100 | mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) | ||
101 | str r4, [r3] @ make it so | ||
102 | mov r2, #0 | ||
103 | nop | ||
104 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | ||
105 | nop | ||
106 | loop: | ||
107 | subs r5, r5, #0x1 @ awake, wait just a bit | ||
108 | bne loop | ||
109 | |||
110 | /* The DPLL has on before we take the DDR out of self refresh */ | ||
111 | bic r4, r4, #0x40 @ now clear self refresh bit. | ||
112 | str r4, [r3] @ put vlaue back. | ||
113 | ldr r4, A_SDRC0 @ make a clock happen | ||
114 | ldr r4, [r4] | ||
115 | nop @ start auto refresh only after clk ok | ||
116 | movs r0, r0 @ see if DDR or SDR | ||
117 | ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl | ||
118 | strne r0, [r1] @ rewrite DLLA to force DLL reload | ||
119 | addne r1, r1, #0x8 @ move to DLLB | ||
120 | strne r0, [r1] @ rewrite DLLB to force DLL reload | ||
121 | |||
122 | mov r5, #0x1000 | ||
123 | loop2: | ||
124 | subs r5, r5, #0x1 | ||
125 | bne loop2 | ||
126 | /* resume*/ | ||
127 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | ||
128 | |||
129 | A_SDRC_POWER: | ||
130 | .word A_SDRC_POWER_V | ||
131 | A_SDRC0: | ||
132 | .word A_SDRC0_V | ||
133 | A_CM_CLKSEL2_PLL_S: | ||
134 | .word A_CM_CLKSEL2_PLL_V | ||
135 | A_CM_CLKEN_PLL: | ||
136 | .word A_CM_CLKEN_PLL_V | ||
137 | A_SDRC_DLLA_CTRL_S: | ||
138 | .word A_SDRC_DLLA_CTRL_V | ||
139 | A_SDRC_MANUAL_S: | ||
140 | .word A_SDRC_MANUAL_V | ||
141 | |||
142 | ENTRY(omap24xx_cpu_suspend_sz) | ||
143 | .word . - omap24xx_cpu_suspend | ||
144 | |||
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S index 2a869e203342..d261e4ff4d9b 100644 --- a/arch/arm/mach-omap2/sram-fn.S +++ b/arch/arm/mach-omap2/sram-fn.S | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap1/sram.S | 2 | * linux/arch/arm/mach-omap2/sram.S |
3 | * | 3 | * |
4 | * Omap2 specific functions that need to be run in internal SRAM | 4 | * Omap2 specific functions that need to be run in internal SRAM |
5 | * | 5 | * |
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/arch/io.h> | 28 | #include <asm/arch/io.h> |
29 | #include <asm/hardware.h> | 29 | #include <asm/hardware.h> |
30 | 30 | ||
31 | #include <asm/arch/prcm.h> | 31 | #include "prcm-regs.h" |
32 | 32 | ||
33 | #define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010) | 33 | #define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010) |
34 | 34 | ||
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index b45560a8f6c4..a042473deedd 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
@@ -307,6 +307,10 @@ static void __init fixup_poodle(struct machine_desc *desc, | |||
307 | struct tag *tags, char **cmdline, struct meminfo *mi) | 307 | struct tag *tags, char **cmdline, struct meminfo *mi) |
308 | { | 308 | { |
309 | sharpsl_save_param(); | 309 | sharpsl_save_param(); |
310 | mi->nr_banks=1; | ||
311 | mi->bank[0].start = 0xa0000000; | ||
312 | mi->bank[0].node = 0; | ||
313 | mi->bank[0].size = (32*1024*1024); | ||
310 | } | 314 | } |
311 | 315 | ||
312 | MACHINE_START(POODLE, "SHARP Poodle") | 316 | MACHINE_START(POODLE, "SHARP Poodle") |
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index ed07c4149d82..ce7d81000695 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
@@ -50,9 +50,15 @@ config MACH_N30 | |||
50 | 50 | ||
51 | <http://zoo.weinigel.se/n30>. | 51 | <http://zoo.weinigel.se/n30>. |
52 | 52 | ||
53 | config MACH_SMDK | ||
54 | bool | ||
55 | help | ||
56 | Common machine code for SMDK2410 and SMDK2440 | ||
57 | |||
53 | config ARCH_SMDK2410 | 58 | config ARCH_SMDK2410 |
54 | bool "SMDK2410/A9M2410" | 59 | bool "SMDK2410/A9M2410" |
55 | select CPU_S3C2410 | 60 | select CPU_S3C2410 |
61 | select MACH_SMDK | ||
56 | help | 62 | help |
57 | Say Y here if you are using the SMDK2410 or the derived module A9M2410 | 63 | Say Y here if you are using the SMDK2410 or the derived module A9M2410 |
58 | <http://www.fsforth.de> | 64 | <http://www.fsforth.de> |
@@ -60,6 +66,7 @@ config ARCH_SMDK2410 | |||
60 | config ARCH_S3C2440 | 66 | config ARCH_S3C2440 |
61 | bool "SMDK2440" | 67 | bool "SMDK2440" |
62 | select CPU_S3C2440 | 68 | select CPU_S3C2440 |
69 | select MACH_SMDK | ||
63 | help | 70 | help |
64 | Say Y here if you are using the SMDK2440. | 71 | Say Y here if you are using the SMDK2440. |
65 | 72 | ||
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 1b3b476e5637..3e5712db6b52 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile | |||
@@ -48,3 +48,5 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o | |||
48 | obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o | 48 | obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o |
49 | obj-$(CONFIG_MACH_OTOM) += mach-otom.o | 49 | obj-$(CONFIG_MACH_OTOM) += mach-otom.o |
50 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o | 50 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o |
51 | |||
52 | obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file | ||
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index fec02c92f95f..b7f85e6d6b76 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -249,7 +249,7 @@ static int s3c24xx_upll_enable(struct clk *clk, int enable) | |||
249 | 249 | ||
250 | /* if we started the UPLL, then allow to settle */ | 250 | /* if we started the UPLL, then allow to settle */ |
251 | 251 | ||
252 | if (enable && !(orig & S3C2410_CLKSLOW_UCLK_OFF)) | 252 | if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF)) |
253 | udelay(200); | 253 | udelay(200); |
254 | 254 | ||
255 | return 0; | 255 | return 0; |
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c new file mode 100644 index 000000000000..36b8291b5e03 --- /dev/null +++ b/arch/arm/mach-s3c2410/common-smdk.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* linux/arch/arm/mach-s3c2410/common-smdk.c | ||
2 | * | ||
3 | * Copyright (c) 2006 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Common code for SMDK2410 and SMDK2440 boards | ||
7 | * | ||
8 | * http://www.fluff.org/ben/smdk2440/ | ||
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/types.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/timer.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/nand_ecc.h> | ||
26 | #include <linux/mtd/partitions.h> | ||
27 | |||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | #include <asm/mach/irq.h> | ||
31 | |||
32 | #include <asm/hardware.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #include <asm/arch/regs-gpio.h> | ||
37 | |||
38 | #include <asm/arch/nand.h> | ||
39 | |||
40 | #include "devs.h" | ||
41 | #include "pm.h" | ||
42 | |||
43 | /* NAND parititon from 2.4.18-swl5 */ | ||
44 | |||
45 | static struct mtd_partition smdk_default_nand_part[] = { | ||
46 | [0] = { | ||
47 | .name = "Boot Agent", | ||
48 | .size = SZ_16K, | ||
49 | .offset = 0, | ||
50 | }, | ||
51 | [1] = { | ||
52 | .name = "S3C2410 flash parition 1", | ||
53 | .offset = 0, | ||
54 | .size = SZ_2M, | ||
55 | }, | ||
56 | [2] = { | ||
57 | .name = "S3C2410 flash partition 2", | ||
58 | .offset = SZ_4M, | ||
59 | .size = SZ_4M, | ||
60 | }, | ||
61 | [3] = { | ||
62 | .name = "S3C2410 flash partition 3", | ||
63 | .offset = SZ_8M, | ||
64 | .size = SZ_2M, | ||
65 | }, | ||
66 | [4] = { | ||
67 | .name = "S3C2410 flash partition 4", | ||
68 | .offset = SZ_1M * 10, | ||
69 | .size = SZ_4M, | ||
70 | }, | ||
71 | [5] = { | ||
72 | .name = "S3C2410 flash partition 5", | ||
73 | .offset = SZ_1M * 14, | ||
74 | .size = SZ_1M * 10, | ||
75 | }, | ||
76 | [6] = { | ||
77 | .name = "S3C2410 flash partition 6", | ||
78 | .offset = SZ_1M * 24, | ||
79 | .size = SZ_1M * 24, | ||
80 | }, | ||
81 | [7] = { | ||
82 | .name = "S3C2410 flash partition 7", | ||
83 | .offset = SZ_1M * 48, | ||
84 | .size = SZ_16M, | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | static struct s3c2410_nand_set smdk_nand_sets[] = { | ||
89 | [0] = { | ||
90 | .name = "NAND", | ||
91 | .nr_chips = 1, | ||
92 | .nr_partitions = ARRAY_SIZE(smdk_default_nand_part), | ||
93 | .partitions = smdk_default_nand_part, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | /* choose a set of timings which should suit most 512Mbit | ||
98 | * chips and beyond. | ||
99 | */ | ||
100 | |||
101 | static struct s3c2410_platform_nand smdk_nand_info = { | ||
102 | .tacls = 20, | ||
103 | .twrph0 = 60, | ||
104 | .twrph1 = 20, | ||
105 | .nr_sets = ARRAY_SIZE(smdk_nand_sets), | ||
106 | .sets = smdk_nand_sets, | ||
107 | }; | ||
108 | |||
109 | /* devices we initialise */ | ||
110 | |||
111 | static struct platform_device __initdata *smdk_devs[] = { | ||
112 | &s3c_device_nand, | ||
113 | }; | ||
114 | |||
115 | void __init smdk_machine_init(void) | ||
116 | { | ||
117 | /* Configure the LEDs (even if we have no LED support)*/ | ||
118 | |||
119 | s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); | ||
120 | s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); | ||
121 | s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); | ||
122 | s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP); | ||
123 | |||
124 | s3c2410_gpio_setpin(S3C2410_GPF4, 1); | ||
125 | s3c2410_gpio_setpin(S3C2410_GPF5, 1); | ||
126 | s3c2410_gpio_setpin(S3C2410_GPF6, 1); | ||
127 | s3c2410_gpio_setpin(S3C2410_GPF7, 1); | ||
128 | |||
129 | s3c_device_nand.dev.platform_data = &smdk_nand_info; | ||
130 | |||
131 | platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); | ||
132 | |||
133 | s3c2410_pm_init(); | ||
134 | } | ||
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/arch/arm/mach-s3c2410/common-smdk.h new file mode 100644 index 000000000000..0e3a3be330a3 --- /dev/null +++ b/arch/arm/mach-s3c2410/common-smdk.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* linux/arch/arm/mach-s3c2410/common-smdk.h | ||
2 | * | ||
3 | * Copyright (c) 2006 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Common code for SMDK2410 and SMDK2440 boards | ||
7 | * | ||
8 | * http://www.fluff.org/ben/smdk2440/ | ||
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 | extern void smdk_machine_init(void); | ||
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 3e327b8e46be..cc97fbf66291 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c | |||
@@ -232,8 +232,8 @@ static void anubis_nand_select(struct s3c2410_nand_set *set, int slot) | |||
232 | 232 | ||
233 | static struct s3c2410_platform_nand anubis_nand_info = { | 233 | static struct s3c2410_platform_nand anubis_nand_info = { |
234 | .tacls = 25, | 234 | .tacls = 25, |
235 | .twrph0 = 80, | 235 | .twrph0 = 55, |
236 | .twrph1 = 80, | 236 | .twrph1 = 40, |
237 | .nr_sets = ARRAY_SIZE(anubis_nand_sets), | 237 | .nr_sets = ARRAY_SIZE(anubis_nand_sets), |
238 | .sets = anubis_nand_sets, | 238 | .sets = anubis_nand_sets, |
239 | .select_chip = anubis_nand_select, | 239 | .select_chip = anubis_nand_select, |
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 0260ed5ab946..306afc1d7cd3 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c | |||
@@ -32,6 +32,11 @@ | |||
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | 34 | ||
35 | #include <linux/mtd/mtd.h> | ||
36 | #include <linux/mtd/nand.h> | ||
37 | #include <linux/mtd/nand_ecc.h> | ||
38 | #include <linux/mtd/partitions.h> | ||
39 | |||
35 | #include <asm/mach/arch.h> | 40 | #include <asm/mach/arch.h> |
36 | #include <asm/mach/map.h> | 41 | #include <asm/mach/map.h> |
37 | #include <asm/mach/irq.h> | 42 | #include <asm/mach/irq.h> |
@@ -46,6 +51,7 @@ | |||
46 | #include <asm/arch/regs-gpio.h> | 51 | #include <asm/arch/regs-gpio.h> |
47 | #include <asm/arch/regs-lcd.h> | 52 | #include <asm/arch/regs-lcd.h> |
48 | 53 | ||
54 | #include <asm/arch/nand.h> | ||
49 | #include <asm/arch/fb.h> | 55 | #include <asm/arch/fb.h> |
50 | 56 | ||
51 | #include "clock.h" | 57 | #include "clock.h" |
@@ -170,12 +176,39 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { | |||
170 | }, | 176 | }, |
171 | }; | 177 | }; |
172 | 178 | ||
179 | static struct mtd_partition rx3715_nand_part[] = { | ||
180 | [0] = { | ||
181 | .name = "Whole Flash", | ||
182 | .offset = 0, | ||
183 | .size = MTDPART_SIZ_FULL, | ||
184 | .mask_flags = MTD_WRITEABLE, | ||
185 | } | ||
186 | }; | ||
187 | |||
188 | static struct s3c2410_nand_set rx3715_nand_sets[] = { | ||
189 | [0] = { | ||
190 | .name = "Internal", | ||
191 | .nr_chips = 1, | ||
192 | .nr_partitions = ARRAY_SIZE(rx3715_nand_part), | ||
193 | .partitions = rx3715_nand_part, | ||
194 | }, | ||
195 | }; | ||
196 | |||
197 | static struct s3c2410_platform_nand rx3715_nand_info = { | ||
198 | .tacls = 25, | ||
199 | .twrph0 = 50, | ||
200 | .twrph1 = 15, | ||
201 | .nr_sets = ARRAY_SIZE(rx3715_nand_sets), | ||
202 | .sets = rx3715_nand_sets, | ||
203 | }; | ||
204 | |||
173 | static struct platform_device *rx3715_devices[] __initdata = { | 205 | static struct platform_device *rx3715_devices[] __initdata = { |
174 | &s3c_device_usb, | 206 | &s3c_device_usb, |
175 | &s3c_device_lcd, | 207 | &s3c_device_lcd, |
176 | &s3c_device_wdt, | 208 | &s3c_device_wdt, |
177 | &s3c_device_i2c, | 209 | &s3c_device_i2c, |
178 | &s3c_device_iis, | 210 | &s3c_device_iis, |
211 | &s3c_device_nand, | ||
179 | }; | 212 | }; |
180 | 213 | ||
181 | static struct s3c24xx_board rx3715_board __initdata = { | 214 | static struct s3c24xx_board rx3715_board __initdata = { |
@@ -185,6 +218,8 @@ static struct s3c24xx_board rx3715_board __initdata = { | |||
185 | 218 | ||
186 | static void __init rx3715_map_io(void) | 219 | static void __init rx3715_map_io(void) |
187 | { | 220 | { |
221 | s3c_device_nand.dev.platform_data = &rx3715_nand_info; | ||
222 | |||
188 | s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); | 223 | s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); |
189 | s3c24xx_init_clocks(16934000); | 224 | s3c24xx_init_clocks(16934000); |
190 | s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); | 225 | s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); |
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 1e76e1fdfcea..2db932d72c5a 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c | |||
@@ -28,7 +28,8 @@ | |||
28 | * Ben Dooks <ben@simtec.co.uk> | 28 | * Ben Dooks <ben@simtec.co.uk> |
29 | * | 29 | * |
30 | * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA | 30 | * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA |
31 | * 20-Sep-2005 BJD Added static to non-exported items | 31 | * 20-Sep-2005 BJD Added static to non-exported items |
32 | * 01-Apr-2006 BJD Moved init code to common smdk | ||
32 | * | 33 | * |
33 | ***********************************************************************/ | 34 | ***********************************************************************/ |
34 | 35 | ||
@@ -54,6 +55,8 @@ | |||
54 | #include "devs.h" | 55 | #include "devs.h" |
55 | #include "cpu.h" | 56 | #include "cpu.h" |
56 | 57 | ||
58 | #include "common-smdk.h" | ||
59 | |||
57 | static struct map_desc smdk2410_iodesc[] __initdata = { | 60 | static struct map_desc smdk2410_iodesc[] __initdata = { |
58 | /* nothing here yet */ | 61 | /* nothing here yet */ |
59 | }; | 62 | }; |
@@ -107,11 +110,6 @@ static void __init smdk2410_map_io(void) | |||
107 | s3c24xx_set_board(&smdk2410_board); | 110 | s3c24xx_set_board(&smdk2410_board); |
108 | } | 111 | } |
109 | 112 | ||
110 | static void __init smdk2410_init_irq(void) | ||
111 | { | ||
112 | s3c24xx_init_irq(); | ||
113 | } | ||
114 | |||
115 | MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch | 113 | MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch |
116 | * to SMDK2410 */ | 114 | * to SMDK2410 */ |
117 | /* Maintainer: Jonas Dietsche */ | 115 | /* Maintainer: Jonas Dietsche */ |
@@ -119,7 +117,8 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc | |||
119 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 117 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
120 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 118 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
121 | .map_io = smdk2410_map_io, | 119 | .map_io = smdk2410_map_io, |
122 | .init_irq = smdk2410_init_irq, | 120 | .init_irq = s3c24xx_init_irq, |
121 | .init_machine = smdk_machine_init, | ||
123 | .timer = &s3c24xx_timer, | 122 | .timer = &s3c24xx_timer, |
124 | MACHINE_END | 123 | MACHINE_END |
125 | 124 | ||
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index f4315721c3b8..5fffd1d51047 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c | |||
@@ -53,7 +53,8 @@ | |||
53 | #include "clock.h" | 53 | #include "clock.h" |
54 | #include "devs.h" | 54 | #include "devs.h" |
55 | #include "cpu.h" | 55 | #include "cpu.h" |
56 | #include "pm.h" | 56 | |
57 | #include "common-smdk.h" | ||
57 | 58 | ||
58 | static struct map_desc smdk2440_iodesc[] __initdata = { | 59 | static struct map_desc smdk2440_iodesc[] __initdata = { |
59 | /* ISA IO Space map (memory space selected by A24) */ | 60 | /* ISA IO Space map (memory space selected by A24) */ |
@@ -197,21 +198,9 @@ static void __init smdk2440_map_io(void) | |||
197 | 198 | ||
198 | static void __init smdk2440_machine_init(void) | 199 | static void __init smdk2440_machine_init(void) |
199 | { | 200 | { |
200 | /* Configure the LEDs (even if we have no LED support)*/ | ||
201 | |||
202 | s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); | ||
203 | s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); | ||
204 | s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); | ||
205 | s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP); | ||
206 | |||
207 | s3c2410_gpio_setpin(S3C2410_GPF4, 0); | ||
208 | s3c2410_gpio_setpin(S3C2410_GPF5, 0); | ||
209 | s3c2410_gpio_setpin(S3C2410_GPF6, 0); | ||
210 | s3c2410_gpio_setpin(S3C2410_GPF7, 0); | ||
211 | |||
212 | s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); | 201 | s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); |
213 | 202 | ||
214 | s3c2410_pm_init(); | 203 | smdk_machine_init(); |
215 | } | 204 | } |
216 | 205 | ||
217 | MACHINE_START(S3C2440, "SMDK2440") | 206 | MACHINE_START(S3C2440, "SMDK2440") |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 102454082474..676b5c5b75bb 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
@@ -11,7 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | * | 12 | * |
13 | * ChangeLog: | 13 | * ChangeLog: |
14 | * 03-06-2004 John Lenz <jelenz@wisc.edu> | 14 | * 2006 Pavel Machek <pavel@suse.cz> |
15 | * 03-06-2004 John Lenz <lenz@cs.wisc.edu> | ||
15 | * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net> | 16 | * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net> |
16 | * 04-16-2001 Lineo Japan,Inc. ... | 17 | * 04-16-2001 Lineo Japan,Inc. ... |
17 | */ | 18 | */ |
@@ -87,12 +88,75 @@ static struct mcp_plat_data collie_mcp_data = { | |||
87 | .sclk_rate = 11981000, | 88 | .sclk_rate = 11981000, |
88 | }; | 89 | }; |
89 | 90 | ||
91 | #ifdef CONFIG_SHARP_LOCOMO | ||
92 | /* | ||
93 | * low-level UART features. | ||
94 | */ | ||
95 | static struct locomo_dev *uart_dev = NULL; | ||
96 | |||
97 | static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) | ||
98 | { | ||
99 | if (!uart_dev) return; | ||
100 | |||
101 | if (mctrl & TIOCM_RTS) | ||
102 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); | ||
103 | else | ||
104 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); | ||
105 | |||
106 | if (mctrl & TIOCM_DTR) | ||
107 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); | ||
108 | else | ||
109 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); | ||
110 | } | ||
111 | |||
112 | static u_int collie_uart_get_mctrl(struct uart_port *port) | ||
113 | { | ||
114 | int ret = TIOCM_CD; | ||
115 | unsigned int r; | ||
116 | if (!uart_dev) return ret; | ||
117 | |||
118 | r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); | ||
119 | if (r & LOCOMO_GPIO_CTS) | ||
120 | ret |= TIOCM_CTS; | ||
121 | if (r & LOCOMO_GPIO_DSR) | ||
122 | ret |= TIOCM_DSR; | ||
123 | |||
124 | return ret; | ||
125 | } | ||
90 | 126 | ||
91 | static struct sa1100_port_fns collie_port_fns __initdata = { | 127 | static struct sa1100_port_fns collie_port_fns __initdata = { |
92 | .set_mctrl = collie_uart_set_mctrl, | 128 | .set_mctrl = collie_uart_set_mctrl, |
93 | .get_mctrl = collie_uart_get_mctrl, | 129 | .get_mctrl = collie_uart_get_mctrl, |
94 | }; | 130 | }; |
95 | 131 | ||
132 | static int collie_uart_probe(struct locomo_dev *dev) | ||
133 | { | ||
134 | uart_dev = dev; | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int collie_uart_remove(struct locomo_dev *dev) | ||
139 | { | ||
140 | uart_dev = NULL; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static struct locomo_driver collie_uart_driver = { | ||
145 | .drv = { | ||
146 | .name = "collie_uart", | ||
147 | }, | ||
148 | .devid = LOCOMO_DEVID_UART, | ||
149 | .probe = collie_uart_probe, | ||
150 | .remove = collie_uart_remove, | ||
151 | }; | ||
152 | |||
153 | static int __init collie_uart_init(void) { | ||
154 | return locomo_driver_register(&collie_uart_driver); | ||
155 | } | ||
156 | device_initcall(collie_uart_init); | ||
157 | |||
158 | #endif | ||
159 | |||
96 | 160 | ||
97 | static struct resource locomo_resources[] = { | 161 | static struct resource locomo_resources[] = { |
98 | [0] = { | 162 | [0] = { |
@@ -218,6 +282,12 @@ static void __init collie_map_io(void) | |||
218 | { | 282 | { |
219 | sa1100_map_io(); | 283 | sa1100_map_io(); |
220 | iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); | 284 | iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); |
285 | |||
286 | #ifdef CONFIG_SHARP_LOCOMO | ||
287 | sa1100_register_uart_fns(&collie_port_fns); | ||
288 | #endif | ||
289 | sa1100_register_uart(0, 3); | ||
290 | sa1100_register_uart(1, 1); | ||
221 | } | 291 | } |
222 | 292 | ||
223 | MACHINE_START(COLLIE, "Sharp-Collie") | 293 | MACHINE_START(COLLIE, "Sharp-Collie") |
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 8a1bfcd50087..50e6b6bfb2e2 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | 20 | ||
21 | #include <asm/memory.h> | ||
21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
22 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
23 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
@@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
272 | void * | 273 | void * |
273 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) | 274 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) |
274 | { | 275 | { |
276 | if (arch_is_coherent()) { | ||
277 | void *virt; | ||
278 | |||
279 | virt = kmalloc(size, gfp); | ||
280 | if (!virt) | ||
281 | return NULL; | ||
282 | *handle = virt_to_dma(dev, virt); | ||
283 | |||
284 | return virt; | ||
285 | } | ||
286 | |||
275 | return __dma_alloc(dev, size, handle, gfp, | 287 | return __dma_alloc(dev, size, handle, gfp, |
276 | pgprot_noncached(pgprot_kernel)); | 288 | pgprot_noncached(pgprot_kernel)); |
277 | } | 289 | } |
@@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr | |||
350 | 362 | ||
351 | WARN_ON(irqs_disabled()); | 363 | WARN_ON(irqs_disabled()); |
352 | 364 | ||
365 | if (arch_is_coherent()) { | ||
366 | kfree(cpu_addr); | ||
367 | return; | ||
368 | } | ||
369 | |||
353 | size = PAGE_ALIGN(size); | 370 | size = PAGE_ALIGN(size); |
354 | 371 | ||
355 | spin_lock_irqsave(&consistent_lock, flags); | 372 | spin_lock_irqsave(&consistent_lock, flags); |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 5e5d05bcad50..f14b2d0f3690 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -389,6 +389,17 @@ void __init build_mem_type_table(void) | |||
389 | kern_pgprot = user_pgprot = cp->pte; | 389 | kern_pgprot = user_pgprot = cp->pte; |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * Enable CPU-specific coherency if supported. | ||
393 | * (Only available on XSC3 at the moment.) | ||
394 | */ | ||
395 | if (arch_is_coherent()) { | ||
396 | if (cpu_is_xsc3()) { | ||
397 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | ||
398 | mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /* | ||
392 | * ARMv6 and above have extended page tables. | 403 | * ARMv6 and above have extended page tables. |
393 | */ | 404 | */ |
394 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { | 405 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { |
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index b9dfce57c272..80873b36c3f7 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S | |||
@@ -371,7 +371,7 @@ ENTRY(cpu_xsc3_switch_mm) | |||
371 | ENTRY(cpu_xsc3_set_pte) | 371 | ENTRY(cpu_xsc3_set_pte) |
372 | str r1, [r0], #-2048 @ linux version | 372 | str r1, [r0], #-2048 @ linux version |
373 | 373 | ||
374 | bic r2, r1, #0xff0 | 374 | bic r2, r1, #0xdf0 @ Keep C, B, coherency bits |
375 | orr r2, r2, #PTE_TYPE_EXT @ extended page | 375 | orr r2, r2, #PTE_TYPE_EXT @ extended page |
376 | 376 | ||
377 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | 377 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY |
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 0887bb2a2551..ec49495e651e 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig | |||
@@ -70,13 +70,13 @@ config OMAP_MPU_TIMER | |||
70 | 70 | ||
71 | config OMAP_32K_TIMER | 71 | config OMAP_32K_TIMER |
72 | bool "Use 32KHz timer" | 72 | bool "Use 32KHz timer" |
73 | depends on ARCH_OMAP16XX | 73 | depends on ARCH_OMAP16XX || ARCH_OMAP24XX |
74 | help | 74 | help |
75 | Select this option if you want to enable the OMAP 32KHz timer. | 75 | Select this option if you want to enable the OMAP 32KHz timer. |
76 | This timer saves power compared to the OMAP_MPU_TIMER, and has | 76 | This timer saves power compared to the OMAP_MPU_TIMER, and has |
77 | support for no tick during idle. The 32KHz timer provides less | 77 | support for no tick during idle. The 32KHz timer provides less |
78 | intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is | 78 | intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is |
79 | currently only available for OMAP-16xx. | 79 | currently only available for OMAP16XX and 24XX. |
80 | 80 | ||
81 | endchoice | 81 | endchoice |
82 | 82 | ||
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 9ccf1943fc94..2896b4546411 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile | |||
@@ -3,16 +3,16 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o | 6 | obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o |
7 | obj-m := | 7 | obj-m := |
8 | obj-n := | 8 | obj-n := |
9 | obj- := | 9 | obj- := |
10 | 10 | ||
11 | obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o | ||
12 | |||
11 | # OCPI interconnect support for 1710, 1610 and 5912 | 13 | # OCPI interconnect support for 1710, 1610 and 5912 |
12 | obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o | 14 | obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o |
13 | 15 | ||
14 | # Power Management | ||
15 | obj-$(CONFIG_PM) += pm.o sleep.o | ||
16 | 16 | ||
17 | obj-$(CONFIG_CPU_FREQ) += cpu-omap.o | 17 | obj-$(CONFIG_CPU_FREQ) += cpu-omap.o |
18 | obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o | 18 | obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o |
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 3c2bfc0efdaf..06485c193ee3 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/platform_device.h> | ||
24 | 25 | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | #include <asm/semaphore.h> | 27 | #include <asm/semaphore.h> |
@@ -37,17 +38,37 @@ static struct clk_functions *arch_clock; | |||
37 | * Standard clock functions defined in include/linux/clk.h | 38 | * Standard clock functions defined in include/linux/clk.h |
38 | *-------------------------------------------------------------------------*/ | 39 | *-------------------------------------------------------------------------*/ |
39 | 40 | ||
41 | /* | ||
42 | * Returns a clock. Note that we first try to use device id on the bus | ||
43 | * and clock name. If this fails, we try to use clock name only. | ||
44 | */ | ||
40 | struct clk * clk_get(struct device *dev, const char *id) | 45 | struct clk * clk_get(struct device *dev, const char *id) |
41 | { | 46 | { |
42 | struct clk *p, *clk = ERR_PTR(-ENOENT); | 47 | struct clk *p, *clk = ERR_PTR(-ENOENT); |
48 | int idno; | ||
49 | |||
50 | if (dev == NULL || dev->bus != &platform_bus_type) | ||
51 | idno = -1; | ||
52 | else | ||
53 | idno = to_platform_device(dev)->id; | ||
43 | 54 | ||
44 | mutex_lock(&clocks_mutex); | 55 | mutex_lock(&clocks_mutex); |
56 | |||
57 | list_for_each_entry(p, &clocks, node) { | ||
58 | if (p->id == idno && | ||
59 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | ||
60 | clk = p; | ||
61 | break; | ||
62 | } | ||
63 | } | ||
64 | |||
45 | list_for_each_entry(p, &clocks, node) { | 65 | list_for_each_entry(p, &clocks, node) { |
46 | if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | 66 | if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { |
47 | clk = p; | 67 | clk = p; |
48 | break; | 68 | break; |
49 | } | 69 | } |
50 | } | 70 | } |
71 | |||
51 | mutex_unlock(&clocks_mutex); | 72 | mutex_unlock(&clocks_mutex); |
52 | 73 | ||
53 | return clk; | 74 | return clk; |
@@ -59,6 +80,9 @@ int clk_enable(struct clk *clk) | |||
59 | unsigned long flags; | 80 | unsigned long flags; |
60 | int ret = 0; | 81 | int ret = 0; |
61 | 82 | ||
83 | if (clk == NULL || IS_ERR(clk)) | ||
84 | return -EINVAL; | ||
85 | |||
62 | spin_lock_irqsave(&clockfw_lock, flags); | 86 | spin_lock_irqsave(&clockfw_lock, flags); |
63 | if (arch_clock->clk_enable) | 87 | if (arch_clock->clk_enable) |
64 | ret = arch_clock->clk_enable(clk); | 88 | ret = arch_clock->clk_enable(clk); |
@@ -72,6 +96,9 @@ void clk_disable(struct clk *clk) | |||
72 | { | 96 | { |
73 | unsigned long flags; | 97 | unsigned long flags; |
74 | 98 | ||
99 | if (clk == NULL || IS_ERR(clk)) | ||
100 | return; | ||
101 | |||
75 | spin_lock_irqsave(&clockfw_lock, flags); | 102 | spin_lock_irqsave(&clockfw_lock, flags); |
76 | if (arch_clock->clk_disable) | 103 | if (arch_clock->clk_disable) |
77 | arch_clock->clk_disable(clk); | 104 | arch_clock->clk_disable(clk); |
@@ -84,6 +111,9 @@ int clk_get_usecount(struct clk *clk) | |||
84 | unsigned long flags; | 111 | unsigned long flags; |
85 | int ret = 0; | 112 | int ret = 0; |
86 | 113 | ||
114 | if (clk == NULL || IS_ERR(clk)) | ||
115 | return 0; | ||
116 | |||
87 | spin_lock_irqsave(&clockfw_lock, flags); | 117 | spin_lock_irqsave(&clockfw_lock, flags); |
88 | ret = clk->usecount; | 118 | ret = clk->usecount; |
89 | spin_unlock_irqrestore(&clockfw_lock, flags); | 119 | spin_unlock_irqrestore(&clockfw_lock, flags); |
@@ -97,6 +127,9 @@ unsigned long clk_get_rate(struct clk *clk) | |||
97 | unsigned long flags; | 127 | unsigned long flags; |
98 | unsigned long ret = 0; | 128 | unsigned long ret = 0; |
99 | 129 | ||
130 | if (clk == NULL || IS_ERR(clk)) | ||
131 | return 0; | ||
132 | |||
100 | spin_lock_irqsave(&clockfw_lock, flags); | 133 | spin_lock_irqsave(&clockfw_lock, flags); |
101 | ret = clk->rate; | 134 | ret = clk->rate; |
102 | spin_unlock_irqrestore(&clockfw_lock, flags); | 135 | spin_unlock_irqrestore(&clockfw_lock, flags); |
@@ -121,6 +154,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
121 | unsigned long flags; | 154 | unsigned long flags; |
122 | long ret = 0; | 155 | long ret = 0; |
123 | 156 | ||
157 | if (clk == NULL || IS_ERR(clk)) | ||
158 | return ret; | ||
159 | |||
124 | spin_lock_irqsave(&clockfw_lock, flags); | 160 | spin_lock_irqsave(&clockfw_lock, flags); |
125 | if (arch_clock->clk_round_rate) | 161 | if (arch_clock->clk_round_rate) |
126 | ret = arch_clock->clk_round_rate(clk, rate); | 162 | ret = arch_clock->clk_round_rate(clk, rate); |
@@ -133,7 +169,10 @@ EXPORT_SYMBOL(clk_round_rate); | |||
133 | int clk_set_rate(struct clk *clk, unsigned long rate) | 169 | int clk_set_rate(struct clk *clk, unsigned long rate) |
134 | { | 170 | { |
135 | unsigned long flags; | 171 | unsigned long flags; |
136 | int ret = 0; | 172 | int ret = -EINVAL; |
173 | |||
174 | if (clk == NULL || IS_ERR(clk)) | ||
175 | return ret; | ||
137 | 176 | ||
138 | spin_lock_irqsave(&clockfw_lock, flags); | 177 | spin_lock_irqsave(&clockfw_lock, flags); |
139 | if (arch_clock->clk_set_rate) | 178 | if (arch_clock->clk_set_rate) |
@@ -147,7 +186,10 @@ EXPORT_SYMBOL(clk_set_rate); | |||
147 | int clk_set_parent(struct clk *clk, struct clk *parent) | 186 | int clk_set_parent(struct clk *clk, struct clk *parent) |
148 | { | 187 | { |
149 | unsigned long flags; | 188 | unsigned long flags; |
150 | int ret = 0; | 189 | int ret = -EINVAL; |
190 | |||
191 | if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) | ||
192 | return ret; | ||
151 | 193 | ||
152 | spin_lock_irqsave(&clockfw_lock, flags); | 194 | spin_lock_irqsave(&clockfw_lock, flags); |
153 | if (arch_clock->clk_set_parent) | 195 | if (arch_clock->clk_set_parent) |
@@ -163,6 +205,9 @@ struct clk *clk_get_parent(struct clk *clk) | |||
163 | unsigned long flags; | 205 | unsigned long flags; |
164 | struct clk * ret = NULL; | 206 | struct clk * ret = NULL; |
165 | 207 | ||
208 | if (clk == NULL || IS_ERR(clk)) | ||
209 | return ret; | ||
210 | |||
166 | spin_lock_irqsave(&clockfw_lock, flags); | 211 | spin_lock_irqsave(&clockfw_lock, flags); |
167 | if (arch_clock->clk_get_parent) | 212 | if (arch_clock->clk_get_parent) |
168 | ret = arch_clock->clk_get_parent(clk); | 213 | ret = arch_clock->clk_get_parent(clk); |
@@ -199,6 +244,9 @@ __setup("mpurate=", omap_clk_setup); | |||
199 | /* Used for clocks that always have same value as the parent clock */ | 244 | /* Used for clocks that always have same value as the parent clock */ |
200 | void followparent_recalc(struct clk *clk) | 245 | void followparent_recalc(struct clk *clk) |
201 | { | 246 | { |
247 | if (clk == NULL || IS_ERR(clk)) | ||
248 | return; | ||
249 | |||
202 | clk->rate = clk->parent->rate; | 250 | clk->rate = clk->parent->rate; |
203 | } | 251 | } |
204 | 252 | ||
@@ -207,6 +255,9 @@ void propagate_rate(struct clk * tclk) | |||
207 | { | 255 | { |
208 | struct clk *clkp; | 256 | struct clk *clkp; |
209 | 257 | ||
258 | if (tclk == NULL || IS_ERR(tclk)) | ||
259 | return; | ||
260 | |||
210 | list_for_each_entry(clkp, &clocks, node) { | 261 | list_for_each_entry(clkp, &clocks, node) { |
211 | if (likely(clkp->parent != tclk)) | 262 | if (likely(clkp->parent != tclk)) |
212 | continue; | 263 | continue; |
@@ -217,6 +268,9 @@ void propagate_rate(struct clk * tclk) | |||
217 | 268 | ||
218 | int clk_register(struct clk *clk) | 269 | int clk_register(struct clk *clk) |
219 | { | 270 | { |
271 | if (clk == NULL || IS_ERR(clk)) | ||
272 | return -EINVAL; | ||
273 | |||
220 | mutex_lock(&clocks_mutex); | 274 | mutex_lock(&clocks_mutex); |
221 | list_add(&clk->node, &clocks); | 275 | list_add(&clk->node, &clocks); |
222 | if (clk->init) | 276 | if (clk->init) |
@@ -229,6 +283,9 @@ EXPORT_SYMBOL(clk_register); | |||
229 | 283 | ||
230 | void clk_unregister(struct clk *clk) | 284 | void clk_unregister(struct clk *clk) |
231 | { | 285 | { |
286 | if (clk == NULL || IS_ERR(clk)) | ||
287 | return; | ||
288 | |||
232 | mutex_lock(&clocks_mutex); | 289 | mutex_lock(&clocks_mutex); |
233 | list_del(&clk->node); | 290 | list_del(&clk->node); |
234 | mutex_unlock(&clocks_mutex); | 291 | mutex_unlock(&clocks_mutex); |
@@ -239,6 +296,9 @@ void clk_deny_idle(struct clk *clk) | |||
239 | { | 296 | { |
240 | unsigned long flags; | 297 | unsigned long flags; |
241 | 298 | ||
299 | if (clk == NULL || IS_ERR(clk)) | ||
300 | return; | ||
301 | |||
242 | spin_lock_irqsave(&clockfw_lock, flags); | 302 | spin_lock_irqsave(&clockfw_lock, flags); |
243 | if (arch_clock->clk_deny_idle) | 303 | if (arch_clock->clk_deny_idle) |
244 | arch_clock->clk_deny_idle(clk); | 304 | arch_clock->clk_deny_idle(clk); |
@@ -250,6 +310,9 @@ void clk_allow_idle(struct clk *clk) | |||
250 | { | 310 | { |
251 | unsigned long flags; | 311 | unsigned long flags; |
252 | 312 | ||
313 | if (clk == NULL || IS_ERR(clk)) | ||
314 | return; | ||
315 | |||
253 | spin_lock_irqsave(&clockfw_lock, flags); | 316 | spin_lock_irqsave(&clockfw_lock, flags); |
254 | if (arch_clock->clk_allow_idle) | 317 | if (arch_clock->clk_allow_idle) |
255 | arch_clock->clk_allow_idle(clk); | 318 | arch_clock->clk_allow_idle(clk); |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 9dcce904b608..079b67deac0f 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/arch/board.h> | 24 | #include <asm/arch/board.h> |
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | #include <asm/arch/menelaus.h> | ||
27 | 28 | ||
28 | 29 | ||
29 | void omap_nop_release(struct device *dev) | 30 | void omap_nop_release(struct device *dev) |
@@ -98,6 +99,62 @@ static inline void omap_init_i2c(void) {} | |||
98 | #endif | 99 | #endif |
99 | 100 | ||
100 | /*-------------------------------------------------------------------------*/ | 101 | /*-------------------------------------------------------------------------*/ |
102 | #if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) | ||
103 | |||
104 | static void omap_init_kp(void) | ||
105 | { | ||
106 | if (machine_is_omap_h2() || machine_is_omap_h3()) { | ||
107 | omap_cfg_reg(F18_1610_KBC0); | ||
108 | omap_cfg_reg(D20_1610_KBC1); | ||
109 | omap_cfg_reg(D19_1610_KBC2); | ||
110 | omap_cfg_reg(E18_1610_KBC3); | ||
111 | omap_cfg_reg(C21_1610_KBC4); | ||
112 | |||
113 | omap_cfg_reg(G18_1610_KBR0); | ||
114 | omap_cfg_reg(F19_1610_KBR1); | ||
115 | omap_cfg_reg(H14_1610_KBR2); | ||
116 | omap_cfg_reg(E20_1610_KBR3); | ||
117 | omap_cfg_reg(E19_1610_KBR4); | ||
118 | omap_cfg_reg(N19_1610_KBR5); | ||
119 | } else if (machine_is_omap_perseus2()) { | ||
120 | omap_cfg_reg(E2_730_KBR0); | ||
121 | omap_cfg_reg(J7_730_KBR1); | ||
122 | omap_cfg_reg(E1_730_KBR2); | ||
123 | omap_cfg_reg(F3_730_KBR3); | ||
124 | omap_cfg_reg(D2_730_KBR4); | ||
125 | |||
126 | omap_cfg_reg(C2_730_KBC0); | ||
127 | omap_cfg_reg(D3_730_KBC1); | ||
128 | omap_cfg_reg(E4_730_KBC2); | ||
129 | omap_cfg_reg(F4_730_KBC3); | ||
130 | omap_cfg_reg(E3_730_KBC4); | ||
131 | } else if (machine_is_omap_h4()) { | ||
132 | omap_cfg_reg(T19_24XX_KBR0); | ||
133 | omap_cfg_reg(R19_24XX_KBR1); | ||
134 | omap_cfg_reg(V18_24XX_KBR2); | ||
135 | omap_cfg_reg(M21_24XX_KBR3); | ||
136 | omap_cfg_reg(E5__24XX_KBR4); | ||
137 | if (omap_has_menelaus()) { | ||
138 | omap_cfg_reg(B3__24XX_KBR5); | ||
139 | omap_cfg_reg(AA4_24XX_KBC2); | ||
140 | omap_cfg_reg(B13_24XX_KBC6); | ||
141 | } else { | ||
142 | omap_cfg_reg(M18_24XX_KBR5); | ||
143 | omap_cfg_reg(H19_24XX_KBC2); | ||
144 | omap_cfg_reg(N19_24XX_KBC6); | ||
145 | } | ||
146 | omap_cfg_reg(R20_24XX_KBC0); | ||
147 | omap_cfg_reg(M14_24XX_KBC1); | ||
148 | omap_cfg_reg(V17_24XX_KBC3); | ||
149 | omap_cfg_reg(P21_24XX_KBC4); | ||
150 | omap_cfg_reg(L14_24XX_KBC5); | ||
151 | } | ||
152 | } | ||
153 | #else | ||
154 | static inline void omap_init_kp(void) {} | ||
155 | #endif | ||
156 | |||
157 | /*-------------------------------------------------------------------------*/ | ||
101 | 158 | ||
102 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | 159 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
103 | 160 | ||
@@ -240,6 +297,55 @@ static void __init omap_init_mmc(void) | |||
240 | static inline void omap_init_mmc(void) {} | 297 | static inline void omap_init_mmc(void) {} |
241 | #endif | 298 | #endif |
242 | 299 | ||
300 | /*-------------------------------------------------------------------------*/ | ||
301 | |||
302 | /* Numbering for the SPI-capable controllers when used for SPI: | ||
303 | * spi = 1 | ||
304 | * uwire = 2 | ||
305 | * mmc1..2 = 3..4 | ||
306 | * mcbsp1..3 = 5..7 | ||
307 | */ | ||
308 | |||
309 | #if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE) | ||
310 | |||
311 | #define OMAP_UWIRE_BASE 0xfffb3000 | ||
312 | |||
313 | static struct resource uwire_resources[] = { | ||
314 | { | ||
315 | .start = OMAP_UWIRE_BASE, | ||
316 | .end = OMAP_UWIRE_BASE + 0x20, | ||
317 | .flags = IORESOURCE_MEM, | ||
318 | }, | ||
319 | }; | ||
320 | |||
321 | static struct platform_device omap_uwire_device = { | ||
322 | .name = "omap_uwire", | ||
323 | .id = -1, | ||
324 | .dev = { | ||
325 | .release = omap_nop_release, | ||
326 | }, | ||
327 | .num_resources = ARRAY_SIZE(uwire_resources), | ||
328 | .resource = uwire_resources, | ||
329 | }; | ||
330 | |||
331 | static void omap_init_uwire(void) | ||
332 | { | ||
333 | /* FIXME define and use a boot tag; not all boards will be hooking | ||
334 | * up devices to the microwire controller, and multi-board configs | ||
335 | * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway... | ||
336 | */ | ||
337 | |||
338 | /* board-specific code must configure chipselects (only a few | ||
339 | * are normally used) and SCLK/SDI/SDO (each has two choices). | ||
340 | */ | ||
341 | (void) platform_device_register(&omap_uwire_device); | ||
342 | } | ||
343 | #else | ||
344 | static inline void omap_init_uwire(void) {} | ||
345 | #endif | ||
346 | |||
347 | /*-------------------------------------------------------------------------*/ | ||
348 | |||
243 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) | 349 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) |
244 | 350 | ||
245 | #ifdef CONFIG_ARCH_OMAP24XX | 351 | #ifdef CONFIG_ARCH_OMAP24XX |
@@ -310,40 +416,6 @@ static void omap_init_rng(void) | |||
310 | static inline void omap_init_rng(void) {} | 416 | static inline void omap_init_rng(void) {} |
311 | #endif | 417 | #endif |
312 | 418 | ||
313 | #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) | ||
314 | |||
315 | static struct omap_lcd_config omap_fb_conf; | ||
316 | |||
317 | static u64 omap_fb_dma_mask = ~(u32)0; | ||
318 | |||
319 | static struct platform_device omap_fb_device = { | ||
320 | .name = "omapfb", | ||
321 | .id = -1, | ||
322 | .dev = { | ||
323 | .release = omap_nop_release, | ||
324 | .dma_mask = &omap_fb_dma_mask, | ||
325 | .coherent_dma_mask = ~(u32)0, | ||
326 | .platform_data = &omap_fb_conf, | ||
327 | }, | ||
328 | .num_resources = 0, | ||
329 | }; | ||
330 | |||
331 | static inline void omap_init_fb(void) | ||
332 | { | ||
333 | const struct omap_lcd_config *conf; | ||
334 | |||
335 | conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); | ||
336 | if (conf != NULL) | ||
337 | omap_fb_conf = *conf; | ||
338 | platform_device_register(&omap_fb_device); | ||
339 | } | ||
340 | |||
341 | #else | ||
342 | |||
343 | static inline void omap_init_fb(void) {} | ||
344 | |||
345 | #endif | ||
346 | |||
347 | /* | 419 | /* |
348 | * This gets called after board-specific INIT_MACHINE, and initializes most | 420 | * This gets called after board-specific INIT_MACHINE, and initializes most |
349 | * on-chip peripherals accessible on this board (except for few like USB): | 421 | * on-chip peripherals accessible on this board (except for few like USB): |
@@ -369,9 +441,10 @@ static int __init omap_init_devices(void) | |||
369 | /* please keep these calls, and their implementations above, | 441 | /* please keep these calls, and their implementations above, |
370 | * in alphabetical order so they're easier to sort through. | 442 | * in alphabetical order so they're easier to sort through. |
371 | */ | 443 | */ |
372 | omap_init_fb(); | ||
373 | omap_init_i2c(); | 444 | omap_init_i2c(); |
445 | omap_init_kp(); | ||
374 | omap_init_mmc(); | 446 | omap_init_mmc(); |
447 | omap_init_uwire(); | ||
375 | omap_init_wdt(); | 448 | omap_init_wdt(); |
376 | omap_init_rng(); | 449 | omap_init_rng(); |
377 | 450 | ||
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index a4e5ac77f6df..5dac4230360d 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -1258,6 +1258,11 @@ void omap_stop_lcd_dma(void) | |||
1258 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); | 1258 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); |
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | int omap_lcd_dma_ext_running(void) | ||
1262 | { | ||
1263 | return lcd_dma.ext_ctrl && lcd_dma.active; | ||
1264 | } | ||
1265 | |||
1261 | /*----------------------------------------------------------------------------*/ | 1266 | /*----------------------------------------------------------------------------*/ |
1262 | 1267 | ||
1263 | static int __init omap_init_dma(void) | 1268 | static int __init omap_init_dma(void) |
@@ -1389,6 +1394,7 @@ EXPORT_SYMBOL(omap_free_lcd_dma); | |||
1389 | EXPORT_SYMBOL(omap_enable_lcd_dma); | 1394 | EXPORT_SYMBOL(omap_enable_lcd_dma); |
1390 | EXPORT_SYMBOL(omap_setup_lcd_dma); | 1395 | EXPORT_SYMBOL(omap_setup_lcd_dma); |
1391 | EXPORT_SYMBOL(omap_stop_lcd_dma); | 1396 | EXPORT_SYMBOL(omap_stop_lcd_dma); |
1397 | EXPORT_SYMBOL(omap_lcd_dma_ext_running); | ||
1392 | EXPORT_SYMBOL(omap_set_lcd_dma_b1); | 1398 | EXPORT_SYMBOL(omap_set_lcd_dma_b1); |
1393 | EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); | 1399 | EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); |
1394 | EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); | 1400 | EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); |
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 38d7ebf87920..eba3cb52ad87 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -97,6 +97,32 @@ int omap_dm_timers_active(void) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | /** | ||
101 | * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR | ||
102 | * @inputmask: current value of idlect mask | ||
103 | */ | ||
104 | __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) | ||
105 | { | ||
106 | int n; | ||
107 | |||
108 | /* If ARMXOR cannot be idled this function call is unnecessary */ | ||
109 | if (!(inputmask & (1 << 1))) | ||
110 | return inputmask; | ||
111 | |||
112 | /* If any active timer is using ARMXOR return modified mask */ | ||
113 | for (n = 0; dm_timers[n].base; ++n) | ||
114 | if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)& | ||
115 | OMAP_TIMER_CTRL_ST) { | ||
116 | if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0) | ||
117 | inputmask &= ~(1 << 1); | ||
118 | else | ||
119 | inputmask &= ~(1 << 2); | ||
120 | } | ||
121 | |||
122 | return inputmask; | ||
123 | } | ||
124 | |||
125 | |||
100 | void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) | 126 | void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) |
101 | { | 127 | { |
102 | int n = (timer - dm_timers) << 1; | 128 | int n = (timer - dm_timers) << 1; |
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c new file mode 100644 index 000000000000..305e9b990b71 --- /dev/null +++ b/arch/arm/plat-omap/fb.c | |||
@@ -0,0 +1,80 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/platform_device.h> | ||
6 | #include <linux/bootmem.h> | ||
7 | |||
8 | #include <asm/hardware.h> | ||
9 | #include <asm/io.h> | ||
10 | #include <asm/mach-types.h> | ||
11 | #include <asm/mach/map.h> | ||
12 | |||
13 | #include <asm/arch/board.h> | ||
14 | #include <asm/arch/sram.h> | ||
15 | #include <asm/arch/omapfb.h> | ||
16 | |||
17 | #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) | ||
18 | |||
19 | static struct omapfb_platform_data omapfb_config; | ||
20 | |||
21 | static u64 omap_fb_dma_mask = ~(u32)0; | ||
22 | |||
23 | static struct platform_device omap_fb_device = { | ||
24 | .name = "omapfb", | ||
25 | .id = -1, | ||
26 | .dev = { | ||
27 | .dma_mask = &omap_fb_dma_mask, | ||
28 | .coherent_dma_mask = ~(u32)0, | ||
29 | .platform_data = &omapfb_config, | ||
30 | }, | ||
31 | .num_resources = 0, | ||
32 | }; | ||
33 | |||
34 | /* called from map_io */ | ||
35 | void omapfb_reserve_mem(void) | ||
36 | { | ||
37 | const struct omap_fbmem_config *fbmem_conf; | ||
38 | |||
39 | omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start; | ||
40 | omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size; | ||
41 | |||
42 | fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config); | ||
43 | |||
44 | if (fbmem_conf != NULL) { | ||
45 | /* indicate that the bootloader already initialized the | ||
46 | * fb device, so we'll skip that part in the fb driver | ||
47 | */ | ||
48 | omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start; | ||
49 | omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size; | ||
50 | if (fbmem_conf->fb_sdram_size) { | ||
51 | pr_info("Reserving %u bytes SDRAM for frame buffer\n", | ||
52 | fbmem_conf->fb_sdram_size); | ||
53 | reserve_bootmem(fbmem_conf->fb_sdram_start, | ||
54 | fbmem_conf->fb_sdram_size); | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static inline int omap_init_fb(void) | ||
60 | { | ||
61 | const struct omap_lcd_config *conf; | ||
62 | |||
63 | conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); | ||
64 | if (conf == NULL) | ||
65 | return 0; | ||
66 | |||
67 | omapfb_config.lcd = *conf; | ||
68 | |||
69 | return platform_device_register(&omap_fb_device); | ||
70 | } | ||
71 | |||
72 | arch_initcall(omap_init_fb); | ||
73 | |||
74 | #else | ||
75 | |||
76 | void omapfb_reserve_mem(void) {} | ||
77 | |||
78 | #endif | ||
79 | |||
80 | |||
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index b4d5b9e4bfce..d3c8ea7eecfd 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -174,7 +174,7 @@ static int gpio_bank_count; | |||
174 | static inline struct gpio_bank *get_gpio_bank(int gpio) | 174 | static inline struct gpio_bank *get_gpio_bank(int gpio) |
175 | { | 175 | { |
176 | #ifdef CONFIG_ARCH_OMAP15XX | 176 | #ifdef CONFIG_ARCH_OMAP15XX |
177 | if (cpu_is_omap1510()) { | 177 | if (cpu_is_omap15xx()) { |
178 | if (OMAP_GPIO_IS_MPUIO(gpio)) | 178 | if (OMAP_GPIO_IS_MPUIO(gpio)) |
179 | return &gpio_bank[0]; | 179 | return &gpio_bank[0]; |
180 | return &gpio_bank[1]; | 180 | return &gpio_bank[1]; |
@@ -223,7 +223,7 @@ static inline int gpio_valid(int gpio) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | #ifdef CONFIG_ARCH_OMAP15XX | 225 | #ifdef CONFIG_ARCH_OMAP15XX |
226 | if (cpu_is_omap1510() && gpio < 16) | 226 | if (cpu_is_omap15xx() && gpio < 16) |
227 | return 0; | 227 | return 0; |
228 | #endif | 228 | #endif |
229 | #if defined(CONFIG_ARCH_OMAP16XX) | 229 | #if defined(CONFIG_ARCH_OMAP16XX) |
@@ -402,13 +402,13 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr | |||
402 | u32 gpio_bit = 1 << gpio; | 402 | u32 gpio_bit = 1 << gpio; |
403 | 403 | ||
404 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 404 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, |
405 | trigger & IRQT_LOW); | 405 | trigger & __IRQT_LOWLVL); |
406 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 406 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, |
407 | trigger & IRQT_HIGH); | 407 | trigger & __IRQT_HIGHLVL); |
408 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 408 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, |
409 | trigger & IRQT_RISING); | 409 | trigger & __IRQT_RISEDGE); |
410 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 410 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, |
411 | trigger & IRQT_FALLING); | 411 | trigger & __IRQT_FALEDGE); |
412 | /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level | 412 | /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level |
413 | * triggering requested. */ | 413 | * triggering requested. */ |
414 | } | 414 | } |
@@ -422,9 +422,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
422 | case METHOD_MPUIO: | 422 | case METHOD_MPUIO: |
423 | reg += OMAP_MPUIO_GPIO_INT_EDGE; | 423 | reg += OMAP_MPUIO_GPIO_INT_EDGE; |
424 | l = __raw_readl(reg); | 424 | l = __raw_readl(reg); |
425 | if (trigger == IRQT_RISING) | 425 | if (trigger & __IRQT_RISEDGE) |
426 | l |= 1 << gpio; | 426 | l |= 1 << gpio; |
427 | else if (trigger == IRQT_FALLING) | 427 | else if (trigger & __IRQT_FALEDGE) |
428 | l &= ~(1 << gpio); | 428 | l &= ~(1 << gpio); |
429 | else | 429 | else |
430 | goto bad; | 430 | goto bad; |
@@ -432,9 +432,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
432 | case METHOD_GPIO_1510: | 432 | case METHOD_GPIO_1510: |
433 | reg += OMAP1510_GPIO_INT_CONTROL; | 433 | reg += OMAP1510_GPIO_INT_CONTROL; |
434 | l = __raw_readl(reg); | 434 | l = __raw_readl(reg); |
435 | if (trigger == IRQT_RISING) | 435 | if (trigger & __IRQT_RISEDGE) |
436 | l |= 1 << gpio; | 436 | l |= 1 << gpio; |
437 | else if (trigger == IRQT_FALLING) | 437 | else if (trigger & __IRQT_FALEDGE) |
438 | l &= ~(1 << gpio); | 438 | l &= ~(1 << gpio); |
439 | else | 439 | else |
440 | goto bad; | 440 | goto bad; |
@@ -446,20 +446,21 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
446 | reg += OMAP1610_GPIO_EDGE_CTRL1; | 446 | reg += OMAP1610_GPIO_EDGE_CTRL1; |
447 | gpio &= 0x07; | 447 | gpio &= 0x07; |
448 | /* We allow only edge triggering, i.e. two lowest bits */ | 448 | /* We allow only edge triggering, i.e. two lowest bits */ |
449 | if (trigger & ~IRQT_BOTHEDGE) | 449 | if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) |
450 | BUG(); | 450 | BUG(); |
451 | /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */ | ||
452 | trigger &= 0x03; | ||
453 | l = __raw_readl(reg); | 451 | l = __raw_readl(reg); |
454 | l &= ~(3 << (gpio << 1)); | 452 | l &= ~(3 << (gpio << 1)); |
455 | l |= trigger << (gpio << 1); | 453 | if (trigger & __IRQT_RISEDGE) |
454 | l |= 2 << (gpio << 1); | ||
455 | if (trigger & __IRQT_FALEDGE) | ||
456 | l |= 1 << (gpio << 1); | ||
456 | break; | 457 | break; |
457 | case METHOD_GPIO_730: | 458 | case METHOD_GPIO_730: |
458 | reg += OMAP730_GPIO_INT_CONTROL; | 459 | reg += OMAP730_GPIO_INT_CONTROL; |
459 | l = __raw_readl(reg); | 460 | l = __raw_readl(reg); |
460 | if (trigger == IRQT_RISING) | 461 | if (trigger & __IRQT_RISEDGE) |
461 | l |= 1 << gpio; | 462 | l |= 1 << gpio; |
462 | else if (trigger == IRQT_FALLING) | 463 | else if (trigger & __IRQT_FALEDGE) |
463 | l &= ~(1 << gpio); | 464 | l &= ~(1 << gpio); |
464 | else | 465 | else |
465 | goto bad; | 466 | goto bad; |
@@ -491,7 +492,9 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
491 | if (check_gpio(gpio) < 0) | 492 | if (check_gpio(gpio) < 0) |
492 | return -EINVAL; | 493 | return -EINVAL; |
493 | 494 | ||
494 | if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE)) | 495 | if (type & IRQT_PROBE) |
496 | return -EINVAL; | ||
497 | if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) | ||
495 | return -EINVAL; | 498 | return -EINVAL; |
496 | 499 | ||
497 | bank = get_gpio_bank(gpio); | 500 | bank = get_gpio_bank(gpio); |
@@ -755,13 +758,32 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
755 | if (bank->method == METHOD_GPIO_24XX) | 758 | if (bank->method == METHOD_GPIO_24XX) |
756 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; | 759 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; |
757 | #endif | 760 | #endif |
758 | |||
759 | while(1) { | 761 | while(1) { |
760 | isr = __raw_readl(isr_reg); | 762 | u32 isr_saved, level_mask = 0; |
761 | _enable_gpio_irqbank(bank, isr, 0); | 763 | |
762 | _clear_gpio_irqbank(bank, isr); | 764 | isr_saved = isr = __raw_readl(isr_reg); |
763 | _enable_gpio_irqbank(bank, isr, 1); | 765 | |
764 | desc->chip->unmask(irq); | 766 | if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) |
767 | isr &= 0x0000ffff; | ||
768 | |||
769 | if (cpu_is_omap24xx()) | ||
770 | level_mask = | ||
771 | __raw_readl(bank->base + | ||
772 | OMAP24XX_GPIO_LEVELDETECT0) | | ||
773 | __raw_readl(bank->base + | ||
774 | OMAP24XX_GPIO_LEVELDETECT1); | ||
775 | |||
776 | /* clear edge sensitive interrupts before handler(s) are | ||
777 | called so that we don't miss any interrupt occurred while | ||
778 | executing them */ | ||
779 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0); | ||
780 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); | ||
781 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); | ||
782 | |||
783 | /* if there is only edge sensitive GPIO pin interrupts | ||
784 | configured, we could unmask GPIO bank interrupt immediately */ | ||
785 | if (!level_mask) | ||
786 | desc->chip->unmask(irq); | ||
765 | 787 | ||
766 | if (!isr) | 788 | if (!isr) |
767 | break; | 789 | break; |
@@ -774,6 +796,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
774 | d = irq_desc + gpio_irq; | 796 | d = irq_desc + gpio_irq; |
775 | desc_handle_irq(gpio_irq, d, regs); | 797 | desc_handle_irq(gpio_irq, d, regs); |
776 | } | 798 | } |
799 | |||
800 | if (cpu_is_omap24xx()) { | ||
801 | /* clear level sensitive interrupts after handler(s) */ | ||
802 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 0); | ||
803 | _clear_gpio_irqbank(bank, isr_saved & level_mask); | ||
804 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); | ||
805 | } | ||
806 | |||
807 | /* if bank has any level sensitive GPIO pin interrupt | ||
808 | configured, we must unmask the bank interrupt only after | ||
809 | handler(s) are executed in order to avoid spurious bank | ||
810 | interrupt */ | ||
811 | if (level_mask) | ||
812 | desc->chip->unmask(irq); | ||
777 | } | 813 | } |
778 | } | 814 | } |
779 | 815 | ||
@@ -848,7 +884,7 @@ static int __init _omap_gpio_init(void) | |||
848 | 884 | ||
849 | initialized = 1; | 885 | initialized = 1; |
850 | 886 | ||
851 | if (cpu_is_omap1510()) { | 887 | if (cpu_is_omap15xx()) { |
852 | gpio_ick = clk_get(NULL, "arm_gpio_ck"); | 888 | gpio_ick = clk_get(NULL, "arm_gpio_ck"); |
853 | if (IS_ERR(gpio_ick)) | 889 | if (IS_ERR(gpio_ick)) |
854 | printk("Could not get arm_gpio_ck\n"); | 890 | printk("Could not get arm_gpio_ck\n"); |
@@ -869,7 +905,7 @@ static int __init _omap_gpio_init(void) | |||
869 | } | 905 | } |
870 | 906 | ||
871 | #ifdef CONFIG_ARCH_OMAP15XX | 907 | #ifdef CONFIG_ARCH_OMAP15XX |
872 | if (cpu_is_omap1510()) { | 908 | if (cpu_is_omap15xx()) { |
873 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); | 909 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); |
874 | gpio_bank_count = 2; | 910 | gpio_bank_count = 2; |
875 | gpio_bank = gpio_bank_1510; | 911 | gpio_bank = gpio_bank_1510; |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 1cd2cace7e1b..196aac3ac329 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #ifdef CONFIG_MCBSP_DEBUG | 34 | #ifdef CONFIG_MCBSP_DEBUG |
35 | #define DBG(x...) printk(x) | 35 | #define DBG(x...) printk(x) |
36 | #else | 36 | #else |
37 | #define DBG(x...) do { } while (0) | 37 | #define DBG(x...) do { } while (0) |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | struct omap_mcbsp { | 40 | struct omap_mcbsp { |
@@ -44,6 +44,7 @@ struct omap_mcbsp { | |||
44 | omap_mcbsp_word_length rx_word_length; | 44 | omap_mcbsp_word_length rx_word_length; |
45 | omap_mcbsp_word_length tx_word_length; | 45 | omap_mcbsp_word_length tx_word_length; |
46 | 46 | ||
47 | omap_mcbsp_io_type_t io_type; /* IRQ or poll */ | ||
47 | /* IRQ based TX/RX */ | 48 | /* IRQ based TX/RX */ |
48 | int rx_irq; | 49 | int rx_irq; |
49 | int tx_irq; | 50 | int tx_irq; |
@@ -64,10 +65,19 @@ struct omap_mcbsp { | |||
64 | }; | 65 | }; |
65 | 66 | ||
66 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; | 67 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; |
68 | #ifdef CONFIG_ARCH_OMAP1 | ||
67 | static struct clk *mcbsp_dsp_ck = 0; | 69 | static struct clk *mcbsp_dsp_ck = 0; |
68 | static struct clk *mcbsp_api_ck = 0; | 70 | static struct clk *mcbsp_api_ck = 0; |
69 | static struct clk *mcbsp_dspxor_ck = 0; | 71 | static struct clk *mcbsp_dspxor_ck = 0; |
70 | 72 | #endif | |
73 | #ifdef CONFIG_ARCH_OMAP2 | ||
74 | static struct clk *mcbsp1_ick = 0; | ||
75 | static struct clk *mcbsp1_fck = 0; | ||
76 | static struct clk *mcbsp2_ick = 0; | ||
77 | static struct clk *mcbsp2_fck = 0; | ||
78 | static struct clk *sys_ck = 0; | ||
79 | static struct clk *sys_clkout = 0; | ||
80 | #endif | ||
71 | 81 | ||
72 | static void omap_mcbsp_dump_reg(u8 id) | 82 | static void omap_mcbsp_dump_reg(u8 id) |
73 | { | 83 | { |
@@ -88,7 +98,6 @@ static void omap_mcbsp_dump_reg(u8 id) | |||
88 | DBG("***********************\n"); | 98 | DBG("***********************\n"); |
89 | } | 99 | } |
90 | 100 | ||
91 | |||
92 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | 101 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) |
93 | { | 102 | { |
94 | struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); | 103 | struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); |
@@ -109,7 +118,6 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_re | |||
109 | return IRQ_HANDLED; | 118 | return IRQ_HANDLED; |
110 | } | 119 | } |
111 | 120 | ||
112 | |||
113 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) | 121 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) |
114 | { | 122 | { |
115 | struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); | 123 | struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); |
@@ -176,7 +184,7 @@ static int omap_mcbsp_check(unsigned int id) | |||
176 | return 0; | 184 | return 0; |
177 | } | 185 | } |
178 | 186 | ||
179 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 187 | if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { |
180 | if (id > OMAP_MAX_MCBSP_COUNT) { | 188 | if (id > OMAP_MAX_MCBSP_COUNT) { |
181 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | 189 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); |
182 | return -1; | 190 | return -1; |
@@ -187,9 +195,10 @@ static int omap_mcbsp_check(unsigned int id) | |||
187 | return -1; | 195 | return -1; |
188 | } | 196 | } |
189 | 197 | ||
198 | #ifdef CONFIG_ARCH_OMAP1 | ||
190 | static void omap_mcbsp_dsp_request(void) | 199 | static void omap_mcbsp_dsp_request(void) |
191 | { | 200 | { |
192 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 201 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { |
193 | clk_enable(mcbsp_dsp_ck); | 202 | clk_enable(mcbsp_dsp_ck); |
194 | clk_enable(mcbsp_api_ck); | 203 | clk_enable(mcbsp_api_ck); |
195 | 204 | ||
@@ -207,12 +216,49 @@ static void omap_mcbsp_dsp_request(void) | |||
207 | 216 | ||
208 | static void omap_mcbsp_dsp_free(void) | 217 | static void omap_mcbsp_dsp_free(void) |
209 | { | 218 | { |
210 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 219 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { |
211 | clk_disable(mcbsp_dspxor_ck); | 220 | clk_disable(mcbsp_dspxor_ck); |
212 | clk_disable(mcbsp_dsp_ck); | 221 | clk_disable(mcbsp_dsp_ck); |
213 | clk_disable(mcbsp_api_ck); | 222 | clk_disable(mcbsp_api_ck); |
214 | } | 223 | } |
215 | } | 224 | } |
225 | #endif | ||
226 | |||
227 | #ifdef CONFIG_ARCH_OMAP2 | ||
228 | static void omap2_mcbsp2_mux_setup(void) | ||
229 | { | ||
230 | omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); | ||
231 | omap_cfg_reg(R14_24XX_MCBSP2_FSX); | ||
232 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | ||
233 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | ||
234 | omap_cfg_reg(V14_24XX_GPIO117); | ||
235 | omap_cfg_reg(W14_24XX_SYS_CLKOUT); | ||
236 | } | ||
237 | #endif | ||
238 | |||
239 | /* | ||
240 | * We can choose between IRQ based or polled IO. | ||
241 | * This needs to be called before omap_mcbsp_request(). | ||
242 | */ | ||
243 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | ||
244 | { | ||
245 | if (omap_mcbsp_check(id) < 0) | ||
246 | return -EINVAL; | ||
247 | |||
248 | spin_lock(&mcbsp[id].lock); | ||
249 | |||
250 | if (!mcbsp[id].free) { | ||
251 | printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); | ||
252 | spin_unlock(&mcbsp[id].lock); | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | |||
256 | mcbsp[id].io_type = io_type; | ||
257 | |||
258 | spin_unlock(&mcbsp[id].lock); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
216 | 262 | ||
217 | int omap_mcbsp_request(unsigned int id) | 263 | int omap_mcbsp_request(unsigned int id) |
218 | { | 264 | { |
@@ -221,12 +267,26 @@ int omap_mcbsp_request(unsigned int id) | |||
221 | if (omap_mcbsp_check(id) < 0) | 267 | if (omap_mcbsp_check(id) < 0) |
222 | return -EINVAL; | 268 | return -EINVAL; |
223 | 269 | ||
270 | #ifdef CONFIG_ARCH_OMAP1 | ||
224 | /* | 271 | /* |
225 | * On 1510, 1610 and 1710, McBSP1 and McBSP3 | 272 | * On 1510, 1610 and 1710, McBSP1 and McBSP3 |
226 | * are DSP public peripherals. | 273 | * are DSP public peripherals. |
227 | */ | 274 | */ |
228 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | 275 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) |
229 | omap_mcbsp_dsp_request(); | 276 | omap_mcbsp_dsp_request(); |
277 | #endif | ||
278 | |||
279 | #ifdef CONFIG_ARCH_OMAP2 | ||
280 | if (cpu_is_omap24xx()) { | ||
281 | if (id == OMAP_MCBSP1) { | ||
282 | clk_enable(mcbsp1_ick); | ||
283 | clk_enable(mcbsp1_fck); | ||
284 | } else { | ||
285 | clk_enable(mcbsp2_ick); | ||
286 | clk_enable(mcbsp2_fck); | ||
287 | } | ||
288 | } | ||
289 | #endif | ||
230 | 290 | ||
231 | spin_lock(&mcbsp[id].lock); | 291 | spin_lock(&mcbsp[id].lock); |
232 | if (!mcbsp[id].free) { | 292 | if (!mcbsp[id].free) { |
@@ -238,30 +298,33 @@ int omap_mcbsp_request(unsigned int id) | |||
238 | mcbsp[id].free = 0; | 298 | mcbsp[id].free = 0; |
239 | spin_unlock(&mcbsp[id].lock); | 299 | spin_unlock(&mcbsp[id].lock); |
240 | 300 | ||
241 | /* We need to get IRQs here */ | 301 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { |
242 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, | 302 | /* We need to get IRQs here */ |
243 | "McBSP", | 303 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, |
244 | (void *) (&mcbsp[id])); | 304 | "McBSP", |
245 | if (err != 0) { | 305 | (void *) (&mcbsp[id])); |
246 | printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", | 306 | if (err != 0) { |
247 | mcbsp[id].tx_irq, mcbsp[id].id); | 307 | printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", |
248 | return err; | 308 | mcbsp[id].tx_irq, mcbsp[id].id); |
249 | } | 309 | return err; |
310 | } | ||
250 | 311 | ||
251 | init_completion(&(mcbsp[id].tx_irq_completion)); | 312 | init_completion(&(mcbsp[id].tx_irq_completion)); |
252 | 313 | ||
253 | 314 | ||
254 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, | 315 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, |
255 | "McBSP", | 316 | "McBSP", |
256 | (void *) (&mcbsp[id])); | 317 | (void *) (&mcbsp[id])); |
257 | if (err != 0) { | 318 | if (err != 0) { |
258 | printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", | 319 | printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", |
259 | mcbsp[id].rx_irq, mcbsp[id].id); | 320 | mcbsp[id].rx_irq, mcbsp[id].id); |
260 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 321 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); |
261 | return err; | 322 | return err; |
323 | } | ||
324 | |||
325 | init_completion(&(mcbsp[id].rx_irq_completion)); | ||
262 | } | 326 | } |
263 | 327 | ||
264 | init_completion(&(mcbsp[id].rx_irq_completion)); | ||
265 | return 0; | 328 | return 0; |
266 | 329 | ||
267 | } | 330 | } |
@@ -271,8 +334,24 @@ void omap_mcbsp_free(unsigned int id) | |||
271 | if (omap_mcbsp_check(id) < 0) | 334 | if (omap_mcbsp_check(id) < 0) |
272 | return; | 335 | return; |
273 | 336 | ||
274 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | 337 | #ifdef CONFIG_ARCH_OMAP1 |
275 | omap_mcbsp_dsp_free(); | 338 | if (cpu_class_is_omap1()) { |
339 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | ||
340 | omap_mcbsp_dsp_free(); | ||
341 | } | ||
342 | #endif | ||
343 | |||
344 | #ifdef CONFIG_ARCH_OMAP2 | ||
345 | if (cpu_is_omap24xx()) { | ||
346 | if (id == OMAP_MCBSP1) { | ||
347 | clk_disable(mcbsp1_ick); | ||
348 | clk_disable(mcbsp1_fck); | ||
349 | } else { | ||
350 | clk_disable(mcbsp2_ick); | ||
351 | clk_disable(mcbsp2_fck); | ||
352 | } | ||
353 | } | ||
354 | #endif | ||
276 | 355 | ||
277 | spin_lock(&mcbsp[id].lock); | 356 | spin_lock(&mcbsp[id].lock); |
278 | if (mcbsp[id].free) { | 357 | if (mcbsp[id].free) { |
@@ -284,9 +363,11 @@ void omap_mcbsp_free(unsigned int id) | |||
284 | mcbsp[id].free = 1; | 363 | mcbsp[id].free = 1; |
285 | spin_unlock(&mcbsp[id].lock); | 364 | spin_unlock(&mcbsp[id].lock); |
286 | 365 | ||
287 | /* Free IRQs */ | 366 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { |
288 | free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); | 367 | /* Free IRQs */ |
289 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 368 | free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); |
369 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | ||
370 | } | ||
290 | } | 371 | } |
291 | 372 | ||
292 | /* | 373 | /* |
@@ -461,6 +542,115 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
461 | } | 542 | } |
462 | 543 | ||
463 | 544 | ||
545 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | ||
546 | { | ||
547 | u32 io_base = mcbsp[id].io_base; | ||
548 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | ||
549 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | ||
550 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | ||
551 | |||
552 | if (tx_word_length != rx_word_length) | ||
553 | return -EINVAL; | ||
554 | |||
555 | /* First we wait for the transmitter to be ready */ | ||
556 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
557 | while (!(spcr2 & XRDY)) { | ||
558 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
559 | if (attempts++ > 1000) { | ||
560 | /* We must reset the transmitter */ | ||
561 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); | ||
562 | udelay(10); | ||
563 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | ||
564 | udelay(10); | ||
565 | printk("McBSP transmitter not ready\n"); | ||
566 | return -EAGAIN; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | /* Now we can push the data */ | ||
571 | if (tx_word_length > OMAP_MCBSP_WORD_16) | ||
572 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); | ||
573 | OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); | ||
574 | |||
575 | /* We wait for the receiver to be ready */ | ||
576 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
577 | while (!(spcr1 & RRDY)) { | ||
578 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
579 | if (attempts++ > 1000) { | ||
580 | /* We must reset the receiver */ | ||
581 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); | ||
582 | udelay(10); | ||
583 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | ||
584 | udelay(10); | ||
585 | printk("McBSP receiver not ready\n"); | ||
586 | return -EAGAIN; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | /* Receiver is ready, let's read the dummy data */ | ||
591 | if (rx_word_length > OMAP_MCBSP_WORD_16) | ||
592 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); | ||
593 | word_lsb = OMAP_MCBSP_READ(io_base, DRR1); | ||
594 | |||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | ||
599 | { | ||
600 | u32 io_base = mcbsp[id].io_base, clock_word = 0; | ||
601 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | ||
602 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | ||
603 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | ||
604 | |||
605 | if (tx_word_length != rx_word_length) | ||
606 | return -EINVAL; | ||
607 | |||
608 | /* First we wait for the transmitter to be ready */ | ||
609 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
610 | while (!(spcr2 & XRDY)) { | ||
611 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
612 | if (attempts++ > 1000) { | ||
613 | /* We must reset the transmitter */ | ||
614 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); | ||
615 | udelay(10); | ||
616 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | ||
617 | udelay(10); | ||
618 | printk("McBSP transmitter not ready\n"); | ||
619 | return -EAGAIN; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | /* We first need to enable the bus clock */ | ||
624 | if (tx_word_length > OMAP_MCBSP_WORD_16) | ||
625 | OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16); | ||
626 | OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff); | ||
627 | |||
628 | /* We wait for the receiver to be ready */ | ||
629 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
630 | while (!(spcr1 & RRDY)) { | ||
631 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
632 | if (attempts++ > 1000) { | ||
633 | /* We must reset the receiver */ | ||
634 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); | ||
635 | udelay(10); | ||
636 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | ||
637 | udelay(10); | ||
638 | printk("McBSP receiver not ready\n"); | ||
639 | return -EAGAIN; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* Receiver is ready, there is something for us */ | ||
644 | if (rx_word_length > OMAP_MCBSP_WORD_16) | ||
645 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); | ||
646 | word_lsb = OMAP_MCBSP_READ(io_base, DRR1); | ||
647 | |||
648 | word[0] = (word_lsb | (word_msb << 16)); | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | |||
464 | /* | 654 | /* |
465 | * Simple DMA based buffer rx/tx routines. | 655 | * Simple DMA based buffer rx/tx routines. |
466 | * Nothing fancy, just a single buffer tx/rx through DMA. | 656 | * Nothing fancy, just a single buffer tx/rx through DMA. |
@@ -471,6 +661,9 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
471 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 661 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) |
472 | { | 662 | { |
473 | int dma_tx_ch; | 663 | int dma_tx_ch; |
664 | int src_port = 0; | ||
665 | int dest_port = 0; | ||
666 | int sync_dev = 0; | ||
474 | 667 | ||
475 | if (omap_mcbsp_check(id) < 0) | 668 | if (omap_mcbsp_check(id) < 0) |
476 | return -EINVAL; | 669 | return -EINVAL; |
@@ -487,20 +680,27 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
487 | 680 | ||
488 | init_completion(&(mcbsp[id].tx_dma_completion)); | 681 | init_completion(&(mcbsp[id].tx_dma_completion)); |
489 | 682 | ||
683 | if (cpu_class_is_omap1()) { | ||
684 | src_port = OMAP_DMA_PORT_TIPB; | ||
685 | dest_port = OMAP_DMA_PORT_EMIFF; | ||
686 | } | ||
687 | if (cpu_is_omap24xx()) | ||
688 | sync_dev = mcbsp[id].dma_tx_sync; | ||
689 | |||
490 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, | 690 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, |
491 | OMAP_DMA_DATA_TYPE_S16, | 691 | OMAP_DMA_DATA_TYPE_S16, |
492 | length >> 1, 1, | 692 | length >> 1, 1, |
493 | OMAP_DMA_SYNC_ELEMENT, | 693 | OMAP_DMA_SYNC_ELEMENT, |
494 | 0, 0); | 694 | sync_dev, 0); |
495 | 695 | ||
496 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, | 696 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, |
497 | OMAP_DMA_PORT_TIPB, | 697 | src_port, |
498 | OMAP_DMA_AMODE_CONSTANT, | 698 | OMAP_DMA_AMODE_CONSTANT, |
499 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, | 699 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, |
500 | 0, 0); | 700 | 0, 0); |
501 | 701 | ||
502 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, | 702 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, |
503 | OMAP_DMA_PORT_EMIFF, | 703 | dest_port, |
504 | OMAP_DMA_AMODE_POST_INC, | 704 | OMAP_DMA_AMODE_POST_INC, |
505 | buffer, | 705 | buffer, |
506 | 0, 0); | 706 | 0, 0); |
@@ -514,6 +714,9 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
514 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 714 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) |
515 | { | 715 | { |
516 | int dma_rx_ch; | 716 | int dma_rx_ch; |
717 | int src_port = 0; | ||
718 | int dest_port = 0; | ||
719 | int sync_dev = 0; | ||
517 | 720 | ||
518 | if (omap_mcbsp_check(id) < 0) | 721 | if (omap_mcbsp_check(id) < 0) |
519 | return -EINVAL; | 722 | return -EINVAL; |
@@ -530,20 +733,27 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
530 | 733 | ||
531 | init_completion(&(mcbsp[id].rx_dma_completion)); | 734 | init_completion(&(mcbsp[id].rx_dma_completion)); |
532 | 735 | ||
736 | if (cpu_class_is_omap1()) { | ||
737 | src_port = OMAP_DMA_PORT_TIPB; | ||
738 | dest_port = OMAP_DMA_PORT_EMIFF; | ||
739 | } | ||
740 | if (cpu_is_omap24xx()) | ||
741 | sync_dev = mcbsp[id].dma_rx_sync; | ||
742 | |||
533 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 743 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, |
534 | OMAP_DMA_DATA_TYPE_S16, | 744 | OMAP_DMA_DATA_TYPE_S16, |
535 | length >> 1, 1, | 745 | length >> 1, 1, |
536 | OMAP_DMA_SYNC_ELEMENT, | 746 | OMAP_DMA_SYNC_ELEMENT, |
537 | 0, 0); | 747 | sync_dev, 0); |
538 | 748 | ||
539 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, | 749 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, |
540 | OMAP_DMA_PORT_TIPB, | 750 | src_port, |
541 | OMAP_DMA_AMODE_CONSTANT, | 751 | OMAP_DMA_AMODE_CONSTANT, |
542 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, | 752 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, |
543 | 0, 0); | 753 | 0, 0); |
544 | 754 | ||
545 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, | 755 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, |
546 | OMAP_DMA_PORT_EMIFF, | 756 | dest_port, |
547 | OMAP_DMA_AMODE_POST_INC, | 757 | OMAP_DMA_AMODE_POST_INC, |
548 | buffer, | 758 | buffer, |
549 | 0, 0); | 759 | 0, 0); |
@@ -688,6 +898,23 @@ static const struct omap_mcbsp_info mcbsp_1610[] = { | |||
688 | }; | 898 | }; |
689 | #endif | 899 | #endif |
690 | 900 | ||
901 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
902 | static const struct omap_mcbsp_info mcbsp_24xx[] = { | ||
903 | [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), | ||
904 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
905 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
906 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
907 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
908 | }, | ||
909 | [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), | ||
910 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
911 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
912 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
913 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
914 | }, | ||
915 | }; | ||
916 | #endif | ||
917 | |||
691 | static int __init omap_mcbsp_init(void) | 918 | static int __init omap_mcbsp_init(void) |
692 | { | 919 | { |
693 | int mcbsp_count = 0, i; | 920 | int mcbsp_count = 0, i; |
@@ -695,6 +922,7 @@ static int __init omap_mcbsp_init(void) | |||
695 | 922 | ||
696 | printk("Initializing OMAP McBSP system\n"); | 923 | printk("Initializing OMAP McBSP system\n"); |
697 | 924 | ||
925 | #ifdef CONFIG_ARCH_OMAP1 | ||
698 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); | 926 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); |
699 | if (IS_ERR(mcbsp_dsp_ck)) { | 927 | if (IS_ERR(mcbsp_dsp_ck)) { |
700 | printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); | 928 | printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); |
@@ -710,6 +938,29 @@ static int __init omap_mcbsp_init(void) | |||
710 | printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); | 938 | printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); |
711 | return PTR_ERR(mcbsp_dspxor_ck); | 939 | return PTR_ERR(mcbsp_dspxor_ck); |
712 | } | 940 | } |
941 | #endif | ||
942 | #ifdef CONFIG_ARCH_OMAP2 | ||
943 | mcbsp1_ick = clk_get(0, "mcbsp1_ick"); | ||
944 | if (IS_ERR(mcbsp1_ick)) { | ||
945 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); | ||
946 | return PTR_ERR(mcbsp1_ick); | ||
947 | } | ||
948 | mcbsp1_fck = clk_get(0, "mcbsp1_fck"); | ||
949 | if (IS_ERR(mcbsp1_fck)) { | ||
950 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); | ||
951 | return PTR_ERR(mcbsp1_fck); | ||
952 | } | ||
953 | mcbsp2_ick = clk_get(0, "mcbsp2_ick"); | ||
954 | if (IS_ERR(mcbsp2_ick)) { | ||
955 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); | ||
956 | return PTR_ERR(mcbsp2_ick); | ||
957 | } | ||
958 | mcbsp2_fck = clk_get(0, "mcbsp2_fck"); | ||
959 | if (IS_ERR(mcbsp2_fck)) { | ||
960 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); | ||
961 | return PTR_ERR(mcbsp2_fck); | ||
962 | } | ||
963 | #endif | ||
713 | 964 | ||
714 | #ifdef CONFIG_ARCH_OMAP730 | 965 | #ifdef CONFIG_ARCH_OMAP730 |
715 | if (cpu_is_omap730()) { | 966 | if (cpu_is_omap730()) { |
@@ -718,7 +969,7 @@ static int __init omap_mcbsp_init(void) | |||
718 | } | 969 | } |
719 | #endif | 970 | #endif |
720 | #ifdef CONFIG_ARCH_OMAP15XX | 971 | #ifdef CONFIG_ARCH_OMAP15XX |
721 | if (cpu_is_omap1510()) { | 972 | if (cpu_is_omap15xx()) { |
722 | mcbsp_info = mcbsp_1510; | 973 | mcbsp_info = mcbsp_1510; |
723 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); | 974 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); |
724 | } | 975 | } |
@@ -729,6 +980,19 @@ static int __init omap_mcbsp_init(void) | |||
729 | mcbsp_count = ARRAY_SIZE(mcbsp_1610); | 980 | mcbsp_count = ARRAY_SIZE(mcbsp_1610); |
730 | } | 981 | } |
731 | #endif | 982 | #endif |
983 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
984 | if (cpu_is_omap24xx()) { | ||
985 | mcbsp_info = mcbsp_24xx; | ||
986 | mcbsp_count = ARRAY_SIZE(mcbsp_24xx); | ||
987 | |||
988 | /* REVISIT: where's the right place? */ | ||
989 | omap2_mcbsp2_mux_setup(); | ||
990 | sys_ck = clk_get(0, "sys_ck"); | ||
991 | sys_clkout = clk_get(0, "sys_clkout"); | ||
992 | clk_set_parent(sys_clkout, sys_ck); | ||
993 | clk_enable(sys_clkout); | ||
994 | } | ||
995 | #endif | ||
732 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { | 996 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { |
733 | if (i >= mcbsp_count) { | 997 | if (i >= mcbsp_count) { |
734 | mcbsp[i].io_base = 0; | 998 | mcbsp[i].io_base = 0; |
@@ -741,6 +1005,7 @@ static int __init omap_mcbsp_init(void) | |||
741 | mcbsp[i].dma_rx_lch = -1; | 1005 | mcbsp[i].dma_rx_lch = -1; |
742 | 1006 | ||
743 | mcbsp[i].io_base = mcbsp_info[i].virt_base; | 1007 | mcbsp[i].io_base = mcbsp_info[i].virt_base; |
1008 | mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ | ||
744 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; | 1009 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; |
745 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; | 1010 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; |
746 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; | 1011 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; |
@@ -751,11 +1016,11 @@ static int __init omap_mcbsp_init(void) | |||
751 | return 0; | 1016 | return 0; |
752 | } | 1017 | } |
753 | 1018 | ||
754 | |||
755 | arch_initcall(omap_mcbsp_init); | 1019 | arch_initcall(omap_mcbsp_init); |
756 | 1020 | ||
757 | EXPORT_SYMBOL(omap_mcbsp_config); | 1021 | EXPORT_SYMBOL(omap_mcbsp_config); |
758 | EXPORT_SYMBOL(omap_mcbsp_request); | 1022 | EXPORT_SYMBOL(omap_mcbsp_request); |
1023 | EXPORT_SYMBOL(omap_mcbsp_set_io_type); | ||
759 | EXPORT_SYMBOL(omap_mcbsp_free); | 1024 | EXPORT_SYMBOL(omap_mcbsp_free); |
760 | EXPORT_SYMBOL(omap_mcbsp_start); | 1025 | EXPORT_SYMBOL(omap_mcbsp_start); |
761 | EXPORT_SYMBOL(omap_mcbsp_stop); | 1026 | EXPORT_SYMBOL(omap_mcbsp_stop); |
@@ -763,4 +1028,6 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); | |||
763 | EXPORT_SYMBOL(omap_mcbsp_recv_word); | 1028 | EXPORT_SYMBOL(omap_mcbsp_recv_word); |
764 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); | 1029 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); |
765 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); | 1030 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); |
1031 | EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | ||
1032 | EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); | ||
766 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | 1033 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); |
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 5cc6775c789c..37792d43738b 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c | |||
@@ -62,9 +62,6 @@ int ocpi_enable(void) | |||
62 | if (!cpu_is_omap16xx()) | 62 | if (!cpu_is_omap16xx()) |
63 | return -ENODEV; | 63 | return -ENODEV; |
64 | 64 | ||
65 | /* Make sure there's clock for OCPI */ | ||
66 | clk_enable(ocpi_ck); | ||
67 | |||
68 | /* Enable access for OHCI in OCPI */ | 65 | /* Enable access for OHCI in OCPI */ |
69 | val = omap_readl(OCPI_PROT); | 66 | val = omap_readl(OCPI_PROT); |
70 | val &= ~0xff; | 67 | val &= ~0xff; |
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index 093efd786f21..1a24e2c10714 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/pm.h> | 38 | #include <linux/pm.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/pm.h> | ||
41 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
42 | 43 | ||
43 | #include <asm/io.h> | 44 | #include <asm/io.h> |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index ee82763b02b8..b7bf09b1b412 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -16,24 +16,94 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | 18 | ||
19 | #include <asm/mach/map.h> | ||
20 | #include <asm/tlb.h> | 19 | #include <asm/tlb.h> |
21 | #include <asm/io.h> | 20 | #include <asm/io.h> |
22 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
23 | 22 | ||
23 | #include <asm/mach/map.h> | ||
24 | |||
24 | #include <asm/arch/sram.h> | 25 | #include <asm/arch/sram.h> |
26 | #include <asm/arch/board.h> | ||
25 | 27 | ||
26 | #define OMAP1_SRAM_PA 0x20000000 | 28 | #define OMAP1_SRAM_PA 0x20000000 |
27 | #define OMAP1_SRAM_VA 0xd0000000 | 29 | #define OMAP1_SRAM_VA 0xd0000000 |
28 | #define OMAP2_SRAM_PA 0x40200000 | 30 | #define OMAP2_SRAM_PA 0x40200000 |
31 | #define OMAP2_SRAM_PUB_PA 0x4020f800 | ||
29 | #define OMAP2_SRAM_VA 0xd0000000 | 32 | #define OMAP2_SRAM_VA 0xd0000000 |
33 | #define OMAP2_SRAM_PUB_VA 0xd0000800 | ||
30 | 34 | ||
35 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
36 | #define SRAM_BOOTLOADER_SZ 0x00 | ||
37 | #else | ||
31 | #define SRAM_BOOTLOADER_SZ 0x80 | 38 | #define SRAM_BOOTLOADER_SZ 0x80 |
39 | #endif | ||
40 | |||
41 | #define VA_REQINFOPERM0 IO_ADDRESS(0x68005048) | ||
42 | #define VA_READPERM0 IO_ADDRESS(0x68005050) | ||
43 | #define VA_WRITEPERM0 IO_ADDRESS(0x68005058) | ||
44 | #define VA_CONTROL_STAT IO_ADDRESS(0x480002F8) | ||
45 | #define GP_DEVICE 0x300 | ||
46 | #define TYPE_MASK 0x700 | ||
47 | |||
48 | #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) | ||
32 | 49 | ||
33 | static unsigned long omap_sram_base; | 50 | static unsigned long omap_sram_base; |
34 | static unsigned long omap_sram_size; | 51 | static unsigned long omap_sram_size; |
35 | static unsigned long omap_sram_ceil; | 52 | static unsigned long omap_sram_ceil; |
36 | 53 | ||
54 | unsigned long omap_fb_sram_start; | ||
55 | unsigned long omap_fb_sram_size; | ||
56 | |||
57 | /* Depending on the target RAMFS firewall setup, the public usable amount of | ||
58 | * SRAM varies. The default accessable size for all device types is 2k. A GP | ||
59 | * device allows ARM11 but not other initators for full size. This | ||
60 | * functionality seems ok until some nice security API happens. | ||
61 | */ | ||
62 | static int is_sram_locked(void) | ||
63 | { | ||
64 | int type = 0; | ||
65 | |||
66 | if (cpu_is_omap242x()) | ||
67 | type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK; | ||
68 | |||
69 | if (type == GP_DEVICE) { | ||
70 | /* RAMFW: R/W access to all initators for all qualifier sets */ | ||
71 | if (cpu_is_omap242x()) { | ||
72 | __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */ | ||
73 | __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */ | ||
74 | __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */ | ||
75 | } | ||
76 | return 0; | ||
77 | } else | ||
78 | return 1; /* assume locked with no PPA or security driver */ | ||
79 | } | ||
80 | |||
81 | void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail, | ||
82 | unsigned long *start, unsigned long *size) | ||
83 | { | ||
84 | const struct omap_fbmem_config *fbmem_conf; | ||
85 | |||
86 | fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config); | ||
87 | if (fbmem_conf != NULL) { | ||
88 | *start = fbmem_conf->fb_sram_start; | ||
89 | *size = fbmem_conf->fb_sram_size; | ||
90 | } else { | ||
91 | *size = 0; | ||
92 | *start = 0; | ||
93 | } | ||
94 | |||
95 | if (*size && ( | ||
96 | *start < start_avail || | ||
97 | *start + *size > start_avail + size_avail)) { | ||
98 | printk(KERN_ERR "invalid FB SRAM configuration\n"); | ||
99 | *start = start_avail; | ||
100 | *size = size_avail; | ||
101 | } | ||
102 | |||
103 | if (*size) | ||
104 | pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size); | ||
105 | } | ||
106 | |||
37 | /* | 107 | /* |
38 | * The amount of SRAM depends on the core type. | 108 | * The amount of SRAM depends on the core type. |
39 | * Note that we cannot try to test for SRAM here because writes | 109 | * Note that we cannot try to test for SRAM here because writes |
@@ -42,26 +112,45 @@ static unsigned long omap_sram_ceil; | |||
42 | */ | 112 | */ |
43 | void __init omap_detect_sram(void) | 113 | void __init omap_detect_sram(void) |
44 | { | 114 | { |
45 | if (!cpu_is_omap24xx()) | 115 | unsigned long sram_start; |
116 | |||
117 | if (cpu_is_omap24xx()) { | ||
118 | if (is_sram_locked()) { | ||
119 | omap_sram_base = OMAP2_SRAM_PUB_VA; | ||
120 | sram_start = OMAP2_SRAM_PUB_PA; | ||
121 | omap_sram_size = 0x800; /* 2K */ | ||
122 | } else { | ||
123 | omap_sram_base = OMAP2_SRAM_VA; | ||
124 | sram_start = OMAP2_SRAM_PA; | ||
125 | if (cpu_is_omap242x()) | ||
126 | omap_sram_size = 0xa0000; /* 640K */ | ||
127 | else if (cpu_is_omap243x()) | ||
128 | omap_sram_size = 0x10000; /* 64K */ | ||
129 | } | ||
130 | } else { | ||
46 | omap_sram_base = OMAP1_SRAM_VA; | 131 | omap_sram_base = OMAP1_SRAM_VA; |
47 | else | 132 | sram_start = OMAP1_SRAM_PA; |
48 | omap_sram_base = OMAP2_SRAM_VA; | 133 | |
49 | 134 | if (cpu_is_omap730()) | |
50 | if (cpu_is_omap730()) | 135 | omap_sram_size = 0x32000; /* 200K */ |
51 | omap_sram_size = 0x32000; /* 200K */ | 136 | else if (cpu_is_omap15xx()) |
52 | else if (cpu_is_omap15xx()) | 137 | omap_sram_size = 0x30000; /* 192K */ |
53 | omap_sram_size = 0x30000; /* 192K */ | 138 | else if (cpu_is_omap1610() || cpu_is_omap1621() || |
54 | else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) | 139 | cpu_is_omap1710()) |
55 | omap_sram_size = 0x4000; /* 16K */ | 140 | omap_sram_size = 0x4000; /* 16K */ |
56 | else if (cpu_is_omap1611()) | 141 | else if (cpu_is_omap1611()) |
57 | omap_sram_size = 0x3e800; /* 250K */ | 142 | omap_sram_size = 0x3e800; /* 250K */ |
58 | else if (cpu_is_omap2420()) | 143 | else { |
59 | omap_sram_size = 0xa0014; /* 640K */ | 144 | printk(KERN_ERR "Could not detect SRAM size\n"); |
60 | else { | 145 | omap_sram_size = 0x4000; |
61 | printk(KERN_ERR "Could not detect SRAM size\n"); | 146 | } |
62 | omap_sram_size = 0x4000; | ||
63 | } | 147 | } |
64 | 148 | get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ, | |
149 | omap_sram_size - SRAM_BOOTLOADER_SZ, | ||
150 | &omap_fb_sram_start, &omap_fb_sram_size); | ||
151 | if (omap_fb_sram_size) | ||
152 | omap_sram_size -= sram_start + omap_sram_size - | ||
153 | omap_fb_sram_start; | ||
65 | omap_sram_ceil = omap_sram_base + omap_sram_size; | 154 | omap_sram_ceil = omap_sram_base + omap_sram_size; |
66 | } | 155 | } |
67 | 156 | ||
@@ -80,12 +169,20 @@ static struct map_desc omap_sram_io_desc[] __initdata = { | |||
80 | */ | 169 | */ |
81 | void __init omap_map_sram(void) | 170 | void __init omap_map_sram(void) |
82 | { | 171 | { |
172 | unsigned long base; | ||
173 | |||
83 | if (omap_sram_size == 0) | 174 | if (omap_sram_size == 0) |
84 | return; | 175 | return; |
85 | 176 | ||
86 | if (cpu_is_omap24xx()) { | 177 | if (cpu_is_omap24xx()) { |
87 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | 178 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; |
88 | omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA); | 179 | |
180 | if (is_sram_locked()) | ||
181 | base = OMAP2_SRAM_PUB_PA; | ||
182 | else | ||
183 | base = OMAP2_SRAM_PA; | ||
184 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
185 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
89 | } | 186 | } |
90 | 187 | ||
91 | omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; | 188 | omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; |
@@ -93,7 +190,8 @@ void __init omap_map_sram(void) | |||
93 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 190 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
94 | 191 | ||
95 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | 192 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
96 | omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual, | 193 | __pfn_to_phys(omap_sram_io_desc[0].pfn), |
194 | omap_sram_io_desc[0].virtual, | ||
97 | omap_sram_io_desc[0].length); | 195 | omap_sram_io_desc[0].length); |
98 | 196 | ||
99 | /* | 197 | /* |
@@ -118,8 +216,9 @@ void * omap_sram_push(void * start, unsigned long size) | |||
118 | printk(KERN_ERR "Not enough space in SRAM\n"); | 216 | printk(KERN_ERR "Not enough space in SRAM\n"); |
119 | return NULL; | 217 | return NULL; |
120 | } | 218 | } |
219 | |||
121 | omap_sram_ceil -= size; | 220 | omap_sram_ceil -= size; |
122 | omap_sram_ceil &= ~0x3; | 221 | omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); |
123 | memcpy((void *)omap_sram_ceil, start, size); | 222 | memcpy((void *)omap_sram_ceil, start, size); |
124 | 223 | ||
125 | return (void *)omap_sram_ceil; | 224 | return (void *)omap_sram_ceil; |
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c new file mode 100644 index 000000000000..b2a943bf11ef --- /dev/null +++ b/arch/arm/plat-omap/timer32k.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/timer32k.c | ||
3 | * | ||
4 | * OMAP 32K Timer | ||
5 | * | ||
6 | * Copyright (C) 2004 - 2005 Nokia Corporation | ||
7 | * Partial timer rewrite and additional dynamic tick timer support by | ||
8 | * Tony Lindgen <tony@atomide.com> and | ||
9 | * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
10 | * | ||
11 | * MPU timer code based on the older MPU timer code for OMAP | ||
12 | * Copyright (C) 2000 RidgeRun, Inc. | ||
13 | * Author: Greg Lonnon <glonnon@ridgerun.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License as published by the | ||
17 | * Free Software Foundation; either version 2 of the License, or (at your | ||
18 | * option) any later version. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
22 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
23 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
26 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
27 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | * | ||
31 | * You should have received a copy of the GNU General Public License along | ||
32 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
33 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
34 | */ | ||
35 | |||
36 | #include <linux/config.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/delay.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/spinlock.h> | ||
43 | #include <linux/err.h> | ||
44 | #include <linux/clk.h> | ||
45 | |||
46 | #include <asm/system.h> | ||
47 | #include <asm/hardware.h> | ||
48 | #include <asm/io.h> | ||
49 | #include <asm/leds.h> | ||
50 | #include <asm/irq.h> | ||
51 | #include <asm/mach/irq.h> | ||
52 | #include <asm/mach/time.h> | ||
53 | |||
54 | struct sys_timer omap_timer; | ||
55 | |||
56 | /* | ||
57 | * --------------------------------------------------------------------------- | ||
58 | * 32KHz OS timer | ||
59 | * | ||
60 | * This currently works only on 16xx, as 1510 does not have the continuous | ||
61 | * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track | ||
62 | * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer | ||
63 | * on 1510 would be possible, but the timer would not be as accurate as | ||
64 | * with the 32KHz synchronized timer. | ||
65 | * --------------------------------------------------------------------------- | ||
66 | */ | ||
67 | |||
68 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
69 | #define TIMER_32K_SYNCHRONIZED 0xfffbc410 | ||
70 | #elif defined(CONFIG_ARCH_OMAP24XX) | ||
71 | #define TIMER_32K_SYNCHRONIZED 0x48004010 | ||
72 | #else | ||
73 | #error OMAP 32KHz timer does not currently work on 15XX! | ||
74 | #endif | ||
75 | |||
76 | /* 16xx specific defines */ | ||
77 | #define OMAP1_32K_TIMER_BASE 0xfffb9000 | ||
78 | #define OMAP1_32K_TIMER_CR 0x08 | ||
79 | #define OMAP1_32K_TIMER_TVR 0x00 | ||
80 | #define OMAP1_32K_TIMER_TCR 0x04 | ||
81 | |||
82 | /* 24xx specific defines */ | ||
83 | #define OMAP2_GP_TIMER_BASE 0x48028000 | ||
84 | #define CM_CLKSEL_WKUP 0x48008440 | ||
85 | #define GP_TIMER_TIDR 0x00 | ||
86 | #define GP_TIMER_TISR 0x18 | ||
87 | #define GP_TIMER_TIER 0x1c | ||
88 | #define GP_TIMER_TCLR 0x24 | ||
89 | #define GP_TIMER_TCRR 0x28 | ||
90 | #define GP_TIMER_TLDR 0x2c | ||
91 | #define GP_TIMER_TTGR 0x30 | ||
92 | #define GP_TIMER_TSICR 0x40 | ||
93 | |||
94 | #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) | ||
95 | |||
96 | /* | ||
97 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 | ||
98 | * so with HZ = 128, TVR = 255. | ||
99 | */ | ||
100 | #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) | ||
101 | |||
102 | #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ | ||
103 | (((nr_jiffies) * (clock_rate)) / HZ) | ||
104 | |||
105 | static inline void omap_32k_timer_write(int val, int reg) | ||
106 | { | ||
107 | if (cpu_class_is_omap1()) | ||
108 | omap_writew(val, OMAP1_32K_TIMER_BASE + reg); | ||
109 | |||
110 | if (cpu_is_omap24xx()) | ||
111 | omap_writel(val, OMAP2_GP_TIMER_BASE + reg); | ||
112 | } | ||
113 | |||
114 | static inline unsigned long omap_32k_timer_read(int reg) | ||
115 | { | ||
116 | if (cpu_class_is_omap1()) | ||
117 | return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; | ||
118 | |||
119 | if (cpu_is_omap24xx()) | ||
120 | return omap_readl(OMAP2_GP_TIMER_BASE + reg); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * The 32KHz synchronized timer is an additional timer on 16xx. | ||
125 | * It is always running. | ||
126 | */ | ||
127 | static inline unsigned long omap_32k_sync_timer_read(void) | ||
128 | { | ||
129 | return omap_readl(TIMER_32K_SYNCHRONIZED); | ||
130 | } | ||
131 | |||
132 | static inline void omap_32k_timer_start(unsigned long load_val) | ||
133 | { | ||
134 | if (cpu_class_is_omap1()) { | ||
135 | omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); | ||
136 | omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); | ||
137 | } | ||
138 | |||
139 | if (cpu_is_omap24xx()) { | ||
140 | omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR); | ||
141 | omap_32k_timer_write((1 << 1), GP_TIMER_TIER); | ||
142 | omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static inline void omap_32k_timer_stop(void) | ||
147 | { | ||
148 | if (cpu_class_is_omap1()) | ||
149 | omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); | ||
150 | |||
151 | if (cpu_is_omap24xx()) | ||
152 | omap_32k_timer_write(0x0, GP_TIMER_TCLR); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Rounds down to nearest usec. Note that this will overflow for larger values. | ||
157 | */ | ||
158 | static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) | ||
159 | { | ||
160 | return (ticks_32k * 5*5*5*5*5*5) >> 9; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Rounds down to nearest nsec. | ||
165 | */ | ||
166 | static inline unsigned long long | ||
167 | omap_32k_ticks_to_nsecs(unsigned long ticks_32k) | ||
168 | { | ||
169 | return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; | ||
170 | } | ||
171 | |||
172 | static unsigned long omap_32k_last_tick = 0; | ||
173 | |||
174 | /* | ||
175 | * Returns elapsed usecs since last 32k timer interrupt | ||
176 | */ | ||
177 | static unsigned long omap_32k_timer_gettimeoffset(void) | ||
178 | { | ||
179 | unsigned long now = omap_32k_sync_timer_read(); | ||
180 | return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Returns current time from boot in nsecs. It's OK for this to wrap | ||
185 | * around for now, as it's just a relative time stamp. | ||
186 | */ | ||
187 | unsigned long long sched_clock(void) | ||
188 | { | ||
189 | return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this | ||
194 | * function is also called from other interrupts to remove latency | ||
195 | * issues with dynamic tick. In the dynamic tick case, we need to lock | ||
196 | * with irqsave. | ||
197 | */ | ||
198 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | ||
199 | struct pt_regs *regs) | ||
200 | { | ||
201 | unsigned long flags; | ||
202 | unsigned long now; | ||
203 | |||
204 | write_seqlock_irqsave(&xtime_lock, flags); | ||
205 | |||
206 | if (cpu_is_omap24xx()) { | ||
207 | u32 status = omap_32k_timer_read(GP_TIMER_TISR); | ||
208 | omap_32k_timer_write(status, GP_TIMER_TISR); | ||
209 | } | ||
210 | |||
211 | now = omap_32k_sync_timer_read(); | ||
212 | |||
213 | while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { | ||
214 | omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; | ||
215 | timer_tick(regs); | ||
216 | } | ||
217 | |||
218 | /* Restart timer so we don't drift off due to modulo or dynamic tick. | ||
219 | * By default we program the next timer to be continuous to avoid | ||
220 | * latencies during high system load. During dynamic tick operation the | ||
221 | * continuous timer can be overridden from pm_idle to be longer. | ||
222 | */ | ||
223 | omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); | ||
224 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
225 | |||
226 | return IRQ_HANDLED; | ||
227 | } | ||
228 | |||
229 | #ifdef CONFIG_NO_IDLE_HZ | ||
230 | /* | ||
231 | * Programs the next timer interrupt needed. Called when dynamic tick is | ||
232 | * enabled, and to reprogram the ticks to skip from pm_idle. Note that | ||
233 | * we can keep the timer continuous, and don't need to set it to run in | ||
234 | * one-shot mode. This is because the timer will get reprogrammed again | ||
235 | * after next interrupt. | ||
236 | */ | ||
237 | void omap_32k_timer_reprogram(unsigned long next_tick) | ||
238 | { | ||
239 | omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); | ||
240 | } | ||
241 | |||
242 | static struct irqaction omap_32k_timer_irq; | ||
243 | extern struct timer_update_handler timer_update; | ||
244 | |||
245 | static int omap_32k_timer_enable_dyn_tick(void) | ||
246 | { | ||
247 | /* No need to reprogram timer, just use the next interrupt */ | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int omap_32k_timer_disable_dyn_tick(void) | ||
252 | { | ||
253 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static struct dyn_tick_timer omap_dyn_tick_timer = { | ||
258 | .enable = omap_32k_timer_enable_dyn_tick, | ||
259 | .disable = omap_32k_timer_disable_dyn_tick, | ||
260 | .reprogram = omap_32k_timer_reprogram, | ||
261 | .handler = omap_32k_timer_interrupt, | ||
262 | }; | ||
263 | #endif /* CONFIG_NO_IDLE_HZ */ | ||
264 | |||
265 | static struct irqaction omap_32k_timer_irq = { | ||
266 | .name = "32KHz timer", | ||
267 | .flags = SA_INTERRUPT | SA_TIMER, | ||
268 | .handler = omap_32k_timer_interrupt, | ||
269 | }; | ||
270 | |||
271 | static struct clk * gpt1_ick; | ||
272 | static struct clk * gpt1_fck; | ||
273 | |||
274 | static __init void omap_init_32k_timer(void) | ||
275 | { | ||
276 | #ifdef CONFIG_NO_IDLE_HZ | ||
277 | omap_timer.dyn_tick = &omap_dyn_tick_timer; | ||
278 | #endif | ||
279 | |||
280 | if (cpu_class_is_omap1()) | ||
281 | setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); | ||
282 | if (cpu_is_omap24xx()) | ||
283 | setup_irq(37, &omap_32k_timer_irq); | ||
284 | omap_timer.offset = omap_32k_timer_gettimeoffset; | ||
285 | omap_32k_last_tick = omap_32k_sync_timer_read(); | ||
286 | |||
287 | /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */ | ||
288 | if (cpu_is_omap24xx()) { | ||
289 | omap_32k_timer_write(0, GP_TIMER_TCLR); | ||
290 | omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */ | ||
291 | |||
292 | gpt1_ick = clk_get(NULL, "gpt1_ick"); | ||
293 | if (IS_ERR(gpt1_ick)) | ||
294 | printk(KERN_ERR "Could not get gpt1_ick\n"); | ||
295 | else | ||
296 | clk_enable(gpt1_ick); | ||
297 | |||
298 | gpt1_fck = clk_get(NULL, "gpt1_fck"); | ||
299 | if (IS_ERR(gpt1_fck)) | ||
300 | printk(KERN_ERR "Could not get gpt1_fck\n"); | ||
301 | else | ||
302 | clk_enable(gpt1_fck); | ||
303 | |||
304 | mdelay(100); /* Wait for clocks to stabilize */ | ||
305 | |||
306 | omap_32k_timer_write(0x7, GP_TIMER_TISR); | ||
307 | } | ||
308 | |||
309 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * --------------------------------------------------------------------------- | ||
314 | * Timer initialization | ||
315 | * --------------------------------------------------------------------------- | ||
316 | */ | ||
317 | static void __init omap_timer_init(void) | ||
318 | { | ||
319 | omap_init_32k_timer(); | ||
320 | } | ||
321 | |||
322 | struct sys_timer omap_timer = { | ||
323 | .init = omap_timer_init, | ||
324 | .offset = NULL, /* Initialized later */ | ||
325 | }; | ||