linux/arch/arm/mach-s3c2440/mach-anubis.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s3c2440/mach-anubis.c
   2 *
   3 * Copyright (c) 2003-2005,2008 Simtec Electronics
   4 *      http://armlinux.simtec.co.uk/
   5 *      Ben Dooks <ben@simtec.co.uk>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10*/
  11
  12#include <linux/kernel.h>
  13#include <linux/types.h>
  14#include <linux/interrupt.h>
  15#include <linux/list.h>
  16#include <linux/timer.h>
  17#include <linux/init.h>
  18#include <linux/gpio.h>
  19#include <linux/serial_core.h>
  20#include <linux/platform_device.h>
  21#include <linux/ata_platform.h>
  22#include <linux/i2c.h>
  23#include <linux/io.h>
  24#include <linux/sm501.h>
  25#include <linux/sm501-regs.h>
  26
  27#include <asm/mach/arch.h>
  28#include <asm/mach/map.h>
  29#include <asm/mach/irq.h>
  30
  31#include <mach/anubis-map.h>
  32#include <mach/anubis-irq.h>
  33#include <mach/anubis-cpld.h>
  34
  35#include <mach/hardware.h>
  36#include <asm/irq.h>
  37#include <asm/mach-types.h>
  38
  39#include <plat/regs-serial.h>
  40#include <mach/regs-gpio.h>
  41#include <mach/regs-mem.h>
  42#include <mach/regs-lcd.h>
  43#include <plat/nand.h>
  44#include <plat/iic.h>
  45
  46#include <linux/mtd/mtd.h>
  47#include <linux/mtd/nand.h>
  48#include <linux/mtd/nand_ecc.h>
  49#include <linux/mtd/partitions.h>
  50
  51#include <net/ax88796.h>
  52
  53#include <plat/clock.h>
  54#include <plat/devs.h>
  55#include <plat/cpu.h>
  56
  57#define COPYRIGHT ", (c) 2005 Simtec Electronics"
  58
  59static struct map_desc anubis_iodesc[] __initdata = {
  60  /* ISA IO areas */
  61
  62  {
  63        .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
  64        .pfn            = __phys_to_pfn(0x0),
  65        .length         = SZ_4M,
  66        .type           = MT_DEVICE,
  67  }, {
  68        .virtual        = (u32)S3C24XX_VA_ISA_WORD,
  69        .pfn            = __phys_to_pfn(0x0),
  70        .length         = SZ_4M,
  71        .type           = MT_DEVICE,
  72  },
  73
  74  /* we could possibly compress the next set down into a set of smaller tables
  75   * pagetables, but that would mean using an L2 section, and it still means
  76   * we cannot actually feed the same register to an LDR due to 16K spacing
  77   */
  78
  79  /* CPLD control registers */
  80
  81  {
  82        .virtual        = (u32)ANUBIS_VA_CTRL1,
  83        .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL1),
  84        .length         = SZ_4K,
  85        .type           = MT_DEVICE,
  86  }, {
  87        .virtual        = (u32)ANUBIS_VA_IDREG,
  88        .pfn            = __phys_to_pfn(ANUBIS_PA_IDREG),
  89        .length         = SZ_4K,
  90        .type           = MT_DEVICE,
  91  },
  92};
  93
  94#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
  95#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
  96#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
  97
  98static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
  99        [0] = {
 100                .name           = "uclk",
 101                .divisor        = 1,
 102                .min_baud       = 0,
 103                .max_baud       = 0,
 104        },
 105        [1] = {
 106                .name           = "pclk",
 107                .divisor        = 1,
 108                .min_baud       = 0,
 109                .max_baud       = 0,
 110        }
 111};
 112
 113
 114static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
 115        [0] = {
 116                .hwport      = 0,
 117                .flags       = 0,
 118                .ucon        = UCON,
 119                .ulcon       = ULCON,
 120                .ufcon       = UFCON,
 121                .clocks      = anubis_serial_clocks,
 122                .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
 123        },
 124        [1] = {
 125                .hwport      = 2,
 126                .flags       = 0,
 127                .ucon        = UCON,
 128                .ulcon       = ULCON,
 129                .ufcon       = UFCON,
 130                .clocks      = anubis_serial_clocks,
 131                .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
 132        },
 133};
 134
 135/* NAND Flash on Anubis board */
 136
 137static int external_map[]   = { 2 };
 138static int chip0_map[]      = { 0 };
 139static int chip1_map[]      = { 1 };
 140
 141static struct mtd_partition anubis_default_nand_part[] = {
 142        [0] = {
 143                .name   = "Boot Agent",
 144                .size   = SZ_16K,
 145                .offset = 0,
 146        },
 147        [1] = {
 148                .name   = "/boot",
 149                .size   = SZ_4M - SZ_16K,
 150                .offset = SZ_16K,
 151        },
 152        [2] = {
 153                .name   = "user1",
 154                .offset = SZ_4M,
 155                .size   = SZ_32M - SZ_4M,
 156        },
 157        [3] = {
 158                .name   = "user2",
 159                .offset = SZ_32M,
 160                .size   = MTDPART_SIZ_FULL,
 161        }
 162};
 163
 164static struct mtd_partition anubis_default_nand_part_large[] = {
 165        [0] = {
 166                .name   = "Boot Agent",
 167                .size   = SZ_128K,
 168                .offset = 0,
 169        },
 170        [1] = {
 171                .name   = "/boot",
 172                .size   = SZ_4M - SZ_128K,
 173                .offset = SZ_128K,
 174        },
 175        [2] = {
 176                .name   = "user1",
 177                .offset = SZ_4M,
 178                .size   = SZ_32M - SZ_4M,
 179        },
 180        [3] = {
 181                .name   = "user2",
 182                .offset = SZ_32M,
 183                .size   = MTDPART_SIZ_FULL,
 184        }
 185};
 186
 187/* the Anubis has 3 selectable slots for nand-flash, the two
 188 * on-board chip areas, as well as the external slot.
 189 *
 190 * Note, there is no current hot-plug support for the External
 191 * socket.
 192*/
 193
 194static struct s3c2410_nand_set anubis_nand_sets[] = {
 195        [1] = {
 196                .name           = "External",
 197                .nr_chips       = 1,
 198                .nr_map         = external_map,
 199                .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
 200                .partitions     = anubis_default_nand_part,
 201        },
 202        [0] = {
 203                .name           = "chip0",
 204                .nr_chips       = 1,
 205                .nr_map         = chip0_map,
 206                .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
 207                .partitions     = anubis_default_nand_part,
 208        },
 209        [2] = {
 210                .name           = "chip1",
 211                .nr_chips       = 1,
 212                .nr_map         = chip1_map,
 213                .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
 214                .partitions     = anubis_default_nand_part,
 215        },
 216};
 217
 218static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
 219{
 220        unsigned int tmp;
 221
 222        slot = set->nr_map[slot] & 3;
 223
 224        pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
 225                 slot, set, set->nr_map);
 226
 227        tmp = __raw_readb(ANUBIS_VA_CTRL1);
 228        tmp &= ~ANUBIS_CTRL1_NANDSEL;
 229        tmp |= slot;
 230
 231        pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
 232
 233        __raw_writeb(tmp, ANUBIS_VA_CTRL1);
 234}
 235
 236static struct s3c2410_platform_nand anubis_nand_info = {
 237        .tacls          = 25,
 238        .twrph0         = 55,
 239        .twrph1         = 40,
 240        .nr_sets        = ARRAY_SIZE(anubis_nand_sets),
 241        .sets           = anubis_nand_sets,
 242        .select_chip    = anubis_nand_select,
 243};
 244
 245/* IDE channels */
 246
 247static struct pata_platform_info anubis_ide_platdata = {
 248        .ioport_shift   = 5,
 249};
 250
 251static struct resource anubis_ide0_resource[] = {
 252        {
 253                .start  = S3C2410_CS3,
 254                .end    = S3C2410_CS3 + (8*32) - 1,
 255                .flags  = IORESOURCE_MEM,
 256        }, {
 257                .start  = S3C2410_CS3 + (1<<26) + (6*32),
 258                .end    = S3C2410_CS3 + (1<<26) + (7*32) - 1,
 259                .flags  = IORESOURCE_MEM,
 260        }, {
 261                .start  = IRQ_IDE0,
 262                .end    = IRQ_IDE0,
 263                .flags  = IORESOURCE_IRQ,
 264        },
 265};
 266
 267static struct platform_device anubis_device_ide0 = {
 268        .name           = "pata_platform",
 269        .id             = 0,
 270        .num_resources  = ARRAY_SIZE(anubis_ide0_resource),
 271        .resource       = anubis_ide0_resource,
 272        .dev    = {
 273                .platform_data = &anubis_ide_platdata,
 274                .coherent_dma_mask = ~0,
 275        },
 276};
 277
 278static struct resource anubis_ide1_resource[] = {
 279        {
 280                .start  = S3C2410_CS4,
 281                .end    = S3C2410_CS4 + (8*32) - 1,
 282                .flags  = IORESOURCE_MEM,
 283        }, {
 284                .start  = S3C2410_CS4 + (1<<26) + (6*32),
 285                .end    = S3C2410_CS4 + (1<<26) + (7*32) - 1,
 286                .flags  = IORESOURCE_MEM,
 287        }, {
 288                .start  = IRQ_IDE0,
 289                .end    = IRQ_IDE0,
 290                .flags  = IORESOURCE_IRQ,
 291        },
 292};
 293
 294static struct platform_device anubis_device_ide1 = {
 295        .name           = "pata_platform",
 296        .id             = 1,
 297        .num_resources  = ARRAY_SIZE(anubis_ide1_resource),
 298        .resource       = anubis_ide1_resource,
 299        .dev    = {
 300                .platform_data = &anubis_ide_platdata,
 301                .coherent_dma_mask = ~0,
 302        },
 303};
 304
 305/* Asix AX88796 10/100 ethernet controller */
 306
 307static struct ax_plat_data anubis_asix_platdata = {
 308        .flags          = AXFLG_MAC_FROMDEV,
 309        .wordlength     = 2,
 310        .dcr_val        = 0x48,
 311        .rcr_val        = 0x40,
 312};
 313
 314static struct resource anubis_asix_resource[] = {
 315        [0] = {
 316                .start = S3C2410_CS5,
 317                .end   = S3C2410_CS5 + (0x20 * 0x20) -1,
 318                .flags = IORESOURCE_MEM
 319        },
 320        [1] = {
 321                .start = IRQ_ASIX,
 322                .end   = IRQ_ASIX,
 323                .flags = IORESOURCE_IRQ
 324        }
 325};
 326
 327static struct platform_device anubis_device_asix = {
 328        .name           = "ax88796",
 329        .id             = 0,
 330        .num_resources  = ARRAY_SIZE(anubis_asix_resource),
 331        .resource       = anubis_asix_resource,
 332        .dev            = {
 333                .platform_data = &anubis_asix_platdata,
 334        }
 335};
 336
 337/* SM501 */
 338
 339static struct resource anubis_sm501_resource[] = {
 340        [0] = {
 341                .start  = S3C2410_CS2,
 342                .end    = S3C2410_CS2 + SZ_8M,
 343                .flags  = IORESOURCE_MEM,
 344        },
 345        [1] = {
 346                .start  = S3C2410_CS2 + SZ_64M - SZ_2M,
 347                .end    = S3C2410_CS2 + SZ_64M - 1,
 348                .flags  = IORESOURCE_MEM,
 349        },
 350        [2] = {
 351                .start  = IRQ_EINT0,
 352                .end    = IRQ_EINT0,
 353                .flags  = IORESOURCE_IRQ,
 354        },
 355};
 356
 357static struct sm501_initdata anubis_sm501_initdata = {
 358        .gpio_high      = {
 359                .set    = 0x3F000000,           /* 24bit panel */
 360                .mask   = 0x0,
 361        },
 362        .misc_timing    = {
 363                .set    = 0x010100,             /* SDRAM timing */
 364                .mask   = 0x1F1F00,
 365        },
 366        .misc_control   = {
 367                .set    = SM501_MISC_PNL_24BIT,
 368                .mask   = 0,
 369        },
 370
 371        .devices        = SM501_USE_GPIO,
 372
 373        /* set the SDRAM and bus clocks */
 374        .mclk           = 72 * MHZ,
 375        .m1xclk         = 144 * MHZ,
 376};
 377
 378static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
 379        [0] = {
 380                .bus_num        = 1,
 381                .pin_scl        = 44,
 382                .pin_sda        = 45,
 383        },
 384        [1] = {
 385                .bus_num        = 2,
 386                .pin_scl        = 40,
 387                .pin_sda        = 41,
 388        },
 389};
 390
 391static struct sm501_platdata anubis_sm501_platdata = {
 392        .init           = &anubis_sm501_initdata,
 393        .gpio_base      = -1,
 394        .gpio_i2c       = anubis_sm501_gpio_i2c,
 395        .gpio_i2c_nr    = ARRAY_SIZE(anubis_sm501_gpio_i2c),
 396};
 397
 398static struct platform_device anubis_device_sm501 = {
 399        .name           = "sm501",
 400        .id             = 0,
 401        .num_resources  = ARRAY_SIZE(anubis_sm501_resource),
 402        .resource       = anubis_sm501_resource,
 403        .dev            = {
 404                .platform_data = &anubis_sm501_platdata,
 405        },
 406};
 407
 408/* Standard Anubis devices */
 409
 410static struct platform_device *anubis_devices[] __initdata = {
 411        &s3c_device_usb,
 412        &s3c_device_wdt,
 413        &s3c_device_adc,
 414        &s3c_device_i2c0,
 415        &s3c_device_rtc,
 416        &s3c_device_nand,
 417        &anubis_device_ide0,
 418        &anubis_device_ide1,
 419        &anubis_device_asix,
 420        &anubis_device_sm501,
 421};
 422
 423static struct clk *anubis_clocks[] __initdata = {
 424        &s3c24xx_dclk0,
 425        &s3c24xx_dclk1,
 426        &s3c24xx_clkout0,
 427        &s3c24xx_clkout1,
 428        &s3c24xx_uclk,
 429};
 430
 431/* I2C devices. */
 432
 433static struct i2c_board_info anubis_i2c_devs[] __initdata = {
 434        {
 435                I2C_BOARD_INFO("tps65011", 0x48),
 436                .irq    = IRQ_EINT20,
 437        }
 438};
 439
 440static void __init anubis_map_io(void)
 441{
 442        /* initialise the clocks */
 443
 444        s3c24xx_dclk0.parent = &clk_upll;
 445        s3c24xx_dclk0.rate   = 12*1000*1000;
 446
 447        s3c24xx_dclk1.parent = &clk_upll;
 448        s3c24xx_dclk1.rate   = 24*1000*1000;
 449
 450        s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
 451        s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
 452
 453        s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 454
 455        s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
 456
 457        s3c_device_nand.dev.platform_data = &anubis_nand_info;
 458
 459        s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 460        s3c24xx_init_clocks(0);
 461        s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
 462
 463        /* check for the newer revision boards with large page nand */
 464
 465        if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
 466                printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
 467                       __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
 468                anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
 469                anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
 470        } else {
 471                /* ensure that the GPIO is setup */
 472                s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
 473        }
 474}
 475
 476static void __init anubis_init(void)
 477{
 478        s3c_i2c0_set_platdata(NULL);
 479        platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
 480
 481        i2c_register_board_info(0, anubis_i2c_devs,
 482                                ARRAY_SIZE(anubis_i2c_devs));
 483}
 484
 485
 486MACHINE_START(ANUBIS, "Simtec-Anubis")
 487        /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 488        .phys_io        = S3C2410_PA_UART,
 489        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 490        .boot_params    = S3C2410_SDRAM_PA + 0x100,
 491        .map_io         = anubis_map_io,
 492        .init_machine   = anubis_init,
 493        .init_irq       = s3c24xx_init_irq,
 494        .timer          = &s3c24xx_timer,
 495MACHINE_END
 496