aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-10 18:17:52 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-10 18:17:52 -0400
commit0b019a41553a919965bb02d07d54e3e6c57a796d (patch)
tree6e329b4159b440d2aac5200a5c07103fe261c096 /arch/arm/mach-shmobile/board-ap4evb.c
parent5f6878b0d22f9b93f9698f88c335007e2a3c3bbc (diff)
parent054d5c9238f3c577ad51195c3ee7803613f322cc (diff)
Merge branches 'master' and 'devel' into for-linus
Conflicts: arch/arm/Kconfig arch/arm/mm/Kconfig
Diffstat (limited to 'arch/arm/mach-shmobile/board-ap4evb.c')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c817
1 files changed, 786 insertions, 31 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 1c2ec96ce261..23d472f9525e 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -17,25 +17,45 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20#include <linux/clk.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/init.h> 22#include <linux/init.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/irq.h> 24#include <linux/irq.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/mfd/sh_mobile_sdhi.h>
28#include <linux/mmc/host.h>
26#include <linux/mtd/mtd.h> 29#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h> 30#include <linux/mtd/partitions.h>
28#include <linux/mtd/physmap.h> 31#include <linux/mtd/physmap.h>
32#include <linux/mmc/host.h>
33#include <linux/mmc/sh_mmcif.h>
34#include <linux/i2c.h>
35#include <linux/i2c/tsc2007.h>
29#include <linux/io.h> 36#include <linux/io.h>
30#include <linux/smsc911x.h> 37#include <linux/smsc911x.h>
38#include <linux/sh_intc.h>
39#include <linux/sh_clk.h>
31#include <linux/gpio.h> 40#include <linux/gpio.h>
32#include <linux/input.h> 41#include <linux/input.h>
33#include <linux/input/sh_keysc.h> 42#include <linux/input/sh_keysc.h>
43#include <linux/usb/r8a66597.h>
44
45#include <sound/sh_fsi.h>
46
47#include <video/sh_mobile_hdmi.h>
48#include <video/sh_mobile_lcdc.h>
49#include <video/sh_mipi_dsi.h>
50
34#include <mach/common.h> 51#include <mach/common.h>
52#include <mach/irqs.h>
35#include <mach/sh7372.h> 53#include <mach/sh7372.h>
54
36#include <asm/mach-types.h> 55#include <asm/mach-types.h>
37#include <asm/mach/arch.h> 56#include <asm/mach/arch.h>
38#include <asm/mach/map.h> 57#include <asm/mach/map.h>
58#include <asm/mach/time.h>
39 59
40/* 60/*
41 * Address Interface BusWidth note 61 * Address Interface BusWidth note
@@ -80,12 +100,56 @@
80 */ 100 */
81 101
82/* 102/*
83 * KEYSC 103 * LCD / IRQ / KEYSC / IrDA
104 *
105 * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (QHD-TouchScreen)
106 * LCD = 2nd LCDC (WVGA)
84 * 107 *
85 * SW43 KEYSC 108 * | SW43 |
86 * ------------------------- 109 * SW3 | ON | OFF |
87 * ON enable 110 * -------------+-----------------------+---------------+
88 * OFF disable 111 * ON | KEY / IrDA | LCD |
112 * OFF | KEY / IrDA / IRQ | IRQ |
113 *
114 *
115 * QHD / WVGA display
116 *
117 * You can choice display type on menuconfig.
118 * Then, check above dip-switch.
119 */
120
121/*
122 * USB
123 *
124 * J7 : 1-2 MAX3355E VBUS
125 * 2-3 DC 5.0V
126 *
127 * S39: bit2: off
128 */
129
130/*
131 * FSI/FSMI
132 *
133 * SW41 : ON : SH-Mobile AP4 Audio Mode
134 * : OFF : Bluetooth Audio Mode
135 */
136
137/*
138 * MMC0/SDHI1 (CN7)
139 *
140 * J22 : select card voltage
141 * 1-2 pin : 1.8v
142 * 2-3 pin : 3.3v
143 *
144 * SW1 | SW33
145 * | bit1 | bit2 | bit3 | bit4
146 * ------------+------+------+------+-------
147 * MMC0 OFF | OFF | ON | ON | X
148 * SDHI1 OFF | ON | X | OFF | ON
149 *
150 * voltage lebel
151 * CN7 : 1.8v
152 * CN12: 3.3v
89 */ 153 */
90 154
91/* MTD */ 155/* MTD */
@@ -148,7 +212,7 @@ static struct resource smc911x_resources[] = {
148 .end = 0x16000000 - 1, 212 .end = 0x16000000 - 1,
149 .flags = IORESOURCE_MEM, 213 .flags = IORESOURCE_MEM,
150 }, { 214 }, {
151 .start = 6, 215 .start = evt2irq(0x02c0) /* IRQ6A */,
152 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 216 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
153 }, 217 },
154}; 218};
@@ -169,6 +233,180 @@ static struct platform_device smc911x_device = {
169 }, 233 },
170}; 234};
171 235
236/* SH_MMCIF */
237static struct resource sh_mmcif_resources[] = {
238 [0] = {
239 .name = "SH_MMCIF",
240 .start = 0xE6BD0000,
241 .end = 0xE6BD00FF,
242 .flags = IORESOURCE_MEM,
243 },
244 [1] = {
245 /* MMC ERR */
246 .start = evt2irq(0x1ac0),
247 .flags = IORESOURCE_IRQ,
248 },
249 [2] = {
250 /* MMC NOR */
251 .start = evt2irq(0x1ae0),
252 .flags = IORESOURCE_IRQ,
253 },
254};
255
256static struct sh_mmcif_plat_data sh_mmcif_plat = {
257 .sup_pclk = 0,
258 .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
259 .caps = MMC_CAP_4_BIT_DATA |
260 MMC_CAP_8_BIT_DATA |
261 MMC_CAP_NEEDS_POLL,
262};
263
264static struct platform_device sh_mmcif_device = {
265 .name = "sh_mmcif",
266 .id = 0,
267 .dev = {
268 .dma_mask = NULL,
269 .coherent_dma_mask = 0xffffffff,
270 .platform_data = &sh_mmcif_plat,
271 },
272 .num_resources = ARRAY_SIZE(sh_mmcif_resources),
273 .resource = sh_mmcif_resources,
274};
275
276/* SDHI0 */
277static struct sh_mobile_sdhi_info sdhi0_info = {
278 .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
279 .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
280};
281
282static struct resource sdhi0_resources[] = {
283 [0] = {
284 .name = "SDHI0",
285 .start = 0xe6850000,
286 .end = 0xe68501ff,
287 .flags = IORESOURCE_MEM,
288 },
289 [1] = {
290 .start = evt2irq(0x0e00) /* SDHI0 */,
291 .flags = IORESOURCE_IRQ,
292 },
293};
294
295static struct platform_device sdhi0_device = {
296 .name = "sh_mobile_sdhi",
297 .num_resources = ARRAY_SIZE(sdhi0_resources),
298 .resource = sdhi0_resources,
299 .id = 0,
300 .dev = {
301 .platform_data = &sdhi0_info,
302 },
303};
304
305/* SDHI1 */
306static struct sh_mobile_sdhi_info sdhi1_info = {
307 .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
308 .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
309 .tmio_ocr_mask = MMC_VDD_165_195,
310};
311
312static struct resource sdhi1_resources[] = {
313 [0] = {
314 .name = "SDHI1",
315 .start = 0xe6860000,
316 .end = 0xe68601ff,
317 .flags = IORESOURCE_MEM,
318 },
319 [1] = {
320 .start = evt2irq(0x0e80),
321 .flags = IORESOURCE_IRQ,
322 },
323};
324
325static struct platform_device sdhi1_device = {
326 .name = "sh_mobile_sdhi",
327 .num_resources = ARRAY_SIZE(sdhi1_resources),
328 .resource = sdhi1_resources,
329 .id = 1,
330 .dev = {
331 .platform_data = &sdhi1_info,
332 },
333};
334
335/* USB1 */
336static void usb1_host_port_power(int port, int power)
337{
338 if (!power) /* only power-on supported for now */
339 return;
340
341 /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
342 __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
343}
344
345static struct r8a66597_platdata usb1_host_data = {
346 .on_chip = 1,
347 .port_power = usb1_host_port_power,
348};
349
350static struct resource usb1_host_resources[] = {
351 [0] = {
352 .name = "USBHS",
353 .start = 0xE68B0000,
354 .end = 0xE68B00E6 - 1,
355 .flags = IORESOURCE_MEM,
356 },
357 [1] = {
358 .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
359 .flags = IORESOURCE_IRQ,
360 },
361};
362
363static struct platform_device usb1_host_device = {
364 .name = "r8a66597_hcd",
365 .id = 1,
366 .dev = {
367 .dma_mask = NULL, /* not use dma */
368 .coherent_dma_mask = 0xffffffff,
369 .platform_data = &usb1_host_data,
370 },
371 .num_resources = ARRAY_SIZE(usb1_host_resources),
372 .resource = usb1_host_resources,
373};
374
375static struct sh_mobile_lcdc_info lcdc_info = {
376 .ch[0] = {
377 .chan = LCDC_CHAN_MAINLCD,
378 .bpp = 16,
379 }
380};
381
382static struct resource lcdc_resources[] = {
383 [0] = {
384 .name = "LCDC",
385 .start = 0xfe940000, /* P4-only space */
386 .end = 0xfe943fff,
387 .flags = IORESOURCE_MEM,
388 },
389 [1] = {
390 .start = intcs_evt2irq(0x580),
391 .flags = IORESOURCE_IRQ,
392 },
393};
394
395static struct platform_device lcdc_device = {
396 .name = "sh_mobile_lcdc_fb",
397 .num_resources = ARRAY_SIZE(lcdc_resources),
398 .resource = lcdc_resources,
399 .dev = {
400 .platform_data = &lcdc_info,
401 .coherent_dma_mask = ~0,
402 },
403};
404
405/*
406 * QHD display
407 */
408#ifdef CONFIG_AP4EVB_QHD
409
172/* KEYSC (Needs SW43 set to ON) */ 410/* KEYSC (Needs SW43 set to ON) */
173static struct sh_keysc_info keysc_info = { 411static struct sh_keysc_info keysc_info = {
174 .mode = SH_KEYSC_MODE_1, 412 .mode = SH_KEYSC_MODE_1,
@@ -191,7 +429,7 @@ static struct resource keysc_resources[] = {
191 .flags = IORESOURCE_MEM, 429 .flags = IORESOURCE_MEM,
192 }, 430 },
193 [1] = { 431 [1] = {
194 .start = 79, 432 .start = evt2irq(0x0be0), /* KEYSC_KEY */
195 .flags = IORESOURCE_IRQ, 433 .flags = IORESOURCE_IRQ,
196 }, 434 },
197}; 435};
@@ -206,32 +444,362 @@ static struct platform_device keysc_device = {
206 }, 444 },
207}; 445};
208 446
209/* SDHI0 */ 447/* MIPI-DSI */
210static struct resource sdhi0_resources[] = { 448static struct resource mipidsi0_resources[] = {
211 [0] = { 449 [0] = {
212 .name = "SDHI0", 450 .start = 0xffc60000,
213 .start = 0xe6850000, 451 .end = 0xffc68fff,
214 .end = 0xe68501ff,
215 .flags = IORESOURCE_MEM, 452 .flags = IORESOURCE_MEM,
216 }, 453 },
454};
455
456static struct sh_mipi_dsi_info mipidsi0_info = {
457 .data_format = MIPI_RGB888,
458 .lcd_chan = &lcdc_info.ch[0],
459};
460
461static struct platform_device mipidsi0_device = {
462 .name = "sh-mipi-dsi",
463 .num_resources = ARRAY_SIZE(mipidsi0_resources),
464 .resource = mipidsi0_resources,
465 .id = 0,
466 .dev = {
467 .platform_data = &mipidsi0_info,
468 },
469};
470
471/* This function will disappear when we switch to (runtime) PM */
472static int __init ap4evb_init_display_clk(void)
473{
474 struct clk *lcdc_clk;
475 struct clk *dsitx_clk;
476 int ret;
477
478 lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0");
479 if (IS_ERR(lcdc_clk))
480 return PTR_ERR(lcdc_clk);
481
482 dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0");
483 if (IS_ERR(dsitx_clk)) {
484 ret = PTR_ERR(dsitx_clk);
485 goto eclkdsitxget;
486 }
487
488 ret = clk_enable(lcdc_clk);
489 if (ret < 0)
490 goto eclklcdcon;
491
492 ret = clk_enable(dsitx_clk);
493 if (ret < 0)
494 goto eclkdsitxon;
495
496 return 0;
497
498eclkdsitxon:
499 clk_disable(lcdc_clk);
500eclklcdcon:
501 clk_put(dsitx_clk);
502eclkdsitxget:
503 clk_put(lcdc_clk);
504
505 return ret;
506}
507device_initcall(ap4evb_init_display_clk);
508
509static struct platform_device *qhd_devices[] __initdata = {
510 &mipidsi0_device,
511 &keysc_device,
512};
513#endif /* CONFIG_AP4EVB_QHD */
514
515/* FSI */
516#define IRQ_FSI evt2irq(0x1840)
517#define FSIACKCR 0xE6150018
518static void fsiackcr_init(struct clk *clk)
519{
520 u32 status = __raw_readl(clk->enable_reg);
521
522 /* use external clock */
523 status &= ~0x000000ff;
524 status |= 0x00000080;
525 __raw_writel(status, clk->enable_reg);
526}
527
528static struct clk_ops fsiackcr_clk_ops = {
529 .init = fsiackcr_init,
530};
531
532static struct clk fsiackcr_clk = {
533 .ops = &fsiackcr_clk_ops,
534 .enable_reg = (void __iomem *)FSIACKCR,
535 .rate = 0, /* unknown */
536};
537
538static struct sh_fsi_platform_info fsi_info = {
539 .porta_flags = SH_FSI_BRS_INV |
540 SH_FSI_OUT_SLAVE_MODE |
541 SH_FSI_IN_SLAVE_MODE |
542 SH_FSI_OFMT(PCM) |
543 SH_FSI_IFMT(PCM),
544};
545
546static struct resource fsi_resources[] = {
547 [0] = {
548 .name = "FSI",
549 .start = 0xFE3C0000,
550 .end = 0xFE3C0400 - 1,
551 .flags = IORESOURCE_MEM,
552 },
217 [1] = { 553 [1] = {
218 .start = 96, 554 .start = IRQ_FSI,
219 .flags = IORESOURCE_IRQ, 555 .flags = IORESOURCE_IRQ,
220 }, 556 },
221}; 557};
222 558
223static struct platform_device sdhi0_device = { 559static struct platform_device fsi_device = {
224 .name = "sh_mobile_sdhi", 560 .name = "sh_fsi2",
225 .num_resources = ARRAY_SIZE(sdhi0_resources), 561 .id = 0,
226 .resource = sdhi0_resources, 562 .num_resources = ARRAY_SIZE(fsi_resources),
227 .id = 0, 563 .resource = fsi_resources,
564 .dev = {
565 .platform_data = &fsi_info,
566 },
567};
568
569static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
570 .clock_source = LCDC_CLK_EXTERNAL,
571 .ch[0] = {
572 .chan = LCDC_CHAN_MAINLCD,
573 .bpp = 16,
574 .interface_type = RGB24,
575 .clock_divider = 1,
576 .flags = LCDC_FLAGS_DWPOL,
577 .lcd_cfg = {
578 .name = "HDMI",
579 /* So far only 720p is supported */
580 .xres = 1280,
581 .yres = 720,
582 /*
583 * If left and right margins are not multiples of 8,
584 * LDHAJR will be adjusted accordingly by the LCDC
585 * driver. Until we start using EDID, these values
586 * might have to be adjusted for different monitors.
587 */
588 .left_margin = 200,
589 .right_margin = 88,
590 .hsync_len = 48,
591 .upper_margin = 20,
592 .lower_margin = 5,
593 .vsync_len = 5,
594 .pixclock = 13468,
595 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
596 },
597 }
598};
599
600static struct resource lcdc1_resources[] = {
601 [0] = {
602 .name = "LCDC1",
603 .start = 0xfe944000,
604 .end = 0xfe947fff,
605 .flags = IORESOURCE_MEM,
606 },
607 [1] = {
608 .start = intcs_evt2irq(0x17a0),
609 .flags = IORESOURCE_IRQ,
610 },
611};
612
613static struct platform_device lcdc1_device = {
614 .name = "sh_mobile_lcdc_fb",
615 .num_resources = ARRAY_SIZE(lcdc1_resources),
616 .resource = lcdc1_resources,
617 .id = 1,
618 .dev = {
619 .platform_data = &sh_mobile_lcdc1_info,
620 .coherent_dma_mask = ~0,
621 },
622};
623
624static struct sh_mobile_hdmi_info hdmi_info = {
625 .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
626 .lcd_dev = &lcdc1_device.dev,
627};
628
629static struct resource hdmi_resources[] = {
630 [0] = {
631 .name = "HDMI",
632 .start = 0xe6be0000,
633 .end = 0xe6be00ff,
634 .flags = IORESOURCE_MEM,
635 },
636 [1] = {
637 /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
638 .start = evt2irq(0x17e0),
639 .flags = IORESOURCE_IRQ,
640 },
641};
642
643static struct platform_device hdmi_device = {
644 .name = "sh-mobile-hdmi",
645 .num_resources = ARRAY_SIZE(hdmi_resources),
646 .resource = hdmi_resources,
647 .id = -1,
648 .dev = {
649 .platform_data = &hdmi_info,
650 },
228}; 651};
229 652
230static struct platform_device *ap4evb_devices[] __initdata = { 653static struct platform_device *ap4evb_devices[] __initdata = {
231 &nor_flash_device, 654 &nor_flash_device,
232 &smc911x_device, 655 &smc911x_device,
233 &keysc_device,
234 &sdhi0_device, 656 &sdhi0_device,
657 &sdhi1_device,
658 &usb1_host_device,
659 &fsi_device,
660 &sh_mmcif_device,
661 &lcdc1_device,
662 &lcdc_device,
663 &hdmi_device,
664};
665
666static int __init hdmi_init_pm_clock(void)
667{
668 struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
669 int ret;
670 long rate;
671
672 if (IS_ERR(hdmi_ick)) {
673 ret = PTR_ERR(hdmi_ick);
674 pr_err("Cannot get HDMI ICK: %d\n", ret);
675 goto out;
676 }
677
678 ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk);
679 if (ret < 0) {
680 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount);
681 goto out;
682 }
683
684 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk));
685
686 rate = clk_round_rate(&pllc2_clk, 594000000);
687 if (rate < 0) {
688 pr_err("Cannot get suitable rate: %ld\n", rate);
689 ret = rate;
690 goto out;
691 }
692
693 ret = clk_set_rate(&pllc2_clk, rate);
694 if (ret < 0) {
695 pr_err("Cannot set rate %ld: %d\n", rate, ret);
696 goto out;
697 }
698
699 pr_debug("PLLC2 set frequency %lu\n", rate);
700
701 ret = clk_set_parent(hdmi_ick, &pllc2_clk);
702 if (ret < 0) {
703 pr_err("Cannot set HDMI parent: %d\n", ret);
704 goto out;
705 }
706
707out:
708 if (!IS_ERR(hdmi_ick))
709 clk_put(hdmi_ick);
710 return ret;
711}
712
713device_initcall(hdmi_init_pm_clock);
714
715/*
716 * FIXME !!
717 *
718 * gpio_no_direction
719 * gpio_pull_up
720 * are quick_hack.
721 *
722 * current gpio frame work doesn't have
723 * the method to control only pull up/down/free.
724 * this function should be replaced by correct gpio function
725 */
726static void __init gpio_no_direction(u32 addr)
727{
728 __raw_writeb(0x00, addr);
729}
730
731static void __init gpio_pull_up(u32 addr)
732{
733 u8 data = __raw_readb(addr);
734
735 data &= 0x0F;
736 data |= 0xC0;
737 __raw_writeb(data, addr);
738}
739
740/* TouchScreen */
741#define IRQ28 evt2irq(0x3380) /* IRQ28A */
742#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
743static int ts_get_pendown_state(void)
744{
745 int val1, val2;
746
747 gpio_free(GPIO_FN_IRQ28_123);
748 gpio_free(GPIO_FN_IRQ7_40);
749
750 gpio_request(GPIO_PORT123, NULL);
751 gpio_request(GPIO_PORT40, NULL);
752
753 gpio_direction_input(GPIO_PORT123);
754 gpio_direction_input(GPIO_PORT40);
755
756 val1 = gpio_get_value(GPIO_PORT123);
757 val2 = gpio_get_value(GPIO_PORT40);
758
759 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */
760 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
761
762 return val1 ^ val2;
763}
764
765#define PORT40CR 0xE6051028
766#define PORT123CR 0xE605007B
767static int ts_init(void)
768{
769 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */
770 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
771
772 gpio_pull_up(PORT40CR);
773 gpio_pull_up(PORT123CR);
774
775 return 0;
776}
777
778static struct tsc2007_platform_data tsc2007_info = {
779 .model = 2007,
780 .x_plate_ohms = 180,
781 .get_pendown_state = ts_get_pendown_state,
782 .init_platform_hw = ts_init,
783};
784
785static struct i2c_board_info tsc_device = {
786 I2C_BOARD_INFO("tsc2007", 0x48),
787 .type = "tsc2007",
788 .platform_data = &tsc2007_info,
789 /*.irq is selected on ap4evb_init */
790};
791
792/* I2C */
793static struct i2c_board_info i2c0_devices[] = {
794 {
795 I2C_BOARD_INFO("ak4643", 0x13),
796 },
797};
798
799static struct i2c_board_info i2c1_devices[] = {
800 {
801 I2C_BOARD_INFO("r2025sd", 0x32),
802 },
235}; 803};
236 804
237static struct map_desc ap4evb_io_desc[] __initdata = { 805static struct map_desc ap4evb_io_desc[] __initdata = {
@@ -250,14 +818,18 @@ static void __init ap4evb_map_io(void)
250{ 818{
251 iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); 819 iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
252 820
253 /* setup early devices, clocks and console here as well */ 821 /* setup early devices and console here as well */
254 sh7372_add_early_devices(); 822 sh7372_add_early_devices();
255 sh7367_clock_init(); /* use g3 clocks for now */
256 shmobile_setup_console(); 823 shmobile_setup_console();
257} 824}
258 825
826#define GPIO_PORT9CR 0xE6051009
827#define GPIO_PORT10CR 0xE605100A
259static void __init ap4evb_init(void) 828static void __init ap4evb_init(void)
260{ 829{
830 u32 srcr4;
831 struct clk *clk;
832
261 sh7372_pinmux_init(); 833 sh7372_pinmux_init();
262 834
263 /* enable SCIFA0 */ 835 /* enable SCIFA0 */
@@ -296,6 +868,93 @@ static void __init ap4evb_init(void)
296 gpio_export(GPIO_PORT34, 0); 868 gpio_export(GPIO_PORT34, 0);
297 gpio_export(GPIO_PORT35, 0); 869 gpio_export(GPIO_PORT35, 0);
298 870
871 /* SDHI0 */
872 gpio_request(GPIO_FN_SDHICD0, NULL);
873 gpio_request(GPIO_FN_SDHIWP0, NULL);
874 gpio_request(GPIO_FN_SDHICMD0, NULL);
875 gpio_request(GPIO_FN_SDHICLK0, NULL);
876 gpio_request(GPIO_FN_SDHID0_3, NULL);
877 gpio_request(GPIO_FN_SDHID0_2, NULL);
878 gpio_request(GPIO_FN_SDHID0_1, NULL);
879 gpio_request(GPIO_FN_SDHID0_0, NULL);
880
881 /* SDHI1 */
882 gpio_request(GPIO_FN_SDHICMD1, NULL);
883 gpio_request(GPIO_FN_SDHICLK1, NULL);
884 gpio_request(GPIO_FN_SDHID1_3, NULL);
885 gpio_request(GPIO_FN_SDHID1_2, NULL);
886 gpio_request(GPIO_FN_SDHID1_1, NULL);
887 gpio_request(GPIO_FN_SDHID1_0, NULL);
888
889 /* MMCIF */
890 gpio_request(GPIO_FN_MMCD0_0, NULL);
891 gpio_request(GPIO_FN_MMCD0_1, NULL);
892 gpio_request(GPIO_FN_MMCD0_2, NULL);
893 gpio_request(GPIO_FN_MMCD0_3, NULL);
894 gpio_request(GPIO_FN_MMCD0_4, NULL);
895 gpio_request(GPIO_FN_MMCD0_5, NULL);
896 gpio_request(GPIO_FN_MMCD0_6, NULL);
897 gpio_request(GPIO_FN_MMCD0_7, NULL);
898 gpio_request(GPIO_FN_MMCCMD0, NULL);
899 gpio_request(GPIO_FN_MMCCLK0, NULL);
900
901 /* USB enable */
902 gpio_request(GPIO_FN_VBUS0_1, NULL);
903 gpio_request(GPIO_FN_IDIN_1_18, NULL);
904 gpio_request(GPIO_FN_PWEN_1_115, NULL);
905 gpio_request(GPIO_FN_OVCN_1_114, NULL);
906 gpio_request(GPIO_FN_EXTLP_1, NULL);
907 gpio_request(GPIO_FN_OVCN2_1, NULL);
908
909 /* setup USB phy */
910 __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */
911
912 /* enable FSI2 */
913 gpio_request(GPIO_FN_FSIAIBT, NULL);
914 gpio_request(GPIO_FN_FSIAILR, NULL);
915 gpio_request(GPIO_FN_FSIAISLD, NULL);
916 gpio_request(GPIO_FN_FSIAOSLD, NULL);
917 gpio_request(GPIO_PORT161, NULL);
918 gpio_direction_output(GPIO_PORT161, 0); /* slave */
919
920 gpio_request(GPIO_PORT9, NULL);
921 gpio_request(GPIO_PORT10, NULL);
922 gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
923 gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
924
925 /* set SPU2 clock to 119.6 MHz */
926 clk = clk_get(NULL, "spu_clk");
927 if (!IS_ERR(clk)) {
928 clk_set_rate(clk, clk_round_rate(clk, 119600000));
929 clk_put(clk);
930 }
931
932 /* change parent of FSI A */
933 clk = clk_get(NULL, "fsia_clk");
934 if (!IS_ERR(clk)) {
935 clk_register(&fsiackcr_clk);
936 clk_set_parent(clk, &fsiackcr_clk);
937 clk_put(clk);
938 }
939
940 /*
941 * set irq priority, to avoid sound chopping
942 * when NFS rootfs is used
943 * FSI(3) > SMSC911X(2)
944 */
945 intc_set_priority(IRQ_FSI, 3);
946
947 i2c_register_board_info(0, i2c0_devices,
948 ARRAY_SIZE(i2c0_devices));
949
950 i2c_register_board_info(1, i2c1_devices,
951 ARRAY_SIZE(i2c1_devices));
952
953#ifdef CONFIG_AP4EVB_QHD
954 /*
955 * QHD
956 */
957
299 /* enable KEYSC */ 958 /* enable KEYSC */
300 gpio_request(GPIO_FN_KEYOUT0, NULL); 959 gpio_request(GPIO_FN_KEYOUT0, NULL);
301 gpio_request(GPIO_FN_KEYOUT1, NULL); 960 gpio_request(GPIO_FN_KEYOUT1, NULL);
@@ -308,26 +967,122 @@ static void __init ap4evb_init(void)
308 gpio_request(GPIO_FN_KEYIN3_133, NULL); 967 gpio_request(GPIO_FN_KEYIN3_133, NULL);
309 gpio_request(GPIO_FN_KEYIN4, NULL); 968 gpio_request(GPIO_FN_KEYIN4, NULL);
310 969
311 /* SDHI0 */ 970 /* enable TouchScreen */
312 gpio_request(GPIO_FN_SDHICD0, NULL); 971 set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
313 gpio_request(GPIO_FN_SDHIWP0, NULL); 972
314 gpio_request(GPIO_FN_SDHICMD0, NULL); 973 tsc_device.irq = IRQ28;
315 gpio_request(GPIO_FN_SDHICLK0, NULL); 974 i2c_register_board_info(1, &tsc_device, 1);
316 gpio_request(GPIO_FN_SDHID0_3, NULL); 975
317 gpio_request(GPIO_FN_SDHID0_2, NULL); 976 /* LCDC0 */
318 gpio_request(GPIO_FN_SDHID0_1, NULL); 977 lcdc_info.clock_source = LCDC_CLK_PERIPHERAL;
319 gpio_request(GPIO_FN_SDHID0_0, NULL); 978 lcdc_info.ch[0].interface_type = RGB24;
979 lcdc_info.ch[0].clock_divider = 1;
980 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
981 lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)";
982 lcdc_info.ch[0].lcd_cfg.xres = 544;
983 lcdc_info.ch[0].lcd_cfg.yres = 961;
984 lcdc_info.ch[0].lcd_cfg.left_margin = 72;
985 lcdc_info.ch[0].lcd_cfg.right_margin = 600;
986 lcdc_info.ch[0].lcd_cfg.hsync_len = 16;
987 lcdc_info.ch[0].lcd_cfg.upper_margin = 8;
988 lcdc_info.ch[0].lcd_cfg.lower_margin = 8;
989 lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
990 lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT |
991 FB_SYNC_HOR_HIGH_ACT;
992 lcdc_info.ch[0].lcd_size_cfg.width = 44;
993 lcdc_info.ch[0].lcd_size_cfg.height = 79;
994
995 platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
996
997#else
998 /*
999 * WVGA
1000 */
1001 gpio_request(GPIO_FN_LCDD17, NULL);
1002 gpio_request(GPIO_FN_LCDD16, NULL);
1003 gpio_request(GPIO_FN_LCDD15, NULL);
1004 gpio_request(GPIO_FN_LCDD14, NULL);
1005 gpio_request(GPIO_FN_LCDD13, NULL);
1006 gpio_request(GPIO_FN_LCDD12, NULL);
1007 gpio_request(GPIO_FN_LCDD11, NULL);
1008 gpio_request(GPIO_FN_LCDD10, NULL);
1009 gpio_request(GPIO_FN_LCDD9, NULL);
1010 gpio_request(GPIO_FN_LCDD8, NULL);
1011 gpio_request(GPIO_FN_LCDD7, NULL);
1012 gpio_request(GPIO_FN_LCDD6, NULL);
1013 gpio_request(GPIO_FN_LCDD5, NULL);
1014 gpio_request(GPIO_FN_LCDD4, NULL);
1015 gpio_request(GPIO_FN_LCDD3, NULL);
1016 gpio_request(GPIO_FN_LCDD2, NULL);
1017 gpio_request(GPIO_FN_LCDD1, NULL);
1018 gpio_request(GPIO_FN_LCDD0, NULL);
1019 gpio_request(GPIO_FN_LCDDISP, NULL);
1020 gpio_request(GPIO_FN_LCDDCK, NULL);
1021
1022 gpio_request(GPIO_PORT189, NULL); /* backlight */
1023 gpio_direction_output(GPIO_PORT189, 1);
1024
1025 gpio_request(GPIO_PORT151, NULL); /* LCDDON */
1026 gpio_direction_output(GPIO_PORT151, 1);
1027
1028 lcdc_info.clock_source = LCDC_CLK_BUS;
1029 lcdc_info.ch[0].interface_type = RGB18;
1030 lcdc_info.ch[0].clock_divider = 2;
1031 lcdc_info.ch[0].flags = 0;
1032 lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel";
1033 lcdc_info.ch[0].lcd_cfg.xres = 800;
1034 lcdc_info.ch[0].lcd_cfg.yres = 480;
1035 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1036 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1037 lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
1038 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1039 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1040 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1041 lcdc_info.ch[0].lcd_cfg.sync = 0;
1042 lcdc_info.ch[0].lcd_size_cfg.width = 152;
1043 lcdc_info.ch[0].lcd_size_cfg.height = 91;
1044
1045 /* enable TouchScreen */
1046 set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
1047
1048 tsc_device.irq = IRQ7;
1049 i2c_register_board_info(0, &tsc_device, 1);
1050#endif /* CONFIG_AP4EVB_QHD */
320 1051
321 sh7372_add_standard_devices(); 1052 sh7372_add_standard_devices();
322 1053
1054 /* HDMI */
1055 gpio_request(GPIO_FN_HDMI_HPD, NULL);
1056 gpio_request(GPIO_FN_HDMI_CEC, NULL);
1057
1058 /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
1059#define SRCR4 0xe61580bc
1060 srcr4 = __raw_readl(SRCR4);
1061 __raw_writel(srcr4 | (1 << 13), SRCR4);
1062 udelay(50);
1063 __raw_writel(srcr4 & ~(1 << 13), SRCR4);
1064
323 platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); 1065 platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
324} 1066}
325 1067
1068static void __init ap4evb_timer_init(void)
1069{
1070 sh7372_clock_init();
1071 shmobile_timer.init();
1072
1073 /* External clock source */
1074 clk_set_rate(&dv_clki_clk, 27000000);
1075}
1076
1077static struct sys_timer ap4evb_timer = {
1078 .init = ap4evb_timer_init,
1079};
1080
326MACHINE_START(AP4EVB, "ap4evb") 1081MACHINE_START(AP4EVB, "ap4evb")
327 .phys_io = 0xe6000000, 1082 .phys_io = 0xe6000000,
328 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, 1083 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
329 .map_io = ap4evb_map_io, 1084 .map_io = ap4evb_map_io,
330 .init_irq = sh7372_init_irq, 1085 .init_irq = sh7372_init_irq,
331 .init_machine = ap4evb_init, 1086 .init_machine = ap4evb_init,
332 .timer = &shmobile_timer, 1087 .timer = &ap4evb_timer,
333MACHINE_END 1088MACHINE_END