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