1/* 2 * linux/arch/arm/mach-omap2/board-omap3beagle.c 3 * 4 * Copyright (C) 2008 Texas Instruments 5 * 6 * Modified from mach-omap2/board-3430sdp.c 7 * 8 * Initial code: Syed Mohammed Khasim 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/delay.h> 19#include <linux/err.h> 20#include <linux/clk.h> 21#include <linux/io.h> 22#include <linux/leds.h> 23#include <linux/pwm.h> 24#include <linux/leds_pwm.h> 25#include <linux/gpio.h> 26#include <linux/input.h> 27#include <linux/gpio_keys.h> 28#include <linux/pm_opp.h> 29#include <linux/cpu.h> 30 31#include <linux/mtd/mtd.h> 32#include <linux/mtd/partitions.h> 33#include <linux/mtd/nand.h> 34#include <linux/mmc/host.h> 35#include <linux/usb/phy.h> 36 37#include <linux/regulator/machine.h> 38#include <linux/i2c/twl.h> 39 40#include <asm/mach-types.h> 41#include <asm/mach/arch.h> 42#include <asm/mach/map.h> 43#include <asm/mach/flash.h> 44 45#include <video/omapdss.h> 46#include <video/omap-panel-data.h> 47#include <linux/platform_data/mtd-nand-omap2.h> 48 49#include "common.h" 50#include "omap_device.h" 51#include "gpmc.h" 52#include "soc.h" 53#include "mux.h" 54#include "hsmmc.h" 55#include "pm.h" 56#include "board-flash.h" 57#include "common-board-devices.h" 58 59#define NAND_CS 0 60 61static struct pwm_lookup pwm_lookup[] = { 62 /* LEDB -> PMU_STAT */ 63 PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat", 64 7812500, PWM_POLARITY_NORMAL), 65}; 66 67static struct led_pwm pwm_leds[] = { 68 { 69 .name = "beagleboard::pmu_stat", 70 .max_brightness = 127, 71 .pwm_period_ns = 7812500, 72 }, 73}; 74 75static struct led_pwm_platform_data pwm_data = { 76 .num_leds = ARRAY_SIZE(pwm_leds), 77 .leds = pwm_leds, 78}; 79 80static struct platform_device leds_pwm = { 81 .name = "leds_pwm", 82 .id = -1, 83 .dev = { 84 .platform_data = &pwm_data, 85 }, 86}; 87 88/* 89 * OMAP3 Beagle revision 90 * Run time detection of Beagle revision is done by reading GPIO. 91 * GPIO ID - 92 * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1 93 * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0 94 * C4 = GPIO173, GPIO172, GPIO171: 1 0 1 95 * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0 96 * XMC = GPIO173, GPIO172, GPIO171: 0 1 0 97 */ 98enum { 99 OMAP3BEAGLE_BOARD_UNKN = 0, 100 OMAP3BEAGLE_BOARD_AXBX, 101 OMAP3BEAGLE_BOARD_C1_3, 102 OMAP3BEAGLE_BOARD_C4, 103 OMAP3BEAGLE_BOARD_XM, 104 OMAP3BEAGLE_BOARD_XMC, 105}; 106 107static u8 omap3_beagle_version; 108 109/* 110 * Board-specific configuration 111 * Defaults to BeagleBoard-xMC 112 */ 113static struct { 114 int mmc1_gpio_wp; 115 bool usb_pwr_level; /* 0 - Active Low, 1 - Active High */ 116 int dvi_pd_gpio; 117 int usr_button_gpio; 118 int mmc_caps; 119} beagle_config = { 120 .mmc1_gpio_wp = -EINVAL, 121 .usb_pwr_level = 0, 122 .dvi_pd_gpio = -EINVAL, 123 .usr_button_gpio = 4, 124 .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, 125}; 126 127static struct gpio omap3_beagle_rev_gpios[] __initdata = { 128 { 171, GPIOF_IN, "rev_id_0" }, 129 { 172, GPIOF_IN, "rev_id_1" }, 130 { 173, GPIOF_IN, "rev_id_2" }, 131}; 132 133static void __init omap3_beagle_init_rev(void) 134{ 135 int ret; 136 u16 beagle_rev = 0; 137 138 omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP); 139 omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP); 140 omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP); 141 142 ret = gpio_request_array(omap3_beagle_rev_gpios, 143 ARRAY_SIZE(omap3_beagle_rev_gpios)); 144 if (ret < 0) { 145 printk(KERN_ERR "Unable to get revision detection GPIO pins\n"); 146 omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; 147 return; 148 } 149 150 beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1) 151 | (gpio_get_value(173) << 2); 152 153 gpio_free_array(omap3_beagle_rev_gpios, 154 ARRAY_SIZE(omap3_beagle_rev_gpios)); 155 156 switch (beagle_rev) { 157 case 7: 158 printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); 159 omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; 160 beagle_config.mmc1_gpio_wp = 29; 161 beagle_config.dvi_pd_gpio = 170; 162 beagle_config.usr_button_gpio = 7; 163 break; 164 case 6: 165 printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); 166 omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; 167 beagle_config.mmc1_gpio_wp = 23; 168 beagle_config.dvi_pd_gpio = 170; 169 beagle_config.usr_button_gpio = 7; 170 break; 171 case 5: 172 printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); 173 omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; 174 beagle_config.mmc1_gpio_wp = 23; 175 beagle_config.dvi_pd_gpio = 170; 176 beagle_config.usr_button_gpio = 7; 177 break; 178 case 0: 179 printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n"); 180 omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; 181 beagle_config.usb_pwr_level = 1; 182 beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA; 183 break; 184 case 2: 185 printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n"); 186 omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC; 187 beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA; 188 break; 189 default: 190 printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev); 191 omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; 192 } 193} 194 195static struct mtd_partition omap3beagle_nand_partitions[] = { 196 /* All the partition sizes are listed in terms of NAND block size */ 197 { 198 .name = "X-Loader", 199 .offset = 0, 200 .size = 4 * NAND_BLOCK_SIZE, 201 .mask_flags = MTD_WRITEABLE, /* force read-only */ 202 }, 203 { 204 .name = "U-Boot", 205 .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ 206 .size = 15 * NAND_BLOCK_SIZE, 207 .mask_flags = MTD_WRITEABLE, /* force read-only */ 208 }, 209 { 210 .name = "U-Boot Env", 211 .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ 212 .size = 1 * NAND_BLOCK_SIZE, 213 }, 214 { 215 .name = "Kernel", 216 .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ 217 .size = 32 * NAND_BLOCK_SIZE, 218 }, 219 { 220 .name = "File System", 221 .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ 222 .size = MTDPART_SIZ_FULL, 223 }, 224}; 225 226/* DSS */ 227 228static struct connector_dvi_platform_data beagle_dvi_connector_pdata = { 229 .name = "dvi", 230 .source = "tfp410.0", 231 .i2c_bus_num = 3, 232}; 233 234static struct platform_device beagle_dvi_connector_device = { 235 .name = "connector-dvi", 236 .id = 0, 237 .dev.platform_data = &beagle_dvi_connector_pdata, 238}; 239 240static struct encoder_tfp410_platform_data beagle_tfp410_pdata = { 241 .name = "tfp410.0", 242 .source = "dpi.0", 243 .data_lines = 24, 244 .power_down_gpio = -1, 245}; 246 247static struct platform_device beagle_tfp410_device = { 248 .name = "tfp410", 249 .id = 0, 250 .dev.platform_data = &beagle_tfp410_pdata, 251}; 252 253static struct connector_atv_platform_data beagle_tv_pdata = { 254 .name = "tv", 255 .source = "venc.0", 256 .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, 257 .invert_polarity = false, 258}; 259 260static struct platform_device beagle_tv_connector_device = { 261 .name = "connector-analog-tv", 262 .id = 0, 263 .dev.platform_data = &beagle_tv_pdata, 264}; 265 266static struct omap_dss_board_info beagle_dss_data = { 267 .default_display_name = "dvi", 268}; 269 270#include "sdram-micron-mt46h32m32lf-6.h" 271 272static struct omap2_hsmmc_info mmc[] = { 273 { 274 .mmc = 1, 275 .caps = MMC_CAP_4_BIT_DATA, 276 .gpio_wp = -EINVAL, 277 .deferred = true, 278 }, 279 {} /* Terminator */ 280}; 281 282static struct regulator_consumer_supply beagle_vmmc1_supply[] = { 283 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), 284}; 285 286static struct regulator_consumer_supply beagle_vsim_supply[] = { 287 REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), 288}; 289 290static struct gpio_led gpio_leds[]; 291 292static struct usbhs_phy_data phy_data[] = { 293 { 294 .port = 2, 295 .reset_gpio = 147, 296 .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ 297 .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ 298 }, 299}; 300 301static int beagle_twl_gpio_setup(struct device *dev, 302 unsigned gpio, unsigned ngpio) 303{ 304 int r; 305 306 mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp; 307 /* gpio + 0 is "mmc0_cd" (input/IRQ) */ 308 mmc[0].gpio_cd = gpio + 0; 309 omap_hsmmc_late_init(mmc); 310 311 /* 312 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active 313 * high / others active low) 314 * DVI reset GPIO is different between beagle revisions 315 */ 316 /* Valid for all -xM revisions */ 317 if (cpu_is_omap3630()) { 318 /* 319 * gpio + 1 on Xm controls the TFP410's enable line (active low) 320 * gpio + 2 control varies depending on the board rev as below: 321 * P7/P8 revisions(prototype): Camera EN 322 * A2+ revisions (production): LDO (DVI, serial, led blocks) 323 */ 324 r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW, 325 "nDVI_PWR_EN"); 326 if (r) 327 pr_err("%s: unable to configure nDVI_PWR_EN\n", 328 __func__); 329 330 beagle_config.dvi_pd_gpio = gpio + 2; 331 332 } else { 333 /* 334 * REVISIT: need ehci-omap hooks for external VBUS 335 * power switch and overcurrent detect 336 */ 337 if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) 338 pr_err("%s: unable to configure EHCI_nOC\n", __func__); 339 } 340 beagle_tfp410_pdata.power_down_gpio = beagle_config.dvi_pd_gpio; 341 342 platform_device_register(&beagle_tfp410_device); 343 platform_device_register(&beagle_dvi_connector_device); 344 platform_device_register(&beagle_tv_connector_device); 345 346 /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ 347 phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; 348 phy_data[0].vcc_polarity = beagle_config.usb_pwr_level; 349 350 usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); 351 return 0; 352} 353 354static struct twl4030_gpio_platform_data beagle_gpio_data = { 355 .use_leds = true, 356 .pullups = BIT(1), 357 .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) 358 | BIT(15) | BIT(16) | BIT(17), 359 .setup = beagle_twl_gpio_setup, 360}; 361 362/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ 363static struct regulator_init_data beagle_vmmc1 = { 364 .constraints = { 365 .min_uV = 1850000, 366 .max_uV = 3150000, 367 .valid_modes_mask = REGULATOR_MODE_NORMAL 368 | REGULATOR_MODE_STANDBY, 369 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE 370 | REGULATOR_CHANGE_MODE 371 | REGULATOR_CHANGE_STATUS, 372 }, 373 .num_consumer_supplies = ARRAY_SIZE(beagle_vmmc1_supply), 374 .consumer_supplies = beagle_vmmc1_supply, 375}; 376 377/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ 378static struct regulator_init_data beagle_vsim = { 379 .constraints = { 380 .min_uV = 1800000, 381 .max_uV = 3000000, 382 .valid_modes_mask = REGULATOR_MODE_NORMAL 383 | REGULATOR_MODE_STANDBY, 384 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE 385 | REGULATOR_CHANGE_MODE 386 | REGULATOR_CHANGE_STATUS, 387 }, 388 .num_consumer_supplies = ARRAY_SIZE(beagle_vsim_supply), 389 .consumer_supplies = beagle_vsim_supply, 390}; 391 392static struct twl4030_platform_data beagle_twldata = { 393 /* platform_data for children goes here */ 394 .gpio = &beagle_gpio_data, 395 .vmmc1 = &beagle_vmmc1, 396 .vsim = &beagle_vsim, 397}; 398 399static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { 400 { 401 I2C_BOARD_INFO("eeprom", 0x50), 402 }, 403}; 404 405static int __init omap3_beagle_i2c_init(void) 406{ 407 omap3_pmic_get_config(&beagle_twldata, 408 TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC | 409 TWL_COMMON_PDATA_AUDIO, 410 TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); 411 412 beagle_twldata.vpll2->constraints.name = "VDVI"; 413 414 omap3_pmic_init("twl4030", &beagle_twldata); 415 /* Bus 3 is attached to the DVI port where devices like the pico DLP 416 * projector don't work reliably with 400kHz */ 417 omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom)); 418 return 0; 419} 420 421static struct gpio_led gpio_leds[] = { 422 { 423 .name = "beagleboard::usr0", 424 .default_trigger = "heartbeat", 425 .gpio = 150, 426 }, 427 { 428 .name = "beagleboard::usr1", 429 .default_trigger = "mmc0", 430 .gpio = 149, 431 }, 432}; 433 434static struct gpio_led_platform_data gpio_led_info = { 435 .leds = gpio_leds, 436 .num_leds = ARRAY_SIZE(gpio_leds), 437}; 438 439static struct platform_device leds_gpio = { 440 .name = "leds-gpio", 441 .id = -1, 442 .dev = { 443 .platform_data = &gpio_led_info, 444 }, 445}; 446 447static struct gpio_keys_button gpio_buttons[] = { 448 { 449 .code = BTN_EXTRA, 450 /* Dynamically assigned depending on board */ 451 .gpio = -EINVAL, 452 .desc = "user", 453 .wakeup = 1, 454 }, 455}; 456 457static struct gpio_keys_platform_data gpio_key_info = { 458 .buttons = gpio_buttons, 459 .nbuttons = ARRAY_SIZE(gpio_buttons), 460}; 461 462static struct platform_device keys_gpio = { 463 .name = "gpio-keys", 464 .id = -1, 465 .dev = { 466 .platform_data = &gpio_key_info, 467 }, 468}; 469 470static struct platform_device madc_hwmon = { 471 .name = "twl4030_madc_hwmon", 472 .id = -1, 473}; 474 475static struct platform_device *omap3_beagle_devices[] __initdata = { 476 &leds_gpio, 477 &keys_gpio, 478 &madc_hwmon, 479 &leds_pwm, 480}; 481 482static struct usbhs_omap_platform_data usbhs_bdata __initdata = { 483 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 484}; 485 486#ifdef CONFIG_OMAP_MUX 487static struct omap_board_mux board_mux[] __initdata = { 488 { .reg_offset = OMAP_MUX_TERMINATOR }, 489}; 490#endif 491 492static int __init beagle_opp_init(void) 493{ 494 int r = 0; 495 496 if (!machine_is_omap3_beagle()) 497 return 0; 498 499 /* Initialize the omap3 opp table if not already created. */ 500 r = omap3_opp_init(); 501 if (r < 0 && (r != -EEXIST)) { 502 pr_err("%s: opp default init failed\n", __func__); 503 return r; 504 } 505 506 /* Custom OPP enabled for all xM versions */ 507 if (cpu_is_omap3630()) { 508 struct device *mpu_dev, *iva_dev; 509 510 mpu_dev = get_cpu_device(0); 511 iva_dev = omap_device_get_by_hwmod_name("iva"); 512 513 if (!mpu_dev || IS_ERR(iva_dev)) { 514 pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", 515 __func__, mpu_dev, iva_dev); 516 return -ENODEV; 517 } 518 /* Enable MPU 1GHz and lower opps */ 519 r = dev_pm_opp_enable(mpu_dev, 800000000); 520 /* TODO: MPU 1GHz needs SR and ABB */ 521 522 /* Enable IVA 800MHz and lower opps */ 523 r |= dev_pm_opp_enable(iva_dev, 660000000); 524 /* TODO: DSP 800MHz needs SR and ABB */ 525 if (r) { 526 pr_err("%s: failed to enable higher opp %d\n", 527 __func__, r); 528 /* 529 * Cleanup - disable the higher freqs - we dont care 530 * about the results 531 */ 532 dev_pm_opp_disable(mpu_dev, 800000000); 533 dev_pm_opp_disable(iva_dev, 660000000); 534 } 535 } 536 return 0; 537} 538omap_device_initcall(beagle_opp_init); 539 540static void __init omap3_beagle_init(void) 541{ 542 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); 543 omap3_beagle_init_rev(); 544 545 if (gpio_is_valid(beagle_config.mmc1_gpio_wp)) 546 omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); 547 mmc[0].caps = beagle_config.mmc_caps; 548 omap_hsmmc_init(mmc); 549 550 omap3_beagle_i2c_init(); 551 552 gpio_buttons[0].gpio = beagle_config.usr_button_gpio; 553 554 platform_add_devices(omap3_beagle_devices, 555 ARRAY_SIZE(omap3_beagle_devices)); 556 if (gpio_is_valid(beagle_config.dvi_pd_gpio)) 557 omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); 558 omap_display_init(&beagle_dss_data); 559 560 omap_serial_init(); 561 omap_sdrc_init(mt46h32m32lf6_sdrc_params, 562 mt46h32m32lf6_sdrc_params); 563 564 usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); 565 usb_musb_init(NULL); 566 567 usbhs_init(&usbhs_bdata); 568 569 board_nand_init(omap3beagle_nand_partitions, 570 ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS, 571 NAND_BUSWIDTH_16, NULL); 572 omap_twl4030_audio_init("omap3beagle", NULL); 573 574 /* Ensure msecure is mux'd to be able to set the RTC. */ 575 omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH); 576 577 /* Ensure SDRC pins are mux'd for self-refresh */ 578 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 579 omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); 580 581 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); 582} 583 584MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") 585 /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ 586 .atag_offset = 0x100, 587 .reserve = omap_reserve, 588 .map_io = omap3_map_io, 589 .init_early = omap3_init_early, 590 .init_irq = omap3_init_irq, 591 .init_machine = omap3_beagle_init, 592 .init_late = omap3_init_late, 593 .init_time = omap3_secure_sync32k_timer_init, 594 .restart = omap3xxx_restart, 595MACHINE_END 596