Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // Copyright (C) 2006 by OpenMoko, Inc.
0004 // Author: Harald Welte <laforge@openmoko.org>
0005 // All rights reserved.
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/types.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/list.h>
0011 #include <linux/timer.h>
0012 #include <linux/init.h>
0013 #include <linux/gpio.h>
0014 #include <linux/gpio/machine.h>
0015 #include <linux/device.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/serial_core.h>
0018 #include <linux/serial_s3c.h>
0019 #include <linux/spi/spi.h>
0020 #include <linux/spi/spi_gpio.h>
0021 #include <linux/io.h>
0022 #include <linux/mtd/mtd.h>
0023 #include <linux/mtd/rawnand.h>
0024 #include <linux/mtd/nand-ecc-sw-hamming.h>
0025 #include <linux/mtd/partitions.h>
0026 
0027 #include <asm/mach/arch.h>
0028 #include <asm/mach/map.h>
0029 #include <asm/mach/irq.h>
0030 
0031 #include <asm/irq.h>
0032 #include <asm/mach-types.h>
0033 
0034 #include <linux/platform_data/leds-s3c24xx.h>
0035 #include <linux/platform_data/fb-s3c2410.h>
0036 #include <linux/platform_data/mtd-nand-s3c2410.h>
0037 #include <linux/platform_data/usb-s3c2410_udc.h>
0038 #include <linux/platform_data/i2c-s3c2410.h>
0039 #include "gpio-samsung.h"
0040 
0041 #include "gpio-cfg.h"
0042 #include "devs.h"
0043 #include "cpu.h"
0044 #include "pm.h"
0045 
0046 #include "s3c24xx.h"
0047 #include "common-smdk-s3c24xx.h"
0048 
0049 static struct map_desc qt2410_iodesc[] __initdata = {
0050     { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
0051 };
0052 
0053 #define UCON S3C2410_UCON_DEFAULT
0054 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
0055 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
0056 
0057 static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
0058     [0] = {
0059         .hwport      = 0,
0060         .flags       = 0,
0061         .ucon        = UCON,
0062         .ulcon       = ULCON,
0063         .ufcon       = UFCON,
0064     },
0065     [1] = {
0066         .hwport      = 1,
0067         .flags       = 0,
0068         .ucon        = UCON,
0069         .ulcon       = ULCON,
0070         .ufcon       = UFCON,
0071     },
0072     [2] = {
0073         .hwport      = 2,
0074         .flags       = 0,
0075         .ucon        = UCON,
0076         .ulcon       = ULCON,
0077         .ufcon       = UFCON,
0078     }
0079 };
0080 
0081 /* LCD driver info */
0082 
0083 static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
0084     {
0085         /* Configuration for 640x480 SHARP LQ080V3DG01 */
0086         .lcdcon5 = S3C2410_LCDCON5_FRM565 |
0087                S3C2410_LCDCON5_INVVLINE |
0088                S3C2410_LCDCON5_INVVFRAME |
0089                S3C2410_LCDCON5_PWREN |
0090                S3C2410_LCDCON5_HWSWP,
0091 
0092         .type       = S3C2410_LCDCON1_TFT,
0093         .width      = 640,
0094         .height     = 480,
0095 
0096         .pixclock   = 40000, /* HCLK/4 */
0097         .xres       = 640,
0098         .yres       = 480,
0099         .bpp        = 16,
0100         .left_margin    = 44,
0101         .right_margin   = 116,
0102         .hsync_len  = 96,
0103         .upper_margin   = 19,
0104         .lower_margin   = 11,
0105         .vsync_len  = 15,
0106     },
0107     {
0108         /* Configuration for 480x640 toppoly TD028TTEC1 */
0109         .lcdcon5 = S3C2410_LCDCON5_FRM565 |
0110                S3C2410_LCDCON5_INVVLINE |
0111                S3C2410_LCDCON5_INVVFRAME |
0112                S3C2410_LCDCON5_PWREN |
0113                S3C2410_LCDCON5_HWSWP,
0114 
0115         .type       = S3C2410_LCDCON1_TFT,
0116         .width      = 480,
0117         .height     = 640,
0118         .pixclock   = 40000, /* HCLK/4 */
0119         .xres       = 480,
0120         .yres       = 640,
0121         .bpp        = 16,
0122         .left_margin    = 8,
0123         .right_margin   = 24,
0124         .hsync_len  = 8,
0125         .upper_margin   = 2,
0126         .lower_margin   = 4,
0127         .vsync_len  = 2,
0128     },
0129     {
0130         /* Config for 240x320 LCD */
0131         .lcdcon5 = S3C2410_LCDCON5_FRM565 |
0132                S3C2410_LCDCON5_INVVLINE |
0133                S3C2410_LCDCON5_INVVFRAME |
0134                S3C2410_LCDCON5_PWREN |
0135                S3C2410_LCDCON5_HWSWP,
0136 
0137         .type       = S3C2410_LCDCON1_TFT,
0138         .width      = 240,
0139         .height     = 320,
0140         .pixclock   = 100000, /* HCLK/10 */
0141         .xres       = 240,
0142         .yres       = 320,
0143         .bpp        = 16,
0144         .left_margin    = 13,
0145         .right_margin   = 8,
0146         .hsync_len  = 4,
0147         .upper_margin   = 2,
0148         .lower_margin   = 7,
0149         .vsync_len  = 4,
0150     },
0151 };
0152 
0153 
0154 static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
0155     .displays   = qt2410_lcd_cfg,
0156     .num_displays   = ARRAY_SIZE(qt2410_lcd_cfg),
0157     .default_display = 0,
0158 
0159     .lpcsel     = ((0xCE6) & ~7) | 1<<4,
0160 };
0161 
0162 /* CS8900 */
0163 
0164 static struct resource qt2410_cs89x0_resources[] = {
0165     [0] = DEFINE_RES_MEM(0x19000000, 17),
0166     [1] = DEFINE_RES_IRQ(IRQ_EINT9),
0167 };
0168 
0169 static struct platform_device qt2410_cs89x0 = {
0170     .name       = "cirrus-cs89x0",
0171     .num_resources  = ARRAY_SIZE(qt2410_cs89x0_resources),
0172     .resource   = qt2410_cs89x0_resources,
0173 };
0174 
0175 /* LED */
0176 
0177 static struct gpiod_lookup_table qt2410_led_gpio_table = {
0178     .dev_id = "s3c24xx_led.0",
0179     .table = {
0180         GPIO_LOOKUP("GPB", 0, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
0181         { },
0182     },
0183 };
0184 
0185 static struct s3c24xx_led_platdata qt2410_pdata_led = {
0186     .name       = "led",
0187     .def_trigger    = "timer",
0188 };
0189 
0190 static struct platform_device qt2410_led = {
0191     .name       = "s3c24xx_led",
0192     .id     = 0,
0193     .dev        = {
0194         .platform_data = &qt2410_pdata_led,
0195     },
0196 };
0197 
0198 /* SPI */
0199 
0200 static struct spi_gpio_platform_data spi_gpio_cfg = {
0201     .num_chipselect = 1,
0202 };
0203 
0204 static struct platform_device qt2410_spi = {
0205     .name       = "spi_gpio",
0206     .id     = 1,
0207     .dev.platform_data = &spi_gpio_cfg,
0208 };
0209 
0210 static struct gpiod_lookup_table qt2410_spi_gpiod_table = {
0211     .dev_id         = "spi_gpio",
0212     .table          = {
0213         GPIO_LOOKUP("GPIOG", 7,
0214                 "sck", GPIO_ACTIVE_HIGH),
0215         GPIO_LOOKUP("GPIOG", 6,
0216                 "mosi", GPIO_ACTIVE_HIGH),
0217         GPIO_LOOKUP("GPIOG", 5,
0218                 "miso", GPIO_ACTIVE_HIGH),
0219         GPIO_LOOKUP("GPIOB", 5,
0220                 "cs", GPIO_ACTIVE_HIGH),
0221         { },
0222     },
0223 };
0224 
0225 static struct gpiod_lookup_table qt2410_mmc_gpiod_table = {
0226     .dev_id = "s3c2410-sdi",
0227     .table = {
0228         /* bus pins */
0229         GPIO_LOOKUP_IDX("GPIOE",  5, "bus", 0, GPIO_ACTIVE_HIGH),
0230         GPIO_LOOKUP_IDX("GPIOE",  6, "bus", 1, GPIO_ACTIVE_HIGH),
0231         GPIO_LOOKUP_IDX("GPIOE",  7, "bus", 2, GPIO_ACTIVE_HIGH),
0232         GPIO_LOOKUP_IDX("GPIOE",  8, "bus", 3, GPIO_ACTIVE_HIGH),
0233         GPIO_LOOKUP_IDX("GPIOE",  9, "bus", 4, GPIO_ACTIVE_HIGH),
0234         GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH),
0235         { },
0236     },
0237 };
0238 
0239 /* Board devices */
0240 
0241 static struct platform_device *qt2410_devices[] __initdata = {
0242     &s3c_device_ohci,
0243     &s3c_device_lcd,
0244     &s3c_device_wdt,
0245     &s3c_device_i2c0,
0246     &s3c_device_iis,
0247     &s3c_device_sdi,
0248     &s3c_device_usbgadget,
0249     &qt2410_spi,
0250     &qt2410_cs89x0,
0251     &qt2410_led,
0252 };
0253 
0254 static struct mtd_partition __initdata qt2410_nand_part[] = {
0255     [0] = {
0256         .name   = "U-Boot",
0257         .size   = 0x30000,
0258         .offset = 0,
0259     },
0260     [1] = {
0261         .name   = "U-Boot environment",
0262         .offset = 0x30000,
0263         .size   = 0x4000,
0264     },
0265     [2] = {
0266         .name   = "kernel",
0267         .offset = 0x34000,
0268         .size   = SZ_2M,
0269     },
0270     [3] = {
0271         .name   = "initrd",
0272         .offset = 0x234000,
0273         .size   = SZ_4M,
0274     },
0275     [4] = {
0276         .name   = "jffs2",
0277         .offset = 0x634000,
0278         .size   = 0x39cc000,
0279     },
0280 };
0281 
0282 static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
0283     [0] = {
0284         .name       = "NAND",
0285         .nr_chips   = 1,
0286         .nr_partitions  = ARRAY_SIZE(qt2410_nand_part),
0287         .partitions = qt2410_nand_part,
0288     },
0289 };
0290 
0291 /* choose a set of timings which should suit most 512Mbit
0292  * chips and beyond.
0293  */
0294 
0295 static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
0296     .tacls      = 20,
0297     .twrph0     = 60,
0298     .twrph1     = 20,
0299     .nr_sets    = ARRAY_SIZE(qt2410_nand_sets),
0300     .sets       = qt2410_nand_sets,
0301     .engine_type    = NAND_ECC_ENGINE_TYPE_SOFT,
0302 };
0303 
0304 /* UDC */
0305 
0306 static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
0307 };
0308 
0309 static char tft_type = 's';
0310 
0311 static int __init qt2410_tft_setup(char *str)
0312 {
0313     tft_type = str[0];
0314     return 1;
0315 }
0316 
0317 __setup("tft=", qt2410_tft_setup);
0318 
0319 static void __init qt2410_map_io(void)
0320 {
0321     s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
0322     s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
0323     s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
0324 }
0325 
0326 static void __init qt2410_init_time(void)
0327 {
0328     s3c2410_init_clocks(12000000);
0329     s3c24xx_timer_init();
0330 }
0331 
0332 static void __init qt2410_machine_init(void)
0333 {
0334     s3c_nand_set_platdata(&qt2410_nand_info);
0335 
0336     switch (tft_type) {
0337     case 'p': /* production */
0338         qt2410_fb_info.default_display = 1;
0339         break;
0340     case 'b': /* big */
0341         qt2410_fb_info.default_display = 0;
0342         break;
0343     case 's': /* small */
0344     default:
0345         qt2410_fb_info.default_display = 2;
0346         break;
0347     }
0348     s3c24xx_fb_set_platdata(&qt2410_fb_info);
0349 
0350     /* set initial state of the LED GPIO */
0351     WARN_ON(gpio_request_one(S3C2410_GPB(0), GPIOF_OUT_INIT_HIGH, NULL));
0352     gpio_free(S3C2410_GPB(0));
0353 
0354     s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
0355     s3c_i2c0_set_platdata(NULL);
0356 
0357     /* Configure the I2S pins (GPE0...GPE4) in correct mode */
0358     s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
0359                   S3C_GPIO_PULL_NONE);
0360     gpiod_add_lookup_table(&qt2410_spi_gpiod_table);
0361     s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
0362     gpiod_add_lookup_table(&qt2410_led_gpio_table);
0363     gpiod_add_lookup_table(&qt2410_mmc_gpiod_table);
0364     platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
0365     s3c_pm_init();
0366 }
0367 
0368 MACHINE_START(QT2410, "QT2410")
0369     .atag_offset    = 0x100,
0370     .nr_irqs    = NR_IRQS_S3C2410,
0371     .map_io     = qt2410_map_io,
0372     .init_irq   = s3c2410_init_irq,
0373     .init_machine   = qt2410_machine_init,
0374     .init_time  = qt2410_init_time,
0375 MACHINE_END