linux/arch/arm/mach-s3c2410/mach-vr1000.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
   2 *
   3 * Copyright (c) 2003-2005,2008 Simtec Electronics
   4 *   Ben Dooks <ben@simtec.co.uk>
   5 *
   6 * Machine support for Thorcom VR1000 board. Designed for Thorcom by
   7 * Simtec Electronics, http://www.simtec.co.uk/
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 *
  13*/
  14
  15#include <linux/kernel.h>
  16#include <linux/types.h>
  17#include <linux/interrupt.h>
  18#include <linux/list.h>
  19#include <linux/timer.h>
  20#include <linux/init.h>
  21#include <linux/gpio.h>
  22#include <linux/dm9000.h>
  23#include <linux/i2c.h>
  24
  25#include <linux/serial.h>
  26#include <linux/tty.h>
  27#include <linux/serial_8250.h>
  28#include <linux/serial_reg.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 <mach/bast-map.h>
  36#include <mach/vr1000-map.h>
  37#include <mach/vr1000-irq.h>
  38#include <mach/vr1000-cpld.h>
  39
  40#include <mach/hardware.h>
  41#include <asm/irq.h>
  42#include <asm/mach-types.h>
  43
  44#include <plat/regs-serial.h>
  45#include <mach/regs-gpio.h>
  46#include <mach/leds-gpio.h>
  47
  48#include <plat/clock.h>
  49#include <plat/devs.h>
  50#include <plat/cpu.h>
  51#include <plat/iic.h>
  52
  53#include "usb-simtec.h"
  54#include "nor-simtec.h"
  55
  56/* macros for virtual address mods for the io space entries */
  57#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
  58#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
  59#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
  60#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
  61
  62/* macros to modify the physical addresses for io space */
  63
  64#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
  65#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
  66#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
  67#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
  68
  69static struct map_desc vr1000_iodesc[] __initdata = {
  70  /* ISA IO areas */
  71  {
  72          .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
  73          .pfn          = PA_CS2(BAST_PA_ISAIO),
  74          .length       = SZ_16M,
  75          .type         = MT_DEVICE,
  76  }, {
  77          .virtual      = (u32)S3C24XX_VA_ISA_WORD,
  78          .pfn          = PA_CS3(BAST_PA_ISAIO),
  79          .length       = SZ_16M,
  80          .type         = MT_DEVICE,
  81  },
  82
  83  /*  CPLD control registers, and external interrupt controls */
  84  {
  85          .virtual      = (u32)VR1000_VA_CTRL1,
  86          .pfn          = __phys_to_pfn(VR1000_PA_CTRL1),
  87          .length       = SZ_1M,
  88          .type         = MT_DEVICE,
  89  }, {
  90          .virtual      = (u32)VR1000_VA_CTRL2,
  91          .pfn          = __phys_to_pfn(VR1000_PA_CTRL2),
  92          .length       = SZ_1M,
  93          .type         = MT_DEVICE,
  94  }, {
  95          .virtual      = (u32)VR1000_VA_CTRL3,
  96          .pfn          = __phys_to_pfn(VR1000_PA_CTRL3),
  97          .length       = SZ_1M,
  98          .type         = MT_DEVICE,
  99  }, {
 100          .virtual      = (u32)VR1000_VA_CTRL4,
 101          .pfn          = __phys_to_pfn(VR1000_PA_CTRL4),
 102          .length       = SZ_1M,
 103          .type         = MT_DEVICE,
 104  },
 105};
 106
 107#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
 108#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 109#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 110
 111/* uart clock source(s) */
 112
 113static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
 114        [0] = {
 115                .name           = "uclk",
 116                .divisor        = 1,
 117                .min_baud       = 0,
 118                .max_baud       = 0,
 119        },
 120        [1] = {
 121                .name           = "pclk",
 122                .divisor        = 1,
 123                .min_baud       = 0,
 124                .max_baud       = 0.
 125        }
 126};
 127
 128static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
 129        [0] = {
 130                .hwport      = 0,
 131                .flags       = 0,
 132                .ucon        = UCON,
 133                .ulcon       = ULCON,
 134                .ufcon       = UFCON,
 135                .clocks      = vr1000_serial_clocks,
 136                .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
 137        },
 138        [1] = {
 139                .hwport      = 1,
 140                .flags       = 0,
 141                .ucon        = UCON,
 142                .ulcon       = ULCON,
 143                .ufcon       = UFCON,
 144                .clocks      = vr1000_serial_clocks,
 145                .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
 146        },
 147        /* port 2 is not actually used */
 148        [2] = {
 149                .hwport      = 2,
 150                .flags       = 0,
 151                .ucon        = UCON,
 152                .ulcon       = ULCON,
 153                .ufcon       = UFCON,
 154                .clocks      = vr1000_serial_clocks,
 155                .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
 156
 157        }
 158};
 159
 160/* definitions for the vr1000 extra 16550 serial ports */
 161
 162#define VR1000_BAUDBASE (3692307)
 163
 164#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
 165
 166static struct plat_serial8250_port serial_platform_data[] = {
 167        [0] = {
 168                .mapbase        = VR1000_SERIAL_MAPBASE(0),
 169                .irq            = IRQ_VR1000_SERIAL + 0,
 170                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 171                .iotype         = UPIO_MEM,
 172                .regshift       = 0,
 173                .uartclk        = VR1000_BAUDBASE,
 174        },
 175        [1] = {
 176                .mapbase        = VR1000_SERIAL_MAPBASE(1),
 177                .irq            = IRQ_VR1000_SERIAL + 1,
 178                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 179                .iotype         = UPIO_MEM,
 180                .regshift       = 0,
 181                .uartclk        = VR1000_BAUDBASE,
 182        },
 183        [2] = {
 184                .mapbase        = VR1000_SERIAL_MAPBASE(2),
 185                .irq            = IRQ_VR1000_SERIAL + 2,
 186                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 187                .iotype         = UPIO_MEM,
 188                .regshift       = 0,
 189                .uartclk        = VR1000_BAUDBASE,
 190        },
 191        [3] = {
 192                .mapbase        = VR1000_SERIAL_MAPBASE(3),
 193                .irq            = IRQ_VR1000_SERIAL + 3,
 194                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
 195                .iotype         = UPIO_MEM,
 196                .regshift       = 0,
 197                .uartclk        = VR1000_BAUDBASE,
 198        },
 199        { },
 200};
 201
 202static struct platform_device serial_device = {
 203        .name                   = "serial8250",
 204        .id                     = PLAT8250_DEV_PLATFORM,
 205        .dev                    = {
 206                .platform_data  = serial_platform_data,
 207        },
 208};
 209
 210/* DM9000 ethernet devices */
 211
 212static struct resource vr1000_dm9k0_resource[] = {
 213        [0] = {
 214                .start = S3C2410_CS5 + VR1000_PA_DM9000,
 215                .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
 216                .flags = IORESOURCE_MEM
 217        },
 218        [1] = {
 219                .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
 220                .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
 221                .flags = IORESOURCE_MEM
 222        },
 223        [2] = {
 224                .start = IRQ_VR1000_DM9000A,
 225                .end   = IRQ_VR1000_DM9000A,
 226                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
 227        }
 228
 229};
 230
 231static struct resource vr1000_dm9k1_resource[] = {
 232        [0] = {
 233                .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
 234                .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
 235                .flags = IORESOURCE_MEM
 236        },
 237        [1] = {
 238                .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
 239                .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
 240                .flags = IORESOURCE_MEM
 241        },
 242        [2] = {
 243                .start = IRQ_VR1000_DM9000N,
 244                .end   = IRQ_VR1000_DM9000N,
 245                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
 246        }
 247};
 248
 249/* for the moment we limit ourselves to 16bit IO until some
 250 * better IO routines can be written and tested
 251*/
 252
 253static struct dm9000_plat_data vr1000_dm9k_platdata = {
 254        .flags          = DM9000_PLATF_16BITONLY,
 255};
 256
 257static struct platform_device vr1000_dm9k0 = {
 258        .name           = "dm9000",
 259        .id             = 0,
 260        .num_resources  = ARRAY_SIZE(vr1000_dm9k0_resource),
 261        .resource       = vr1000_dm9k0_resource,
 262        .dev            = {
 263                .platform_data = &vr1000_dm9k_platdata,
 264        }
 265};
 266
 267static struct platform_device vr1000_dm9k1 = {
 268        .name           = "dm9000",
 269        .id             = 1,
 270        .num_resources  = ARRAY_SIZE(vr1000_dm9k1_resource),
 271        .resource       = vr1000_dm9k1_resource,
 272        .dev            = {
 273                .platform_data = &vr1000_dm9k_platdata,
 274        }
 275};
 276
 277/* LEDS */
 278
 279static struct s3c24xx_led_platdata vr1000_led1_pdata = {
 280        .name           = "led1",
 281        .gpio           = S3C2410_GPB(0),
 282        .def_trigger    = "",
 283};
 284
 285static struct s3c24xx_led_platdata vr1000_led2_pdata = {
 286        .name           = "led2",
 287        .gpio           = S3C2410_GPB(1),
 288        .def_trigger    = "",
 289};
 290
 291static struct s3c24xx_led_platdata vr1000_led3_pdata = {
 292        .name           = "led3",
 293        .gpio           = S3C2410_GPB(2),
 294        .def_trigger    = "",
 295};
 296
 297static struct platform_device vr1000_led1 = {
 298        .name           = "s3c24xx_led",
 299        .id             = 1,
 300        .dev            = {
 301                .platform_data  = &vr1000_led1_pdata,
 302        },
 303};
 304
 305static struct platform_device vr1000_led2 = {
 306        .name           = "s3c24xx_led",
 307        .id             = 2,
 308        .dev            = {
 309                .platform_data  = &vr1000_led2_pdata,
 310        },
 311};
 312
 313static struct platform_device vr1000_led3 = {
 314        .name           = "s3c24xx_led",
 315        .id             = 3,
 316        .dev            = {
 317                .platform_data  = &vr1000_led3_pdata,
 318        },
 319};
 320
 321/* I2C devices. */
 322
 323static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
 324        {
 325                I2C_BOARD_INFO("tlv320aic23", 0x1a),
 326        }, {
 327                I2C_BOARD_INFO("tmp101", 0x48),
 328        }, {
 329                I2C_BOARD_INFO("m41st87", 0x68),
 330        },
 331};
 332
 333/* devices for this board */
 334
 335static struct platform_device *vr1000_devices[] __initdata = {
 336        &s3c_device_usb,
 337        &s3c_device_lcd,
 338        &s3c_device_wdt,
 339        &s3c_device_i2c0,
 340        &s3c_device_adc,
 341        &serial_device,
 342        &vr1000_dm9k0,
 343        &vr1000_dm9k1,
 344        &vr1000_led1,
 345        &vr1000_led2,
 346        &vr1000_led3,
 347};
 348
 349static struct clk *vr1000_clocks[] __initdata = {
 350        &s3c24xx_dclk0,
 351        &s3c24xx_dclk1,
 352        &s3c24xx_clkout0,
 353        &s3c24xx_clkout1,
 354        &s3c24xx_uclk,
 355};
 356
 357static void vr1000_power_off(void)
 358{
 359        s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT);
 360        s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
 361}
 362
 363static void __init vr1000_map_io(void)
 364{
 365        /* initialise clock sources */
 366
 367        s3c24xx_dclk0.parent = &clk_upll;
 368        s3c24xx_dclk0.rate   = 12*1000*1000;
 369
 370        s3c24xx_dclk1.parent = NULL;
 371        s3c24xx_dclk1.rate   = 3692307;
 372
 373        s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
 374        s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
 375
 376        s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 377
 378        s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
 379
 380        pm_power_off = vr1000_power_off;
 381
 382        s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 383        s3c24xx_init_clocks(0);
 384        s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 385}
 386
 387static void __init vr1000_init(void)
 388{
 389        s3c_i2c0_set_platdata(NULL);
 390        platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
 391
 392        i2c_register_board_info(0, vr1000_i2c_devs,
 393                                ARRAY_SIZE(vr1000_i2c_devs));
 394
 395        nor_simtec_init();
 396}
 397
 398MACHINE_START(VR1000, "Thorcom-VR1000")
 399        /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 400        .phys_io        = S3C2410_PA_UART,
 401        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 402        .boot_params    = S3C2410_SDRAM_PA + 0x100,
 403        .map_io         = vr1000_map_io,
 404        .init_machine   = vr1000_init,
 405        .init_irq       = s3c24xx_init_irq,
 406        .timer          = &s3c24xx_timer,
 407MACHINE_END
 408