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/init.h>
  13#include <linux/platform_device.h>
  14#include <linux/dma-mapping.h>
  15#include <linux/io.h>
  16
  17#include <mach/hardware.h>
  18#include <mach/i2c.h>
  19#include <mach/irqs.h>
  20#include <mach/cputype.h>
  21#include <mach/mux.h>
  22#include <mach/edma.h>
  23#include <mach/mmc.h>
  24#include <mach/time.h>
  25
  26#include "davinci.h"
  27#include "clock.h"
  28
  29#define DAVINCI_I2C_BASE             0x01C21000
  30#define DAVINCI_ATA_BASE             0x01C66000
  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
  37void __iomem  *davinci_sysmod_base;
  38
  39void davinci_map_sysmod(void)
  40{
  41        davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE,
  42                                              0x800);
  43        /*
  44         * Throw a bug since a lot of board initialization code depends
  45         * on system module availability. ioremap() failing this early
  46         * need careful looking into anyway.
  47         */
  48        BUG_ON(!davinci_sysmod_base);
  49}
  50
  51static struct resource i2c_resources[] = {
  52        {
  53                .start          = DAVINCI_I2C_BASE,
  54                .end            = DAVINCI_I2C_BASE + 0x40,
  55                .flags          = IORESOURCE_MEM,
  56        },
  57        {
  58                .start          = IRQ_I2C,
  59                .flags          = IORESOURCE_IRQ,
  60        },
  61};
  62
  63static struct platform_device davinci_i2c_device = {
  64        .name           = "i2c_davinci",
  65        .id             = 1,
  66        .num_resources  = ARRAY_SIZE(i2c_resources),
  67        .resource       = i2c_resources,
  68};
  69
  70void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
  71{
  72        if (cpu_is_davinci_dm644x())
  73                davinci_cfg_reg(DM644X_I2C);
  74
  75        davinci_i2c_device.dev.platform_data = pdata;
  76        (void) platform_device_register(&davinci_i2c_device);
  77}
  78
  79static struct resource ide_resources[] = {
  80        {
  81                .start          = DAVINCI_ATA_BASE,
  82                .end            = DAVINCI_ATA_BASE + 0x7ff,
  83                .flags          = IORESOURCE_MEM,
  84        },
  85        {
  86                .start          = IRQ_IDE,
  87                .end            = IRQ_IDE,
  88                .flags          = IORESOURCE_IRQ,
  89        },
  90};
  91
  92static u64 ide_dma_mask = DMA_BIT_MASK(32);
  93
  94static struct platform_device ide_device = {
  95        .name           = "palm_bk3710",
  96        .id             = -1,
  97        .resource       = ide_resources,
  98        .num_resources  = ARRAY_SIZE(ide_resources),
  99        .dev = {
 100                .dma_mask               = &ide_dma_mask,
 101                .coherent_dma_mask      = DMA_BIT_MASK(32),
 102        },
 103};
 104
 105void __init davinci_init_ide(void)
 106{
 107        if (cpu_is_davinci_dm644x()) {
 108                davinci_cfg_reg(DM644X_HPIEN_DISABLE);
 109                davinci_cfg_reg(DM644X_ATAEN);
 110                davinci_cfg_reg(DM644X_HDIREN);
 111        } else if (cpu_is_davinci_dm646x()) {
 112                /* IRQ_DM646X_IDE is the same as IRQ_IDE */
 113                davinci_cfg_reg(DM646X_ATAEN);
 114        } else {
 115                WARN_ON(1);
 116                return;
 117        }
 118
 119        platform_device_register(&ide_device);
 120}
 121
 122#if     defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
 123
 124static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
 125
 126static struct resource mmcsd0_resources[] = {
 127        {
 128                /* different on dm355 */
 129                .start = DAVINCI_MMCSD0_BASE,
 130                .end   = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
 131                .flags = IORESOURCE_MEM,
 132        },
 133        /* IRQs:  MMC/SD, then SDIO */
 134        {
 135                .start = IRQ_MMCINT,
 136                .flags = IORESOURCE_IRQ,
 137        }, {
 138                /* different on dm355 */
 139                .start = IRQ_SDIOINT,
 140                .flags = IORESOURCE_IRQ,
 141        },
 142        /* DMA channels: RX, then TX */
 143        {
 144                .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
 145                .flags = IORESOURCE_DMA,
 146        }, {
 147                .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
 148                .flags = IORESOURCE_DMA,
 149        },
 150};
 151
 152static struct platform_device davinci_mmcsd0_device = {
 153        .name = "davinci_mmc",
 154        .id = 0,
 155        .dev = {
 156                .dma_mask = &mmcsd0_dma_mask,
 157                .coherent_dma_mask = DMA_BIT_MASK(32),
 158        },
 159        .num_resources = ARRAY_SIZE(mmcsd0_resources),
 160        .resource = mmcsd0_resources,
 161};
 162
 163static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
 164
 165static struct resource mmcsd1_resources[] = {
 166        {
 167                .start = DM355_MMCSD1_BASE,
 168                .end   = DM355_MMCSD1_BASE + SZ_4K - 1,
 169                .flags = IORESOURCE_MEM,
 170        },
 171        /* IRQs:  MMC/SD, then SDIO */
 172        {
 173                .start = IRQ_DM355_MMCINT1,
 174                .flags = IORESOURCE_IRQ,
 175        }, {
 176                .start = IRQ_DM355_SDIOINT1,
 177                .flags = IORESOURCE_IRQ,
 178        },
 179        /* DMA channels: RX, then TX */
 180        {
 181                .start = EDMA_CTLR_CHAN(0, 30), /* rx */
 182                .flags = IORESOURCE_DMA,
 183        }, {
 184                .start = EDMA_CTLR_CHAN(0, 31), /* tx */
 185                .flags = IORESOURCE_DMA,
 186        },
 187};
 188
 189static struct platform_device davinci_mmcsd1_device = {
 190        .name = "davinci_mmc",
 191        .id = 1,
 192        .dev = {
 193                .dma_mask = &mmcsd1_dma_mask,
 194                .coherent_dma_mask = DMA_BIT_MASK(32),
 195        },
 196        .num_resources = ARRAY_SIZE(mmcsd1_resources),
 197        .resource = mmcsd1_resources,
 198};
 199
 200
 201void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 202{
 203        struct platform_device  *pdev = NULL;
 204
 205        if (WARN_ON(cpu_is_davinci_dm646x()))
 206                return;
 207
 208        /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
 209         * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
 210         *
 211         * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
 212         * not handled right here ...
 213         */
 214        switch (module) {
 215        case 1:
 216                if (cpu_is_davinci_dm355()) {
 217                        /* REVISIT we may not need all these pins if e.g. this
 218                         * is a hard-wired SDIO device...
 219                         */
 220                        davinci_cfg_reg(DM355_SD1_CMD);
 221                        davinci_cfg_reg(DM355_SD1_CLK);
 222                        davinci_cfg_reg(DM355_SD1_DATA0);
 223                        davinci_cfg_reg(DM355_SD1_DATA1);
 224                        davinci_cfg_reg(DM355_SD1_DATA2);
 225                        davinci_cfg_reg(DM355_SD1_DATA3);
 226                } else if (cpu_is_davinci_dm365()) {
 227                        /* Configure pull down control */
 228                        unsigned v;
 229
 230                        v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
 231                        __raw_writel(v & ~0xfc0,
 232                                        DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
 233
 234                        mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
 235                        mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
 236                                                        SZ_4K - 1;
 237                        mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
 238                } else
 239                        break;
 240
 241                pdev = &davinci_mmcsd1_device;
 242                break;
 243        case 0:
 244                if (cpu_is_davinci_dm355()) {
 245                        mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
 246                        mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
 247                        mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
 248
 249                        /* expose all 6 MMC0 signals:  CLK, CMD, DATA[0..3] */
 250                        davinci_cfg_reg(DM355_MMCSD0);
 251
 252                        /* enable RX EDMA */
 253                        davinci_cfg_reg(DM355_EVT26_MMC0_RX);
 254                } else if (cpu_is_davinci_dm365()) {
 255                        mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
 256                        mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
 257                                                        SZ_4K - 1;
 258                        mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
 259                } else if (cpu_is_davinci_dm644x()) {
 260                        /* REVISIT: should this be in board-init code? */
 261                        /* Power-on 3.3V IO cells */
 262                        __raw_writel(0,
 263                                DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
 264                        /*Set up the pull regiter for MMC */
 265                        davinci_cfg_reg(DM644X_MSTK);
 266                }
 267
 268                pdev = &davinci_mmcsd0_device;
 269                break;
 270        }
 271
 272        if (WARN_ON(!pdev))
 273                return;
 274
 275        pdev->dev.platform_data = config;
 276        platform_device_register(pdev);
 277}
 278
 279#else
 280
 281void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 282{
 283}
 284
 285#endif
 286
 287/*-------------------------------------------------------------------------*/
 288
 289static struct resource wdt_resources[] = {
 290        {
 291                .start  = DAVINCI_WDOG_BASE,
 292                .end    = DAVINCI_WDOG_BASE + SZ_1K - 1,
 293                .flags  = IORESOURCE_MEM,
 294        },
 295};
 296
 297struct platform_device davinci_wdt_device = {
 298        .name           = "watchdog",
 299        .id             = -1,
 300        .num_resources  = ARRAY_SIZE(wdt_resources),
 301        .resource       = wdt_resources,
 302};
 303
 304void davinci_restart(char mode, const char *cmd)
 305{
 306        davinci_watchdog_reset(&davinci_wdt_device);
 307}
 308
 309static void davinci_init_wdt(void)
 310{
 311        platform_device_register(&davinci_wdt_device);
 312}
 313
 314/*-------------------------------------------------------------------------*/
 315
 316static struct platform_device davinci_pcm_device = {
 317        .name           = "davinci-pcm-audio",
 318        .id             = -1,
 319};
 320
 321static void davinci_init_pcm(void)
 322{
 323        platform_device_register(&davinci_pcm_device);
 324}
 325
 326/*-------------------------------------------------------------------------*/
 327
 328struct davinci_timer_instance davinci_timer_instance[2] = {
 329        {
 330                .base           = DAVINCI_TIMER0_BASE,
 331                .bottom_irq     = IRQ_TINT0_TINT12,
 332                .top_irq        = IRQ_TINT0_TINT34,
 333        },
 334        {
 335                .base           = DAVINCI_TIMER1_BASE,
 336                .bottom_irq     = IRQ_TINT1_TINT12,
 337                .top_irq        = IRQ_TINT1_TINT34,
 338        },
 339};
 340
 341/*-------------------------------------------------------------------------*/
 342
 343static int __init davinci_init_devices(void)
 344{
 345        /* please keep these calls, and their implementations above,
 346         * in alphabetical order so they're easier to sort through.
 347         */
 348        davinci_init_pcm();
 349        davinci_init_wdt();
 350
 351        return 0;
 352}
 353arch_initcall(davinci_init_devices);
 354
 355