]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-apollon.c
ARM: OMAP: Apollon Plus board support
[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,2006 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/delay.h>
26 #include <linux/leds.h>
27 #include <linux/err.h>
28 #include <linux/clk.h>
29
30 #include <asm/hardware.h>
31 #include <asm/mach-types.h>
32 #include <asm/mach/arch.h>
33 #include <asm/mach/flash.h>
34
35 #include <asm/arch/gpio.h>
36 #include <asm/arch/led.h>
37 #include <asm/arch/mux.h>
38 #include <asm/arch/usb.h>
39 #include <asm/arch/board.h>
40 #include <asm/arch/common.h>
41 #include <asm/arch/gpmc.h>
42
43 /* LED & Switch macros */
44 #define LED0_GPIO13             13
45 #define LED1_GPIO14             14
46 #define LED2_GPIO15             15
47 #define LED3_GPIO92             92
48 #define LED4_GPIO93             93
49
50 #define APOLLON_FLASH_CS        0
51 #define APOLLON_ETH_CS          1
52
53 static struct mtd_partition apollon_partitions[] = {
54         {
55                 .name           = "X-Loader + U-Boot",
56                 .offset         = 0,
57                 .size           = SZ_128K,
58                 .mask_flags     = MTD_WRITEABLE,
59         },
60         {
61                 .name           = "params",
62                 .offset         = MTDPART_OFS_APPEND,
63                 .size           = SZ_128K,
64         },
65         {
66                 .name           = "kernel",
67                 .offset         = MTDPART_OFS_APPEND,
68                 .size           = SZ_2M,
69         },
70         {
71                 .name           = "rootfs",
72                 .offset         = MTDPART_OFS_APPEND,
73                 .size           = SZ_16M,
74         },
75         {
76                 .name           = "filesystem00",
77                 .offset         = MTDPART_OFS_APPEND,
78                 .size           = SZ_32M,
79         },
80         {
81                 .name           = "filesystem01",
82                 .offset         = MTDPART_OFS_APPEND,
83                 .size           = MTDPART_SIZ_FULL,
84         },
85 };
86
87 static struct flash_platform_data apollon_flash_data = {
88         .parts          = apollon_partitions,
89         .nr_parts       = ARRAY_SIZE(apollon_partitions),
90 };
91
92 static struct resource apollon_flash_resource[] = {
93         [0] = {
94                 .flags          = IORESOURCE_MEM,
95         },
96 };
97
98 static struct platform_device apollon_onenand_device = {
99         .name           = "onenand",
100         .id             = -1,
101         .dev            = {
102                 .platform_data  = &apollon_flash_data,
103         },
104         .num_resources  = ARRAY_SIZE(apollon_flash_resource),
105         .resource       = apollon_flash_resource,
106 };
107
108 static void __init apollon_flash_init(void)
109 {
110         unsigned long base;
111
112         if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
113                 printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
114                 return;
115         }
116         apollon_flash_resource[0].start = base;
117         apollon_flash_resource[0].end   = base + SZ_128K - 1;
118 }
119
120 static struct resource apollon_smc91x_resources[] = {
121         [0] = {
122                 .flags  = IORESOURCE_MEM,
123         },
124         [1] = {
125                 .start  = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
126                 .end    = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
127                 .flags  = IORESOURCE_IRQ,
128         },
129 };
130
131 static struct platform_device apollon_smc91x_device = {
132         .name           = "smc91x",
133         .id             = -1,
134         .num_resources  = ARRAY_SIZE(apollon_smc91x_resources),
135         .resource       = apollon_smc91x_resources,
136 };
137
138 static struct platform_device apollon_lcd_device = {
139         .name           = "apollon_lcd",
140         .id             = -1,
141 };
142
143 static struct omap_led_config apollon_led_config[] = {
144         {
145                 .cdev   = {
146                         .name   = "apollon:led0",
147                 },
148                 .gpio   = LED0_GPIO13,
149         },
150         {
151                 .cdev   = {
152                         .name   = "apollon:led1",
153                 },
154                 .gpio   = LED1_GPIO14,
155         },
156         {
157                 .cdev   = {
158                         .name   = "apollon:led2",
159                 },
160                 .gpio   = LED2_GPIO15,
161         },
162 #ifdef CONFIG_MACH_OMAP_APOLLON_PLUS
163         {
164                 .cdev   = {
165                         .name   = "apollon:led3",
166                 },
167                 .gpio   = LED3_GPIO92,
168         },
169         {
170                 .cdev   = {
171                         .name   = "apollon:led4",
172                 },
173                 .gpio   = LED4_GPIO93,
174         },
175 #endif
176 };
177
178 static struct omap_led_platform_data apollon_led_data = {
179         .nr_leds        = ARRAY_SIZE(apollon_led_config),
180         .leds           = apollon_led_config,
181 };
182
183 static struct platform_device apollon_led_device = {
184         .name           = "omap-led",
185         .id             = -1,
186         .dev            = {
187                 .platform_data  = &apollon_led_data,
188         },
189 };
190
191 static struct platform_device *apollon_devices[] __initdata = {
192         &apollon_onenand_device,
193         &apollon_smc91x_device,
194         &apollon_lcd_device,
195         &apollon_led_device,
196 };
197
198 static inline void __init apollon_init_smc91x(void)
199 {
200         unsigned long base;
201         unsigned int rate;
202         struct clk *l3ck;
203         int eth_cs;
204
205         l3ck = clk_get(NULL, "core_l3_ck");
206         if (IS_ERR(l3ck))
207                 rate = 100000000;
208         else
209                 rate = clk_get_rate(l3ck);
210
211         eth_cs = APOLLON_ETH_CS;
212
213         /* Make sure CS1 timings are correct */
214         gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
215
216         if (rate >= 160000000) {
217                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
218                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
219                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
220                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
221                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
222         } else if (rate >= 130000000) {
223                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
224                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
225                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
226                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
227                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
228         } else {/* rate = 100000000 */
229                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
230                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
231                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
232                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
233                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
234         }
235
236         if (gpmc_cs_request(eth_cs, SZ_16M, &base) < 0) {
237                 printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
238                 return;
239         }
240         apollon_smc91x_resources[0].start = base + 0x300;
241         apollon_smc91x_resources[0].end   = base + 0x30f;
242         udelay(100);
243
244         omap_cfg_reg(W4__24XX_GPIO74);
245         if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
246                 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
247                         APOLLON_ETHR_GPIO_IRQ);
248                 gpmc_cs_free(eth_cs);
249                 return;
250         }
251         omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
252 }
253
254 static void __init omap_apollon_init_irq(void)
255 {
256         omap2_init_common_hw();
257         omap_init_irq();
258         omap_gpio_init();
259         apollon_init_smc91x();
260 }
261
262 static struct omap_uart_config apollon_uart_config __initdata = {
263         .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
264 };
265
266 static struct omap_mmc_config apollon_mmc_config __initdata = {
267         .mmc [0] = {
268                 .enabled        = 1,
269                 .wire4          = 1,
270         /* Use internal loop-back in MMC/SDIO Module Input Clock selection */
271                 .internal_clock = 1,
272                 .wp_pin         = -1,
273                 .power_pin      = -1,
274         /* Note: If you want to detect card feature, please assign 37 */
275                 .switch_pin     = -1,
276         },
277 };
278
279 static struct omap_usb_config apollon_usb_config __initdata = {
280         .register_dev   = 1,
281         .hmc_mode       = 0x14, /* 0:dev 1:host1 2:disable */
282
283         .pins[0]        = 6,
284 };
285
286 static struct omap_lcd_config apollon_lcd_config __initdata = {
287         .ctrl_name      = "internal",
288 };
289
290 static struct omap_board_config_kernel apollon_config[] __initdata = {
291         { OMAP_TAG_UART,        &apollon_uart_config },
292         { OMAP_TAG_MMC,         &apollon_mmc_config },
293         { OMAP_TAG_USB,         &apollon_usb_config },
294         { OMAP_TAG_LCD,         &apollon_lcd_config },
295 };
296
297 static void __init apollon_led_init(void)
298 {
299         /* LED0 - AA10 */
300         omap_cfg_reg(AA10_242X_GPIO13);
301         omap_request_gpio(LED0_GPIO13);
302         omap_set_gpio_direction(LED0_GPIO13, 0);
303         omap_set_gpio_dataout(LED0_GPIO13, 0);
304         /* LED1  - AA6 */
305         omap_cfg_reg(AA6_242X_GPIO14);
306         omap_request_gpio(LED1_GPIO14);
307         omap_set_gpio_direction(LED1_GPIO14, 0);
308         omap_set_gpio_dataout(LED1_GPIO14, 0);
309         /* LED2  - AA4 */
310         omap_cfg_reg(AA4_242X_GPIO15);
311         omap_request_gpio(LED2_GPIO15);
312         omap_set_gpio_direction(LED2_GPIO15, 0);
313         omap_set_gpio_dataout(LED2_GPIO15, 0);
314 #ifdef CONFIG_MACH_OMAP_APOLLON_PLUS
315         /* LED3 - M15 */
316         omap_cfg_reg(M15_24XX_GPIO92);
317         omap_request_gpio(LED3_GPIO92);
318         omap_set_gpio_direction(LED3_GPIO92, 0);
319         omap_set_gpio_dataout(LED3_GPIO92, 0);
320         /* LED4 - P20 */
321         omap_cfg_reg(P20_24XX_GPIO93);
322         omap_request_gpio(LED4_GPIO93);
323         omap_set_gpio_direction(LED4_GPIO93, 0);
324         omap_set_gpio_dataout(LED4_GPIO93, 0);
325 #endif
326 }
327
328 static void __init apollon_usb_init(void)
329 {
330         /* USB device */
331         /* DEVICE_SUSPEND */
332         omap_cfg_reg(P21_242X_GPIO12);
333         omap_request_gpio(12);
334         omap_set_gpio_direction(12, 0);         /* OUT */
335         omap_set_gpio_dataout(12, 0);
336 }
337
338 static void __init omap_apollon_init(void)
339 {
340         apollon_led_init();
341         apollon_flash_init();
342         apollon_usb_init();
343
344         /*
345          * Make sure the serial ports are muxed on at this point.
346          * You have to mux them off in device drivers later on
347          * if not needed.
348          */
349         platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
350         omap_board_config = apollon_config;
351         omap_board_config_size = ARRAY_SIZE(apollon_config);
352         omap_serial_init();
353 }
354
355 static void __init omap_apollon_map_io(void)
356 {
357         omap2_map_common_io();
358 }
359
360 MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
361         /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
362         .phys_io        = 0x48000000,
363         .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
364         .boot_params    = 0x80000100,
365         .map_io         = omap_apollon_map_io,
366         .init_irq       = omap_apollon_init_irq,
367         .init_machine   = omap_apollon_init,
368         .timer          = &omap_timer,
369 MACHINE_END