diff options
Diffstat (limited to 'arch/arm/mach-davinci/board-dm644x-evm.c')
-rw-r--r-- | arch/arm/mach-davinci/board-dm644x-evm.c | 694 |
1 files changed, 694 insertions, 0 deletions
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c new file mode 100644 index 000000000000..d9d40450bdc5 --- /dev/null +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
@@ -0,0 +1,694 @@ | |||
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 | #include <linux/memory.h> | ||
19 | |||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/i2c/pcf857x.h> | ||
22 | #include <linux/i2c/at24.h> | ||
23 | #include <linux/etherdevice.h> | ||
24 | #include <linux/mtd/mtd.h> | ||
25 | #include <linux/mtd/nand.h> | ||
26 | #include <linux/mtd/partitions.h> | ||
27 | #include <linux/mtd/physmap.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/phy.h> | ||
30 | #include <linux/clk.h> | ||
31 | |||
32 | #include <asm/setup.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | |||
35 | #include <asm/mach/arch.h> | ||
36 | #include <asm/mach/map.h> | ||
37 | #include <asm/mach/flash.h> | ||
38 | |||
39 | #include <mach/dm644x.h> | ||
40 | #include <mach/common.h> | ||
41 | #include <mach/i2c.h> | ||
42 | #include <mach/serial.h> | ||
43 | #include <mach/mux.h> | ||
44 | #include <mach/psc.h> | ||
45 | #include <mach/nand.h> | ||
46 | #include <mach/mmc.h> | ||
47 | #include <mach/emac.h> | ||
48 | #include <mach/common.h> | ||
49 | |||
50 | #define DM644X_EVM_PHY_MASK (0x2) | ||
51 | #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ | ||
52 | |||
53 | #define DAVINCI_CFC_ATA_BASE 0x01C66000 | ||
54 | |||
55 | #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 | ||
56 | #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 | ||
57 | #define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 | ||
58 | #define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 | ||
59 | #define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 | ||
60 | |||
61 | #define LXT971_PHY_ID (0x001378e2) | ||
62 | #define LXT971_PHY_MASK (0xfffffff0) | ||
63 | |||
64 | static struct mtd_partition davinci_evm_norflash_partitions[] = { | ||
65 | /* bootloader (UBL, U-Boot, etc) in first 5 sectors */ | ||
66 | { | ||
67 | .name = "bootloader", | ||
68 | .offset = 0, | ||
69 | .size = 5 * SZ_64K, | ||
70 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
71 | }, | ||
72 | /* bootloader params in the next 1 sectors */ | ||
73 | { | ||
74 | .name = "params", | ||
75 | .offset = MTDPART_OFS_APPEND, | ||
76 | .size = SZ_64K, | ||
77 | .mask_flags = 0, | ||
78 | }, | ||
79 | /* kernel */ | ||
80 | { | ||
81 | .name = "kernel", | ||
82 | .offset = MTDPART_OFS_APPEND, | ||
83 | .size = SZ_2M, | ||
84 | .mask_flags = 0 | ||
85 | }, | ||
86 | /* file system */ | ||
87 | { | ||
88 | .name = "filesystem", | ||
89 | .offset = MTDPART_OFS_APPEND, | ||
90 | .size = MTDPART_SIZ_FULL, | ||
91 | .mask_flags = 0 | ||
92 | } | ||
93 | }; | ||
94 | |||
95 | static struct physmap_flash_data davinci_evm_norflash_data = { | ||
96 | .width = 2, | ||
97 | .parts = davinci_evm_norflash_partitions, | ||
98 | .nr_parts = ARRAY_SIZE(davinci_evm_norflash_partitions), | ||
99 | }; | ||
100 | |||
101 | /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF | ||
102 | * limits addresses to 16M, so using addresses past 16M will wrap */ | ||
103 | static struct resource davinci_evm_norflash_resource = { | ||
104 | .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, | ||
105 | .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, | ||
106 | .flags = IORESOURCE_MEM, | ||
107 | }; | ||
108 | |||
109 | static struct platform_device davinci_evm_norflash_device = { | ||
110 | .name = "physmap-flash", | ||
111 | .id = 0, | ||
112 | .dev = { | ||
113 | .platform_data = &davinci_evm_norflash_data, | ||
114 | }, | ||
115 | .num_resources = 1, | ||
116 | .resource = &davinci_evm_norflash_resource, | ||
117 | }; | ||
118 | |||
119 | /* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks). | ||
120 | * It may used instead of the (default) NOR chip to boot, using TI's | ||
121 | * tools to install the secondary boot loader (UBL) and U-Boot. | ||
122 | */ | ||
123 | struct mtd_partition davinci_evm_nandflash_partition[] = { | ||
124 | /* Bootloader layout depends on whose u-boot is installed, but we | ||
125 | * can hide all the details. | ||
126 | * - block 0 for u-boot environment ... in mainline u-boot | ||
127 | * - block 1 for UBL (plus up to four backup copies in blocks 2..5) | ||
128 | * - blocks 6...? for u-boot | ||
129 | * - blocks 16..23 for u-boot environment ... in TI's u-boot | ||
130 | */ | ||
131 | { | ||
132 | .name = "bootloader", | ||
133 | .offset = 0, | ||
134 | .size = SZ_256K + SZ_128K, | ||
135 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
136 | }, | ||
137 | /* Kernel */ | ||
138 | { | ||
139 | .name = "kernel", | ||
140 | .offset = MTDPART_OFS_APPEND, | ||
141 | .size = SZ_4M, | ||
142 | .mask_flags = 0, | ||
143 | }, | ||
144 | /* File system (older GIT kernels started this on the 5MB mark) */ | ||
145 | { | ||
146 | .name = "filesystem", | ||
147 | .offset = MTDPART_OFS_APPEND, | ||
148 | .size = MTDPART_SIZ_FULL, | ||
149 | .mask_flags = 0, | ||
150 | } | ||
151 | /* A few blocks at end hold a flash BBT ... created by TI's CCS | ||
152 | * using flashwriter_nand.out, but ignored by TI's versions of | ||
153 | * Linux and u-boot. We boot faster by using them. | ||
154 | */ | ||
155 | }; | ||
156 | |||
157 | static struct davinci_nand_pdata davinci_evm_nandflash_data = { | ||
158 | .parts = davinci_evm_nandflash_partition, | ||
159 | .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), | ||
160 | .ecc_mode = NAND_ECC_HW, | ||
161 | .options = NAND_USE_FLASH_BBT, | ||
162 | }; | ||
163 | |||
164 | static struct resource davinci_evm_nandflash_resource[] = { | ||
165 | { | ||
166 | .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, | ||
167 | .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, | ||
168 | .flags = IORESOURCE_MEM, | ||
169 | }, { | ||
170 | .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, | ||
171 | .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }, | ||
174 | }; | ||
175 | |||
176 | static struct platform_device davinci_evm_nandflash_device = { | ||
177 | .name = "davinci_nand", | ||
178 | .id = 0, | ||
179 | .dev = { | ||
180 | .platform_data = &davinci_evm_nandflash_data, | ||
181 | }, | ||
182 | .num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource), | ||
183 | .resource = davinci_evm_nandflash_resource, | ||
184 | }; | ||
185 | |||
186 | static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32); | ||
187 | |||
188 | static struct platform_device davinci_fb_device = { | ||
189 | .name = "davincifb", | ||
190 | .id = -1, | ||
191 | .dev = { | ||
192 | .dma_mask = &davinci_fb_dma_mask, | ||
193 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
194 | }, | ||
195 | .num_resources = 0, | ||
196 | }; | ||
197 | |||
198 | static struct platform_device rtc_dev = { | ||
199 | .name = "rtc_davinci_evm", | ||
200 | .id = -1, | ||
201 | }; | ||
202 | |||
203 | static struct resource ide_resources[] = { | ||
204 | { | ||
205 | .start = DAVINCI_CFC_ATA_BASE, | ||
206 | .end = DAVINCI_CFC_ATA_BASE + 0x7ff, | ||
207 | .flags = IORESOURCE_MEM, | ||
208 | }, | ||
209 | { | ||
210 | .start = IRQ_IDE, | ||
211 | .end = IRQ_IDE, | ||
212 | .flags = IORESOURCE_IRQ, | ||
213 | }, | ||
214 | }; | ||
215 | |||
216 | static u64 ide_dma_mask = DMA_BIT_MASK(32); | ||
217 | |||
218 | static struct platform_device ide_dev = { | ||
219 | .name = "palm_bk3710", | ||
220 | .id = -1, | ||
221 | .resource = ide_resources, | ||
222 | .num_resources = ARRAY_SIZE(ide_resources), | ||
223 | .dev = { | ||
224 | .dma_mask = &ide_dma_mask, | ||
225 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
226 | }, | ||
227 | }; | ||
228 | |||
229 | /*----------------------------------------------------------------------*/ | ||
230 | |||
231 | /* | ||
232 | * I2C GPIO expanders | ||
233 | */ | ||
234 | |||
235 | #define PCF_Uxx_BASE(x) (DAVINCI_N_GPIO + ((x) * 8)) | ||
236 | |||
237 | |||
238 | /* U2 -- LEDs */ | ||
239 | |||
240 | static struct gpio_led evm_leds[] = { | ||
241 | { .name = "DS8", .active_low = 1, | ||
242 | .default_trigger = "heartbeat", }, | ||
243 | { .name = "DS7", .active_low = 1, }, | ||
244 | { .name = "DS6", .active_low = 1, }, | ||
245 | { .name = "DS5", .active_low = 1, }, | ||
246 | { .name = "DS4", .active_low = 1, }, | ||
247 | { .name = "DS3", .active_low = 1, }, | ||
248 | { .name = "DS2", .active_low = 1, | ||
249 | .default_trigger = "mmc0", }, | ||
250 | { .name = "DS1", .active_low = 1, | ||
251 | .default_trigger = "ide-disk", }, | ||
252 | }; | ||
253 | |||
254 | static const struct gpio_led_platform_data evm_led_data = { | ||
255 | .num_leds = ARRAY_SIZE(evm_leds), | ||
256 | .leds = evm_leds, | ||
257 | }; | ||
258 | |||
259 | static struct platform_device *evm_led_dev; | ||
260 | |||
261 | static int | ||
262 | evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
263 | { | ||
264 | struct gpio_led *leds = evm_leds; | ||
265 | int status; | ||
266 | |||
267 | while (ngpio--) { | ||
268 | leds->gpio = gpio++; | ||
269 | leds++; | ||
270 | } | ||
271 | |||
272 | /* what an extremely annoying way to be forced to handle | ||
273 | * device unregistration ... | ||
274 | */ | ||
275 | evm_led_dev = platform_device_alloc("leds-gpio", 0); | ||
276 | platform_device_add_data(evm_led_dev, | ||
277 | &evm_led_data, sizeof evm_led_data); | ||
278 | |||
279 | evm_led_dev->dev.parent = &client->dev; | ||
280 | status = platform_device_add(evm_led_dev); | ||
281 | if (status < 0) { | ||
282 | platform_device_put(evm_led_dev); | ||
283 | evm_led_dev = NULL; | ||
284 | } | ||
285 | return status; | ||
286 | } | ||
287 | |||
288 | static int | ||
289 | evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
290 | { | ||
291 | if (evm_led_dev) { | ||
292 | platform_device_unregister(evm_led_dev); | ||
293 | evm_led_dev = NULL; | ||
294 | } | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static struct pcf857x_platform_data pcf_data_u2 = { | ||
299 | .gpio_base = PCF_Uxx_BASE(0), | ||
300 | .setup = evm_led_setup, | ||
301 | .teardown = evm_led_teardown, | ||
302 | }; | ||
303 | |||
304 | |||
305 | /* U18 - A/V clock generator and user switch */ | ||
306 | |||
307 | static int sw_gpio; | ||
308 | |||
309 | static ssize_t | ||
310 | sw_show(struct device *d, struct device_attribute *a, char *buf) | ||
311 | { | ||
312 | char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n"; | ||
313 | |||
314 | strcpy(buf, s); | ||
315 | return strlen(s); | ||
316 | } | ||
317 | |||
318 | static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL); | ||
319 | |||
320 | static int | ||
321 | evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
322 | { | ||
323 | int status; | ||
324 | |||
325 | /* export dip switch option */ | ||
326 | sw_gpio = gpio + 7; | ||
327 | status = gpio_request(sw_gpio, "user_sw"); | ||
328 | if (status == 0) | ||
329 | status = gpio_direction_input(sw_gpio); | ||
330 | if (status == 0) | ||
331 | status = device_create_file(&client->dev, &dev_attr_user_sw); | ||
332 | else | ||
333 | gpio_free(sw_gpio); | ||
334 | if (status != 0) | ||
335 | sw_gpio = -EINVAL; | ||
336 | |||
337 | /* audio PLL: 48 kHz (vs 44.1 or 32), single rate (vs double) */ | ||
338 | gpio_request(gpio + 3, "pll_fs2"); | ||
339 | gpio_direction_output(gpio + 3, 0); | ||
340 | |||
341 | gpio_request(gpio + 2, "pll_fs1"); | ||
342 | gpio_direction_output(gpio + 2, 0); | ||
343 | |||
344 | gpio_request(gpio + 1, "pll_sr"); | ||
345 | gpio_direction_output(gpio + 1, 0); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int | ||
351 | evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
352 | { | ||
353 | gpio_free(gpio + 1); | ||
354 | gpio_free(gpio + 2); | ||
355 | gpio_free(gpio + 3); | ||
356 | |||
357 | if (sw_gpio > 0) { | ||
358 | device_remove_file(&client->dev, &dev_attr_user_sw); | ||
359 | gpio_free(sw_gpio); | ||
360 | } | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static struct pcf857x_platform_data pcf_data_u18 = { | ||
365 | .gpio_base = PCF_Uxx_BASE(1), | ||
366 | .n_latch = (1 << 3) | (1 << 2) | (1 << 1), | ||
367 | .setup = evm_u18_setup, | ||
368 | .teardown = evm_u18_teardown, | ||
369 | }; | ||
370 | |||
371 | |||
372 | /* U35 - various I/O signals used to manage USB, CF, ATA, etc */ | ||
373 | |||
374 | static int | ||
375 | evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
376 | { | ||
377 | /* p0 = nDRV_VBUS (initial: don't supply it) */ | ||
378 | gpio_request(gpio + 0, "nDRV_VBUS"); | ||
379 | gpio_direction_output(gpio + 0, 1); | ||
380 | |||
381 | /* p1 = VDDIMX_EN */ | ||
382 | gpio_request(gpio + 1, "VDDIMX_EN"); | ||
383 | gpio_direction_output(gpio + 1, 1); | ||
384 | |||
385 | /* p2 = VLYNQ_EN */ | ||
386 | gpio_request(gpio + 2, "VLYNQ_EN"); | ||
387 | gpio_direction_output(gpio + 2, 1); | ||
388 | |||
389 | /* p3 = n3V3_CF_RESET (initial: stay in reset) */ | ||
390 | gpio_request(gpio + 3, "nCF_RESET"); | ||
391 | gpio_direction_output(gpio + 3, 0); | ||
392 | |||
393 | /* (p4 unused) */ | ||
394 | |||
395 | /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */ | ||
396 | gpio_request(gpio + 5, "WLAN_RESET"); | ||
397 | gpio_direction_output(gpio + 5, 1); | ||
398 | |||
399 | /* p6 = nATA_SEL (initial: select) */ | ||
400 | gpio_request(gpio + 6, "nATA_SEL"); | ||
401 | gpio_direction_output(gpio + 6, 0); | ||
402 | |||
403 | /* p7 = nCF_SEL (initial: deselect) */ | ||
404 | gpio_request(gpio + 7, "nCF_SEL"); | ||
405 | gpio_direction_output(gpio + 7, 1); | ||
406 | |||
407 | /* irlml6401 switches over 1A, in under 8 msec; | ||
408 | * now it can be managed by nDRV_VBUS ... | ||
409 | */ | ||
410 | setup_usb(500, 8); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int | ||
416 | evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) | ||
417 | { | ||
418 | gpio_free(gpio + 7); | ||
419 | gpio_free(gpio + 6); | ||
420 | gpio_free(gpio + 5); | ||
421 | gpio_free(gpio + 3); | ||
422 | gpio_free(gpio + 2); | ||
423 | gpio_free(gpio + 1); | ||
424 | gpio_free(gpio + 0); | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static struct pcf857x_platform_data pcf_data_u35 = { | ||
429 | .gpio_base = PCF_Uxx_BASE(2), | ||
430 | .setup = evm_u35_setup, | ||
431 | .teardown = evm_u35_teardown, | ||
432 | }; | ||
433 | |||
434 | /*----------------------------------------------------------------------*/ | ||
435 | |||
436 | /* Most of this EEPROM is unused, but U-Boot uses some data: | ||
437 | * - 0x7f00, 6 bytes Ethernet Address | ||
438 | * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL) | ||
439 | * - ... newer boards may have more | ||
440 | */ | ||
441 | |||
442 | static struct at24_platform_data eeprom_info = { | ||
443 | .byte_len = (256*1024) / 8, | ||
444 | .page_size = 64, | ||
445 | .flags = AT24_FLAG_ADDR16, | ||
446 | .setup = davinci_get_mac_addr, | ||
447 | .context = (void *)0x7f00, | ||
448 | }; | ||
449 | |||
450 | /* | ||
451 | * MSP430 supports RTC, card detection, input from IR remote, and | ||
452 | * a bit more. It triggers interrupts on GPIO(7) from pressing | ||
453 | * buttons on the IR remote, and for card detect switches. | ||
454 | */ | ||
455 | static struct i2c_client *dm6446evm_msp; | ||
456 | |||
457 | static int dm6446evm_msp_probe(struct i2c_client *client, | ||
458 | const struct i2c_device_id *id) | ||
459 | { | ||
460 | dm6446evm_msp = client; | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int dm6446evm_msp_remove(struct i2c_client *client) | ||
465 | { | ||
466 | dm6446evm_msp = NULL; | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static const struct i2c_device_id dm6446evm_msp_ids[] = { | ||
471 | { "dm6446evm_msp", 0, }, | ||
472 | { /* end of list */ }, | ||
473 | }; | ||
474 | |||
475 | static struct i2c_driver dm6446evm_msp_driver = { | ||
476 | .driver.name = "dm6446evm_msp", | ||
477 | .id_table = dm6446evm_msp_ids, | ||
478 | .probe = dm6446evm_msp_probe, | ||
479 | .remove = dm6446evm_msp_remove, | ||
480 | }; | ||
481 | |||
482 | static int dm6444evm_msp430_get_pins(void) | ||
483 | { | ||
484 | static const char txbuf[2] = { 2, 4, }; | ||
485 | char buf[4]; | ||
486 | struct i2c_msg msg[2] = { | ||
487 | { | ||
488 | .addr = dm6446evm_msp->addr, | ||
489 | .flags = 0, | ||
490 | .len = 2, | ||
491 | .buf = (void __force *)txbuf, | ||
492 | }, | ||
493 | { | ||
494 | .addr = dm6446evm_msp->addr, | ||
495 | .flags = I2C_M_RD, | ||
496 | .len = 4, | ||
497 | .buf = buf, | ||
498 | }, | ||
499 | }; | ||
500 | int status; | ||
501 | |||
502 | if (!dm6446evm_msp) | ||
503 | return -ENXIO; | ||
504 | |||
505 | /* Command 4 == get input state, returns port 2 and port3 data | ||
506 | * S Addr W [A] len=2 [A] cmd=4 [A] | ||
507 | * RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P | ||
508 | */ | ||
509 | status = i2c_transfer(dm6446evm_msp->adapter, msg, 2); | ||
510 | if (status < 0) | ||
511 | return status; | ||
512 | |||
513 | dev_dbg(&dm6446evm_msp->dev, | ||
514 | "PINS: %02x %02x %02x %02x\n", | ||
515 | buf[0], buf[1], buf[2], buf[3]); | ||
516 | |||
517 | return (buf[3] << 8) | buf[2]; | ||
518 | } | ||
519 | |||
520 | static int dm6444evm_mmc_get_cd(int module) | ||
521 | { | ||
522 | int status = dm6444evm_msp430_get_pins(); | ||
523 | |||
524 | return (status < 0) ? status : !(status & BIT(1)); | ||
525 | } | ||
526 | |||
527 | static int dm6444evm_mmc_get_ro(int module) | ||
528 | { | ||
529 | int status = dm6444evm_msp430_get_pins(); | ||
530 | |||
531 | return (status < 0) ? status : status & BIT(6 + 8); | ||
532 | } | ||
533 | |||
534 | static struct davinci_mmc_config dm6446evm_mmc_config = { | ||
535 | .get_cd = dm6444evm_mmc_get_cd, | ||
536 | .get_ro = dm6444evm_mmc_get_ro, | ||
537 | .wires = 4, | ||
538 | .version = MMC_CTLR_VERSION_1 | ||
539 | }; | ||
540 | |||
541 | static struct i2c_board_info __initdata i2c_info[] = { | ||
542 | { | ||
543 | I2C_BOARD_INFO("dm6446evm_msp", 0x23), | ||
544 | }, | ||
545 | { | ||
546 | I2C_BOARD_INFO("pcf8574", 0x38), | ||
547 | .platform_data = &pcf_data_u2, | ||
548 | }, | ||
549 | { | ||
550 | I2C_BOARD_INFO("pcf8574", 0x39), | ||
551 | .platform_data = &pcf_data_u18, | ||
552 | }, | ||
553 | { | ||
554 | I2C_BOARD_INFO("pcf8574", 0x3a), | ||
555 | .platform_data = &pcf_data_u35, | ||
556 | }, | ||
557 | { | ||
558 | I2C_BOARD_INFO("24c256", 0x50), | ||
559 | .platform_data = &eeprom_info, | ||
560 | }, | ||
561 | /* ALSO: | ||
562 | * - tvl320aic33 audio codec (0x1b) | ||
563 | * - tvp5146 video decoder (0x5d) | ||
564 | */ | ||
565 | }; | ||
566 | |||
567 | /* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz), | ||
568 | * which requires 100 usec of idle bus after i2c writes sent to it. | ||
569 | */ | ||
570 | static struct davinci_i2c_platform_data i2c_pdata = { | ||
571 | .bus_freq = 20 /* kHz */, | ||
572 | .bus_delay = 100 /* usec */, | ||
573 | }; | ||
574 | |||
575 | static void __init evm_init_i2c(void) | ||
576 | { | ||
577 | davinci_init_i2c(&i2c_pdata); | ||
578 | i2c_add_driver(&dm6446evm_msp_driver); | ||
579 | i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); | ||
580 | } | ||
581 | |||
582 | static struct platform_device *davinci_evm_devices[] __initdata = { | ||
583 | &davinci_fb_device, | ||
584 | &rtc_dev, | ||
585 | }; | ||
586 | |||
587 | static struct davinci_uart_config uart_config __initdata = { | ||
588 | .enabled_uarts = (1 << 0), | ||
589 | }; | ||
590 | |||
591 | static void __init | ||
592 | davinci_evm_map_io(void) | ||
593 | { | ||
594 | dm644x_init(); | ||
595 | } | ||
596 | |||
597 | static int davinci_phy_fixup(struct phy_device *phydev) | ||
598 | { | ||
599 | unsigned int control; | ||
600 | /* CRITICAL: Fix for increasing PHY signal drive strength for | ||
601 | * TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY | ||
602 | * signal strength was low causing TX to fail randomly. The | ||
603 | * fix is to Set bit 11 (Increased MII drive strength) of PHY | ||
604 | * register 26 (Digital Config register) on this phy. */ | ||
605 | control = phy_read(phydev, 26); | ||
606 | phy_write(phydev, 26, (control | 0x800)); | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ | ||
611 | defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) | ||
612 | #define HAS_ATA 1 | ||
613 | #else | ||
614 | #define HAS_ATA 0 | ||
615 | #endif | ||
616 | |||
617 | #if defined(CONFIG_MTD_PHYSMAP) || \ | ||
618 | defined(CONFIG_MTD_PHYSMAP_MODULE) | ||
619 | #define HAS_NOR 1 | ||
620 | #else | ||
621 | #define HAS_NOR 0 | ||
622 | #endif | ||
623 | |||
624 | #if defined(CONFIG_MTD_NAND_DAVINCI) || \ | ||
625 | defined(CONFIG_MTD_NAND_DAVINCI_MODULE) | ||
626 | #define HAS_NAND 1 | ||
627 | #else | ||
628 | #define HAS_NAND 0 | ||
629 | #endif | ||
630 | |||
631 | static __init void davinci_evm_init(void) | ||
632 | { | ||
633 | struct clk *aemif_clk; | ||
634 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
635 | |||
636 | aemif_clk = clk_get(NULL, "aemif"); | ||
637 | clk_enable(aemif_clk); | ||
638 | |||
639 | if (HAS_ATA) { | ||
640 | if (HAS_NAND || HAS_NOR) | ||
641 | pr_warning("WARNING: both IDE and Flash are " | ||
642 | "enabled, but they share AEMIF pins.\n" | ||
643 | "\tDisable IDE for NAND/NOR support.\n"); | ||
644 | davinci_cfg_reg(DM644X_HPIEN_DISABLE); | ||
645 | davinci_cfg_reg(DM644X_ATAEN); | ||
646 | davinci_cfg_reg(DM644X_HDIREN); | ||
647 | platform_device_register(&ide_dev); | ||
648 | } else if (HAS_NAND || HAS_NOR) { | ||
649 | davinci_cfg_reg(DM644X_HPIEN_DISABLE); | ||
650 | davinci_cfg_reg(DM644X_ATAEN_DISABLE); | ||
651 | |||
652 | /* only one device will be jumpered and detected */ | ||
653 | if (HAS_NAND) { | ||
654 | platform_device_register(&davinci_evm_nandflash_device); | ||
655 | evm_leds[7].default_trigger = "nand-disk"; | ||
656 | if (HAS_NOR) | ||
657 | pr_warning("WARNING: both NAND and NOR flash " | ||
658 | "are enabled; disable one of them.\n"); | ||
659 | } else if (HAS_NOR) | ||
660 | platform_device_register(&davinci_evm_norflash_device); | ||
661 | } | ||
662 | |||
663 | platform_add_devices(davinci_evm_devices, | ||
664 | ARRAY_SIZE(davinci_evm_devices)); | ||
665 | evm_init_i2c(); | ||
666 | |||
667 | davinci_setup_mmc(0, &dm6446evm_mmc_config); | ||
668 | |||
669 | davinci_serial_init(&uart_config); | ||
670 | |||
671 | soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK; | ||
672 | soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY; | ||
673 | |||
674 | /* Register the fixup for PHY on DaVinci */ | ||
675 | phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, | ||
676 | davinci_phy_fixup); | ||
677 | |||
678 | } | ||
679 | |||
680 | static __init void davinci_evm_irq_init(void) | ||
681 | { | ||
682 | davinci_irq_init(); | ||
683 | } | ||
684 | |||
685 | MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") | ||
686 | /* Maintainer: MontaVista Software <source@mvista.com> */ | ||
687 | .phys_io = IO_PHYS, | ||
688 | .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, | ||
689 | .boot_params = (DAVINCI_DDR_BASE + 0x100), | ||
690 | .map_io = davinci_evm_map_io, | ||
691 | .init_irq = davinci_evm_irq_init, | ||
692 | .timer = &davinci_timer, | ||
693 | .init_machine = davinci_evm_init, | ||
694 | MACHINE_END | ||