linux/arch/arm/mach-omap2/board-omap3beagle.c
<<
>>
Prefs
   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/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#include <linux/usb/nop-usb-xceiv.h>
  37
  38#include <linux/regulator/machine.h>
  39#include <linux/i2c/twl.h>
  40
  41#include <asm/mach-types.h>
  42#include <asm/mach/arch.h>
  43#include <asm/mach/map.h>
  44#include <asm/mach/flash.h>
  45
  46#include <video/omapdss.h>
  47#include <video/omap-panel-data.h>
  48#include <linux/platform_data/mtd-nand-omap2.h>
  49
  50#include "common.h"
  51#include "omap_device.h"
  52#include "gpmc.h"
  53#include "soc.h"
  54#include "mux.h"
  55#include "hsmmc.h"
  56#include "pm.h"
  57#include "board-flash.h"
  58#include "common-board-devices.h"
  59
  60#define NAND_CS 0
  61
  62static struct pwm_lookup pwm_lookup[] = {
  63        /* LEDB -> PMU_STAT */
  64        PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat"),
  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 tfp410_platform_data dvi_panel = {
 229        .i2c_bus_num = 3,
 230        .power_down_gpio = -1,
 231};
 232
 233static struct omap_dss_device beagle_dvi_device = {
 234        .type = OMAP_DISPLAY_TYPE_DPI,
 235        .name = "dvi",
 236        .driver_name = "tfp410",
 237        .data = &dvi_panel,
 238        .phy.dpi.data_lines = 24,
 239};
 240
 241static struct omap_dss_device beagle_tv_device = {
 242        .name = "tv",
 243        .driver_name = "venc",
 244        .type = OMAP_DISPLAY_TYPE_VENC,
 245        .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
 246};
 247
 248static struct omap_dss_device *beagle_dss_devices[] = {
 249        &beagle_dvi_device,
 250        &beagle_tv_device,
 251};
 252
 253static struct omap_dss_board_info beagle_dss_data = {
 254        .num_devices = ARRAY_SIZE(beagle_dss_devices),
 255        .devices = beagle_dss_devices,
 256        .default_device = &beagle_dvi_device,
 257};
 258
 259#include "sdram-micron-mt46h32m32lf-6.h"
 260
 261static struct omap2_hsmmc_info mmc[] = {
 262        {
 263                .mmc            = 1,
 264                .caps           = MMC_CAP_4_BIT_DATA,
 265                .gpio_wp        = -EINVAL,
 266                .deferred       = true,
 267        },
 268        {}      /* Terminator */
 269};
 270
 271static struct regulator_consumer_supply beagle_vmmc1_supply[] = {
 272        REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
 273};
 274
 275static struct regulator_consumer_supply beagle_vsim_supply[] = {
 276        REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
 277};
 278
 279static struct gpio_led gpio_leds[];
 280
 281/* PHY's VCC regulator might be added later, so flag that we need it */
 282static struct nop_usb_xceiv_platform_data hsusb2_phy_data = {
 283        .needs_vcc = true,
 284};
 285
 286static struct usbhs_phy_data phy_data[] = {
 287        {
 288                .port = 2,
 289                .reset_gpio = 147,
 290                .vcc_gpio = -1,         /* updated in beagle_twl_gpio_setup */
 291                .vcc_polarity = 1,      /* updated in beagle_twl_gpio_setup */
 292                .platform_data = &hsusb2_phy_data,
 293        },
 294};
 295
 296static int beagle_twl_gpio_setup(struct device *dev,
 297                unsigned gpio, unsigned ngpio)
 298{
 299        int r;
 300
 301        mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
 302        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
 303        mmc[0].gpio_cd = gpio + 0;
 304        omap_hsmmc_late_init(mmc);
 305
 306        /*
 307         * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
 308         * high / others active low)
 309         * DVI reset GPIO is different between beagle revisions
 310         */
 311        /* Valid for all -xM revisions */
 312        if (cpu_is_omap3630()) {
 313                /*
 314                 * gpio + 1 on Xm controls the TFP410's enable line (active low)
 315                 * gpio + 2 control varies depending on the board rev as below:
 316                 * P7/P8 revisions(prototype): Camera EN
 317                 * A2+ revisions (production): LDO (DVI, serial, led blocks)
 318                 */
 319                r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW,
 320                                     "nDVI_PWR_EN");
 321                if (r)
 322                        pr_err("%s: unable to configure nDVI_PWR_EN\n",
 323                                __func__);
 324
 325                beagle_config.dvi_pd_gpio = gpio + 2;
 326
 327        } else {
 328                /*
 329                 * REVISIT: need ehci-omap hooks for external VBUS
 330                 * power switch and overcurrent detect
 331                 */
 332                if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
 333                        pr_err("%s: unable to configure EHCI_nOC\n", __func__);
 334        }
 335        dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
 336
 337        /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */
 338        phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX;
 339        phy_data[0].vcc_polarity = beagle_config.usb_pwr_level;
 340
 341        usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
 342        return 0;
 343}
 344
 345static struct twl4030_gpio_platform_data beagle_gpio_data = {
 346        .use_leds       = true,
 347        .pullups        = BIT(1),
 348        .pulldowns      = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
 349                                | BIT(15) | BIT(16) | BIT(17),
 350        .setup          = beagle_twl_gpio_setup,
 351};
 352
 353/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
 354static struct regulator_init_data beagle_vmmc1 = {
 355        .constraints = {
 356                .min_uV                 = 1850000,
 357                .max_uV                 = 3150000,
 358                .valid_modes_mask       = REGULATOR_MODE_NORMAL
 359                                        | REGULATOR_MODE_STANDBY,
 360                .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
 361                                        | REGULATOR_CHANGE_MODE
 362                                        | REGULATOR_CHANGE_STATUS,
 363        },
 364        .num_consumer_supplies  = ARRAY_SIZE(beagle_vmmc1_supply),
 365        .consumer_supplies      = beagle_vmmc1_supply,
 366};
 367
 368/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
 369static struct regulator_init_data beagle_vsim = {
 370        .constraints = {
 371                .min_uV                 = 1800000,
 372                .max_uV                 = 3000000,
 373                .valid_modes_mask       = REGULATOR_MODE_NORMAL
 374                                        | REGULATOR_MODE_STANDBY,
 375                .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
 376                                        | REGULATOR_CHANGE_MODE
 377                                        | REGULATOR_CHANGE_STATUS,
 378        },
 379        .num_consumer_supplies  = ARRAY_SIZE(beagle_vsim_supply),
 380        .consumer_supplies      = beagle_vsim_supply,
 381};
 382
 383static struct twl4030_platform_data beagle_twldata = {
 384        /* platform_data for children goes here */
 385        .gpio           = &beagle_gpio_data,
 386        .vmmc1          = &beagle_vmmc1,
 387        .vsim           = &beagle_vsim,
 388};
 389
 390static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
 391       {
 392               I2C_BOARD_INFO("eeprom", 0x50),
 393       },
 394};
 395
 396static int __init omap3_beagle_i2c_init(void)
 397{
 398        omap3_pmic_get_config(&beagle_twldata,
 399                        TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
 400                        TWL_COMMON_PDATA_AUDIO,
 401                        TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
 402
 403        beagle_twldata.vpll2->constraints.name = "VDVI";
 404
 405        omap3_pmic_init("twl4030", &beagle_twldata);
 406        /* Bus 3 is attached to the DVI port where devices like the pico DLP
 407         * projector don't work reliably with 400kHz */
 408        omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
 409        return 0;
 410}
 411
 412static struct gpio_led gpio_leds[] = {
 413        {
 414                .name                   = "beagleboard::usr0",
 415                .default_trigger        = "heartbeat",
 416                .gpio                   = 150,
 417        },
 418        {
 419                .name                   = "beagleboard::usr1",
 420                .default_trigger        = "mmc0",
 421                .gpio                   = 149,
 422        },
 423};
 424
 425static struct gpio_led_platform_data gpio_led_info = {
 426        .leds           = gpio_leds,
 427        .num_leds       = ARRAY_SIZE(gpio_leds),
 428};
 429
 430static struct platform_device leds_gpio = {
 431        .name   = "leds-gpio",
 432        .id     = -1,
 433        .dev    = {
 434                .platform_data  = &gpio_led_info,
 435        },
 436};
 437
 438static struct gpio_keys_button gpio_buttons[] = {
 439        {
 440                .code                   = BTN_EXTRA,
 441                /* Dynamically assigned depending on board */
 442                .gpio                   = -EINVAL,
 443                .desc                   = "user",
 444                .wakeup                 = 1,
 445        },
 446};
 447
 448static struct gpio_keys_platform_data gpio_key_info = {
 449        .buttons        = gpio_buttons,
 450        .nbuttons       = ARRAY_SIZE(gpio_buttons),
 451};
 452
 453static struct platform_device keys_gpio = {
 454        .name   = "gpio-keys",
 455        .id     = -1,
 456        .dev    = {
 457                .platform_data  = &gpio_key_info,
 458        },
 459};
 460
 461static struct platform_device madc_hwmon = {
 462        .name   = "twl4030_madc_hwmon",
 463        .id     = -1,
 464};
 465
 466static struct platform_device *omap3_beagle_devices[] __initdata = {
 467        &leds_gpio,
 468        &keys_gpio,
 469        &madc_hwmon,
 470        &leds_pwm,
 471};
 472
 473static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
 474        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
 475};
 476
 477#ifdef CONFIG_OMAP_MUX
 478static struct omap_board_mux board_mux[] __initdata = {
 479        { .reg_offset = OMAP_MUX_TERMINATOR },
 480};
 481#endif
 482
 483static int __init beagle_opp_init(void)
 484{
 485        int r = 0;
 486
 487        if (!machine_is_omap3_beagle())
 488                return 0;
 489
 490        /* Initialize the omap3 opp table if not already created. */
 491        r = omap3_opp_init();
 492        if (r < 0 && (r != -EEXIST)) {
 493                pr_err("%s: opp default init failed\n", __func__);
 494                return r;
 495        }
 496
 497        /* Custom OPP enabled for all xM versions */
 498        if (cpu_is_omap3630()) {
 499                struct device *mpu_dev, *iva_dev;
 500
 501                mpu_dev = get_cpu_device(0);
 502                iva_dev = omap_device_get_by_hwmod_name("iva");
 503
 504                if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
 505                        pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
 506                                __func__, mpu_dev, iva_dev);
 507                        return -ENODEV;
 508                }
 509                /* Enable MPU 1GHz and lower opps */
 510                r = opp_enable(mpu_dev, 800000000);
 511                /* TODO: MPU 1GHz needs SR and ABB */
 512
 513                /* Enable IVA 800MHz and lower opps */
 514                r |= opp_enable(iva_dev, 660000000);
 515                /* TODO: DSP 800MHz needs SR and ABB */
 516                if (r) {
 517                        pr_err("%s: failed to enable higher opp %d\n",
 518                                __func__, r);
 519                        /*
 520                         * Cleanup - disable the higher freqs - we dont care
 521                         * about the results
 522                         */
 523                        opp_disable(mpu_dev, 800000000);
 524                        opp_disable(iva_dev, 660000000);
 525                }
 526        }
 527        return 0;
 528}
 529omap_device_initcall(beagle_opp_init);
 530
 531static void __init omap3_beagle_init(void)
 532{
 533        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 534        omap3_beagle_init_rev();
 535
 536        if (gpio_is_valid(beagle_config.mmc1_gpio_wp))
 537                omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 538        mmc[0].caps = beagle_config.mmc_caps;
 539        omap_hsmmc_init(mmc);
 540
 541        omap3_beagle_i2c_init();
 542
 543        gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
 544
 545        platform_add_devices(omap3_beagle_devices,
 546                        ARRAY_SIZE(omap3_beagle_devices));
 547        if (gpio_is_valid(beagle_config.dvi_pd_gpio))
 548                omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT);
 549        omap_display_init(&beagle_dss_data);
 550        omap_serial_init();
 551        omap_sdrc_init(mt46h32m32lf6_sdrc_params,
 552                                  mt46h32m32lf6_sdrc_params);
 553
 554        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
 555        usb_musb_init(NULL);
 556
 557        usbhs_init(&usbhs_bdata);
 558
 559        board_nand_init(omap3beagle_nand_partitions,
 560                        ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
 561                        NAND_BUSWIDTH_16, NULL);
 562        omap_twl4030_audio_init("omap3beagle", NULL);
 563
 564        /* Ensure msecure is mux'd to be able to set the RTC. */
 565        omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
 566
 567        /* Ensure SDRC pins are mux'd for self-refresh */
 568        omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
 569        omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 570
 571        pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
 572}
 573
 574MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
 575        /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
 576        .atag_offset    = 0x100,
 577        .reserve        = omap_reserve,
 578        .map_io         = omap3_map_io,
 579        .init_early     = omap3_init_early,
 580        .init_irq       = omap3_init_irq,
 581        .handle_irq     = omap3_intc_handle_irq,
 582        .init_machine   = omap3_beagle_init,
 583        .init_late      = omap3_init_late,
 584        .init_time      = omap3_secure_sync32k_timer_init,
 585        .restart        = omap3xxx_restart,
 586MACHINE_END
 587