linux/arch/arm/mach-s3c24xx/mach-vr1000.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2003-2008 Simtec Electronics
   3 *   Ben Dooks <ben@simtec.co.uk>
   4 *
   5 * Machine support for Thorcom VR1000 board. Designed for Thorcom by
   6 * Simtec Electronics, http://www.simtec.co.uk/
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12*/
  13
  14#include <linux/kernel.h>
  15#include <linux/types.h>
  16#include <linux/interrupt.h>
  17#include <linux/list.h>
  18#include <linux/timer.h>
  19#include <linux/init.h>
  20#include <linux/gpio.h>
  21#include <linux/dm9000.h>
  22#include <linux/i2c.h>
  23
  24#include <linux/serial.h>
  25#include <linux/tty.h>
  26#include <linux/serial_8250.h>
  27#include <linux/serial_reg.h>
  28#include <linux/serial_s3c.h>
  29#include <linux/io.h>
  30
  31#include <asm/mach/arch.h>
  32#include <asm/mach/map.h>
  33#include <asm/mach/irq.h>
  34
  35#include <asm/irq.h>
  36#include <asm/mach-types.h>
  37
  38#include <linux/platform_data/leds-s3c24xx.h>
  39#include <linux/platform_data/i2c-s3c2410.h>
  40#include <linux/platform_data/asoc-s3c24xx_simtec.h>
  41
  42#include <mach/hardware.h>
  43#include <mach/regs-gpio.h>
  44#include <mach/gpio-samsung.h>
  45
  46#include <plat/cpu.h>
  47#include <plat/devs.h>
  48#include <plat/samsung-time.h>
  49
  50#include "bast.h"
  51#include "common.h"
  52#include "simtec.h"
  53#include "vr1000.h"
  54
  55/* macros for virtual address mods for the io space entries */
  56#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
  57#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
  58#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
  59#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
  60
  61/* macros to modify the physical addresses for io space */
  62
  63#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
  64#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
  65#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
  66#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
  67
  68static struct map_desc vr1000_iodesc[] __initdata = {
  69  /* ISA IO areas */
  70  {
  71          .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
  72          .pfn          = PA_CS2(BAST_PA_ISAIO),
  73          .length       = SZ_16M,
  74          .type         = MT_DEVICE,
  75  }, {
  76          .virtual      = (u32)S3C24XX_VA_ISA_WORD,
  77          .pfn          = PA_CS3(BAST_PA_ISAIO),
  78          .length       = SZ_16M,
  79          .type         = MT_DEVICE,
  80  },
  81
  82  /*  CPLD control registers, and external interrupt controls */
  83  {
  84          .virtual      = (u32)VR1000_VA_CTRL1,
  85          .pfn          = __phys_to_pfn(VR1000_PA_CTRL1),
  86          .length       = SZ_1M,
  87          .type         = MT_DEVICE,
  88  }, {
  89          .virtual      = (u32)VR1000_VA_CTRL2,
  90          .pfn          = __phys_to_pfn(VR1000_PA_CTRL2),
  91          .length       = SZ_1M,
  92          .type         = MT_DEVICE,
  93  }, {
  94          .virtual      = (u32)VR1000_VA_CTRL3,
  95          .pfn          = __phys_to_pfn(VR1000_PA_CTRL3),
  96          .length       = SZ_1M,
  97          .type         = MT_DEVICE,
  98  }, {
  99          .virtual      = (u32)VR1000_VA_CTRL4,
 100          .pfn          = __phys_to_pfn(VR1000_PA_CTRL4),
 101          .length       = SZ_1M,
 102          .type         = MT_DEVICE,
 103  },
 104};
 105
 106#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
 107#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 108#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 109
 110static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
 111        [0] = {
 112                .hwport      = 0,
 113                .flags       = 0,
 114                .ucon        = UCON,
 115                .ulcon       = ULCON,
 116                .ufcon       = UFCON,
 117        },
 118        [1] = {
 119                .hwport      = 1,
 120                .flags       = 0,
 121                .ucon        = UCON,
 122                .ulcon       = ULCON,
 123                .ufcon       = UFCON,
 124        },
 125        /* port 2 is not actually used */
 126        [2] = {
 127                .hwport      = 2,
 128                .flags       = 0,
 129                .ucon        = UCON,
 130                .ulcon       = ULCON,
 131                .ufcon       = UFCON,
 132        }
 133};
 134
 135/* definitions for the vr1000 extra 16550 serial ports */
 136
 137#define VR1000_BAUDBASE (3692307)
 138
 139#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
 140
 141static struct plat_serial8250_port serial_platform_data[] = {
 142        [0] = {
 143                .mapbase        = VR1000_SERIAL_MAPBASE(0),
 144                .irq            = VR1000_IRQ_SERIAL + 0,
 145                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 146                .iotype         = UPIO_MEM,
 147                .regshift       = 0,
 148                .uartclk        = VR1000_BAUDBASE,
 149        },
 150        [1] = {
 151                .mapbase        = VR1000_SERIAL_MAPBASE(1),
 152                .irq            = VR1000_IRQ_SERIAL + 1,
 153                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 154                .iotype         = UPIO_MEM,
 155                .regshift       = 0,
 156                .uartclk        = VR1000_BAUDBASE,
 157        },
 158        [2] = {
 159                .mapbase        = VR1000_SERIAL_MAPBASE(2),
 160                .irq            = VR1000_IRQ_SERIAL + 2,
 161                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 162                .iotype         = UPIO_MEM,
 163                .regshift       = 0,
 164                .uartclk        = VR1000_BAUDBASE,
 165        },
 166        [3] = {
 167                .mapbase        = VR1000_SERIAL_MAPBASE(3),
 168                .irq            = VR1000_IRQ_SERIAL + 3,
 169                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 170                .iotype         = UPIO_MEM,
 171                .regshift       = 0,
 172                .uartclk        = VR1000_BAUDBASE,
 173        },
 174        { },
 175};
 176
 177static struct platform_device serial_device = {
 178        .name                   = "serial8250",
 179        .id                     = PLAT8250_DEV_PLATFORM,
 180        .dev                    = {
 181                .platform_data  = serial_platform_data,
 182        },
 183};
 184
 185/* DM9000 ethernet devices */
 186
 187static struct resource vr1000_dm9k0_resource[] = {
 188        [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000, 4),
 189        [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x40, 0x40),
 190        [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000A, 1, NULL, IORESOURCE_IRQ \
 191                                                | IORESOURCE_IRQ_HIGHLEVEL),
 192};
 193
 194static struct resource vr1000_dm9k1_resource[] = {
 195        [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x80, 4),
 196        [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0, 0x40),
 197        [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000N, 1, NULL, IORESOURCE_IRQ \
 198                                                | IORESOURCE_IRQ_HIGHLEVEL),
 199};
 200
 201/* for the moment we limit ourselves to 16bit IO until some
 202 * better IO routines can be written and tested
 203*/
 204
 205static struct dm9000_plat_data vr1000_dm9k_platdata = {
 206        .flags          = DM9000_PLATF_16BITONLY,
 207};
 208
 209static struct platform_device vr1000_dm9k0 = {
 210        .name           = "dm9000",
 211        .id             = 0,
 212        .num_resources  = ARRAY_SIZE(vr1000_dm9k0_resource),
 213        .resource       = vr1000_dm9k0_resource,
 214        .dev            = {
 215                .platform_data = &vr1000_dm9k_platdata,
 216        }
 217};
 218
 219static struct platform_device vr1000_dm9k1 = {
 220        .name           = "dm9000",
 221        .id             = 1,
 222        .num_resources  = ARRAY_SIZE(vr1000_dm9k1_resource),
 223        .resource       = vr1000_dm9k1_resource,
 224        .dev            = {
 225                .platform_data = &vr1000_dm9k_platdata,
 226        }
 227};
 228
 229/* LEDS */
 230
 231static struct s3c24xx_led_platdata vr1000_led1_pdata = {
 232        .name           = "led1",
 233        .gpio           = S3C2410_GPB(0),
 234        .def_trigger    = "",
 235};
 236
 237static struct s3c24xx_led_platdata vr1000_led2_pdata = {
 238        .name           = "led2",
 239        .gpio           = S3C2410_GPB(1),
 240        .def_trigger    = "",
 241};
 242
 243static struct s3c24xx_led_platdata vr1000_led3_pdata = {
 244        .name           = "led3",
 245        .gpio           = S3C2410_GPB(2),
 246        .def_trigger    = "",
 247};
 248
 249static struct platform_device vr1000_led1 = {
 250        .name           = "s3c24xx_led",
 251        .id             = 1,
 252        .dev            = {
 253                .platform_data  = &vr1000_led1_pdata,
 254        },
 255};
 256
 257static struct platform_device vr1000_led2 = {
 258        .name           = "s3c24xx_led",
 259        .id             = 2,
 260        .dev            = {
 261                .platform_data  = &vr1000_led2_pdata,
 262        },
 263};
 264
 265static struct platform_device vr1000_led3 = {
 266        .name           = "s3c24xx_led",
 267        .id             = 3,
 268        .dev            = {
 269                .platform_data  = &vr1000_led3_pdata,
 270        },
 271};
 272
 273/* I2C devices. */
 274
 275static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
 276        {
 277                I2C_BOARD_INFO("tlv320aic23", 0x1a),
 278        }, {
 279                I2C_BOARD_INFO("tmp101", 0x48),
 280        }, {
 281                I2C_BOARD_INFO("m41st87", 0x68),
 282        },
 283};
 284
 285/* devices for this board */
 286
 287static struct platform_device *vr1000_devices[] __initdata = {
 288        &s3c2410_device_dclk,
 289        &s3c_device_ohci,
 290        &s3c_device_lcd,
 291        &s3c_device_wdt,
 292        &s3c_device_i2c0,
 293        &s3c_device_adc,
 294        &serial_device,
 295        &vr1000_dm9k0,
 296        &vr1000_dm9k1,
 297        &vr1000_led1,
 298        &vr1000_led2,
 299        &vr1000_led3,
 300};
 301
 302static void vr1000_power_off(void)
 303{
 304        gpio_direction_output(S3C2410_GPB(9), 1);
 305}
 306
 307static void __init vr1000_map_io(void)
 308{
 309        pm_power_off = vr1000_power_off;
 310
 311        s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 312        s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 313        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 314}
 315
 316static void __init vr1000_init_time(void)
 317{
 318        s3c2410_init_clocks(12000000);
 319        samsung_timer_init();
 320}
 321
 322static void __init vr1000_init(void)
 323{
 324        s3c_i2c0_set_platdata(NULL);
 325        platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
 326
 327        i2c_register_board_info(0, vr1000_i2c_devs,
 328                                ARRAY_SIZE(vr1000_i2c_devs));
 329
 330        nor_simtec_init();
 331        simtec_audio_add(NULL, true, NULL);
 332
 333        WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
 334}
 335
 336MACHINE_START(VR1000, "Thorcom-VR1000")
 337        /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 338        .atag_offset    = 0x100,
 339        .map_io         = vr1000_map_io,
 340        .init_machine   = vr1000_init,
 341        .init_irq       = s3c2410_init_irq,
 342        .init_time      = vr1000_init_time,
 343MACHINE_END
 344