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