linux/arch/arm/mach-davinci/devices-tnetv107x.c
<<
>>
Prefs
   1/*
   2 * Texas Instruments TNETV107X SoC devices
   3 *
   4 * Copyright (C) 2010 Texas Instruments
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation version 2.
   9 *
  10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  11 * kind, whether express or implied; without even the implied warranty
  12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15#include <linux/kernel.h>
  16#include <linux/init.h>
  17#include <linux/platform_device.h>
  18#include <linux/dma-mapping.h>
  19#include <linux/clk.h>
  20#include <linux/slab.h>
  21
  22#include <mach/common.h>
  23#include <mach/irqs.h>
  24#include <mach/edma.h>
  25#include <mach/tnetv107x.h>
  26
  27#include "clock.h"
  28
  29/* Base addresses for on-chip devices */
  30#define TNETV107X_TPCC_BASE                     0x01c00000
  31#define TNETV107X_TPTC0_BASE                    0x01c10000
  32#define TNETV107X_TPTC1_BASE                    0x01c10400
  33#define TNETV107X_WDOG_BASE                     0x08086700
  34#define TNETV107X_TSC_BASE                      0x08088500
  35#define TNETV107X_SDIO0_BASE                    0x08088700
  36#define TNETV107X_SDIO1_BASE                    0x08088800
  37#define TNETV107X_KEYPAD_BASE                   0x08088a00
  38#define TNETV107X_SSP_BASE                      0x08088c00
  39#define TNETV107X_ASYNC_EMIF_CNTRL_BASE         0x08200000
  40#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE      0x30000000
  41#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE      0x40000000
  42#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE      0x44000000
  43#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE      0x48000000
  44
  45/* TNETV107X specific EDMA3 information */
  46#define EDMA_TNETV107X_NUM_DMACH        64
  47#define EDMA_TNETV107X_NUM_TCC          64
  48#define EDMA_TNETV107X_NUM_PARAMENTRY   128
  49#define EDMA_TNETV107X_NUM_EVQUE        2
  50#define EDMA_TNETV107X_NUM_TC           2
  51#define EDMA_TNETV107X_CHMAP_EXIST      0
  52#define EDMA_TNETV107X_NUM_REGIONS      4
  53#define TNETV107X_DMACH2EVENT_MAP0      0x3C0CE000u
  54#define TNETV107X_DMACH2EVENT_MAP1      0x000FFFFFu
  55
  56#define TNETV107X_DMACH_SDIO0_RX                26
  57#define TNETV107X_DMACH_SDIO0_TX                27
  58#define TNETV107X_DMACH_SDIO1_RX                28
  59#define TNETV107X_DMACH_SDIO1_TX                29
  60
  61static const s8 edma_tc_mapping[][2] = {
  62        /* event queue no       TC no   */
  63        {        0,              0      },
  64        {        1,              1      },
  65        {       -1,             -1      }
  66};
  67
  68static const s8 edma_priority_mapping[][2] = {
  69        /* event queue no       Prio    */
  70        {        0,              3      },
  71        {        1,              7      },
  72        {       -1,             -1      }
  73};
  74
  75static struct edma_soc_info edma_cc0_info = {
  76        .n_channel              = EDMA_TNETV107X_NUM_DMACH,
  77        .n_region               = EDMA_TNETV107X_NUM_REGIONS,
  78        .n_slot                 = EDMA_TNETV107X_NUM_PARAMENTRY,
  79        .n_tc                   = EDMA_TNETV107X_NUM_TC,
  80        .n_cc                   = 1,
  81        .queue_tc_mapping       = edma_tc_mapping,
  82        .queue_priority_mapping = edma_priority_mapping,
  83        .default_queue          = EVENTQ_1,
  84};
  85
  86static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
  87        &edma_cc0_info,
  88};
  89
  90static struct resource edma_resources[] = {
  91        {
  92                .name   = "edma_cc0",
  93                .start  = TNETV107X_TPCC_BASE,
  94                .end    = TNETV107X_TPCC_BASE + SZ_32K - 1,
  95                .flags  = IORESOURCE_MEM,
  96        },
  97        {
  98                .name   = "edma_tc0",
  99                .start  = TNETV107X_TPTC0_BASE,
 100                .end    = TNETV107X_TPTC0_BASE + SZ_1K - 1,
 101                .flags  = IORESOURCE_MEM,
 102        },
 103        {
 104                .name   = "edma_tc1",
 105                .start  = TNETV107X_TPTC1_BASE,
 106                .end    = TNETV107X_TPTC1_BASE + SZ_1K - 1,
 107                .flags  = IORESOURCE_MEM,
 108        },
 109        {
 110                .name   = "edma0",
 111                .start  = IRQ_TNETV107X_TPCC,
 112                .flags  = IORESOURCE_IRQ,
 113        },
 114        {
 115                .name   = "edma0_err",
 116                .start  = IRQ_TNETV107X_TPCC_ERR,
 117                .flags  = IORESOURCE_IRQ,
 118        },
 119};
 120
 121static struct platform_device edma_device = {
 122        .name           = "edma",
 123        .id             = -1,
 124        .num_resources  = ARRAY_SIZE(edma_resources),
 125        .resource       = edma_resources,
 126        .dev.platform_data = tnetv107x_edma_info,
 127};
 128
 129static struct plat_serial8250_port serial_data[] = {
 130        {
 131                .mapbase        = TNETV107X_UART0_BASE,
 132                .irq            = IRQ_TNETV107X_UART0,
 133                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
 134                                        UPF_FIXED_TYPE | UPF_IOREMAP,
 135                .type           = PORT_AR7,
 136                .iotype         = UPIO_MEM32,
 137                .regshift       = 2,
 138        },
 139        {
 140                .mapbase        = TNETV107X_UART1_BASE,
 141                .irq            = IRQ_TNETV107X_UART1,
 142                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
 143                                        UPF_FIXED_TYPE | UPF_IOREMAP,
 144                .type           = PORT_AR7,
 145                .iotype         = UPIO_MEM32,
 146                .regshift       = 2,
 147        },
 148        {
 149                .mapbase        = TNETV107X_UART2_BASE,
 150                .irq            = IRQ_TNETV107X_UART2,
 151                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
 152                                        UPF_FIXED_TYPE | UPF_IOREMAP,
 153                .type           = PORT_AR7,
 154                .iotype         = UPIO_MEM32,
 155                .regshift       = 2,
 156        },
 157        {
 158                .flags  = 0,
 159        },
 160};
 161
 162struct platform_device tnetv107x_serial_device = {
 163        .name                   = "serial8250",
 164        .id                     = PLAT8250_DEV_PLATFORM,
 165        .dev.platform_data      = serial_data,
 166};
 167
 168static struct resource mmc0_resources[] = {
 169        { /* Memory mapped registers */
 170                .start  = TNETV107X_SDIO0_BASE,
 171                .end    = TNETV107X_SDIO0_BASE + 0x0ff,
 172                .flags  = IORESOURCE_MEM
 173        },
 174        { /* MMC interrupt */
 175                .start  = IRQ_TNETV107X_MMC0,
 176                .flags  = IORESOURCE_IRQ
 177        },
 178        { /* SDIO interrupt */
 179                .start  = IRQ_TNETV107X_SDIO0,
 180                .flags  = IORESOURCE_IRQ
 181        },
 182        { /* DMA RX */
 183                .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),
 184                .flags  = IORESOURCE_DMA
 185        },
 186        { /* DMA TX */
 187                .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),
 188                .flags  = IORESOURCE_DMA
 189        },
 190};
 191
 192static struct resource mmc1_resources[] = {
 193        { /* Memory mapped registers */
 194                .start  = TNETV107X_SDIO1_BASE,
 195                .end    = TNETV107X_SDIO1_BASE + 0x0ff,
 196                .flags  = IORESOURCE_MEM
 197        },
 198        { /* MMC interrupt */
 199                .start  = IRQ_TNETV107X_MMC1,
 200                .flags  = IORESOURCE_IRQ
 201        },
 202        { /* SDIO interrupt */
 203                .start  = IRQ_TNETV107X_SDIO1,
 204                .flags  = IORESOURCE_IRQ
 205        },
 206        { /* DMA RX */
 207                .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),
 208                .flags  = IORESOURCE_DMA
 209        },
 210        { /* DMA TX */
 211                .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),
 212                .flags  = IORESOURCE_DMA
 213        },
 214};
 215
 216static u64 mmc0_dma_mask = DMA_BIT_MASK(32);
 217static u64 mmc1_dma_mask = DMA_BIT_MASK(32);
 218
 219static struct platform_device mmc_devices[2] = {
 220        {
 221                .name           = "dm6441-mmc",
 222                .id             = 0,
 223                .dev            = {
 224                        .dma_mask               = &mmc0_dma_mask,
 225                        .coherent_dma_mask      = DMA_BIT_MASK(32),
 226                },
 227                .num_resources  = ARRAY_SIZE(mmc0_resources),
 228                .resource       = mmc0_resources
 229        },
 230        {
 231                .name           = "dm6441-mmc",
 232                .id             = 1,
 233                .dev            = {
 234                        .dma_mask               = &mmc1_dma_mask,
 235                        .coherent_dma_mask      = DMA_BIT_MASK(32),
 236                },
 237                .num_resources  = ARRAY_SIZE(mmc1_resources),
 238                .resource       = mmc1_resources
 239        },
 240};
 241
 242static const u32 emif_windows[] = {
 243        TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,
 244        TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,
 245};
 246
 247static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };
 248
 249static struct resource wdt_resources[] = {
 250        {
 251                .start  = TNETV107X_WDOG_BASE,
 252                .end    = TNETV107X_WDOG_BASE + SZ_4K - 1,
 253                .flags  = IORESOURCE_MEM,
 254        },
 255};
 256
 257struct platform_device tnetv107x_wdt_device = {
 258        .name           = "tnetv107x_wdt",
 259        .id             = 0,
 260        .num_resources  = ARRAY_SIZE(wdt_resources),
 261        .resource       = wdt_resources,
 262};
 263
 264static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
 265{
 266        struct resource res[2];
 267        struct platform_device *pdev;
 268        u32     range;
 269        int     ret;
 270
 271        /* Figure out the resource range from the ale/cle masks */
 272        range = max(data->mask_cle, data->mask_ale);
 273        range = PAGE_ALIGN(range + 4) - 1;
 274
 275        if (range >= emif_window_sizes[chipsel])
 276                return -EINVAL;
 277
 278        pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
 279        if (!pdev)
 280                return -ENOMEM;
 281
 282        pdev->name              = "davinci_nand";
 283        pdev->id                = chipsel;
 284        pdev->dev.platform_data = data;
 285
 286        memset(res, 0, sizeof(res));
 287
 288        res[0].start    = emif_windows[chipsel];
 289        res[0].end      = res[0].start + range;
 290        res[0].flags    = IORESOURCE_MEM;
 291
 292        res[1].start    = TNETV107X_ASYNC_EMIF_CNTRL_BASE;
 293        res[1].end      = res[1].start + SZ_4K - 1;
 294        res[1].flags    = IORESOURCE_MEM;
 295
 296        ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
 297        if (ret < 0) {
 298                kfree(pdev);
 299                return ret;
 300        }
 301
 302        return platform_device_register(pdev);
 303}
 304
 305static struct resource keypad_resources[] = {
 306        {
 307                .start  = TNETV107X_KEYPAD_BASE,
 308                .end    = TNETV107X_KEYPAD_BASE + 0xff,
 309                .flags  = IORESOURCE_MEM,
 310        },
 311        {
 312                .start  = IRQ_TNETV107X_KEYPAD,
 313                .flags  = IORESOURCE_IRQ,
 314                .name   = "press",
 315        },
 316        {
 317                .start  = IRQ_TNETV107X_KEYPAD_FREE,
 318                .flags  = IORESOURCE_IRQ,
 319                .name   = "release",
 320        },
 321};
 322
 323static struct platform_device keypad_device = {
 324        .name           = "tnetv107x-keypad",
 325        .num_resources  = ARRAY_SIZE(keypad_resources),
 326        .resource       = keypad_resources,
 327};
 328
 329static struct resource tsc_resources[] = {
 330        {
 331                .start  = TNETV107X_TSC_BASE,
 332                .end    = TNETV107X_TSC_BASE + 0xff,
 333                .flags  = IORESOURCE_MEM,
 334        },
 335        {
 336                .start  = IRQ_TNETV107X_TSC,
 337                .flags  = IORESOURCE_IRQ,
 338        },
 339};
 340
 341static struct platform_device tsc_device = {
 342        .name           = "tnetv107x-ts",
 343        .num_resources  = ARRAY_SIZE(tsc_resources),
 344        .resource       = tsc_resources,
 345};
 346
 347static struct resource ssp_resources[] = {
 348        {
 349                .start  = TNETV107X_SSP_BASE,
 350                .end    = TNETV107X_SSP_BASE + 0x1ff,
 351                .flags  = IORESOURCE_MEM,
 352        },
 353        {
 354                .start  = IRQ_TNETV107X_SSP,
 355                .flags  = IORESOURCE_IRQ,
 356        },
 357};
 358
 359static struct platform_device ssp_device = {
 360        .name           = "ti-ssp",
 361        .id             = -1,
 362        .num_resources  = ARRAY_SIZE(ssp_resources),
 363        .resource       = ssp_resources,
 364};
 365
 366void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
 367{
 368        int i, error;
 369        struct clk *tsc_clk;
 370
 371        /*
 372         * The reset defaults for tnetv107x tsc clock divider is set too high.
 373         * This forces the clock down to a range that allows the ADC to
 374         * complete sample conversion in time.
 375         */
 376        tsc_clk = clk_get(NULL, "sys_tsc_clk");
 377        if (!IS_ERR(tsc_clk)) {
 378                error = clk_set_rate(tsc_clk, 5000000);
 379                WARN_ON(error < 0);
 380                clk_put(tsc_clk);
 381        }
 382
 383        platform_device_register(&edma_device);
 384        platform_device_register(&tnetv107x_wdt_device);
 385        platform_device_register(&tsc_device);
 386
 387        if (info->serial_config)
 388                davinci_serial_init(info->serial_config);
 389
 390        for (i = 0; i < 2; i++)
 391                if (info->mmc_config[i]) {
 392                        mmc_devices[i].dev.platform_data = info->mmc_config[i];
 393                        platform_device_register(&mmc_devices[i]);
 394                }
 395
 396        for (i = 0; i < 4; i++)
 397                if (info->nand_config[i])
 398                        nand_init(i, info->nand_config[i]);
 399
 400        if (info->keypad_config) {
 401                keypad_device.dev.platform_data = info->keypad_config;
 402                platform_device_register(&keypad_device);
 403        }
 404
 405        if (info->ssp_config) {
 406                ssp_device.dev.platform_data = info->ssp_config;
 407                platform_device_register(&ssp_device);
 408        }
 409}
 410