[S390] cpu topology: introduce kernel parameter
[linux-2.6] / arch / arm / mach-davinci / board-evm.c
1 /*
2  * TI DaVinci EVM board support
3  *
4  * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
5  *
6  * 2007 (c) MontaVista Software, Inc. This file is licensed under
7  * the terms of the GNU General Public License version 2. This program
8  * is licensed "as is" without any warranty of any kind, whether express
9  * or implied.
10  */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/platform_device.h>
16 #include <linux/gpio.h>
17 #include <linux/leds.h>
18
19 #include <linux/i2c.h>
20 #include <linux/i2c/pcf857x.h>
21 #include <linux/i2c/at24.h>
22
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/partitions.h>
25 #include <linux/mtd/physmap.h>
26 #include <linux/io.h>
27
28 #include <asm/setup.h>
29 #include <asm/mach-types.h>
30
31 #include <asm/mach/arch.h>
32 #include <asm/mach/map.h>
33 #include <asm/mach/flash.h>
34
35 #include <mach/hardware.h>
36 #include <mach/common.h>
37 #include <mach/i2c.h>
38
39 /* other misc. init functions */
40 void __init davinci_psc_init(void);
41 void __init davinci_irq_init(void);
42 void __init davinci_map_common_io(void);
43 void __init davinci_init_common_hw(void);
44
45 #if defined(CONFIG_MTD_PHYSMAP) || \
46     defined(CONFIG_MTD_PHYSMAP_MODULE)
47
48 static struct mtd_partition davinci_evm_norflash_partitions[] = {
49         /* bootloader (U-Boot, etc) in first 4 sectors */
50         {
51                 .name           = "bootloader",
52                 .offset         = 0,
53                 .size           = 4 * SZ_64K,
54                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
55         },
56         /* bootloader params in the next 1 sectors */
57         {
58                 .name           = "params",
59                 .offset         = MTDPART_OFS_APPEND,
60                 .size           = SZ_64K,
61                 .mask_flags     = 0,
62         },
63         /* kernel */
64         {
65                 .name           = "kernel",
66                 .offset         = MTDPART_OFS_APPEND,
67                 .size           = SZ_2M,
68                 .mask_flags     = 0
69         },
70         /* file system */
71         {
72                 .name           = "filesystem",
73                 .offset         = MTDPART_OFS_APPEND,
74                 .size           = MTDPART_SIZ_FULL,
75                 .mask_flags     = 0
76         }
77 };
78
79 static struct physmap_flash_data davinci_evm_norflash_data = {
80         .width          = 2,
81         .parts          = davinci_evm_norflash_partitions,
82         .nr_parts       = ARRAY_SIZE(davinci_evm_norflash_partitions),
83 };
84
85 /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
86  * limits addresses to 16M, so using addresses past 16M will wrap */
87 static struct resource davinci_evm_norflash_resource = {
88         .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
89         .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
90         .flags          = IORESOURCE_MEM,
91 };
92
93 static struct platform_device davinci_evm_norflash_device = {
94         .name           = "physmap-flash",
95         .id             = 0,
96         .dev            = {
97                 .platform_data  = &davinci_evm_norflash_data,
98         },
99         .num_resources  = 1,
100         .resource       = &davinci_evm_norflash_resource,
101 };
102
103 #endif
104
105 #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
106     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
107
108 static struct resource ide_resources[] = {
109         {
110                 .start          = DAVINCI_CFC_ATA_BASE,
111                 .end            = DAVINCI_CFC_ATA_BASE + 0x7ff,
112                 .flags          = IORESOURCE_MEM,
113         },
114         {
115                 .start          = IRQ_IDE,
116                 .end            = IRQ_IDE,
117                 .flags          = IORESOURCE_IRQ,
118         },
119 };
120
121 static u64 ide_dma_mask = DMA_32BIT_MASK;
122
123 static struct platform_device ide_dev = {
124         .name           = "palm_bk3710",
125         .id             = -1,
126         .resource       = ide_resources,
127         .num_resources  = ARRAY_SIZE(ide_resources),
128         .dev = {
129                 .dma_mask               = &ide_dma_mask,
130                 .coherent_dma_mask      = DMA_32BIT_MASK,
131         },
132 };
133
134 #endif
135
136 /*----------------------------------------------------------------------*/
137
138 /*
139  * I2C GPIO expanders
140  */
141
142 #define PCF_Uxx_BASE(x) (DAVINCI_N_GPIO + ((x) * 8))
143
144
145 /* U2 -- LEDs */
146
147 static struct gpio_led evm_leds[] = {
148         { .name = "DS8", .active_low = 1,
149                 .default_trigger = "heartbeat", },
150         { .name = "DS7", .active_low = 1, },
151         { .name = "DS6", .active_low = 1, },
152         { .name = "DS5", .active_low = 1, },
153         { .name = "DS4", .active_low = 1, },
154         { .name = "DS3", .active_low = 1, },
155         { .name = "DS2", .active_low = 1,
156                 .default_trigger = "mmc0", },
157         { .name = "DS1", .active_low = 1,
158                 .default_trigger = "ide-disk", },
159 };
160
161 static const struct gpio_led_platform_data evm_led_data = {
162         .num_leds       = ARRAY_SIZE(evm_leds),
163         .leds           = evm_leds,
164 };
165
166 static struct platform_device *evm_led_dev;
167
168 static int
169 evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
170 {
171         struct gpio_led *leds = evm_leds;
172         int status;
173
174         while (ngpio--) {
175                 leds->gpio = gpio++;
176                 leds++;
177         }
178
179         /* what an extremely annoying way to be forced to handle
180          * device unregistration ...
181          */
182         evm_led_dev = platform_device_alloc("leds-gpio", 0);
183         platform_device_add_data(evm_led_dev,
184                         &evm_led_data, sizeof evm_led_data);
185
186         evm_led_dev->dev.parent = &client->dev;
187         status = platform_device_add(evm_led_dev);
188         if (status < 0) {
189                 platform_device_put(evm_led_dev);
190                 evm_led_dev = NULL;
191         }
192         return status;
193 }
194
195 static int
196 evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
197 {
198         if (evm_led_dev) {
199                 platform_device_unregister(evm_led_dev);
200                 evm_led_dev = NULL;
201         }
202         return 0;
203 }
204
205 static struct pcf857x_platform_data pcf_data_u2 = {
206         .gpio_base      = PCF_Uxx_BASE(0),
207         .setup          = evm_led_setup,
208         .teardown       = evm_led_teardown,
209 };
210
211
212 /* U18 - A/V clock generator and user switch */
213
214 static int sw_gpio;
215
216 static ssize_t
217 sw_show(struct device *d, struct device_attribute *a, char *buf)
218 {
219         char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
220
221         strcpy(buf, s);
222         return strlen(s);
223 }
224
225 static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
226
227 static int
228 evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
229 {
230         int     status;
231
232         /* export dip switch option */
233         sw_gpio = gpio + 7;
234         status = gpio_request(sw_gpio, "user_sw");
235         if (status == 0)
236                 status = gpio_direction_input(sw_gpio);
237         if (status == 0)
238                 status = device_create_file(&client->dev, &dev_attr_user_sw);
239         else
240                 gpio_free(sw_gpio);
241         if (status != 0)
242                 sw_gpio = -EINVAL;
243
244         /* audio PLL:  48 kHz (vs 44.1 or 32), single rate (vs double) */
245         gpio_request(gpio + 3, "pll_fs2");
246         gpio_direction_output(gpio + 3, 0);
247
248         gpio_request(gpio + 2, "pll_fs1");
249         gpio_direction_output(gpio + 2, 0);
250
251         gpio_request(gpio + 1, "pll_sr");
252         gpio_direction_output(gpio + 1, 0);
253
254         return 0;
255 }
256
257 static int
258 evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
259 {
260         gpio_free(gpio + 1);
261         gpio_free(gpio + 2);
262         gpio_free(gpio + 3);
263
264         if (sw_gpio > 0) {
265                 device_remove_file(&client->dev, &dev_attr_user_sw);
266                 gpio_free(sw_gpio);
267         }
268         return 0;
269 }
270
271 static struct pcf857x_platform_data pcf_data_u18 = {
272         .gpio_base      = PCF_Uxx_BASE(1),
273         .n_latch        = (1 << 3) | (1 << 2) | (1 << 1),
274         .setup          = evm_u18_setup,
275         .teardown       = evm_u18_teardown,
276 };
277
278
279 /* U35 - various I/O signals used to manage USB, CF, ATA, etc */
280
281 static int
282 evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
283 {
284         /* p0 = nDRV_VBUS (initial:  don't supply it) */
285         gpio_request(gpio + 0, "nDRV_VBUS");
286         gpio_direction_output(gpio + 0, 1);
287
288         /* p1 = VDDIMX_EN */
289         gpio_request(gpio + 1, "VDDIMX_EN");
290         gpio_direction_output(gpio + 1, 1);
291
292         /* p2 = VLYNQ_EN */
293         gpio_request(gpio + 2, "VLYNQ_EN");
294         gpio_direction_output(gpio + 2, 1);
295
296         /* p3 = n3V3_CF_RESET (initial: stay in reset) */
297         gpio_request(gpio + 3, "nCF_RESET");
298         gpio_direction_output(gpio + 3, 0);
299
300         /* (p4 unused) */
301
302         /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
303         gpio_request(gpio + 5, "WLAN_RESET");
304         gpio_direction_output(gpio + 5, 1);
305
306         /* p6 = nATA_SEL (initial: select) */
307         gpio_request(gpio + 6, "nATA_SEL");
308         gpio_direction_output(gpio + 6, 0);
309
310         /* p7 = nCF_SEL (initial: deselect) */
311         gpio_request(gpio + 7, "nCF_SEL");
312         gpio_direction_output(gpio + 7, 1);
313
314         return 0;
315 }
316
317 static int
318 evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
319 {
320         gpio_free(gpio + 7);
321         gpio_free(gpio + 6);
322         gpio_free(gpio + 5);
323         gpio_free(gpio + 3);
324         gpio_free(gpio + 2);
325         gpio_free(gpio + 1);
326         gpio_free(gpio + 0);
327         return 0;
328 }
329
330 static struct pcf857x_platform_data pcf_data_u35 = {
331         .gpio_base      = PCF_Uxx_BASE(2),
332         .setup          = evm_u35_setup,
333         .teardown       = evm_u35_teardown,
334 };
335
336 /*----------------------------------------------------------------------*/
337
338 /* Most of this EEPROM is unused, but U-Boot uses some data:
339  *  - 0x7f00, 6 bytes Ethernet Address
340  *  - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
341  *  - ... newer boards may have more
342  */
343 static struct at24_platform_data eeprom_info = {
344         .byte_len       = (256*1024) / 8,
345         .page_size      = 64,
346         .flags          = AT24_FLAG_ADDR16,
347 };
348
349 static struct i2c_board_info __initdata i2c_info[] =  {
350         {
351                 I2C_BOARD_INFO("pcf8574", 0x38),
352                 .platform_data  = &pcf_data_u2,
353         },
354         {
355                 I2C_BOARD_INFO("pcf8574", 0x39),
356                 .platform_data  = &pcf_data_u18,
357         },
358         {
359                 I2C_BOARD_INFO("pcf8574", 0x3a),
360                 .platform_data  = &pcf_data_u35,
361         },
362         {
363                 I2C_BOARD_INFO("24c256", 0x50),
364                 .platform_data  = &eeprom_info,
365         },
366         /* ALSO:
367          * - tvl320aic33 audio codec (0x1b)
368          * - msp430 microcontroller (0x23)
369          * - tvp5146 video decoder (0x5d)
370          */
371 };
372
373 /* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
374  * which requires 100 usec of idle bus after i2c writes sent to it.
375  */
376 static struct davinci_i2c_platform_data i2c_pdata = {
377         .bus_freq       = 20 /* kHz */,
378         .bus_delay      = 100 /* usec */,
379 };
380
381 static void __init evm_init_i2c(void)
382 {
383         davinci_init_i2c(&i2c_pdata);
384         i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
385 }
386
387 static struct platform_device *davinci_evm_devices[] __initdata = {
388 #if defined(CONFIG_MTD_PHYSMAP) || \
389     defined(CONFIG_MTD_PHYSMAP_MODULE)
390         &davinci_evm_norflash_device,
391 #endif
392 #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
393     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
394         &ide_dev,
395 #endif
396 };
397
398 static void __init
399 davinci_evm_map_io(void)
400 {
401         davinci_map_common_io();
402 }
403
404 static __init void davinci_evm_init(void)
405 {
406         davinci_psc_init();
407
408 #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
409     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
410 #if defined(CONFIG_MTD_PHYSMAP) || \
411     defined(CONFIG_MTD_PHYSMAP_MODULE)
412         printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
413                "but share pins.\n\t Disable IDE for NOR support.\n");
414 #endif
415 #endif
416
417         platform_add_devices(davinci_evm_devices,
418                              ARRAY_SIZE(davinci_evm_devices));
419         evm_init_i2c();
420
421         /* irlml6401 sustains over 3A, switches 5V in under 8 msec */
422         setup_usb(500, 8);
423 }
424
425 static __init void davinci_evm_irq_init(void)
426 {
427         davinci_init_common_hw();
428         davinci_irq_init();
429 }
430
431 MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
432         /* Maintainer: MontaVista Software <source@mvista.com> */
433         .phys_io      = IO_PHYS,
434         .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
435         .boot_params  = (DAVINCI_DDR_BASE + 0x100),
436         .map_io       = davinci_evm_map_io,
437         .init_irq     = davinci_evm_irq_init,
438         .timer        = &davinci_timer,
439         .init_machine = davinci_evm_init,
440 MACHINE_END