1 /* 2 * TI DaVinci DM365 EVM board support 3 * 4 * Copyright (C) 2009 Texas Instruments Incorporated 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/init.h> 18 #include <linux/dma-mapping.h> 19 #include <linux/i2c.h> 20 #include <linux/io.h> 21 #include <linux/clk.h> 22 #include <linux/i2c/at24.h> 23 #include <linux/leds.h> 24 #include <linux/mtd/mtd.h> 25 #include <linux/mtd/partitions.h> 26 #include <linux/mtd/nand.h> 27 #include <asm/setup.h> 28 #include <asm/mach-types.h> 29 #include <asm/mach/arch.h> 30 #include <asm/mach/map.h> 31 #include <mach/mux.h> 32 #include <mach/hardware.h> 33 #include <mach/dm365.h> 34 #include <mach/psc.h> 35 #include <mach/common.h> 36 #include <mach/i2c.h> 37 #include <mach/serial.h> 38 #include <mach/mmc.h> 39 #include <mach/nand.h> 40 41 42 static inline int have_imager(void) 43 { 44 /* REVISIT when it's supported, trigger via Kconfig */ 45 return 0; 46 } 47 48 static inline int have_tvp7002(void) 49 { 50 /* REVISIT when it's supported, trigger via Kconfig */ 51 return 0; 52 } 53 54 55 #define DM365_ASYNC_EMIF_CONTROL_BASE 0x01d10000 56 #define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 57 #define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 58 59 #define DM365_EVM_PHY_MASK (0x2) 60 #define DM365_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ 61 62 /* 63 * A MAX-II CPLD is used for various board control functions. 64 */ 65 #define CPLD_OFFSET(a13a8,a2a1) (((a13a8) << 10) + ((a2a1) << 3)) 66 67 #define CPLD_VERSION CPLD_OFFSET(0,0) /* r/o */ 68 #define CPLD_TEST CPLD_OFFSET(0,1) 69 #define CPLD_LEDS CPLD_OFFSET(0,2) 70 #define CPLD_MUX CPLD_OFFSET(0,3) 71 #define CPLD_SWITCH CPLD_OFFSET(1,0) /* r/o */ 72 #define CPLD_POWER CPLD_OFFSET(1,1) 73 #define CPLD_VIDEO CPLD_OFFSET(1,2) 74 #define CPLD_CARDSTAT CPLD_OFFSET(1,3) /* r/o */ 75 76 #define CPLD_DILC_OUT CPLD_OFFSET(2,0) 77 #define CPLD_DILC_IN CPLD_OFFSET(2,1) /* r/o */ 78 79 #define CPLD_IMG_DIR0 CPLD_OFFSET(2,2) 80 #define CPLD_IMG_MUX0 CPLD_OFFSET(2,3) 81 #define CPLD_IMG_MUX1 CPLD_OFFSET(3,0) 82 #define CPLD_IMG_DIR1 CPLD_OFFSET(3,1) 83 #define CPLD_IMG_MUX2 CPLD_OFFSET(3,2) 84 #define CPLD_IMG_MUX3 CPLD_OFFSET(3,3) 85 #define CPLD_IMG_DIR2 CPLD_OFFSET(4,0) 86 #define CPLD_IMG_MUX4 CPLD_OFFSET(4,1) 87 #define CPLD_IMG_MUX5 CPLD_OFFSET(4,2) 88 89 #define CPLD_RESETS CPLD_OFFSET(4,3) 90 91 #define CPLD_CCD_DIR1 CPLD_OFFSET(0x3e,0) 92 #define CPLD_CCD_IO1 CPLD_OFFSET(0x3e,1) 93 #define CPLD_CCD_DIR2 CPLD_OFFSET(0x3e,2) 94 #define CPLD_CCD_IO2 CPLD_OFFSET(0x3e,3) 95 #define CPLD_CCD_DIR3 CPLD_OFFSET(0x3f,0) 96 #define CPLD_CCD_IO3 CPLD_OFFSET(0x3f,1) 97 98 static void __iomem *cpld; 99 100 101 /* NOTE: this is geared for the standard config, with a socketed 102 * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you 103 * swap chips with a different block size, partitioning will 104 * need to be changed. This NAND chip MT29F16G08FAA is the default 105 * NAND shipped with the Spectrum Digital DM365 EVM 106 */ 107 #define NAND_BLOCK_SIZE SZ_128K 108 109 static struct mtd_partition davinci_nand_partitions[] = { 110 { 111 /* UBL (a few copies) plus U-Boot */ 112 .name = "bootloader", 113 .offset = 0, 114 .size = 28 * NAND_BLOCK_SIZE, 115 .mask_flags = MTD_WRITEABLE, /* force read-only */ 116 }, { 117 /* U-Boot environment */ 118 .name = "params", 119 .offset = MTDPART_OFS_APPEND, 120 .size = 2 * NAND_BLOCK_SIZE, 121 .mask_flags = 0, 122 }, { 123 .name = "kernel", 124 .offset = MTDPART_OFS_APPEND, 125 .size = SZ_4M, 126 .mask_flags = 0, 127 }, { 128 .name = "filesystem1", 129 .offset = MTDPART_OFS_APPEND, 130 .size = SZ_512M, 131 .mask_flags = 0, 132 }, { 133 .name = "filesystem2", 134 .offset = MTDPART_OFS_APPEND, 135 .size = MTDPART_SIZ_FULL, 136 .mask_flags = 0, 137 } 138 /* two blocks with bad block table (and mirror) at the end */ 139 }; 140 141 static struct davinci_nand_pdata davinci_nand_data = { 142 .mask_chipsel = BIT(14), 143 .parts = davinci_nand_partitions, 144 .nr_parts = ARRAY_SIZE(davinci_nand_partitions), 145 .ecc_mode = NAND_ECC_HW, 146 .options = NAND_USE_FLASH_BBT, 147 }; 148 149 static struct resource davinci_nand_resources[] = { 150 { 151 .start = DM365_ASYNC_EMIF_DATA_CE0_BASE, 152 .end = DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, 153 .flags = IORESOURCE_MEM, 154 }, { 155 .start = DM365_ASYNC_EMIF_CONTROL_BASE, 156 .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, 157 .flags = IORESOURCE_MEM, 158 }, 159 }; 160 161 static struct platform_device davinci_nand_device = { 162 .name = "davinci_nand", 163 .id = 0, 164 .num_resources = ARRAY_SIZE(davinci_nand_resources), 165 .resource = davinci_nand_resources, 166 .dev = { 167 .platform_data = &davinci_nand_data, 168 }, 169 }; 170 171 static struct at24_platform_data eeprom_info = { 172 .byte_len = (256*1024) / 8, 173 .page_size = 64, 174 .flags = AT24_FLAG_ADDR16, 175 .setup = davinci_get_mac_addr, 176 .context = (void *)0x7f00, 177 }; 178 179 static struct i2c_board_info i2c_info[] = { 180 { 181 I2C_BOARD_INFO("24c256", 0x50), 182 .platform_data = &eeprom_info, 183 }, 184 }; 185 186 static struct davinci_i2c_platform_data i2c_pdata = { 187 .bus_freq = 400 /* kHz */, 188 .bus_delay = 0 /* usec */, 189 }; 190 191 static int cpld_mmc_get_cd(int module) 192 { 193 if (!cpld) 194 return -ENXIO; 195 196 /* low == card present */ 197 return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0)); 198 } 199 200 static int cpld_mmc_get_ro(int module) 201 { 202 if (!cpld) 203 return -ENXIO; 204 205 /* high == card's write protect switch active */ 206 return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1)); 207 } 208 209 static struct davinci_mmc_config dm365evm_mmc_config = { 210 .get_cd = cpld_mmc_get_cd, 211 .get_ro = cpld_mmc_get_ro, 212 .wires = 4, 213 .max_freq = 50000000, 214 .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, 215 .version = MMC_CTLR_VERSION_2, 216 }; 217 218 static void dm365evm_emac_configure(void) 219 { 220 /* 221 * EMAC pins are multiplexed with GPIO and UART 222 * Further details are available at the DM365 ARM 223 * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127 224 */ 225 davinci_cfg_reg(DM365_EMAC_TX_EN); 226 davinci_cfg_reg(DM365_EMAC_TX_CLK); 227 davinci_cfg_reg(DM365_EMAC_COL); 228 davinci_cfg_reg(DM365_EMAC_TXD3); 229 davinci_cfg_reg(DM365_EMAC_TXD2); 230 davinci_cfg_reg(DM365_EMAC_TXD1); 231 davinci_cfg_reg(DM365_EMAC_TXD0); 232 davinci_cfg_reg(DM365_EMAC_RXD3); 233 davinci_cfg_reg(DM365_EMAC_RXD2); 234 davinci_cfg_reg(DM365_EMAC_RXD1); 235 davinci_cfg_reg(DM365_EMAC_RXD0); 236 davinci_cfg_reg(DM365_EMAC_RX_CLK); 237 davinci_cfg_reg(DM365_EMAC_RX_DV); 238 davinci_cfg_reg(DM365_EMAC_RX_ER); 239 davinci_cfg_reg(DM365_EMAC_CRS); 240 davinci_cfg_reg(DM365_EMAC_MDIO); 241 davinci_cfg_reg(DM365_EMAC_MDCLK); 242 243 /* 244 * EMAC interrupts are multiplexed with GPIO interrupts 245 * Details are available at the DM365 ARM 246 * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134 247 */ 248 davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH); 249 davinci_cfg_reg(DM365_INT_EMAC_RXPULSE); 250 davinci_cfg_reg(DM365_INT_EMAC_TXPULSE); 251 davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE); 252 } 253 254 static void dm365evm_mmc_configure(void) 255 { 256 /* 257 * MMC/SD pins are multiplexed with GPIO and EMIF 258 * Further details are available at the DM365 ARM 259 * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131 260 */ 261 davinci_cfg_reg(DM365_SD1_CLK); 262 davinci_cfg_reg(DM365_SD1_CMD); 263 davinci_cfg_reg(DM365_SD1_DATA3); 264 davinci_cfg_reg(DM365_SD1_DATA2); 265 davinci_cfg_reg(DM365_SD1_DATA1); 266 davinci_cfg_reg(DM365_SD1_DATA0); 267 } 268 269 static void __init evm_init_i2c(void) 270 { 271 davinci_init_i2c(&i2c_pdata); 272 i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); 273 } 274 275 static struct platform_device *dm365_evm_nand_devices[] __initdata = { 276 &davinci_nand_device, 277 }; 278 279 static inline int have_leds(void) 280 { 281 #ifdef CONFIG_LEDS_CLASS 282 return 1; 283 #else 284 return 0; 285 #endif 286 } 287 288 struct cpld_led { 289 struct led_classdev cdev; 290 u8 mask; 291 }; 292 293 static const struct { 294 const char *name; 295 const char *trigger; 296 } cpld_leds[] = { 297 { "dm365evm::ds2", }, 298 { "dm365evm::ds3", }, 299 { "dm365evm::ds4", }, 300 { "dm365evm::ds5", }, 301 { "dm365evm::ds6", "nand-disk", }, 302 { "dm365evm::ds7", "mmc1", }, 303 { "dm365evm::ds8", "mmc0", }, 304 { "dm365evm::ds9", "heartbeat", }, 305 }; 306 307 static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b) 308 { 309 struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); 310 u8 reg = __raw_readb(cpld + CPLD_LEDS); 311 312 if (b != LED_OFF) 313 reg &= ~led->mask; 314 else 315 reg |= led->mask; 316 __raw_writeb(reg, cpld + CPLD_LEDS); 317 } 318 319 static enum led_brightness cpld_led_get(struct led_classdev *cdev) 320 { 321 struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); 322 u8 reg = __raw_readb(cpld + CPLD_LEDS); 323 324 return (reg & led->mask) ? LED_OFF : LED_FULL; 325 } 326 327 static int __init cpld_leds_init(void) 328 { 329 int i; 330 331 if (!have_leds() || !cpld) 332 return 0; 333 334 /* setup LEDs */ 335 __raw_writeb(0xff, cpld + CPLD_LEDS); 336 for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) { 337 struct cpld_led *led; 338 339 led = kzalloc(sizeof(*led), GFP_KERNEL); 340 if (!led) 341 break; 342 343 led->cdev.name = cpld_leds[i].name; 344 led->cdev.brightness_set = cpld_led_set; 345 led->cdev.brightness_get = cpld_led_get; 346 led->cdev.default_trigger = cpld_leds[i].trigger; 347 led->mask = BIT(i); 348 349 if (led_classdev_register(NULL, &led->cdev) < 0) { 350 kfree(led); 351 break; 352 } 353 } 354 355 return 0; 356 } 357 /* run after subsys_initcall() for LEDs */ 358 fs_initcall(cpld_leds_init); 359 360 361 static void __init evm_init_cpld(void) 362 { 363 u8 mux, resets; 364 const char *label; 365 struct clk *aemif_clk; 366 367 /* Make sure we can configure the CPLD through CS1. Then 368 * leave it on for later access to MMC and LED registers. 369 */ 370 aemif_clk = clk_get(NULL, "aemif"); 371 if (IS_ERR(aemif_clk)) 372 return; 373 clk_enable(aemif_clk); 374 375 if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE, 376 "cpld") == NULL) 377 goto fail; 378 cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE); 379 if (!cpld) { 380 release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, 381 SECTION_SIZE); 382 fail: 383 pr_err("ERROR: can't map CPLD\n"); 384 clk_disable(aemif_clk); 385 return; 386 } 387 388 /* External muxing for some signals */ 389 mux = 0; 390 391 /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read). 392 * NOTE: SW4 bus width setting must match! 393 */ 394 if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) { 395 /* external keypad mux */ 396 mux |= BIT(7); 397 398 platform_add_devices(dm365_evm_nand_devices, 399 ARRAY_SIZE(dm365_evm_nand_devices)); 400 } else { 401 /* no OneNAND support yet */ 402 } 403 404 /* Leave external chips in reset when unused. */ 405 resets = BIT(3) | BIT(2) | BIT(1) | BIT(0); 406 407 /* Static video input config with SN74CBT16214 1-of-3 mux: 408 * - port b1 == tvp7002 (mux lowbits == 1 or 6) 409 * - port b2 == imager (mux lowbits == 2 or 7) 410 * - port b3 == tvp5146 (mux lowbits == 5) 411 * 412 * Runtime switching could work too, with limitations. 413 */ 414 if (have_imager()) { 415 label = "HD imager"; 416 mux |= 2; 417 418 /* externally mux MMC1/ENET/AIC33 to imager */ 419 mux |= BIT(6) | BIT(5) | BIT(3); 420 } else { 421 struct davinci_soc_info *soc_info = &davinci_soc_info; 422 423 /* we can use MMC1 ... */ 424 dm365evm_mmc_configure(); 425 davinci_setup_mmc(1, &dm365evm_mmc_config); 426 427 /* ... and ENET ... */ 428 dm365evm_emac_configure(); 429 soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK; 430 soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY; 431 resets &= ~BIT(3); 432 433 /* ... and AIC33 */ 434 resets &= ~BIT(1); 435 436 if (have_tvp7002()) { 437 mux |= 1; 438 resets &= ~BIT(2); 439 label = "tvp7002 HD"; 440 } else { 441 /* default to tvp5146 */ 442 mux |= 5; 443 resets &= ~BIT(0); 444 label = "tvp5146 SD"; 445 } 446 } 447 __raw_writeb(mux, cpld + CPLD_MUX); 448 __raw_writeb(resets, cpld + CPLD_RESETS); 449 pr_info("EVM: %s video input\n", label); 450 451 /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */ 452 } 453 454 static struct davinci_uart_config uart_config __initdata = { 455 .enabled_uarts = (1 << 0), 456 }; 457 458 static void __init dm365_evm_map_io(void) 459 { 460 dm365_init(); 461 } 462 463 static __init void dm365_evm_init(void) 464 { 465 evm_init_i2c(); 466 davinci_serial_init(&uart_config); 467 468 dm365evm_emac_configure(); 469 dm365evm_mmc_configure(); 470 471 davinci_setup_mmc(0, &dm365evm_mmc_config); 472 473 /* maybe setup mmc1/etc ... _after_ mmc0 */ 474 evm_init_cpld(); 475 } 476 477 static __init void dm365_evm_irq_init(void) 478 { 479 davinci_irq_init(); 480 } 481 482 MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") 483 .phys_io = IO_PHYS, 484 .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, 485 .boot_params = (0x80000100), 486 .map_io = dm365_evm_map_io, 487 .init_irq = dm365_evm_irq_init, 488 .timer = &davinci_timer, 489 .init_machine = dm365_evm_init, 490 MACHINE_END 491 492
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.