linux/arch/arm/mach-s3c24xx/mach-qt2410.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// Copyright (C) 2006 by OpenMoko, Inc.
   4// Author: Harald Welte <laforge@openmoko.org>
   5// All rights reserved.
   6
   7#include <linux/kernel.h>
   8#include <linux/types.h>
   9#include <linux/interrupt.h>
  10#include <linux/list.h>
  11#include <linux/timer.h>
  12#include <linux/init.h>
  13#include <linux/gpio.h>
  14#include <linux/gpio/machine.h>
  15#include <linux/device.h>
  16#include <linux/platform_device.h>
  17#include <linux/serial_core.h>
  18#include <linux/serial_s3c.h>
  19#include <linux/spi/spi.h>
  20#include <linux/spi/spi_gpio.h>
  21#include <linux/io.h>
  22#include <linux/mtd/mtd.h>
  23#include <linux/mtd/rawnand.h>
  24#include <linux/mtd/nand_ecc.h>
  25#include <linux/mtd/partitions.h>
  26
  27#include <asm/mach/arch.h>
  28#include <asm/mach/map.h>
  29#include <asm/mach/irq.h>
  30
  31#include <mach/hardware.h>
  32#include <asm/irq.h>
  33#include <asm/mach-types.h>
  34
  35#include <linux/platform_data/leds-s3c24xx.h>
  36#include <mach/regs-lcd.h>
  37#include <mach/fb.h>
  38#include <linux/platform_data/mtd-nand-s3c2410.h>
  39#include <linux/platform_data/usb-s3c2410_udc.h>
  40#include <linux/platform_data/i2c-s3c2410.h>
  41#include <mach/gpio-samsung.h>
  42
  43#include <plat/gpio-cfg.h>
  44#include <plat/devs.h>
  45#include <plat/cpu.h>
  46#include <plat/pm.h>
  47#include <plat/samsung-time.h>
  48
  49#include "common.h"
  50#include "common-smdk.h"
  51
  52static struct map_desc qt2410_iodesc[] __initdata = {
  53        { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
  54};
  55
  56#define UCON S3C2410_UCON_DEFAULT
  57#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
  58#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
  59
  60static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
  61        [0] = {
  62                .hwport      = 0,
  63                .flags       = 0,
  64                .ucon        = UCON,
  65                .ulcon       = ULCON,
  66                .ufcon       = UFCON,
  67        },
  68        [1] = {
  69                .hwport      = 1,
  70                .flags       = 0,
  71                .ucon        = UCON,
  72                .ulcon       = ULCON,
  73                .ufcon       = UFCON,
  74        },
  75        [2] = {
  76                .hwport      = 2,
  77                .flags       = 0,
  78                .ucon        = UCON,
  79                .ulcon       = ULCON,
  80                .ufcon       = UFCON,
  81        }
  82};
  83
  84/* LCD driver info */
  85
  86static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
  87        {
  88                /* Configuration for 640x480 SHARP LQ080V3DG01 */
  89                .lcdcon5 = S3C2410_LCDCON5_FRM565 |
  90                           S3C2410_LCDCON5_INVVLINE |
  91                           S3C2410_LCDCON5_INVVFRAME |
  92                           S3C2410_LCDCON5_PWREN |
  93                           S3C2410_LCDCON5_HWSWP,
  94
  95                .type           = S3C2410_LCDCON1_TFT,
  96                .width          = 640,
  97                .height         = 480,
  98
  99                .pixclock       = 40000, /* HCLK/4 */
 100                .xres           = 640,
 101                .yres           = 480,
 102                .bpp            = 16,
 103                .left_margin    = 44,
 104                .right_margin   = 116,
 105                .hsync_len      = 96,
 106                .upper_margin   = 19,
 107                .lower_margin   = 11,
 108                .vsync_len      = 15,
 109        },
 110        {
 111                /* Configuration for 480x640 toppoly TD028TTEC1 */
 112                .lcdcon5 = S3C2410_LCDCON5_FRM565 |
 113                           S3C2410_LCDCON5_INVVLINE |
 114                           S3C2410_LCDCON5_INVVFRAME |
 115                           S3C2410_LCDCON5_PWREN |
 116                           S3C2410_LCDCON5_HWSWP,
 117
 118                .type           = S3C2410_LCDCON1_TFT,
 119                .width          = 480,
 120                .height         = 640,
 121                .pixclock       = 40000, /* HCLK/4 */
 122                .xres           = 480,
 123                .yres           = 640,
 124                .bpp            = 16,
 125                .left_margin    = 8,
 126                .right_margin   = 24,
 127                .hsync_len      = 8,
 128                .upper_margin   = 2,
 129                .lower_margin   = 4,
 130                .vsync_len      = 2,
 131        },
 132        {
 133                /* Config for 240x320 LCD */
 134                .lcdcon5 = S3C2410_LCDCON5_FRM565 |
 135                           S3C2410_LCDCON5_INVVLINE |
 136                           S3C2410_LCDCON5_INVVFRAME |
 137                           S3C2410_LCDCON5_PWREN |
 138                           S3C2410_LCDCON5_HWSWP,
 139
 140                .type           = S3C2410_LCDCON1_TFT,
 141                .width          = 240,
 142                .height         = 320,
 143                .pixclock       = 100000, /* HCLK/10 */
 144                .xres           = 240,
 145                .yres           = 320,
 146                .bpp            = 16,
 147                .left_margin    = 13,
 148                .right_margin   = 8,
 149                .hsync_len      = 4,
 150                .upper_margin   = 2,
 151                .lower_margin   = 7,
 152                .vsync_len      = 4,
 153        },
 154};
 155
 156
 157static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
 158        .displays       = qt2410_lcd_cfg,
 159        .num_displays   = ARRAY_SIZE(qt2410_lcd_cfg),
 160        .default_display = 0,
 161
 162        .lpcsel         = ((0xCE6) & ~7) | 1<<4,
 163};
 164
 165/* CS8900 */
 166
 167static struct resource qt2410_cs89x0_resources[] = {
 168        [0] = DEFINE_RES_MEM(0x19000000, 17),
 169        [1] = DEFINE_RES_IRQ(IRQ_EINT9),
 170};
 171
 172static struct platform_device qt2410_cs89x0 = {
 173        .name           = "cirrus-cs89x0",
 174        .num_resources  = ARRAY_SIZE(qt2410_cs89x0_resources),
 175        .resource       = qt2410_cs89x0_resources,
 176};
 177
 178/* LED */
 179
 180static struct s3c24xx_led_platdata qt2410_pdata_led = {
 181        .gpio           = S3C2410_GPB(0),
 182        .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
 183        .name           = "led",
 184        .def_trigger    = "timer",
 185};
 186
 187static struct platform_device qt2410_led = {
 188        .name           = "s3c24xx_led",
 189        .id             = 0,
 190        .dev            = {
 191                .platform_data = &qt2410_pdata_led,
 192        },
 193};
 194
 195/* SPI */
 196
 197static struct spi_gpio_platform_data spi_gpio_cfg = {
 198        .num_chipselect = 1,
 199};
 200
 201static struct platform_device qt2410_spi = {
 202        .name           = "spi_gpio",
 203        .id             = 1,
 204        .dev.platform_data = &spi_gpio_cfg,
 205};
 206
 207static struct gpiod_lookup_table qt2410_spi_gpiod_table = {
 208        .dev_id         = "spi_gpio",
 209        .table          = {
 210                GPIO_LOOKUP("GPIOG", 7,
 211                            "sck", GPIO_ACTIVE_HIGH),
 212                GPIO_LOOKUP("GPIOG", 6,
 213                            "mosi", GPIO_ACTIVE_HIGH),
 214                GPIO_LOOKUP("GPIOG", 5,
 215                            "miso", GPIO_ACTIVE_HIGH),
 216                GPIO_LOOKUP("GPIOB", 5,
 217                            "cs", GPIO_ACTIVE_HIGH),
 218                { },
 219        },
 220};
 221
 222/* Board devices */
 223
 224static struct platform_device *qt2410_devices[] __initdata = {
 225        &s3c_device_ohci,
 226        &s3c_device_lcd,
 227        &s3c_device_wdt,
 228        &s3c_device_i2c0,
 229        &s3c_device_iis,
 230        &s3c_device_sdi,
 231        &s3c_device_usbgadget,
 232        &qt2410_spi,
 233        &qt2410_cs89x0,
 234        &qt2410_led,
 235};
 236
 237static struct mtd_partition __initdata qt2410_nand_part[] = {
 238        [0] = {
 239                .name   = "U-Boot",
 240                .size   = 0x30000,
 241                .offset = 0,
 242        },
 243        [1] = {
 244                .name   = "U-Boot environment",
 245                .offset = 0x30000,
 246                .size   = 0x4000,
 247        },
 248        [2] = {
 249                .name   = "kernel",
 250                .offset = 0x34000,
 251                .size   = SZ_2M,
 252        },
 253        [3] = {
 254                .name   = "initrd",
 255                .offset = 0x234000,
 256                .size   = SZ_4M,
 257        },
 258        [4] = {
 259                .name   = "jffs2",
 260                .offset = 0x634000,
 261                .size   = 0x39cc000,
 262        },
 263};
 264
 265static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
 266        [0] = {
 267                .name           = "NAND",
 268                .nr_chips       = 1,
 269                .nr_partitions  = ARRAY_SIZE(qt2410_nand_part),
 270                .partitions     = qt2410_nand_part,
 271        },
 272};
 273
 274/* choose a set of timings which should suit most 512Mbit
 275 * chips and beyond.
 276 */
 277
 278static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
 279        .tacls          = 20,
 280        .twrph0         = 60,
 281        .twrph1         = 20,
 282        .nr_sets        = ARRAY_SIZE(qt2410_nand_sets),
 283        .sets           = qt2410_nand_sets,
 284        .ecc_mode       = NAND_ECC_SOFT,
 285};
 286
 287/* UDC */
 288
 289static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
 290};
 291
 292static char tft_type = 's';
 293
 294static int __init qt2410_tft_setup(char *str)
 295{
 296        tft_type = str[0];
 297        return 1;
 298}
 299
 300__setup("tft=", qt2410_tft_setup);
 301
 302static void __init qt2410_map_io(void)
 303{
 304        s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
 305        s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 306        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 307}
 308
 309static void __init qt2410_init_time(void)
 310{
 311        s3c2410_init_clocks(12000000);
 312        samsung_timer_init();
 313}
 314
 315static void __init qt2410_machine_init(void)
 316{
 317        s3c_nand_set_platdata(&qt2410_nand_info);
 318
 319        switch (tft_type) {
 320        case 'p': /* production */
 321                qt2410_fb_info.default_display = 1;
 322                break;
 323        case 'b': /* big */
 324                qt2410_fb_info.default_display = 0;
 325                break;
 326        case 's': /* small */
 327        default:
 328                qt2410_fb_info.default_display = 2;
 329                break;
 330        }
 331        s3c24xx_fb_set_platdata(&qt2410_fb_info);
 332
 333        /* set initial state of the LED GPIO */
 334        WARN_ON(gpio_request_one(S3C2410_GPB(0), GPIOF_OUT_INIT_HIGH, NULL));
 335        gpio_free(S3C2410_GPB(0));
 336
 337        s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
 338        s3c_i2c0_set_platdata(NULL);
 339
 340        gpiod_add_lookup_table(&qt2410_spi_gpiod_table);
 341        platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
 342        s3c_pm_init();
 343}
 344
 345MACHINE_START(QT2410, "QT2410")
 346        .atag_offset    = 0x100,
 347        .map_io         = qt2410_map_io,
 348        .init_irq       = s3c2410_init_irq,
 349        .init_machine   = qt2410_machine_init,
 350        .init_time      = qt2410_init_time,
 351MACHINE_END
 352