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