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