[ARM] JIVE: Initialise the sleep configuration registers
[linux-2.6] / arch / arm / mach-s3c2412 / mach-jive.c
1 /* linux/arch/arm/mach-s3c2410/mach-jive.c
2  *
3  * Copyright 2007 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * http://armlinux.simtec.co.uk/
7  *
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.
11 */
12
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>
22
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/partitions.h>
25
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <asm/mach/irq.h>
29
30 #include <asm/plat-s3c/regs-serial.h>
31 #include <asm/plat-s3c/nand.h>
32
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
38 #include <asm/mach-types.h>
39
40 #include <linux/mtd/mtd.h>
41 #include <linux/mtd/nand.h>
42 #include <linux/mtd/nand_ecc.h>
43 #include <linux/mtd/partitions.h>
44
45 #include <asm/plat-s3c24xx/clock.h>
46 #include <asm/plat-s3c24xx/devs.h>
47 #include <asm/plat-s3c24xx/cpu.h>
48 #include <asm/plat-s3c24xx/pm.h>
49 #include <asm/plat-s3c24xx/udc.h>
50
51 static struct map_desc jive_iodesc[] __initdata = {
52 };
53
54 #define UCON S3C2410_UCON_DEFAULT
55 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
56 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
57
58 static struct s3c2410_uartcfg jive_uartcfgs[] = {
59         [0] = {
60                 .hwport      = 0,
61                 .flags       = 0,
62                 .ucon        = UCON,
63                 .ulcon       = ULCON,
64                 .ufcon       = UFCON,
65         },
66         [1] = {
67                 .hwport      = 1,
68                 .flags       = 0,
69                 .ucon        = UCON,
70                 .ulcon       = ULCON,
71                 .ufcon       = UFCON,
72         },
73         [2] = {
74                 .hwport      = 2,
75                 .flags       = 0,
76                 .ucon        = UCON,
77                 .ulcon       = ULCON,
78                 .ufcon       = UFCON,
79         }
80 };
81
82 /* Jive flash assignment
83  *
84  * 0x00000000-0x00028000 : uboot
85  * 0x00028000-0x0002c000 : uboot env
86  * 0x0002c000-0x00030000 : spare
87  * 0x00030000-0x00200000 : zimage A
88  * 0x00200000-0x01600000 : cramfs A
89  * 0x01600000-0x017d0000 : zimage B
90  * 0x017d0000-0x02bd0000 : cramfs B
91  * 0x02bd0000-0x03fd0000 : yaffs
92  */
93 static struct mtd_partition jive_imageA_nand_part[] = {
94
95 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
96         /* Don't allow access to the bootloader from linux */
97         {
98                 .name           = "uboot",
99                 .offset         = 0,
100                 .size           = (160 * SZ_1K),
101                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
102         },
103
104         /* spare */
105         {
106                 .name           = "spare",
107                 .offset         = (176 * SZ_1K),
108                 .size           = (16 * SZ_1K),
109         },
110 #endif
111
112         /* booted images */
113         {
114                 .name           = "kernel (ro)",
115                 .offset         = (192 * SZ_1K),
116                 .size           = (SZ_2M) - (192 * SZ_1K),
117                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
118         }, {
119                 .name           = "root (ro)",
120                 .offset         = (SZ_2M),
121                 .size           = (20 * SZ_1M),
122                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
123         },
124
125         /* yaffs */
126         {
127                 .name           = "yaffs",
128                 .offset         = (44 * SZ_1M),
129                 .size           = (20 * SZ_1M),
130         },
131
132         /* bootloader environment */
133         {
134                 .name           = "env",
135                 .offset         = (160 * SZ_1K),
136                 .size           = (16 * SZ_1K),
137         },
138
139         /* upgrade images */
140         {
141                 .name           = "zimage",
142                 .offset         = (22 * SZ_1M),
143                 .size           = (2 * SZ_1M) - (192 * SZ_1K),
144         }, {
145                 .name           = "cramfs",
146                 .offset         = (24 * SZ_1M) - (192*SZ_1K),
147                 .size           = (20 * SZ_1M),
148         },
149 };
150
151 static struct mtd_partition jive_imageB_nand_part[] = {
152
153 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
154         /* Don't allow access to the bootloader from linux */
155         {
156                 .name           = "uboot",
157                 .offset         = 0,
158                 .size           = (160 * SZ_1K),
159                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
160         },
161
162         /* spare */
163         {
164                 .name           = "spare",
165                 .offset         = (176 * SZ_1K),
166                 .size           = (16 * SZ_1K),
167         },
168 #endif
169
170         /* booted images */
171         {
172                 .name           = "kernel (ro)",
173                 .offset         = (22 * SZ_1M),
174                 .size           = (2 * SZ_1M) - (192 * SZ_1K),
175                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
176         },
177         {
178                 .name           = "root (ro)",
179                 .offset         = (24 * SZ_1M) - (192 * SZ_1K),
180                 .size           = (20 * SZ_1M),
181                 .mask_flags     = MTD_WRITEABLE, /* force read-only */
182         },
183
184         /* yaffs */
185         {
186                 .name           = "yaffs",
187                 .offset         = (44 * SZ_1M),
188                 .size           = (20 * SZ_1M),
189         },
190
191         /* bootloader environment */
192         {
193                 .name           = "env",
194                 .offset         = (160 * SZ_1K),
195                 .size           = (16 * SZ_1K),
196         },
197
198         /* upgrade images */
199         {
200                 .name           = "zimage",
201                 .offset         = (192 * SZ_1K),
202                 .size           = (2 * SZ_1M) - (192 * SZ_1K),
203         }, {
204                 .name           = "cramfs",
205                 .offset         = (2 * SZ_1M),
206                 .size           = (20 * SZ_1M),
207         },
208 };
209
210 static struct s3c2410_nand_set jive_nand_sets[] = {
211         [0] = {
212                 .name           = "flash",
213                 .nr_chips       = 1,
214                 .nr_partitions  = ARRAY_SIZE(jive_imageA_nand_part),
215                 .partitions     = jive_imageA_nand_part,
216         },
217 };
218
219 static struct s3c2410_platform_nand jive_nand_info = {
220         /* set taken from osiris nand timings, possibly still conservative */
221         .tacls          = 30,
222         .twrph0         = 55,
223         .twrph1         = 40,
224         .sets           = jive_nand_sets,
225         .nr_sets        = ARRAY_SIZE(jive_nand_sets),
226 };
227
228 static int __init jive_mtdset(char *options)
229 {
230         struct s3c2410_nand_set *nand = &jive_nand_sets[0];
231         unsigned long set;
232
233         if (options == NULL || options[0] == '\0')
234                 return 0;
235
236         if (strict_strtoul(options, 10, &set)) {
237                 printk(KERN_ERR "failed to parse mtdset=%s\n", options);
238                 return 0;
239         }
240
241         switch (set) {
242         case 1:
243                 nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
244                 nand->partitions = jive_imageB_nand_part;
245         case 0:
246                 /* this is already setup in the nand info */
247                 break;
248         default:
249                 printk(KERN_ERR "Unknown mtd set %ld specified,"
250                        "using default.", set);
251         }
252
253         return 0;
254 }
255
256 /* parse the mtdset= option given to the kernel command line */
257 __setup("mtdset=", jive_mtdset);
258
259 static struct platform_device *jive_devices[] __initdata = {
260         &s3c_device_usb,
261         &s3c_device_rtc,
262         &s3c_device_wdt,
263         &s3c_device_i2c,
264         &s3c_device_nand,
265         &s3c_device_usbgadget,
266 };
267
268 static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
269         .vbus_pin       = S3C2410_GPG1,         /* detect is on GPG1 */
270 };
271
272 /* Jive power management device */
273
274 #ifdef CONFIG_PM
275 static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
276 {
277         /* Write the magic value u-boot uses to check for resume into
278          * the INFORM0 register, and ensure INFORM1 is set to the
279          * correct address to resume from. */
280
281         __raw_writel(0x2BED, S3C2412_INFORM0);
282         __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1);
283
284         return 0;
285 }
286
287 static int jive_pm_resume(struct sys_device *sd)
288 {
289         __raw_writel(0x0, S3C2412_INFORM0);
290         return 0;
291 }
292
293 #else
294 #define jive_pm_suspend NULL
295 #define jive_pm_resume NULL
296 #endif
297
298 static struct sysdev_class jive_pm_sysclass = {
299         .name           = "jive-pm",
300         .suspend        = jive_pm_suspend,
301         .resume         = jive_pm_resume,
302 };
303
304 static struct sys_device jive_pm_sysdev = {
305         .cls            = &jive_pm_sysclass,
306 };
307
308 static void __init jive_map_io(void)
309 {
310         s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
311         s3c24xx_init_clocks(12000000);
312         s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
313 }
314
315 static void __init jive_machine_init(void)
316 {
317         /* register system devices for managing low level suspend */
318
319         sysdev_class_register(&jive_pm_sysclass);
320         sysdev_register(&jive_pm_sysdev);
321
322         /* write our sleep configurations for the IO. Pull down all unused
323          * IO, ensure that we have turned off all peripherals we do not
324          * need, and configure the ones we do need. */
325
326         /* Port B sleep */
327
328         __raw_writel(S3C2412_SLPCON_IN(0)   |
329                      S3C2412_SLPCON_PULL(1) |
330                      S3C2412_SLPCON_HIGH(2) |
331                      S3C2412_SLPCON_PULL(3) |
332                      S3C2412_SLPCON_PULL(4) |
333                      S3C2412_SLPCON_PULL(5) |
334                      S3C2412_SLPCON_PULL(6) |
335                      S3C2412_SLPCON_HIGH(7) |
336                      S3C2412_SLPCON_PULL(8) |
337                      S3C2412_SLPCON_PULL(9) |
338                      S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
339
340         /* Port C sleep */
341
342         __raw_writel(S3C2412_SLPCON_PULL(0) |
343                      S3C2412_SLPCON_PULL(1) |
344                      S3C2412_SLPCON_PULL(2) |
345                      S3C2412_SLPCON_PULL(3) |
346                      S3C2412_SLPCON_PULL(4) |
347                      S3C2412_SLPCON_PULL(5) |
348                      S3C2412_SLPCON_LOW(6)  |
349                      S3C2412_SLPCON_PULL(6) |
350                      S3C2412_SLPCON_PULL(7) |
351                      S3C2412_SLPCON_PULL(8) |
352                      S3C2412_SLPCON_PULL(9) |
353                      S3C2412_SLPCON_PULL(10) |
354                      S3C2412_SLPCON_PULL(11) |
355                      S3C2412_SLPCON_PULL(12) |
356                      S3C2412_SLPCON_PULL(13) |
357                      S3C2412_SLPCON_PULL(14) |
358                      S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
359
360         /* Port D sleep */
361
362         __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
363
364         /* Port F sleep */
365
366         __raw_writel(S3C2412_SLPCON_LOW(0)  |
367                      S3C2412_SLPCON_LOW(1)  |
368                      S3C2412_SLPCON_LOW(2)  |
369                      S3C2412_SLPCON_EINT(3) |
370                      S3C2412_SLPCON_EINT(4) |
371                      S3C2412_SLPCON_EINT(5) |
372                      S3C2412_SLPCON_EINT(6) |
373                      S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
374
375         /* Port G sleep */
376
377         __raw_writel(S3C2412_SLPCON_IN(0)    |
378                      S3C2412_SLPCON_IN(1)    |
379                      S3C2412_SLPCON_IN(2)    |
380                      S3C2412_SLPCON_IN(3)    |
381                      S3C2412_SLPCON_IN(4)    |
382                      S3C2412_SLPCON_IN(5)    |
383                      S3C2412_SLPCON_IN(6)    |
384                      S3C2412_SLPCON_IN(7)    |
385                      S3C2412_SLPCON_PULL(8)  |
386                      S3C2412_SLPCON_PULL(9)  |
387                      S3C2412_SLPCON_IN(10)   |
388                      S3C2412_SLPCON_PULL(11) |
389                      S3C2412_SLPCON_PULL(12) |
390                      S3C2412_SLPCON_PULL(13) |
391                      S3C2412_SLPCON_IN(14)   |
392                      S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
393
394         /* Port H sleep */
395
396         __raw_writel(S3C2412_SLPCON_PULL(0) |
397                      S3C2412_SLPCON_PULL(1) |
398                      S3C2412_SLPCON_PULL(2) |
399                      S3C2412_SLPCON_PULL(3) |
400                      S3C2412_SLPCON_PULL(4) |
401                      S3C2412_SLPCON_PULL(5) |
402                      S3C2412_SLPCON_PULL(6) |
403                      S3C2412_SLPCON_IN(7)   |
404                      S3C2412_SLPCON_IN(8)   |
405                      S3C2412_SLPCON_PULL(9) |
406                      S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
407
408         /* initialise the power management now we've setup everything. */
409
410         s3c2410_pm_init();
411
412         s3c_device_nand.dev.platform_data = &jive_nand_info;
413
414         /* Turn off suspend on both USB ports, and switch the
415          * selectable USB port to USB device mode. */
416
417         s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
418                               S3C2410_MISCCR_USBSUSPND0 |
419                               S3C2410_MISCCR_USBSUSPND1, 0x0);
420
421         s3c24xx_udc_set_platdata(&jive_udc_cfg);
422
423         platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
424 }
425
426 MACHINE_START(JIVE, "JIVE")
427         /* Maintainer: Ben Dooks <ben@fluff.org> */
428         .phys_io        = S3C2410_PA_UART,
429         .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
430         .boot_params    = S3C2410_SDRAM_PA + 0x100,
431
432         .init_irq       = s3c24xx_init_irq,
433         .map_io         = jive_map_io,
434         .init_machine   = jive_machine_init,
435         .timer          = &s3c24xx_timer,
436 MACHINE_END