linux/arch/arm/mach-davinci/board-omapl138-hawk.c
<<
>>
Prefs
   1/*
   2 * Hawkboard.org based on TI's OMAP-L138 Platform
   3 *
   4 * Initial code: Syed Mohammed Khasim
   5 *
   6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
   7 *
   8 * This file is licensed under the terms of the GNU General Public License
   9 * version 2. This program is licensed "as is" without any warranty of
  10 * any kind, whether express or implied.
  11 */
  12#include <linux/kernel.h>
  13#include <linux/init.h>
  14#include <linux/console.h>
  15#include <linux/interrupt.h>
  16#include <linux/gpio.h>
  17#include <linux/gpio/machine.h>
  18#include <linux/platform_data/gpio-davinci.h>
  19#include <linux/regulator/machine.h>
  20
  21#include <asm/mach-types.h>
  22#include <asm/mach/arch.h>
  23
  24#include <mach/common.h>
  25#include "cp_intc.h"
  26#include <mach/da8xx.h>
  27#include <mach/mux.h>
  28
  29#define HAWKBOARD_PHY_ID                "davinci_mdio-0:07"
  30
  31#define DA850_USB1_VBUS_PIN             GPIO_TO_PIN(2, 4)
  32#define DA850_USB1_OC_PIN               GPIO_TO_PIN(6, 13)
  33
  34static short omapl138_hawk_mii_pins[] __initdata = {
  35        DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
  36        DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
  37        DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
  38        DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
  39        DA850_MDIO_D,
  40        -1
  41};
  42
  43static __init void omapl138_hawk_config_emac(void)
  44{
  45        void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
  46        int ret;
  47        u32 val;
  48        struct davinci_soc_info *soc_info = &davinci_soc_info;
  49
  50        val = __raw_readl(cfgchip3);
  51        val &= ~BIT(8);
  52        ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
  53        if (ret) {
  54                pr_warn("%s: CPGMAC/MII mux setup failed: %d\n", __func__, ret);
  55                return;
  56        }
  57
  58        /* configure the CFGCHIP3 register for MII */
  59        __raw_writel(val, cfgchip3);
  60        pr_info("EMAC: MII PHY configured\n");
  61
  62        soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
  63
  64        ret = da8xx_register_emac();
  65        if (ret)
  66                pr_warn("%s: EMAC registration failed: %d\n", __func__, ret);
  67}
  68
  69/*
  70 * The following EDMA channels/slots are not being used by drivers (for
  71 * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
  72 * hence they are being reserved for codecs on the DSP side.
  73 */
  74static const s16 da850_dma0_rsv_chans[][2] = {
  75        /* (offset, number) */
  76        { 8,  6},
  77        {24,  4},
  78        {30,  2},
  79        {-1, -1}
  80};
  81
  82static const s16 da850_dma0_rsv_slots[][2] = {
  83        /* (offset, number) */
  84        { 8,  6},
  85        {24,  4},
  86        {30, 50},
  87        {-1, -1}
  88};
  89
  90static const s16 da850_dma1_rsv_chans[][2] = {
  91        /* (offset, number) */
  92        { 0, 28},
  93        {30,  2},
  94        {-1, -1}
  95};
  96
  97static const s16 da850_dma1_rsv_slots[][2] = {
  98        /* (offset, number) */
  99        { 0, 28},
 100        {30, 90},
 101        {-1, -1}
 102};
 103
 104static struct edma_rsv_info da850_edma_cc0_rsv = {
 105        .rsv_chans      = da850_dma0_rsv_chans,
 106        .rsv_slots      = da850_dma0_rsv_slots,
 107};
 108
 109static struct edma_rsv_info da850_edma_cc1_rsv = {
 110        .rsv_chans      = da850_dma1_rsv_chans,
 111        .rsv_slots      = da850_dma1_rsv_slots,
 112};
 113
 114static struct edma_rsv_info *da850_edma_rsv[2] = {
 115        &da850_edma_cc0_rsv,
 116        &da850_edma_cc1_rsv,
 117};
 118
 119static const short hawk_mmcsd0_pins[] = {
 120        DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
 121        DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
 122        DA850_GPIO3_12, DA850_GPIO3_13,
 123        -1
 124};
 125
 126static struct gpiod_lookup_table mmc_gpios_table = {
 127        .dev_id = "da830-mmc.0",
 128        .table = {
 129                /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/
 130                GPIO_LOOKUP("davinci_gpio.0", 28, "cd", GPIO_ACTIVE_LOW),
 131                GPIO_LOOKUP("davinci_gpio.0", 29, "wp", GPIO_ACTIVE_LOW),
 132        },
 133};
 134
 135static struct davinci_mmc_config da850_mmc_config = {
 136        .wires          = 4,
 137        .max_freq       = 50000000,
 138        .caps           = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
 139};
 140
 141static __init void omapl138_hawk_mmc_init(void)
 142{
 143        int ret;
 144
 145        ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
 146        if (ret) {
 147                pr_warn("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret);
 148                return;
 149        }
 150
 151        gpiod_add_lookup_table(&mmc_gpios_table);
 152
 153        ret = da8xx_register_mmcsd0(&da850_mmc_config);
 154        if (ret) {
 155                pr_warn("%s: MMC/SD0 registration failed: %d\n", __func__, ret);
 156                goto mmc_setup_mmcsd_fail;
 157        }
 158
 159        return;
 160
 161mmc_setup_mmcsd_fail:
 162        gpiod_remove_lookup_table(&mmc_gpios_table);
 163}
 164
 165static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
 166static da8xx_ocic_handler_t hawk_usb_ocic_handler;
 167
 168static const short da850_hawk_usb11_pins[] = {
 169        DA850_GPIO2_4, DA850_GPIO6_13,
 170        -1
 171};
 172
 173static int hawk_usb_set_power(unsigned port, int on)
 174{
 175        gpio_set_value(DA850_USB1_VBUS_PIN, on);
 176        return 0;
 177}
 178
 179static int hawk_usb_get_power(unsigned port)
 180{
 181        return gpio_get_value(DA850_USB1_VBUS_PIN);
 182}
 183
 184static int hawk_usb_get_oci(unsigned port)
 185{
 186        return !gpio_get_value(DA850_USB1_OC_PIN);
 187}
 188
 189static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
 190{
 191        int irq         = gpio_to_irq(DA850_USB1_OC_PIN);
 192        int error       = 0;
 193
 194        if (handler != NULL) {
 195                hawk_usb_ocic_handler = handler;
 196
 197                error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
 198                                        IRQF_TRIGGER_RISING |
 199                                        IRQF_TRIGGER_FALLING,
 200                                        "OHCI over-current indicator", NULL);
 201                if (error)
 202                        pr_err("%s: could not request IRQ to watch "
 203                                "over-current indicator changes\n", __func__);
 204        } else {
 205                free_irq(irq, NULL);
 206        }
 207        return error;
 208}
 209
 210static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
 211        .set_power      = hawk_usb_set_power,
 212        .get_power      = hawk_usb_get_power,
 213        .get_oci        = hawk_usb_get_oci,
 214        .ocic_notify    = hawk_usb_ocic_notify,
 215        /* TPS2087 switch @ 5V */
 216        .potpgt         = (3 + 1) / 2,  /* 3 ms max */
 217};
 218
 219static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
 220{
 221        hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
 222        return IRQ_HANDLED;
 223}
 224
 225static __init void omapl138_hawk_usb_init(void)
 226{
 227        int ret;
 228
 229        ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
 230        if (ret) {
 231                pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
 232                return;
 233        }
 234
 235        ret = da8xx_register_usb20_phy_clk(false);
 236        if (ret)
 237                pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
 238                        __func__, ret);
 239
 240        ret = da8xx_register_usb11_phy_clk(false);
 241        if (ret)
 242                pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
 243                        __func__, ret);
 244
 245        ret = da8xx_register_usb_phy();
 246        if (ret)
 247                pr_warn("%s: USB PHY registration failed: %d\n",
 248                        __func__, ret);
 249
 250        ret = gpio_request_one(DA850_USB1_VBUS_PIN,
 251                        GPIOF_DIR_OUT, "USB1 VBUS");
 252        if (ret < 0) {
 253                pr_err("%s: failed to request GPIO for USB 1.1 port "
 254                        "power control: %d\n", __func__, ret);
 255                return;
 256        }
 257
 258        ret = gpio_request_one(DA850_USB1_OC_PIN,
 259                        GPIOF_DIR_IN, "USB1 OC");
 260        if (ret < 0) {
 261                pr_err("%s: failed to request GPIO for USB 1.1 port "
 262                        "over-current indicator: %d\n", __func__, ret);
 263                goto usb11_setup_oc_fail;
 264        }
 265
 266        ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
 267        if (ret) {
 268                pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
 269                goto usb11_setup_fail;
 270        }
 271
 272        return;
 273
 274usb11_setup_fail:
 275        gpio_free(DA850_USB1_OC_PIN);
 276usb11_setup_oc_fail:
 277        gpio_free(DA850_USB1_VBUS_PIN);
 278}
 279
 280static __init void omapl138_hawk_init(void)
 281{
 282        int ret;
 283
 284        ret = da8xx_register_cfgchip();
 285        if (ret)
 286                pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
 287
 288        ret = da850_register_gpio();
 289        if (ret)
 290                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
 291
 292        davinci_serial_init(da8xx_serial_device);
 293
 294        omapl138_hawk_config_emac();
 295
 296        ret = da850_register_edma(da850_edma_rsv);
 297        if (ret)
 298                pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
 299
 300        omapl138_hawk_mmc_init();
 301
 302        omapl138_hawk_usb_init();
 303
 304        ret = da8xx_register_watchdog();
 305        if (ret)
 306                pr_warn("%s: watchdog registration failed: %d\n",
 307                        __func__, ret);
 308
 309        ret = da8xx_register_rproc();
 310        if (ret)
 311                pr_warn("%s: dsp/rproc registration failed: %d\n",
 312                        __func__, ret);
 313
 314        regulator_has_full_constraints();
 315}
 316
 317#ifdef CONFIG_SERIAL_8250_CONSOLE
 318static int __init omapl138_hawk_console_init(void)
 319{
 320        if (!machine_is_omapl138_hawkboard())
 321                return 0;
 322
 323        return add_preferred_console("ttyS", 2, "115200");
 324}
 325console_initcall(omapl138_hawk_console_init);
 326#endif
 327
 328static void __init omapl138_hawk_map_io(void)
 329{
 330        da850_init();
 331}
 332
 333MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
 334        .atag_offset    = 0x100,
 335        .map_io         = omapl138_hawk_map_io,
 336        .init_irq       = cp_intc_init,
 337        .init_time      = davinci_timer_init,
 338        .init_machine   = omapl138_hawk_init,
 339        .init_late      = davinci_init_late,
 340        .dma_zone_size  = SZ_128M,
 341        .restart        = da8xx_restart,
 342        .reserve        = da8xx_rproc_reserve_cma,
 343MACHINE_END
 344