]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-apollon.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-apollon.c
1 /*
2  * linux/arch/arm/mach-omap2/board-apollon.c
3  *
4  * Copyright (C) 2005-2008 Samsung Electronics
5  * Author: Kyungmin Park <kyungmin.park@samsung.com>
6  *
7  * Modified from mach-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/irq.h>
26 #include <linux/interrupt.h>
27 #include <linux/delay.h>
28 #include <linux/leds.h>
29 #include <linux/err.h>
30 #include <linux/clk.h>
31 #include <linux/spi/spi.h>
32 #include <linux/spi/tsc210x.h>
33
34 #include <asm/io.h>
35 #include <asm/hardware.h>
36 #include <asm/mach-types.h>
37 #include <asm/mach/arch.h>
38 #include <asm/mach/flash.h>
39
40 #include <asm/arch/gpio.h>
41 #include <asm/arch/led.h>
42 #include <asm/arch/mux.h>
43 #include <asm/arch/usb.h>
44 #include <asm/arch/board.h>
45 #include <asm/arch/common.h>
46 #include <asm/arch/gpmc.h>
47
48 /* LED & Switch macros */
49 #define LED0_GPIO13             13
50 #define LED1_GPIO14             14
51 #define LED2_GPIO15             15
52 #define LED3_GPIO92             92
53 #define LED4_GPIO93             93
54
55 #define APOLLON_FLASH_CS        0
56 #define APOLLON_ETH_CS          1
57 #define APOLLON_NOR_CS          3
58
59 #define APOLLON_ONENAND_CS2_ADDRESS     (0x00000e40 | (0x10000000 >> 24))
60 #define APOLLON_EXT_CS3_ADDRESS         (0x00000c40 | (0x18000000 >> 24))
61
62 static struct mtd_partition apollon_partitions[] = {
63         {
64                 .name           = "X-Loader + U-Boot",
65                 .offset         = 0,
66                 .size           = SZ_128K,
67                 .mask_flags     = MTD_WRITEABLE,
68         },
69         {
70                 .name           = "params",
71                 .offset         = MTDPART_OFS_APPEND,
72                 .size           = SZ_128K,
73         },
74         {
75                 .name           = "kernel",
76                 .offset         = MTDPART_OFS_APPEND,
77                 .size           = SZ_2M,
78         },
79         {
80                 .name           = "rootfs",
81                 .offset         = MTDPART_OFS_APPEND,
82                 .size           = SZ_16M,
83         },
84         {
85                 .name           = "filesystem00",
86                 .offset         = MTDPART_OFS_APPEND,
87                 .size           = SZ_32M,
88         },
89         {
90                 .name           = "filesystem01",
91                 .offset         = MTDPART_OFS_APPEND,
92                 .size           = MTDPART_SIZ_FULL,
93         },
94 };
95
96 static struct flash_platform_data apollon_flash_data = {
97         .parts          = apollon_partitions,
98         .nr_parts       = ARRAY_SIZE(apollon_partitions),
99 };
100
101 static struct resource apollon_flash_resource[] = {
102         [0] = {
103                 .flags          = IORESOURCE_MEM,
104         },
105 };
106
107 static struct platform_device apollon_onenand_device = {
108         .name           = "onenand",
109         .id             = -1,
110         .dev            = {
111                 .platform_data  = &apollon_flash_data,
112         },
113         .num_resources  = ARRAY_SIZE(apollon_flash_resource),
114         .resource       = apollon_flash_resource,
115 };
116
117 static struct mtd_partition apollon_nor_partitions[] = {
118         {
119                 .name           = "U-Boot",
120                 .offset         = 0,
121                 .size           = SZ_128K,
122                 .mask_flags     = MTD_WRITEABLE,
123         },
124         {
125                 .name           = "params",
126                 .offset         = MTDPART_OFS_APPEND,
127                 .size           = SZ_128K,
128         },
129         {
130                 .name           = "kernel",
131                 .offset         = MTDPART_OFS_APPEND,
132                 .size           = SZ_2M,
133         },
134         {
135                 .name           = "rootfs",
136                 .offset         = MTDPART_OFS_APPEND,
137                 .size           = SZ_4M - SZ_256K,
138         },
139         {
140                 .name           = "application",
141                 .offset         = MTDPART_OFS_APPEND,
142                 .size           = SZ_8M + SZ_2M,
143         },
144         {
145                 .name           = "reserved",
146                 .offset         = MTDPART_OFS_APPEND,
147                 .size           = MTDPART_SIZ_FULL,
148         },
149 };
150
151 static struct flash_platform_data apollon_nor_data = {
152         .map_name               = "cfi_probe",
153         .width          = 2,
154         .parts          = apollon_nor_partitions,
155         .nr_parts       = ARRAY_SIZE(apollon_nor_partitions),
156 };
157
158 static struct resource apollon_nor_resource[] = {
159         [0] = {
160                 .flags  = IORESOURCE_MEM,
161         }
162 };
163
164 static struct platform_device apollon_nor_device = {
165         .name           = "omapflash",
166         .id             = -1,
167         .dev            = {
168                 .platform_data  = &apollon_nor_data,
169         },
170         .num_resources  = ARRAY_SIZE(apollon_nor_resource),
171         .resource       = apollon_nor_resource,
172 };
173
174 static void __init apollon_flash_init(void)
175 {
176         unsigned long base;
177
178         if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
179                 printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
180                 return;
181         }
182         apollon_flash_resource[0].start = base;
183         apollon_flash_resource[0].end   = base + SZ_128K - 1;
184
185         if (gpmc_cs_request(APOLLON_NOR_CS, SZ_32M, &base) < 0) {
186                 printk(KERN_ERR "Cannot request NOR GPMC CS\n");
187                 return;
188         }
189         apollon_nor_resource[0].start = base;
190         apollon_nor_resource[0].end   = base + SZ_32M - 1;
191 }
192
193 static struct resource apollon_smc91x_resources[] = {
194         [0] = {
195                 .flags  = IORESOURCE_MEM,
196         },
197         [1] = {
198                 .start  = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
199                 .end    = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
200                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
201         },
202 };
203
204 static struct platform_device apollon_smc91x_device = {
205         .name           = "smc91x",
206         .id             = -1,
207         .num_resources  = ARRAY_SIZE(apollon_smc91x_resources),
208         .resource       = apollon_smc91x_resources,
209 };
210
211 static struct platform_device apollon_lcd_device = {
212         .name           = "apollon_lcd",
213         .id             = -1,
214 };
215
216 static struct omap_led_config apollon_led_config[] = {
217         {
218                 .cdev   = {
219                         .name   = "apollon:led0",
220                 },
221                 .gpio   = LED0_GPIO13,
222         },
223         {
224                 .cdev   = {
225                         .name   = "apollon:led1",
226                 },
227                 .gpio   = LED1_GPIO14,
228         },
229         {
230                 .cdev   = {
231                         .name   = "apollon:led2",
232                 },
233                 .gpio   = LED2_GPIO15,
234         },
235 #ifdef CONFIG_MACH_OMAP_APOLLON_PLUS
236         {
237                 .cdev   = {
238                         .name   = "apollon:led3",
239                 },
240                 .gpio   = LED3_GPIO92,
241         },
242         {
243                 .cdev   = {
244                         .name   = "apollon:led4",
245                 },
246                 .gpio   = LED4_GPIO93,
247         },
248 #endif
249 };
250
251 static struct omap_led_platform_data apollon_led_data = {
252         .nr_leds        = ARRAY_SIZE(apollon_led_config),
253         .leds           = apollon_led_config,
254 };
255
256 static struct platform_device apollon_led_device = {
257         .name           = "omap-led",
258         .id             = -1,
259         .dev            = {
260                 .platform_data  = &apollon_led_data,
261         },
262 };
263
264 static struct platform_device *apollon_devices[] __initdata = {
265         &apollon_onenand_device,
266         &apollon_nor_device,
267         &apollon_smc91x_device,
268         &apollon_lcd_device,
269         &apollon_led_device,
270 };
271
272 static inline void __init apollon_init_smc91x(void)
273 {
274         unsigned long base;
275         unsigned int rate;
276         struct clk *l3ck;
277         int eth_cs;
278
279         l3ck = clk_get(NULL, "core_l3_ck");
280         if (IS_ERR(l3ck))
281                 rate = 100000000;
282         else
283                 rate = clk_get_rate(l3ck);
284
285         eth_cs = APOLLON_ETH_CS;
286
287         /* Make sure CS1 timings are correct */
288         gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
289
290         if (rate >= 160000000) {
291                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
292                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
293                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
294                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
295                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
296         } else if (rate >= 130000000) {
297                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
298                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
299                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
300                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
301                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
302         } else {/* rate = 100000000 */
303                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
304                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
305                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
306                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
307                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
308         }
309
310         if (gpmc_cs_request(eth_cs, SZ_16M, &base) < 0) {
311                 printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
312                 return;
313         }
314         apollon_smc91x_resources[0].start = base + 0x300;
315         apollon_smc91x_resources[0].end   = base + 0x30f;
316         udelay(100);
317
318         omap_cfg_reg(W4__24XX_GPIO74);
319         if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
320                 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
321                         APOLLON_ETHR_GPIO_IRQ);
322                 gpmc_cs_free(eth_cs);
323                 return;
324         }
325         omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
326 }
327
328 static void __init omap_apollon_init_irq(void)
329 {
330         omap2_init_common_hw();
331         omap_init_irq();
332         omap_gpio_init();
333         apollon_init_smc91x();
334 }
335
336 static struct tsc210x_config tsc_platform_data = {
337         .use_internal           = 1,
338         .monitor                = TSC_TEMP,
339         .mclk                   = "sys_clkout",
340 };
341
342 static struct spi_board_info apollon_spi_board_info[] = {
343         [0] = {
344                 .modalias       = "tsc2101",
345                 .irq            = OMAP_GPIO_IRQ(85),
346                 .bus_num        = 1,
347                 .chip_select    = 0,
348                 .mode           = SPI_MODE_1,
349                 .max_speed_hz   = 6000000,
350                 .platform_data  = &tsc_platform_data,
351         },
352 };
353
354 static struct omap_uart_config apollon_uart_config __initdata = {
355         .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
356 };
357
358 /*
359  * Note: If you want to detect card feature, please assign GPIO 37
360  */
361 static struct omap_mmc_config apollon_mmc_config __initdata = {
362         .mmc [0] = {
363                 .enabled        = 1,
364                 .wire4          = 1,
365         /* Use internal loop-back in MMC/SDIO Module Input Clock selection */
366                 .internal_clock = 1,
367         },
368 };
369
370 static struct omap_usb_config apollon_usb_config __initdata = {
371         .register_dev   = 1,
372         .hmc_mode       = 0x14, /* 0:dev 1:host1 2:disable */
373
374         .pins[0]        = 6,
375 };
376
377 static struct omap_lcd_config apollon_lcd_config __initdata = {
378         .ctrl_name      = "internal",
379 };
380
381 static struct omap_board_config_kernel apollon_config[] __initdata = {
382         { OMAP_TAG_UART,        &apollon_uart_config },
383         { OMAP_TAG_MMC,         &apollon_mmc_config },
384         { OMAP_TAG_USB,         &apollon_usb_config },
385         { OMAP_TAG_LCD,         &apollon_lcd_config },
386 };
387
388 static void __init apollon_led_init(void)
389 {
390         /* LED0 - AA10 */
391         omap_cfg_reg(AA10_242X_GPIO13);
392         omap_request_gpio(LED0_GPIO13);
393         omap_set_gpio_direction(LED0_GPIO13, 0);
394         omap_set_gpio_dataout(LED0_GPIO13, 0);
395         /* LED1  - AA6 */
396         omap_cfg_reg(AA6_242X_GPIO14);
397         omap_request_gpio(LED1_GPIO14);
398         omap_set_gpio_direction(LED1_GPIO14, 0);
399         omap_set_gpio_dataout(LED1_GPIO14, 0);
400         /* LED2  - AA4 */
401         omap_cfg_reg(AA4_242X_GPIO15);
402         omap_request_gpio(LED2_GPIO15);
403         omap_set_gpio_direction(LED2_GPIO15, 0);
404         omap_set_gpio_dataout(LED2_GPIO15, 0);
405 #ifdef CONFIG_MACH_OMAP_APOLLON_PLUS
406         /* LED3 - M15 */
407         omap_cfg_reg(M15_24XX_GPIO92);
408         omap_request_gpio(LED3_GPIO92);
409         omap_set_gpio_direction(LED3_GPIO92, 0);
410         omap_set_gpio_dataout(LED3_GPIO92, 0);
411         /* LED4 - P20 */
412         omap_cfg_reg(P20_24XX_GPIO93);
413         omap_request_gpio(LED4_GPIO93);
414         omap_set_gpio_direction(LED4_GPIO93, 0);
415         omap_set_gpio_dataout(LED4_GPIO93, 0);
416 #endif
417 }
418
419 static void __init apollon_usb_init(void)
420 {
421         /* USB device */
422         /* DEVICE_SUSPEND */
423         omap_cfg_reg(P21_242X_GPIO12);
424         omap_request_gpio(12);
425         omap_set_gpio_direction(12, 0);         /* OUT */
426         omap_set_gpio_dataout(12, 0);
427 }
428
429 static void __init apollon_tsc_init(void)
430 {
431         /* TSC2101 */
432         omap_cfg_reg(N15_24XX_GPIO85);
433         omap_request_gpio(85);
434         omap_set_gpio_direction(85, 1);
435
436         omap_cfg_reg(W14_24XX_SYS_CLKOUT);      /* mclk */
437 }
438
439 static void __init apollon_cs_init(void)
440 {
441         unsigned long base;
442         unsigned int rate;
443         struct clk *l3ck;
444         u32 value;
445         int cs, sync = 0;
446
447         l3ck = clk_get(NULL, "core_l3_ck");
448         if (IS_ERR(l3ck))
449                 rate = 100000000;
450         else
451                 rate = clk_get_rate(l3ck);
452
453         /* CS2: OneNAND */
454         cs = 2;
455         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG1);
456         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, value);
457         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG2);
458         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, value);
459         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG3);
460         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, value);
461         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG4);
462         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, value);
463         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG5);
464         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, value);
465         value = gpmc_cs_read_reg(0, GPMC_CS_CONFIG6);
466         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, value);
467
468         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, APOLLON_ONENAND_CS2_ADDRESS);
469
470         /* CS3: External NOR */
471         cs = APOLLON_NOR_CS;
472         if (rate >= 160000000) {
473                 sync = 1;
474                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0xe5011211);
475                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00090b01);
476                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00020201);
477                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x09030b03);
478                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x010a0a0c);
479                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
480         } else if (rate >= 130000000) {
481                 /* Not yet know ... Use the async values */
482                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0x00021201);
483                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00121601);
484                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00040401);
485                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x12061605);
486                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x01151317);
487                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
488         } else {/* rate = 100000000 */
489                 sync = 1;
490                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, 0xe1001202);
491                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, 0x00151501);
492                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, 0x00050501);
493                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, 0x0e070e07);
494                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG5, 0x01131F1F);
495                 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, 0x00000000);
496         }
497
498         gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, APOLLON_EXT_CS3_ADDRESS);
499
500         if (gpmc_cs_request(cs, SZ_32M, &base) < 0) {
501                 printk(KERN_ERR "Failed to request GPMC CS for external\n");
502                 return;
503         }
504
505         /* Synchronous mode */
506         if (sync) {
507                 void __iomem *addr = ioremap(base, SZ_32M);
508                 writew(0xaa, addr + 0xaaa);
509                 writew(0x55, addr + 0x554);
510                 writew(0xc0, addr + 0x24aaa);
511                 iounmap(addr);
512         }
513
514         gpmc_cs_free(cs);
515 }
516
517 static void __init omap_apollon_init(void)
518 {
519         apollon_cs_init();
520         apollon_led_init();
521         apollon_flash_init();
522         apollon_usb_init();
523         apollon_tsc_init();
524
525         /*
526          * Make sure the serial ports are muxed on at this point.
527          * You have to mux them off in device drivers later on
528          * if not needed.
529          */
530         platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
531         omap_board_config = apollon_config;
532         omap_board_config_size = ARRAY_SIZE(apollon_config);
533         omap_serial_init();
534         omap_register_i2c_bus(1, 100, NULL, 0);
535         omap_register_i2c_bus(2, 100, NULL, 0);
536
537         spi_register_board_info(apollon_spi_board_info,
538                                 ARRAY_SIZE(apollon_spi_board_info));
539
540         apollon_mmc_init();
541 }
542
543 static void __init omap_apollon_map_io(void)
544 {
545         omap2_set_globals_242x();
546         omap2_map_common_io();
547 }
548
549 MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
550         /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
551         .phys_io        = 0x48000000,
552         .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
553         .boot_params    = 0x80000100,
554         .map_io         = omap_apollon_map_io,
555         .init_irq       = omap_apollon_init_irq,
556         .init_machine   = omap_apollon_init,
557         .timer          = &omap_timer,
558 MACHINE_END