linux/arch/m68k/platform/527x/config.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *      linux/arch/m68knommu/platform/527x/config.c
   5 *
   6 *      Sub-architcture dependent initialization code for the Freescale
   7 *      5270/5271 CPUs.
   8 *
   9 *      Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
  10 *      Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
  11 */
  12
  13/***************************************************************************/
  14
  15#include <linux/kernel.h>
  16#include <linux/param.h>
  17#include <linux/init.h>
  18#include <linux/io.h>
  19#include <linux/spi/spi.h>
  20#include <linux/gpio.h>
  21#include <asm/machdep.h>
  22#include <asm/coldfire.h>
  23#include <asm/mcfsim.h>
  24#include <asm/mcfuart.h>
  25#include <asm/mcfqspi.h>
  26
  27/***************************************************************************/
  28
  29static struct mcf_platform_uart m527x_uart_platform[] = {
  30        {
  31                .mapbase        = MCFUART_BASE1,
  32                .irq            = MCFINT_VECBASE + MCFINT_UART0,
  33        },
  34        {
  35                .mapbase        = MCFUART_BASE2,
  36                .irq            = MCFINT_VECBASE + MCFINT_UART1,
  37        },
  38        {
  39                .mapbase        = MCFUART_BASE3,
  40                .irq            = MCFINT_VECBASE + MCFINT_UART2,
  41        },
  42        { },
  43};
  44
  45static struct platform_device m527x_uart = {
  46        .name                   = "mcfuart",
  47        .id                     = 0,
  48        .dev.platform_data      = m527x_uart_platform,
  49};
  50
  51static struct resource m527x_fec0_resources[] = {
  52        {
  53                .start          = MCFFEC_BASE0,
  54                .end            = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
  55                .flags          = IORESOURCE_MEM,
  56        },
  57        {
  58                .start          = 64 + 23,
  59                .end            = 64 + 23,
  60                .flags          = IORESOURCE_IRQ,
  61        },
  62        {
  63                .start          = 64 + 27,
  64                .end            = 64 + 27,
  65                .flags          = IORESOURCE_IRQ,
  66        },
  67        {
  68                .start          = 64 + 29,
  69                .end            = 64 + 29,
  70                .flags          = IORESOURCE_IRQ,
  71        },
  72};
  73
  74static struct resource m527x_fec1_resources[] = {
  75        {
  76                .start          = MCFFEC_BASE1,
  77                .end            = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
  78                .flags          = IORESOURCE_MEM,
  79        },
  80        {
  81                .start          = 128 + 23,
  82                .end            = 128 + 23,
  83                .flags          = IORESOURCE_IRQ,
  84        },
  85        {
  86                .start          = 128 + 27,
  87                .end            = 128 + 27,
  88                .flags          = IORESOURCE_IRQ,
  89        },
  90        {
  91                .start          = 128 + 29,
  92                .end            = 128 + 29,
  93                .flags          = IORESOURCE_IRQ,
  94        },
  95};
  96
  97static struct platform_device m527x_fec[] = {
  98        {
  99                .name           = "fec",
 100                .id             = 0,
 101                .num_resources  = ARRAY_SIZE(m527x_fec0_resources),
 102                .resource       = m527x_fec0_resources,
 103        },
 104        {
 105                .name           = "fec",
 106                .id             = 1,
 107                .num_resources  = ARRAY_SIZE(m527x_fec1_resources),
 108                .resource       = m527x_fec1_resources,
 109        },
 110};
 111
 112#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 113static struct resource m527x_qspi_resources[] = {
 114        {
 115                .start          = MCFQSPI_IOBASE,
 116                .end            = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
 117                .flags          = IORESOURCE_MEM,
 118        },
 119        {
 120                .start          = MCFINT_VECBASE + MCFINT_QSPI,
 121                .end            = MCFINT_VECBASE + MCFINT_QSPI,
 122                .flags          = IORESOURCE_IRQ,
 123        },
 124};
 125
 126#if defined(CONFIG_M5271)
 127#define MCFQSPI_CS0    91
 128#define MCFQSPI_CS1    92
 129#define MCFQSPI_CS2    99
 130#define MCFQSPI_CS3    103
 131#elif defined(CONFIG_M5275)
 132#define MCFQSPI_CS0    59
 133#define MCFQSPI_CS1    60
 134#define MCFQSPI_CS2    61
 135#define MCFQSPI_CS3    62
 136#endif
 137
 138static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control)
 139{
 140        int status;
 141
 142        status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
 143        if (status) {
 144                pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
 145                goto fail0;
 146        }
 147        status = gpio_direction_output(MCFQSPI_CS0, 1);
 148        if (status) {
 149                pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
 150                goto fail1;
 151        }
 152
 153        status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
 154        if (status) {
 155                pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
 156                goto fail1;
 157        }
 158        status = gpio_direction_output(MCFQSPI_CS1, 1);
 159        if (status) {
 160                pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
 161                goto fail2;
 162        }
 163
 164        status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
 165        if (status) {
 166                pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
 167                goto fail2;
 168        }
 169        status = gpio_direction_output(MCFQSPI_CS2, 1);
 170        if (status) {
 171                pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
 172                goto fail3;
 173        }
 174
 175        status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
 176        if (status) {
 177                pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
 178                goto fail3;
 179        }
 180        status = gpio_direction_output(MCFQSPI_CS3, 1);
 181        if (status) {
 182                pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
 183                goto fail4;
 184        }
 185
 186        return 0;
 187
 188fail4:
 189        gpio_free(MCFQSPI_CS3);
 190fail3:
 191        gpio_free(MCFQSPI_CS2);
 192fail2:
 193        gpio_free(MCFQSPI_CS1);
 194fail1:
 195        gpio_free(MCFQSPI_CS0);
 196fail0:
 197        return status;
 198}
 199
 200static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control)
 201{
 202        gpio_free(MCFQSPI_CS3);
 203        gpio_free(MCFQSPI_CS2);
 204        gpio_free(MCFQSPI_CS1);
 205        gpio_free(MCFQSPI_CS0);
 206}
 207
 208static void m527x_cs_select(struct mcfqspi_cs_control *cs_control,
 209                            u8 chip_select, bool cs_high)
 210{
 211        switch (chip_select) {
 212        case 0:
 213                gpio_set_value(MCFQSPI_CS0, cs_high);
 214                break;
 215        case 1:
 216                gpio_set_value(MCFQSPI_CS1, cs_high);
 217                break;
 218        case 2:
 219                gpio_set_value(MCFQSPI_CS2, cs_high);
 220                break;
 221        case 3:
 222                gpio_set_value(MCFQSPI_CS3, cs_high);
 223                break;
 224        }
 225}
 226
 227static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control,
 228                              u8 chip_select, bool cs_high)
 229{
 230        switch (chip_select) {
 231        case 0:
 232                gpio_set_value(MCFQSPI_CS0, !cs_high);
 233                break;
 234        case 1:
 235                gpio_set_value(MCFQSPI_CS1, !cs_high);
 236                break;
 237        case 2:
 238                gpio_set_value(MCFQSPI_CS2, !cs_high);
 239                break;
 240        case 3:
 241                gpio_set_value(MCFQSPI_CS3, !cs_high);
 242                break;
 243        }
 244}
 245
 246static struct mcfqspi_cs_control m527x_cs_control = {
 247        .setup                  = m527x_cs_setup,
 248        .teardown               = m527x_cs_teardown,
 249        .select                 = m527x_cs_select,
 250        .deselect               = m527x_cs_deselect,
 251};
 252
 253static struct mcfqspi_platform_data m527x_qspi_data = {
 254        .bus_num                = 0,
 255        .num_chipselect         = 4,
 256        .cs_control             = &m527x_cs_control,
 257};
 258
 259static struct platform_device m527x_qspi = {
 260        .name                   = "mcfqspi",
 261        .id                     = 0,
 262        .num_resources          = ARRAY_SIZE(m527x_qspi_resources),
 263        .resource               = m527x_qspi_resources,
 264        .dev.platform_data      = &m527x_qspi_data,
 265};
 266
 267static void __init m527x_qspi_init(void)
 268{
 269#if defined(CONFIG_M5271)
 270        u16 par;
 271
 272        /* setup QSPS pins for QSPI with gpio CS control */
 273        writeb(0x1f, MCFGPIO_PAR_QSPI);
 274        /* and CS2 & CS3 as gpio */
 275        par = readw(MCFGPIO_PAR_TIMER);
 276        par &= 0x3f3f;
 277        writew(par, MCFGPIO_PAR_TIMER);
 278#elif defined(CONFIG_M5275)
 279        /* setup QSPS pins for QSPI with gpio CS control */
 280        writew(0x003e, MCFGPIO_PAR_QSPI);
 281#endif
 282}
 283#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
 284
 285static struct platform_device *m527x_devices[] __initdata = {
 286        &m527x_uart,
 287        &m527x_fec[0],
 288#ifdef CONFIG_FEC2
 289        &m527x_fec[1],
 290#endif
 291#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 292        &m527x_qspi,
 293#endif
 294};
 295
 296/***************************************************************************/
 297
 298static void __init m527x_uart_init_line(int line, int irq)
 299{
 300        u16 sepmask;
 301
 302        if ((line < 0) || (line > 2))
 303                return;
 304
 305        /*
 306         * External Pin Mask Setting & Enable External Pin for Interface
 307         */
 308        sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
 309        if (line == 0)
 310                sepmask |= UART0_ENABLE_MASK;
 311        else if (line == 1)
 312                sepmask |= UART1_ENABLE_MASK;
 313        else if (line == 2)
 314                sepmask |= UART2_ENABLE_MASK;
 315        writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART);
 316}
 317
 318static void __init m527x_uarts_init(void)
 319{
 320        const int nrlines = ARRAY_SIZE(m527x_uart_platform);
 321        int line;
 322
 323        for (line = 0; (line < nrlines); line++)
 324                m527x_uart_init_line(line, m527x_uart_platform[line].irq);
 325}
 326
 327/***************************************************************************/
 328
 329static void __init m527x_fec_init(void)
 330{
 331        u16 par;
 332        u8 v;
 333
 334        /* Set multi-function pins to ethernet mode for fec0 */
 335#if defined(CONFIG_M5271)
 336        v = readb(MCF_IPSBAR + 0x100047);
 337        writeb(v | 0xf0, MCF_IPSBAR + 0x100047);
 338#else
 339        par = readw(MCF_IPSBAR + 0x100082);
 340        writew(par | 0xf00, MCF_IPSBAR + 0x100082);
 341        v = readb(MCF_IPSBAR + 0x100078);
 342        writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
 343#endif
 344
 345#ifdef CONFIG_FEC2
 346        /* Set multi-function pins to ethernet mode for fec1 */
 347        par = readw(MCF_IPSBAR + 0x100082);
 348        writew(par | 0xa0, MCF_IPSBAR + 0x100082);
 349        v = readb(MCF_IPSBAR + 0x100079);
 350        writeb(v | 0xc0, MCF_IPSBAR + 0x100079);
 351#endif
 352}
 353
 354/***************************************************************************/
 355
 356static void m527x_cpu_reset(void)
 357{
 358        local_irq_disable();
 359        __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
 360}
 361
 362/***************************************************************************/
 363
 364void __init config_BSP(char *commandp, int size)
 365{
 366        mach_reset = m527x_cpu_reset;
 367        m527x_uarts_init();
 368        m527x_fec_init();
 369#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 370        m527x_qspi_init();
 371#endif
 372}
 373
 374/***************************************************************************/
 375
 376static int __init init_BSP(void)
 377{
 378        platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
 379        return 0;
 380}
 381
 382arch_initcall(init_BSP);
 383
 384/***************************************************************************/
 385