linux/arch/arm/mach-sa1100/simpad.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-sa1100/simpad.c
   3 */
   4
   5#include <linux/module.h>
   6#include <linux/init.h>
   7#include <linux/kernel.h>
   8#include <linux/tty.h>
   9#include <linux/proc_fs.h>
  10#include <linux/string.h> 
  11#include <linux/pm.h>
  12#include <linux/platform_device.h>
  13#include <linux/mtd/mtd.h>
  14#include <linux/mtd/partitions.h>
  15#include <linux/io.h>
  16
  17#include <asm/irq.h>
  18#include <mach/hardware.h>
  19#include <asm/setup.h>
  20
  21#include <asm/mach-types.h>
  22#include <asm/mach/arch.h>
  23#include <asm/mach/flash.h>
  24#include <asm/mach/map.h>
  25#include <asm/mach/serial_sa1100.h>
  26#include <mach/mcp.h>
  27#include <mach/simpad.h>
  28
  29#include <linux/serial_core.h>
  30#include <linux/ioport.h>
  31
  32#include "generic.h"
  33
  34long cs3_shadow;
  35
  36long get_cs3_shadow(void)
  37{
  38        return cs3_shadow;
  39}
  40
  41void set_cs3(long value)
  42{
  43        *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
  44}
  45
  46void set_cs3_bit(int value)
  47{
  48        cs3_shadow |= value;
  49        *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
  50}
  51
  52void clear_cs3_bit(int value)
  53{
  54        cs3_shadow &= ~value;
  55        *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
  56}
  57
  58EXPORT_SYMBOL(set_cs3_bit);
  59EXPORT_SYMBOL(clear_cs3_bit);
  60
  61static struct map_desc simpad_io_desc[] __initdata = {
  62        {       /* MQ200 */
  63                .virtual        =  0xf2800000,
  64                .pfn            = __phys_to_pfn(0x4b800000),
  65                .length         = 0x00800000,
  66                .type           = MT_DEVICE
  67        }, {    /* Paules CS3, write only */
  68                .virtual        =  0xf1000000,
  69                .pfn            = __phys_to_pfn(0x18000000),
  70                .length         = 0x00100000,
  71                .type           = MT_DEVICE
  72        },
  73};
  74
  75
  76static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
  77{
  78        if (port->mapbase == (u_int)&Ser1UTCR0) {
  79                if (state)
  80                {
  81                        clear_cs3_bit(RS232_ON);
  82                        clear_cs3_bit(DECT_POWER_ON);
  83                }else
  84                {
  85                        set_cs3_bit(RS232_ON);
  86                        set_cs3_bit(DECT_POWER_ON);
  87                }
  88        }
  89}
  90
  91static struct sa1100_port_fns simpad_port_fns __initdata = {
  92        .pm        = simpad_uart_pm,
  93};
  94
  95
  96static struct mtd_partition simpad_partitions[] = {
  97        {
  98                .name       = "SIMpad boot firmware",
  99                .size       = 0x00080000,
 100                .offset     = 0,
 101                .mask_flags = MTD_WRITEABLE,
 102        }, {
 103                .name       = "SIMpad kernel",
 104                .size       = 0x0010000,
 105                .offset     = MTDPART_OFS_APPEND,
 106        }, {
 107                .name       = "SIMpad root jffs2",
 108                .size       = MTDPART_SIZ_FULL,
 109                .offset     = MTDPART_OFS_APPEND,
 110        }
 111};
 112
 113static struct flash_platform_data simpad_flash_data = {
 114        .map_name    = "cfi_probe",
 115        .parts       = simpad_partitions,
 116        .nr_parts    = ARRAY_SIZE(simpad_partitions),
 117};
 118
 119
 120static struct resource simpad_flash_resources [] = {
 121        {
 122                .start     = SA1100_CS0_PHYS,
 123                .end       = SA1100_CS0_PHYS + SZ_16M -1,
 124                .flags     = IORESOURCE_MEM,
 125        }, {
 126                .start     = SA1100_CS1_PHYS,
 127                .end       = SA1100_CS1_PHYS + SZ_16M -1,
 128                .flags     = IORESOURCE_MEM,
 129        }
 130};
 131
 132static struct mcp_plat_data simpad_mcp_data = {
 133        .mccr0          = MCCR0_ADM,
 134        .sclk_rate      = 11981000,
 135};
 136
 137
 138
 139static void __init simpad_map_io(void)
 140{
 141        sa1100_map_io();
 142
 143        iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
 144
 145        set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
 146                      ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
 147
 148
 149        sa1100_register_uart_fns(&simpad_port_fns);
 150        sa1100_register_uart(0, 3);  /* serial interface */
 151        sa1100_register_uart(1, 1);  /* DECT             */
 152
 153        // Reassign UART 1 pins
 154        GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
 155        GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
 156        GPDR &= ~GPIO_UART_RXD;
 157        PPAR |= PPAR_UPR;
 158
 159        /*
 160         * Set up registers for sleep mode.
 161         */
 162
 163
 164        PWER = PWER_GPIO0| PWER_RTC;
 165        PGSR = 0x818;
 166        PCFR = 0;
 167        PSDR = 0;
 168
 169        sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources,
 170                              ARRAY_SIZE(simpad_flash_resources));
 171        sa11x0_set_mcp_data(&simpad_mcp_data);
 172}
 173
 174static void simpad_power_off(void)
 175{
 176        local_irq_disable(); // was cli
 177        set_cs3(0x800);        /* only SD_MEDIAQ */
 178
 179        /* disable internal oscillator, float CS lines */
 180        PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
 181        /* enable wake-up on GPIO0 (Assabet...) */
 182        PWER = GFER = GRER = 1;
 183        /*
 184         * set scratchpad to zero, just in case it is used as a
 185         * restart address by the bootloader.
 186         */
 187        PSPR = 0;
 188        PGSR = 0;
 189        /* enter sleep mode */
 190        PMCR = PMCR_SF;
 191        while(1);
 192
 193        local_irq_enable(); /* we won't ever call it */
 194
 195
 196}
 197
 198
 199/*
 200 * MediaQ Video Device
 201 */
 202static struct platform_device simpad_mq200fb = {
 203        .name = "simpad-mq200",
 204        .id   = 0,
 205};
 206
 207static struct platform_device *devices[] __initdata = {
 208        &simpad_mq200fb
 209};
 210
 211
 212
 213static int __init simpad_init(void)
 214{
 215        int ret;
 216
 217        pm_power_off = simpad_power_off;
 218
 219        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 220        if(ret)
 221                printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
 222
 223        return 0;
 224}
 225
 226arch_initcall(simpad_init);
 227
 228
 229MACHINE_START(SIMPAD, "Simpad")
 230        /* Maintainer: Holger Freyther */
 231        .phys_io        = 0x80000000,
 232        .io_pg_offst    = ((0xf8000000) >> 18) & 0xfffc,
 233        .boot_params    = 0xc0000100,
 234        .map_io         = simpad_map_io,
 235        .init_irq       = sa1100_init_irq,
 236        .timer          = &sa1100_timer,
 237MACHINE_END
 238