1 /* linux/arch/arm/mach-s3c2410/mach-jive.c
3 * Copyright 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/interrupt.h>
16 #include <linux/list.h>
17 #include <linux/timer.h>
18 #include <linux/init.h>
19 #include <linux/sysdev.h>
20 #include <linux/serial_core.h>
21 #include <linux/platform_device.h>
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/partitions.h>
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <asm/mach/irq.h>
30 #include <asm/plat-s3c/regs-serial.h>
31 #include <asm/plat-s3c/nand.h>
33 #include <asm/arch/regs-power.h>
34 #include <asm/arch/regs-gpio.h>
35 #include <asm/arch/regs-mem.h>
36 #include <asm/arch/regs-lcd.h>
37 #include <asm/arch/fb.h>
39 #include <asm/mach-types.h>
41 #include <linux/mtd/mtd.h>
42 #include <linux/mtd/nand.h>
43 #include <linux/mtd/nand_ecc.h>
44 #include <linux/mtd/partitions.h>
46 #include <asm/plat-s3c24xx/clock.h>
47 #include <asm/plat-s3c24xx/devs.h>
48 #include <asm/plat-s3c24xx/cpu.h>
49 #include <asm/plat-s3c24xx/pm.h>
50 #include <asm/plat-s3c24xx/udc.h>
52 static struct map_desc jive_iodesc[] __initdata = {
55 #define UCON S3C2410_UCON_DEFAULT
56 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
57 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
59 static struct s3c2410_uartcfg jive_uartcfgs[] = {
83 /* Jive flash assignment
85 * 0x00000000-0x00028000 : uboot
86 * 0x00028000-0x0002c000 : uboot env
87 * 0x0002c000-0x00030000 : spare
88 * 0x00030000-0x00200000 : zimage A
89 * 0x00200000-0x01600000 : cramfs A
90 * 0x01600000-0x017d0000 : zimage B
91 * 0x017d0000-0x02bd0000 : cramfs B
92 * 0x02bd0000-0x03fd0000 : yaffs
94 static struct mtd_partition jive_imageA_nand_part[] = {
96 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
97 /* Don't allow access to the bootloader from linux */
101 .size = (160 * SZ_1K),
102 .mask_flags = MTD_WRITEABLE, /* force read-only */
108 .offset = (176 * SZ_1K),
109 .size = (16 * SZ_1K),
115 .name = "kernel (ro)",
116 .offset = (192 * SZ_1K),
117 .size = (SZ_2M) - (192 * SZ_1K),
118 .mask_flags = MTD_WRITEABLE, /* force read-only */
122 .size = (20 * SZ_1M),
123 .mask_flags = MTD_WRITEABLE, /* force read-only */
129 .offset = (44 * SZ_1M),
130 .size = (20 * SZ_1M),
133 /* bootloader environment */
136 .offset = (160 * SZ_1K),
137 .size = (16 * SZ_1K),
143 .offset = (22 * SZ_1M),
144 .size = (2 * SZ_1M) - (192 * SZ_1K),
147 .offset = (24 * SZ_1M) - (192*SZ_1K),
148 .size = (20 * SZ_1M),
152 static struct mtd_partition jive_imageB_nand_part[] = {
154 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
155 /* Don't allow access to the bootloader from linux */
159 .size = (160 * SZ_1K),
160 .mask_flags = MTD_WRITEABLE, /* force read-only */
166 .offset = (176 * SZ_1K),
167 .size = (16 * SZ_1K),
173 .name = "kernel (ro)",
174 .offset = (22 * SZ_1M),
175 .size = (2 * SZ_1M) - (192 * SZ_1K),
176 .mask_flags = MTD_WRITEABLE, /* force read-only */
180 .offset = (24 * SZ_1M) - (192 * SZ_1K),
181 .size = (20 * SZ_1M),
182 .mask_flags = MTD_WRITEABLE, /* force read-only */
188 .offset = (44 * SZ_1M),
189 .size = (20 * SZ_1M),
192 /* bootloader environment */
195 .offset = (160 * SZ_1K),
196 .size = (16 * SZ_1K),
202 .offset = (192 * SZ_1K),
203 .size = (2 * SZ_1M) - (192 * SZ_1K),
206 .offset = (2 * SZ_1M),
207 .size = (20 * SZ_1M),
211 static struct s3c2410_nand_set jive_nand_sets[] = {
215 .nr_partitions = ARRAY_SIZE(jive_imageA_nand_part),
216 .partitions = jive_imageA_nand_part,
220 static struct s3c2410_platform_nand jive_nand_info = {
221 /* set taken from osiris nand timings, possibly still conservative */
225 .sets = jive_nand_sets,
226 .nr_sets = ARRAY_SIZE(jive_nand_sets),
229 static int __init jive_mtdset(char *options)
231 struct s3c2410_nand_set *nand = &jive_nand_sets[0];
234 if (options == NULL || options[0] == '\0')
237 if (strict_strtoul(options, 10, &set)) {
238 printk(KERN_ERR "failed to parse mtdset=%s\n", options);
244 nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
245 nand->partitions = jive_imageB_nand_part;
247 /* this is already setup in the nand info */
250 printk(KERN_ERR "Unknown mtd set %ld specified,"
251 "using default.", set);
257 /* parse the mtdset= option given to the kernel command line */
258 __setup("mtdset=", jive_mtdset);
260 /* LCD timing and setup */
262 #define LCD_XRES (240)
263 #define LCD_YRES (320)
264 #define LCD_LEFT_MARGIN (12)
265 #define LCD_RIGHT_MARGIN (12)
266 #define LCD_LOWER_MARGIN (12)
267 #define LCD_UPPER_MARGIN (12)
268 #define LCD_VSYNC (2)
269 #define LCD_HSYNC (2)
271 #define LCD_REFRESH (60)
273 #define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
274 #define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
276 struct s3c2410fb_display jive_vgg2432a4_display[] = {
282 .left_margin = LCD_LEFT_MARGIN,
283 .right_margin = LCD_RIGHT_MARGIN,
284 .upper_margin = LCD_UPPER_MARGIN,
285 .lower_margin = LCD_LOWER_MARGIN,
286 .hsync_len = LCD_HSYNC,
287 .vsync_len = LCD_VSYNC,
289 .pixclock = (1000000000000LL /
290 (LCD_REFRESH * LCD_HTOT * LCD_VTOT)),
293 .type = (S3C2410_LCDCON1_TFT16BPP |
294 S3C2410_LCDCON1_TFT),
296 .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
297 S3C2410_LCDCON5_INVVLINE |
298 S3C2410_LCDCON5_INVVFRAME |
299 S3C2410_LCDCON5_INVVDEN |
300 S3C2410_LCDCON5_PWREN),
304 /* todo - put into gpio header */
306 #define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
307 #define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
309 struct s3c2410fb_mach_info jive_lcd_config = {
310 .displays = jive_vgg2432a4_display,
311 .num_displays = ARRAY_SIZE(jive_vgg2432a4_display),
312 .default_display = 0,
314 /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
315 * and disable the pull down resistors on pins we are using for LCD
318 .gpcup = (0xf << 1) | (0x3f << 10),
320 .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE |
321 S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
322 S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 |
323 S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 |
324 S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7),
326 .gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) |
327 S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) |
328 S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
329 S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
330 S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
332 .gpdup = (0x3f << 2) | (0x3f << 10),
334 .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 |
335 S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 |
336 S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 |
337 S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
338 S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
339 S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
341 .gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) |
342 S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) |
343 S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) |
344 S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
345 S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
346 S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
349 static struct platform_device *jive_devices[] __initdata = {
356 &s3c_device_usbgadget,
359 static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
360 .vbus_pin = S3C2410_GPG1, /* detect is on GPG1 */
363 /* Jive power management device */
366 static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
368 /* Write the magic value u-boot uses to check for resume into
369 * the INFORM0 register, and ensure INFORM1 is set to the
370 * correct address to resume from. */
372 __raw_writel(0x2BED, S3C2412_INFORM0);
373 __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1);
378 static int jive_pm_resume(struct sys_device *sd)
380 __raw_writel(0x0, S3C2412_INFORM0);
385 #define jive_pm_suspend NULL
386 #define jive_pm_resume NULL
389 static struct sysdev_class jive_pm_sysclass = {
391 .suspend = jive_pm_suspend,
392 .resume = jive_pm_resume,
395 static struct sys_device jive_pm_sysdev = {
396 .cls = &jive_pm_sysclass,
399 static void __init jive_map_io(void)
401 s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
402 s3c24xx_init_clocks(12000000);
403 s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
406 static void __init jive_machine_init(void)
408 /* register system devices for managing low level suspend */
410 sysdev_class_register(&jive_pm_sysclass);
411 sysdev_register(&jive_pm_sysdev);
413 /* write our sleep configurations for the IO. Pull down all unused
414 * IO, ensure that we have turned off all peripherals we do not
415 * need, and configure the ones we do need. */
419 __raw_writel(S3C2412_SLPCON_IN(0) |
420 S3C2412_SLPCON_PULL(1) |
421 S3C2412_SLPCON_HIGH(2) |
422 S3C2412_SLPCON_PULL(3) |
423 S3C2412_SLPCON_PULL(4) |
424 S3C2412_SLPCON_PULL(5) |
425 S3C2412_SLPCON_PULL(6) |
426 S3C2412_SLPCON_HIGH(7) |
427 S3C2412_SLPCON_PULL(8) |
428 S3C2412_SLPCON_PULL(9) |
429 S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
433 __raw_writel(S3C2412_SLPCON_PULL(0) |
434 S3C2412_SLPCON_PULL(1) |
435 S3C2412_SLPCON_PULL(2) |
436 S3C2412_SLPCON_PULL(3) |
437 S3C2412_SLPCON_PULL(4) |
438 S3C2412_SLPCON_PULL(5) |
439 S3C2412_SLPCON_LOW(6) |
440 S3C2412_SLPCON_PULL(6) |
441 S3C2412_SLPCON_PULL(7) |
442 S3C2412_SLPCON_PULL(8) |
443 S3C2412_SLPCON_PULL(9) |
444 S3C2412_SLPCON_PULL(10) |
445 S3C2412_SLPCON_PULL(11) |
446 S3C2412_SLPCON_PULL(12) |
447 S3C2412_SLPCON_PULL(13) |
448 S3C2412_SLPCON_PULL(14) |
449 S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
453 __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
457 __raw_writel(S3C2412_SLPCON_LOW(0) |
458 S3C2412_SLPCON_LOW(1) |
459 S3C2412_SLPCON_LOW(2) |
460 S3C2412_SLPCON_EINT(3) |
461 S3C2412_SLPCON_EINT(4) |
462 S3C2412_SLPCON_EINT(5) |
463 S3C2412_SLPCON_EINT(6) |
464 S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
468 __raw_writel(S3C2412_SLPCON_IN(0) |
469 S3C2412_SLPCON_IN(1) |
470 S3C2412_SLPCON_IN(2) |
471 S3C2412_SLPCON_IN(3) |
472 S3C2412_SLPCON_IN(4) |
473 S3C2412_SLPCON_IN(5) |
474 S3C2412_SLPCON_IN(6) |
475 S3C2412_SLPCON_IN(7) |
476 S3C2412_SLPCON_PULL(8) |
477 S3C2412_SLPCON_PULL(9) |
478 S3C2412_SLPCON_IN(10) |
479 S3C2412_SLPCON_PULL(11) |
480 S3C2412_SLPCON_PULL(12) |
481 S3C2412_SLPCON_PULL(13) |
482 S3C2412_SLPCON_IN(14) |
483 S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
487 __raw_writel(S3C2412_SLPCON_PULL(0) |
488 S3C2412_SLPCON_PULL(1) |
489 S3C2412_SLPCON_PULL(2) |
490 S3C2412_SLPCON_PULL(3) |
491 S3C2412_SLPCON_PULL(4) |
492 S3C2412_SLPCON_PULL(5) |
493 S3C2412_SLPCON_PULL(6) |
494 S3C2412_SLPCON_IN(7) |
495 S3C2412_SLPCON_IN(8) |
496 S3C2412_SLPCON_PULL(9) |
497 S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
499 /* initialise the power management now we've setup everything. */
503 s3c_device_nand.dev.platform_data = &jive_nand_info;
505 /* Turn off suspend on both USB ports, and switch the
506 * selectable USB port to USB device mode. */
508 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
509 S3C2410_MISCCR_USBSUSPND0 |
510 S3C2410_MISCCR_USBSUSPND1, 0x0);
512 s3c24xx_udc_set_platdata(&jive_udc_cfg);
513 s3c24xx_fb_set_platdata(&jive_lcd_config);
515 platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
518 MACHINE_START(JIVE, "JIVE")
519 /* Maintainer: Ben Dooks <ben@fluff.org> */
520 .phys_io = S3C2410_PA_UART,
521 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
522 .boot_params = S3C2410_SDRAM_PA + 0x100,
524 .init_irq = s3c24xx_init_irq,
525 .map_io = jive_map_io,
526 .init_machine = jive_machine_init,
527 .timer = &s3c24xx_timer,