linux/arch/arm/mach-davinci/devices.c
<<
>>
Prefs
   1/*
   2 * mach-davinci/devices.c
   3 *
   4 * DaVinci platform device setup/initialization
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/platform_device.h>
  16#include <linux/dma-mapping.h>
  17#include <linux/io.h>
  18
  19#include <asm/mach/map.h>
  20
  21#include <mach/hardware.h>
  22#include <mach/i2c.h>
  23#include <mach/irqs.h>
  24#include <mach/cputype.h>
  25#include <mach/mux.h>
  26#include <mach/edma.h>
  27#include <mach/mmc.h>
  28#include <mach/time.h>
  29
  30#define DAVINCI_I2C_BASE             0x01C21000
  31#define DAVINCI_MMCSD0_BASE          0x01E10000
  32#define DM355_MMCSD0_BASE            0x01E11000
  33#define DM355_MMCSD1_BASE            0x01E00000
  34#define DM365_MMCSD0_BASE            0x01D11000
  35#define DM365_MMCSD1_BASE            0x01D00000
  36
  37static struct resource i2c_resources[] = {
  38        {
  39                .start          = DAVINCI_I2C_BASE,
  40                .end            = DAVINCI_I2C_BASE + 0x40,
  41                .flags          = IORESOURCE_MEM,
  42        },
  43        {
  44                .start          = IRQ_I2C,
  45                .flags          = IORESOURCE_IRQ,
  46        },
  47};
  48
  49static struct platform_device davinci_i2c_device = {
  50        .name           = "i2c_davinci",
  51        .id             = 1,
  52        .num_resources  = ARRAY_SIZE(i2c_resources),
  53        .resource       = i2c_resources,
  54};
  55
  56void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
  57{
  58        if (cpu_is_davinci_dm644x())
  59                davinci_cfg_reg(DM644X_I2C);
  60
  61        davinci_i2c_device.dev.platform_data = pdata;
  62        (void) platform_device_register(&davinci_i2c_device);
  63}
  64
  65#if     defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
  66
  67static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
  68
  69static struct resource mmcsd0_resources[] = {
  70        {
  71                /* different on dm355 */
  72                .start = DAVINCI_MMCSD0_BASE,
  73                .end   = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
  74                .flags = IORESOURCE_MEM,
  75        },
  76        /* IRQs:  MMC/SD, then SDIO */
  77        {
  78                .start = IRQ_MMCINT,
  79                .flags = IORESOURCE_IRQ,
  80        }, {
  81                /* different on dm355 */
  82                .start = IRQ_SDIOINT,
  83                .flags = IORESOURCE_IRQ,
  84        },
  85        /* DMA channels: RX, then TX */
  86        {
  87                .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
  88                .flags = IORESOURCE_DMA,
  89        }, {
  90                .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
  91                .flags = IORESOURCE_DMA,
  92        },
  93};
  94
  95static struct platform_device davinci_mmcsd0_device = {
  96        .name = "davinci_mmc",
  97        .id = 0,
  98        .dev = {
  99                .dma_mask = &mmcsd0_dma_mask,
 100                .coherent_dma_mask = DMA_BIT_MASK(32),
 101        },
 102        .num_resources = ARRAY_SIZE(mmcsd0_resources),
 103        .resource = mmcsd0_resources,
 104};
 105
 106static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
 107
 108static struct resource mmcsd1_resources[] = {
 109        {
 110                .start = DM355_MMCSD1_BASE,
 111                .end   = DM355_MMCSD1_BASE + SZ_4K - 1,
 112                .flags = IORESOURCE_MEM,
 113        },
 114        /* IRQs:  MMC/SD, then SDIO */
 115        {
 116                .start = IRQ_DM355_MMCINT1,
 117                .flags = IORESOURCE_IRQ,
 118        }, {
 119                .start = IRQ_DM355_SDIOINT1,
 120                .flags = IORESOURCE_IRQ,
 121        },
 122        /* DMA channels: RX, then TX */
 123        {
 124                .start = EDMA_CTLR_CHAN(0, 30), /* rx */
 125                .flags = IORESOURCE_DMA,
 126        }, {
 127                .start = EDMA_CTLR_CHAN(0, 31), /* tx */
 128                .flags = IORESOURCE_DMA,
 129        },
 130};
 131
 132static struct platform_device davinci_mmcsd1_device = {
 133        .name = "davinci_mmc",
 134        .id = 1,
 135        .dev = {
 136                .dma_mask = &mmcsd1_dma_mask,
 137                .coherent_dma_mask = DMA_BIT_MASK(32),
 138        },
 139        .num_resources = ARRAY_SIZE(mmcsd1_resources),
 140        .resource = mmcsd1_resources,
 141};
 142
 143
 144void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 145{
 146        struct platform_device  *pdev = NULL;
 147
 148        if (WARN_ON(cpu_is_davinci_dm646x()))
 149                return;
 150
 151        /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
 152         * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
 153         *
 154         * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
 155         * not handled right here ...
 156         */
 157        switch (module) {
 158        case 1:
 159                if (cpu_is_davinci_dm355()) {
 160                        /* REVISIT we may not need all these pins if e.g. this
 161                         * is a hard-wired SDIO device...
 162                         */
 163                        davinci_cfg_reg(DM355_SD1_CMD);
 164                        davinci_cfg_reg(DM355_SD1_CLK);
 165                        davinci_cfg_reg(DM355_SD1_DATA0);
 166                        davinci_cfg_reg(DM355_SD1_DATA1);
 167                        davinci_cfg_reg(DM355_SD1_DATA2);
 168                        davinci_cfg_reg(DM355_SD1_DATA3);
 169                } else if (cpu_is_davinci_dm365()) {
 170                        void __iomem *pupdctl1 =
 171                                IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
 172
 173                        /* Configure pull down control */
 174                        __raw_writel((__raw_readl(pupdctl1) & ~0x400),
 175                                        pupdctl1);
 176
 177                        mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
 178                        mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
 179                                                        SZ_4K - 1;
 180                        mmcsd0_resources[2].start = IRQ_DM365_SDIOINT1;
 181                } else
 182                        break;
 183
 184                pdev = &davinci_mmcsd1_device;
 185                break;
 186        case 0:
 187                if (cpu_is_davinci_dm355()) {
 188                        mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
 189                        mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
 190                        mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
 191
 192                        /* expose all 6 MMC0 signals:  CLK, CMD, DATA[0..3] */
 193                        davinci_cfg_reg(DM355_MMCSD0);
 194
 195                        /* enable RX EDMA */
 196                        davinci_cfg_reg(DM355_EVT26_MMC0_RX);
 197                } else if (cpu_is_davinci_dm365()) {
 198                        mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
 199                        mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
 200                                                        SZ_4K - 1;
 201                        mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
 202                } else if (cpu_is_davinci_dm644x()) {
 203                        /* REVISIT: should this be in board-init code? */
 204                        void __iomem *base =
 205                                IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
 206
 207                        /* Power-on 3.3V IO cells */
 208                        __raw_writel(0, base + DM64XX_VDD3P3V_PWDN);
 209                        /*Set up the pull regiter for MMC */
 210                        davinci_cfg_reg(DM644X_MSTK);
 211                }
 212
 213                pdev = &davinci_mmcsd0_device;
 214                break;
 215        }
 216
 217        if (WARN_ON(!pdev))
 218                return;
 219
 220        pdev->dev.platform_data = config;
 221        platform_device_register(pdev);
 222}
 223
 224#else
 225
 226void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 227{
 228}
 229
 230#endif
 231
 232/*-------------------------------------------------------------------------*/
 233
 234static struct resource wdt_resources[] = {
 235        {
 236                .start  = DAVINCI_WDOG_BASE,
 237                .end    = DAVINCI_WDOG_BASE + SZ_1K - 1,
 238                .flags  = IORESOURCE_MEM,
 239        },
 240};
 241
 242struct platform_device davinci_wdt_device = {
 243        .name           = "watchdog",
 244        .id             = -1,
 245        .num_resources  = ARRAY_SIZE(wdt_resources),
 246        .resource       = wdt_resources,
 247};
 248
 249static void davinci_init_wdt(void)
 250{
 251        platform_device_register(&davinci_wdt_device);
 252}
 253
 254/*-------------------------------------------------------------------------*/
 255
 256struct davinci_timer_instance davinci_timer_instance[2] = {
 257        {
 258                .base           = IO_ADDRESS(DAVINCI_TIMER0_BASE),
 259                .bottom_irq     = IRQ_TINT0_TINT12,
 260                .top_irq        = IRQ_TINT0_TINT34,
 261        },
 262        {
 263                .base           = IO_ADDRESS(DAVINCI_TIMER1_BASE),
 264                .bottom_irq     = IRQ_TINT1_TINT12,
 265                .top_irq        = IRQ_TINT1_TINT34,
 266        },
 267};
 268
 269/*-------------------------------------------------------------------------*/
 270
 271static int __init davinci_init_devices(void)
 272{
 273        /* please keep these calls, and their implementations above,
 274         * in alphabetical order so they're easier to sort through.
 275         */
 276        davinci_init_wdt();
 277
 278        return 0;
 279}
 280arch_initcall(davinci_init_devices);
 281
 282