linux/arch/m68knommu/platform/528x/config.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *      linux/arch/m68knommu/platform/528x/config.c
   5 *
   6 *      Sub-architcture dependant initialization code for the Freescale
   7 *      5280, 5281 and 5282 CPUs.
   8 *
   9 *      Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
  10 *      Copyright (C) 2001-2003, 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/platform_device.h>
  19#include <linux/io.h>
  20#include <linux/spi/spi.h>
  21#include <linux/gpio.h>
  22#include <asm/machdep.h>
  23#include <asm/coldfire.h>
  24#include <asm/mcfsim.h>
  25#include <asm/mcfuart.h>
  26#include <asm/mcfqspi.h>
  27
  28/***************************************************************************/
  29
  30static struct mcf_platform_uart m528x_uart_platform[] = {
  31        {
  32                .mapbase        = MCF_MBAR + MCFUART_BASE1,
  33                .irq            = MCFINT_VECBASE + MCFINT_UART0,
  34        },
  35        {
  36                .mapbase        = MCF_MBAR + MCFUART_BASE2,
  37                .irq            = MCFINT_VECBASE + MCFINT_UART0 + 1,
  38        },
  39        {
  40                .mapbase        = MCF_MBAR + MCFUART_BASE3,
  41                .irq            = MCFINT_VECBASE + MCFINT_UART0 + 2,
  42        },
  43        { },
  44};
  45
  46static struct platform_device m528x_uart = {
  47        .name                   = "mcfuart",
  48        .id                     = 0,
  49        .dev.platform_data      = m528x_uart_platform,
  50};
  51
  52static struct resource m528x_fec_resources[] = {
  53        {
  54                .start          = MCF_MBAR + 0x1000,
  55                .end            = MCF_MBAR + 0x1000 + 0x7ff,
  56                .flags          = IORESOURCE_MEM,
  57        },
  58        {
  59                .start          = 64 + 23,
  60                .end            = 64 + 23,
  61                .flags          = IORESOURCE_IRQ,
  62        },
  63        {
  64                .start          = 64 + 27,
  65                .end            = 64 + 27,
  66                .flags          = IORESOURCE_IRQ,
  67        },
  68        {
  69                .start          = 64 + 29,
  70                .end            = 64 + 29,
  71                .flags          = IORESOURCE_IRQ,
  72        },
  73};
  74
  75static struct platform_device m528x_fec = {
  76        .name                   = "fec",
  77        .id                     = 0,
  78        .num_resources          = ARRAY_SIZE(m528x_fec_resources),
  79        .resource               = m528x_fec_resources,
  80};
  81
  82#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
  83static struct resource m528x_qspi_resources[] = {
  84        {
  85                .start          = MCFQSPI_IOBASE,
  86                .end            = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
  87                .flags          = IORESOURCE_MEM,
  88        },
  89        {
  90                .start          = MCFINT_VECBASE + MCFINT_QSPI,
  91                .end            = MCFINT_VECBASE + MCFINT_QSPI,
  92                .flags          = IORESOURCE_IRQ,
  93        },
  94};
  95
  96#define MCFQSPI_CS0    147
  97#define MCFQSPI_CS1    148
  98#define MCFQSPI_CS2    149
  99#define MCFQSPI_CS3    150
 100
 101static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
 102{
 103        int status;
 104
 105        status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
 106        if (status) {
 107                pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
 108                goto fail0;
 109        }
 110        status = gpio_direction_output(MCFQSPI_CS0, 1);
 111        if (status) {
 112                pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
 113                goto fail1;
 114        }
 115
 116        status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
 117        if (status) {
 118                pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
 119                goto fail1;
 120        }
 121        status = gpio_direction_output(MCFQSPI_CS1, 1);
 122        if (status) {
 123                pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
 124                goto fail2;
 125        }
 126
 127        status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
 128        if (status) {
 129                pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
 130                goto fail2;
 131        }
 132        status = gpio_direction_output(MCFQSPI_CS2, 1);
 133        if (status) {
 134                pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
 135                goto fail3;
 136        }
 137
 138        status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
 139        if (status) {
 140                pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
 141                goto fail3;
 142        }
 143        status = gpio_direction_output(MCFQSPI_CS3, 1);
 144        if (status) {
 145                pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
 146                goto fail4;
 147        }
 148
 149        return 0;
 150
 151fail4:
 152        gpio_free(MCFQSPI_CS3);
 153fail3:
 154        gpio_free(MCFQSPI_CS2);
 155fail2:
 156        gpio_free(MCFQSPI_CS1);
 157fail1:
 158        gpio_free(MCFQSPI_CS0);
 159fail0:
 160        return status;
 161}
 162
 163static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
 164{
 165        gpio_free(MCFQSPI_CS3);
 166        gpio_free(MCFQSPI_CS2);
 167        gpio_free(MCFQSPI_CS1);
 168        gpio_free(MCFQSPI_CS0);
 169}
 170
 171static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
 172                            u8 chip_select, bool cs_high)
 173{
 174        gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
 175}
 176
 177static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
 178                              u8 chip_select, bool cs_high)
 179{
 180        gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
 181}
 182
 183static struct mcfqspi_cs_control m528x_cs_control = {
 184        .setup                  = m528x_cs_setup,
 185        .teardown               = m528x_cs_teardown,
 186        .select                 = m528x_cs_select,
 187        .deselect               = m528x_cs_deselect,
 188};
 189
 190static struct mcfqspi_platform_data m528x_qspi_data = {
 191        .bus_num                = 0,
 192        .num_chipselect         = 4,
 193        .cs_control             = &m528x_cs_control,
 194};
 195
 196static struct platform_device m528x_qspi = {
 197        .name                   = "mcfqspi",
 198        .id                     = 0,
 199        .num_resources          = ARRAY_SIZE(m528x_qspi_resources),
 200        .resource               = m528x_qspi_resources,
 201        .dev.platform_data      = &m528x_qspi_data,
 202};
 203
 204static void __init m528x_qspi_init(void)
 205{
 206        /* setup Port QS for QSPI with gpio CS control */
 207        __raw_writeb(0x07, MCFGPIO_PQSPAR);
 208}
 209#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
 210
 211static struct platform_device *m528x_devices[] __initdata = {
 212        &m528x_uart,
 213        &m528x_fec,
 214#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 215        &m528x_qspi,
 216#endif
 217};
 218
 219/***************************************************************************/
 220
 221static void __init m528x_uart_init_line(int line, int irq)
 222{
 223        u8 port;
 224
 225        if ((line < 0) || (line > 2))
 226                return;
 227
 228        /* make sure PUAPAR is set for UART0 and UART1 */
 229        if (line < 2) {
 230                port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
 231                port |= (0x03 << (line * 2));
 232                writeb(port, MCF_MBAR + MCF5282_GPIO_PUAPAR);
 233        }
 234}
 235
 236static void __init m528x_uarts_init(void)
 237{
 238        const int nrlines = ARRAY_SIZE(m528x_uart_platform);
 239        int line;
 240
 241        for (line = 0; (line < nrlines); line++)
 242                m528x_uart_init_line(line, m528x_uart_platform[line].irq);
 243}
 244
 245/***************************************************************************/
 246
 247static void __init m528x_fec_init(void)
 248{
 249        u16 v16;
 250
 251        /* Set multi-function pins to ethernet mode for fec0 */
 252        v16 = readw(MCF_IPSBAR + 0x100056);
 253        writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
 254        writeb(0xc0, MCF_IPSBAR + 0x100058);
 255}
 256
 257/***************************************************************************/
 258
 259static void m528x_cpu_reset(void)
 260{
 261        local_irq_disable();
 262        __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
 263}
 264
 265/***************************************************************************/
 266
 267#ifdef CONFIG_WILDFIRE
 268void wildfire_halt(void)
 269{
 270        writeb(0, 0x30000007);
 271        writeb(0x2, 0x30000007);
 272}
 273#endif
 274
 275#ifdef CONFIG_WILDFIREMOD
 276void wildfiremod_halt(void)
 277{
 278        printk(KERN_INFO "WildFireMod hibernating...\n");
 279
 280        /* Set portE.5 to Digital IO */
 281        MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
 282
 283        /* Make portE.5 an output */
 284        MCF5282_GPIO_DDRE |= (1 << 5);
 285
 286        /* Now toggle portE.5 from low to high */
 287        MCF5282_GPIO_PORTE &= ~(1 << 5);
 288        MCF5282_GPIO_PORTE |= (1 << 5);
 289
 290        printk(KERN_EMERG "Failed to hibernate. Halting!\n");
 291}
 292#endif
 293
 294void __init config_BSP(char *commandp, int size)
 295{
 296#ifdef CONFIG_WILDFIRE
 297        mach_halt = wildfire_halt;
 298#endif
 299#ifdef CONFIG_WILDFIREMOD
 300        mach_halt = wildfiremod_halt;
 301#endif
 302}
 303
 304/***************************************************************************/
 305
 306static int __init init_BSP(void)
 307{
 308        mach_reset = m528x_cpu_reset;
 309        m528x_uarts_init();
 310        m528x_fec_init();
 311#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 312        m528x_qspi_init();
 313#endif
 314        platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
 315        return 0;
 316}
 317
 318arch_initcall(init_BSP);
 319
 320/***************************************************************************/
 321