au1xmmc: raise segment size limit.
[pandora-kernel.git] / arch / sh / boards / renesas / migor / setup.c
1 /*
2  * Renesas System Solutions Asia Pte. Ltd - Migo-R
3  *
4  * Copyright (C) 2008 Magnus Damm
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10 #include <linux/init.h>
11 #include <linux/platform_device.h>
12 #include <linux/interrupt.h>
13 #include <linux/input.h>
14 #include <linux/mtd/physmap.h>
15 #include <linux/mtd/nand.h>
16 #include <linux/i2c.h>
17 #include <linux/smc91x.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <media/soc_camera_platform.h>
21 #include <media/sh_mobile_ceu.h>
22 #include <asm/clock.h>
23 #include <asm/machvec.h>
24 #include <asm/io.h>
25 #include <asm/sh_keysc.h>
26 #include <asm/sh_mobile_lcdc.h>
27 #include <asm/migor.h>
28
29 /* Address     IRQ  Size  Bus  Description
30  * 0x00000000       64MB  16   NOR Flash (SP29PL256N)
31  * 0x0c000000       64MB  64   SDRAM (2xK4M563233G)
32  * 0x10000000  IRQ0       16   Ethernet (SMC91C111)
33  * 0x14000000  IRQ4       16   USB 2.0 Host Controller (M66596)
34  * 0x18000000       8GB    8   NAND Flash (K9K8G08U0A)
35  */
36
37 static struct smc91x_platdata smc91x_info = {
38         .flags = SMC91X_USE_16BIT,
39 };
40
41 static struct resource smc91x_eth_resources[] = {
42         [0] = {
43                 .name   = "SMC91C111" ,
44                 .start  = 0x10000300,
45                 .end    = 0x1000030f,
46                 .flags  = IORESOURCE_MEM,
47         },
48         [1] = {
49                 .start  = 32, /* IRQ0 */
50                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
51         },
52 };
53
54 static struct platform_device smc91x_eth_device = {
55         .name           = "smc91x",
56         .num_resources  = ARRAY_SIZE(smc91x_eth_resources),
57         .resource       = smc91x_eth_resources,
58         .dev    = {
59                 .platform_data  = &smc91x_info,
60         },
61 };
62
63 static struct sh_keysc_info sh_keysc_info = {
64         .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */
65         .scan_timing = 3,
66         .delay = 5,
67         .keycodes = {
68                 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER,
69                 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1,
70                 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
71                 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0,
72                 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD,
73         },
74 };
75
76 static struct resource sh_keysc_resources[] = {
77         [0] = {
78                 .start  = 0x044b0000,
79                 .end    = 0x044b000f,
80                 .flags  = IORESOURCE_MEM,
81         },
82         [1] = {
83                 .start  = 79,
84                 .flags  = IORESOURCE_IRQ,
85         },
86 };
87
88 static struct platform_device sh_keysc_device = {
89         .name           = "sh_keysc",
90         .num_resources  = ARRAY_SIZE(sh_keysc_resources),
91         .resource       = sh_keysc_resources,
92         .dev    = {
93                 .platform_data  = &sh_keysc_info,
94         },
95 };
96
97 static struct mtd_partition migor_nor_flash_partitions[] =
98 {
99         {
100                 .name = "uboot",
101                 .offset = 0,
102                 .size = (1 * 1024 * 1024),
103                 .mask_flags = MTD_WRITEABLE,    /* Read-only */
104         },
105         {
106                 .name = "rootfs",
107                 .offset = MTDPART_OFS_APPEND,
108                 .size = (15 * 1024 * 1024),
109         },
110         {
111                 .name = "other",
112                 .offset = MTDPART_OFS_APPEND,
113                 .size = MTDPART_SIZ_FULL,
114         },
115 };
116
117 static struct physmap_flash_data migor_nor_flash_data = {
118         .width          = 2,
119         .parts          = migor_nor_flash_partitions,
120         .nr_parts       = ARRAY_SIZE(migor_nor_flash_partitions),
121 };
122
123 static struct resource migor_nor_flash_resources[] = {
124         [0] = {
125                 .name           = "NOR Flash",
126                 .start          = 0x00000000,
127                 .end            = 0x03ffffff,
128                 .flags          = IORESOURCE_MEM,
129         }
130 };
131
132 static struct platform_device migor_nor_flash_device = {
133         .name           = "physmap-flash",
134         .resource       = migor_nor_flash_resources,
135         .num_resources  = ARRAY_SIZE(migor_nor_flash_resources),
136         .dev            = {
137                 .platform_data = &migor_nor_flash_data,
138         },
139 };
140
141 static struct mtd_partition migor_nand_flash_partitions[] = {
142         {
143                 .name           = "nanddata1",
144                 .offset         = 0x0,
145                 .size           = 512 * 1024 * 1024,
146         },
147         {
148                 .name           = "nanddata2",
149                 .offset         = MTDPART_OFS_APPEND,
150                 .size           = 512 * 1024 * 1024,
151         },
152 };
153
154 static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
155                                      unsigned int ctrl)
156 {
157         struct nand_chip *chip = mtd->priv;
158
159         if (cmd == NAND_CMD_NONE)
160                 return;
161
162         if (ctrl & NAND_CLE)
163                 writeb(cmd, chip->IO_ADDR_W + 0x00400000);
164         else if (ctrl & NAND_ALE)
165                 writeb(cmd, chip->IO_ADDR_W + 0x00800000);
166         else
167                 writeb(cmd, chip->IO_ADDR_W);
168 }
169
170 static int migor_nand_flash_ready(struct mtd_info *mtd)
171 {
172         return ctrl_inb(PORT_PADR) & 0x02; /* PTA1 */
173 }
174
175 struct platform_nand_data migor_nand_flash_data = {
176         .chip = {
177                 .nr_chips = 1,
178                 .partitions = migor_nand_flash_partitions,
179                 .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions),
180                 .chip_delay = 20,
181                 .part_probe_types = (const char *[]) { "cmdlinepart", NULL },
182         },
183         .ctrl = {
184                 .dev_ready = migor_nand_flash_ready,
185                 .cmd_ctrl = migor_nand_flash_cmd_ctl,
186         },
187 };
188
189 static struct resource migor_nand_flash_resources[] = {
190         [0] = {
191                 .name           = "NAND Flash",
192                 .start          = 0x18000000,
193                 .end            = 0x18ffffff,
194                 .flags          = IORESOURCE_MEM,
195         },
196 };
197
198 static struct platform_device migor_nand_flash_device = {
199         .name           = "gen_nand",
200         .resource       = migor_nand_flash_resources,
201         .num_resources  = ARRAY_SIZE(migor_nand_flash_resources),
202         .dev            = {
203                 .platform_data = &migor_nand_flash_data,
204         }
205 };
206
207 static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
208 #ifdef CONFIG_SH_MIGOR_RTA_WVGA
209         .clock_source = LCDC_CLK_BUS,
210         .ch[0] = {
211                 .chan = LCDC_CHAN_MAINLCD,
212                 .bpp = 16,
213                 .interface_type = RGB16,
214                 .clock_divider = 2,
215                 .lcd_cfg = {
216                         .name = "LB070WV1",
217                         .xres = 800,
218                         .yres = 480,
219                         .left_margin = 64,
220                         .right_margin = 16,
221                         .hsync_len = 120,
222                         .upper_margin = 1,
223                         .lower_margin = 17,
224                         .vsync_len = 2,
225                         .sync = 0,
226                 },
227         }
228 #endif
229 #ifdef CONFIG_SH_MIGOR_QVGA
230         .clock_source = LCDC_CLK_PERIPHERAL,
231         .ch[0] = {
232                 .chan = LCDC_CHAN_MAINLCD,
233                 .bpp = 16,
234                 .interface_type = SYS16A,
235                 .clock_divider = 10,
236                 .lcd_cfg = {
237                         .name = "PH240320T",
238                         .xres = 320,
239                         .yres = 240,
240                         .left_margin = 0,
241                         .right_margin = 16,
242                         .hsync_len = 8,
243                         .upper_margin = 1,
244                         .lower_margin = 17,
245                         .vsync_len = 2,
246                         .sync = FB_SYNC_HOR_HIGH_ACT,
247                 },
248                 .board_cfg = {
249                         .setup_sys = migor_lcd_qvga_setup,
250                 },
251                 .sys_bus_cfg = {
252                         .ldmt2r = 0x06000a09,
253                         .ldmt3r = 0x180e3418,
254                 },
255         }
256 #endif
257 };
258
259 static struct resource migor_lcdc_resources[] = {
260         [0] = {
261                 .name   = "LCDC",
262                 .start  = 0xfe940000, /* P4-only space */
263                 .end    = 0xfe941fff,
264                 .flags  = IORESOURCE_MEM,
265         },
266 };
267
268 static struct platform_device migor_lcdc_device = {
269         .name           = "sh_mobile_lcdc_fb",
270         .num_resources  = ARRAY_SIZE(migor_lcdc_resources),
271         .resource       = migor_lcdc_resources,
272         .dev    = {
273                 .platform_data  = &sh_mobile_lcdc_info,
274         },
275 };
276
277 static struct clk *camera_clk;
278
279 static void camera_power_on(void)
280 {
281         unsigned char value;
282
283         camera_clk = clk_get(NULL, "video_clk");
284         clk_set_rate(camera_clk, 24000000);
285         clk_enable(camera_clk); /* start VIO_CKO */
286
287         mdelay(10);
288         value = ctrl_inb(PORT_PTDR);
289         value &= ~0x09;
290 #ifndef CONFIG_SH_MIGOR_RTA_WVGA
291         value |= 0x01;
292 #endif
293         ctrl_outb(value, PORT_PTDR);
294         mdelay(10);
295
296         ctrl_outb(value | 8, PORT_PTDR);
297 }
298
299 static void camera_power_off(void)
300 {
301         clk_disable(camera_clk); /* stop VIO_CKO */
302         clk_put(camera_clk);
303
304         ctrl_outb(ctrl_inb(PORT_PTDR) & ~0x08, PORT_PTDR);
305 }
306
307 static unsigned char camera_ov772x_magic[] =
308 {
309         0x09, 0x01, 0x0c, 0x10, 0x0d, 0x41, 0x0e, 0x01,
310         0x12, 0x00, 0x13, 0x8F, 0x14, 0x4A, 0x15, 0x00,
311         0x16, 0x00, 0x17, 0x23, 0x18, 0xa0, 0x19, 0x07,
312         0x1a, 0xf0, 0x1b, 0x40, 0x1f, 0x00, 0x20, 0x10,
313         0x22, 0xff, 0x23, 0x01, 0x28, 0x00, 0x29, 0xa0,
314         0x2a, 0x00, 0x2b, 0x00, 0x2c, 0xf0, 0x2d, 0x00,
315         0x2e, 0x00, 0x30, 0x80, 0x31, 0x60, 0x32, 0x00,
316         0x33, 0x00, 0x34, 0x00, 0x3d, 0x80, 0x3e, 0xe2,
317         0x3f, 0x1f, 0x42, 0x80, 0x43, 0x80, 0x44, 0x80,
318         0x45, 0x80, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00,
319         0x49, 0x50, 0x4a, 0x30, 0x4b, 0x50, 0x4c, 0x50,
320         0x4d, 0x00, 0x4e, 0xef, 0x4f, 0x10, 0x50, 0x60,
321         0x51, 0x00, 0x52, 0x00, 0x53, 0x24, 0x54, 0x7a,
322         0x55, 0xfc, 0x62, 0xff, 0x63, 0xf0, 0x64, 0x1f,
323         0x65, 0x00, 0x66, 0x10, 0x67, 0x00, 0x68, 0x00,
324         0x69, 0x5c, 0x6a, 0x11, 0x6b, 0xa2, 0x6c, 0x01,
325         0x6d, 0x50, 0x6e, 0x80, 0x6f, 0x80, 0x70, 0x0f,
326         0x71, 0x00, 0x72, 0x00, 0x73, 0x0f, 0x74, 0x0f,
327         0x75, 0xff, 0x78, 0x10, 0x79, 0x70, 0x7a, 0x70,
328         0x7b, 0xf0, 0x7c, 0xf0, 0x7d, 0xf0, 0x7e, 0x0e,
329         0x7f, 0x1a, 0x80, 0x31, 0x81, 0x5a, 0x82, 0x69,
330         0x83, 0x75, 0x84, 0x7e, 0x85, 0x88, 0x86, 0x8f,
331         0x87, 0x96, 0x88, 0xa3, 0x89, 0xaf, 0x8a, 0xc4,
332         0x8b, 0xd7, 0x8c, 0xe8, 0x8d, 0x20, 0x8e, 0x00,
333         0x8f, 0x00, 0x90, 0x08, 0x91, 0x10, 0x92, 0x1f,
334         0x93, 0x01, 0x94, 0x2c, 0x95, 0x24, 0x96, 0x08,
335         0x97, 0x14, 0x98, 0x24, 0x99, 0x38, 0x9a, 0x9e,
336         0x9b, 0x00, 0x9c, 0x40, 0x9e, 0x11, 0x9f, 0x02,
337         0xa0, 0x00, 0xa1, 0x40, 0xa2, 0x40, 0xa3, 0x06,
338         0xa4, 0x00, 0xa6, 0x00, 0xa7, 0x40, 0xa8, 0x40,
339         0xa9, 0x80, 0xaa, 0x80, 0xab, 0x06, 0xac, 0xff,
340         0x12, 0x06, 0x64, 0x3f, 0x12, 0x46, 0x17, 0x3f,
341         0x18, 0x50, 0x19, 0x03, 0x1a, 0x78, 0x29, 0x50,
342         0x2c, 0x78,
343 };
344
345 static int ov772x_set_capture(struct soc_camera_platform_info *info,
346                               int enable)
347 {
348         struct i2c_adapter *a = i2c_get_adapter(0);
349         struct i2c_msg msg;
350         int ret = 0;
351         int i;
352
353         if (!enable)
354                 return 0; /* camera_power_off() is enough */
355
356         for (i = 0; i < ARRAY_SIZE(camera_ov772x_magic); i += 2) {
357                 u_int8_t buf[8];
358
359                 msg.addr = 0x21;
360                 msg.buf = buf;
361                 msg.len = 2;
362                 msg.flags = 0;
363
364                 buf[0] = camera_ov772x_magic[i];
365                 buf[1] = camera_ov772x_magic[i + 1];
366
367                 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
368         }
369
370         return ret;
371 }
372
373 static struct soc_camera_platform_info ov772x_info = {
374         .iface = 0,
375         .format_name = "RGB565",
376         .format_depth = 16,
377         .format = {
378                 .pixelformat = V4L2_PIX_FMT_RGB565,
379                 .colorspace = V4L2_COLORSPACE_SRGB,
380                 .width = 320,
381                 .height = 240,
382         },
383         .bus_param =  SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
384         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
385         .set_capture = ov772x_set_capture,
386 };
387
388 static struct platform_device migor_camera_device = {
389         .name           = "soc_camera_platform",
390         .dev    = {
391                 .platform_data  = &ov772x_info,
392         },
393 };
394
395 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
396         .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \
397         | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH,
398         .enable_camera = camera_power_on,
399         .disable_camera = camera_power_off,
400 };
401
402 static struct resource migor_ceu_resources[] = {
403         [0] = {
404                 .name   = "CEU",
405                 .start  = 0xfe910000,
406                 .end    = 0xfe91009f,
407                 .flags  = IORESOURCE_MEM,
408         },
409         [1] = {
410                 .start  = 52,
411                 .flags  = IORESOURCE_IRQ,
412         },
413         [2] = {
414                 /* place holder for contiguous memory */
415         },
416 };
417
418 static struct platform_device migor_ceu_device = {
419         .name           = "sh_mobile_ceu",
420         .num_resources  = ARRAY_SIZE(migor_ceu_resources),
421         .resource       = migor_ceu_resources,
422         .dev    = {
423                 .platform_data  = &sh_mobile_ceu_info,
424         },
425 };
426
427 static struct platform_device *migor_devices[] __initdata = {
428         &smc91x_eth_device,
429         &sh_keysc_device,
430         &migor_lcdc_device,
431         &migor_ceu_device,
432         &migor_camera_device,
433         &migor_nor_flash_device,
434         &migor_nand_flash_device,
435 };
436
437 static struct i2c_board_info migor_i2c_devices[] = {
438         {
439                 I2C_BOARD_INFO("rs5c372b", 0x32),
440         },
441         {
442                 I2C_BOARD_INFO("migor_ts", 0x51),
443                 .irq = 38, /* IRQ6 */
444         },
445 };
446
447 static int __init migor_devices_setup(void)
448 {
449         clk_always_enable("mstp214"); /* KEYSC */
450         clk_always_enable("mstp200"); /* LCDC */
451         clk_always_enable("mstp203"); /* CEU */
452
453         platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
454
455         i2c_register_board_info(0, migor_i2c_devices,
456                                 ARRAY_SIZE(migor_i2c_devices));
457  
458         return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
459 }
460 __initcall(migor_devices_setup);
461
462 static void __init migor_setup(char **cmdline_p)
463 {
464         /* SMC91C111 - Enable IRQ0 */
465         ctrl_outw(ctrl_inw(PORT_PJCR) & ~0x0003, PORT_PJCR);
466
467         /* KEYSC */
468         ctrl_outw(ctrl_inw(PORT_PYCR) & ~0x0fff, PORT_PYCR);
469         ctrl_outw(ctrl_inw(PORT_PZCR) & ~0x0ff0, PORT_PZCR);
470         ctrl_outw(ctrl_inw(PORT_PSELA) & ~0x4100, PORT_PSELA);
471         ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
472         ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
473
474         /* NAND Flash */
475         ctrl_outw(ctrl_inw(PORT_PXCR) & 0x0fff, PORT_PXCR);
476         ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x00000600) | 0x00000200,
477                   BSC_CS6ABCR);
478
479         /* Touch Panel - Enable IRQ6 */
480         ctrl_outw(ctrl_inw(PORT_PZCR) & ~0xc, PORT_PZCR);
481         ctrl_outw((ctrl_inw(PORT_PSELA) | 0x8000), PORT_PSELA);
482         ctrl_outw((ctrl_inw(PORT_HIZCRC) & ~0x4000), PORT_HIZCRC);
483
484 #ifdef CONFIG_SH_MIGOR_RTA_WVGA
485         /* LCDC - WVGA - Enable RGB Interface signals */
486         ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR);
487         ctrl_outw(0x0000, PORT_PHCR);
488         ctrl_outw(0x0000, PORT_PLCR);
489         ctrl_outw(0x0000, PORT_PMCR);
490         ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x000f, PORT_PRCR);
491         ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x000d) | 0x0400, PORT_PSELD);
492         ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0100, PORT_MSELCRB);
493         ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA);
494 #endif
495 #ifdef CONFIG_SH_MIGOR_QVGA
496         /* LCDC - QVGA - Enable SYS Interface signals */
497         ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR);
498         ctrl_outw((ctrl_inw(PORT_PHCR) & ~0xcfff) | 0x0010, PORT_PHCR);
499         ctrl_outw(0x0000, PORT_PLCR);
500         ctrl_outw(0x0000, PORT_PMCR);
501         ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x030f, PORT_PRCR);
502         ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x0001) | 0x0420, PORT_PSELD);
503         ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x0100, PORT_MSELCRB);
504         ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA);
505 #endif
506
507         /* CEU */
508         ctrl_outw((ctrl_inw(PORT_PTCR) & ~0x03c3) | 0x0051, PORT_PTCR);
509         ctrl_outw(ctrl_inw(PORT_PUCR) & ~0x03ff, PORT_PUCR);
510         ctrl_outw(ctrl_inw(PORT_PVCR) & ~0x03ff, PORT_PVCR);
511         ctrl_outw(ctrl_inw(PORT_PWCR) & ~0x3c00, PORT_PWCR);
512         ctrl_outw(ctrl_inw(PORT_PSELC) | 0x0001, PORT_PSELC);
513         ctrl_outw(ctrl_inw(PORT_PSELD) & ~0x2000, PORT_PSELD);
514         ctrl_outw(ctrl_inw(PORT_PSELE) | 0x000f, PORT_PSELE);
515         ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2200, PORT_MSELCRB);
516         ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x0a00, PORT_HIZCRA);
517         ctrl_outw(ctrl_inw(PORT_HIZCRB) & ~0x0003, PORT_HIZCRB);
518 }
519
520 static struct sh_machine_vector mv_migor __initmv = {
521         .mv_name                = "Migo-R",
522         .mv_setup               = migor_setup,
523 };