aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Kconfig26
-rw-r--r--arch/arm/mach-shmobile/Makefile6
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c817
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c59
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c153
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c357
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c560
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c369
-rw-r--r--arch/arm/mach-shmobile/clock.c44
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h10
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/memory.h3
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h30
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h3
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c178
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c232
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c300
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c3
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c30
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c391
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c34
21 files changed, 3454 insertions, 157 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 4c704b4e8b34..54b479c35ee0 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -7,6 +7,7 @@ config ARCH_SH7367
7 select CPU_V6 7 select CPU_V6
8 select HAVE_CLK 8 select HAVE_CLK
9 select COMMON_CLKDEV 9 select COMMON_CLKDEV
10 select SH_CLK_CPG
10 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
11 12
12config ARCH_SH7377 13config ARCH_SH7377
@@ -14,6 +15,7 @@ config ARCH_SH7377
14 select CPU_V7 15 select CPU_V7
15 select HAVE_CLK 16 select HAVE_CLK
16 select COMMON_CLKDEV 17 select COMMON_CLKDEV
18 select SH_CLK_CPG
17 select GENERIC_CLOCKEVENTS 19 select GENERIC_CLOCKEVENTS
18 20
19config ARCH_SH7372 21config ARCH_SH7372
@@ -21,6 +23,7 @@ config ARCH_SH7372
21 select CPU_V7 23 select CPU_V7
22 select HAVE_CLK 24 select HAVE_CLK
23 select COMMON_CLKDEV 25 select COMMON_CLKDEV
26 select SH_CLK_CPG
24 select GENERIC_CLOCKEVENTS 27 select GENERIC_CLOCKEVENTS
25 28
26comment "SH-Mobile Board Type" 29comment "SH-Mobile Board Type"
@@ -39,6 +42,20 @@ config MACH_AP4EVB
39 bool "AP4EVB board" 42 bool "AP4EVB board"
40 depends on ARCH_SH7372 43 depends on ARCH_SH7372
41 select ARCH_REQUIRE_GPIOLIB 44 select ARCH_REQUIRE_GPIOLIB
45 select SH_LCD_MIPI_DSI
46
47choice
48 prompt "AP4EVB LCD panel selection"
49 default AP4EVB_QHD
50 depends on MACH_AP4EVB
51
52config AP4EVB_QHD
53 bool "MIPI-DSI QHD (960x540)"
54
55config AP4EVB_WVGA
56 bool "Parallel WVGA (800x480)"
57
58endchoice
42 59
43comment "SH-Mobile System Configuration" 60comment "SH-Mobile System Configuration"
44 61
@@ -88,6 +105,15 @@ config SH_TIMER_CMT
88 help 105 help
89 This enables build of the CMT timer driver. 106 This enables build of the CMT timer driver.
90 107
108config SH_TIMER_TMU
109 bool "TMU timer driver"
110 default y
111 help
112 This enables build of the TMU timer driver.
113
91endmenu 114endmenu
92 115
116config SH_CLK_CPG
117 bool
118
93endif 119endif
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 6d385d371c33..5e16b4c69222 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,12 +3,12 @@
3# 3#
4 4
5# Common objects 5# Common objects
6obj-y := timer.o console.o 6obj-y := timer.o console.o clock.o
7 7
8# CPU objects 8# CPU objects
9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o 9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
10obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o intc-sh7377.o 10obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
11obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7367.o intc-sh7372.o 11obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
12 12
13# Pinmux setup 13# Pinmux setup
14pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o 14pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o
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
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 9247503296c4..a5525901e91f 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -37,6 +37,15 @@
37#include <asm/mach-types.h> 37#include <asm/mach-types.h>
38#include <asm/mach/arch.h> 38#include <asm/mach/arch.h>
39#include <asm/mach/map.h> 39#include <asm/mach/map.h>
40#include <asm/mach/time.h>
41
42/*
43 * IrDA
44 *
45 * S67: 5bit : ON power
46 * : 6bit : ON remote control
47 * OFF IrDA
48 */
40 49
41static struct mtd_partition nor_flash_partitions[] = { 50static struct mtd_partition nor_flash_partitions[] = {
42 { 51 {
@@ -91,7 +100,7 @@ static struct platform_device nor_flash_device = {
91}; 100};
92 101
93/* USBHS */ 102/* USBHS */
94void usb_host_port_power(int port, int power) 103static void usb_host_port_power(int port, int power)
95{ 104{
96 if (!power) /* only power-on supported for now */ 105 if (!power) /* only power-on supported for now */
97 return; 106 return;
@@ -113,7 +122,7 @@ static struct resource usb_host_resources[] = {
113 .flags = IORESOURCE_MEM, 122 .flags = IORESOURCE_MEM,
114 }, 123 },
115 [1] = { 124 [1] = {
116 .start = 65, 125 .start = evt2irq(0xa20), /* USBHS_USHI0 */
117 .flags = IORESOURCE_IRQ, 126 .flags = IORESOURCE_IRQ,
118 }, 127 },
119}; 128};
@@ -153,7 +162,7 @@ static struct resource keysc_resources[] = {
153 .flags = IORESOURCE_MEM, 162 .flags = IORESOURCE_MEM,
154 }, 163 },
155 [1] = { 164 [1] = {
156 .start = 79, 165 .start = evt2irq(0xbe0), /* KEYSC_KEY */
157 .flags = IORESOURCE_IRQ, 166 .flags = IORESOURCE_IRQ,
158 }, 167 },
159}; 168};
@@ -209,11 +218,31 @@ static struct platform_device nand_flash_device = {
209 }, 218 },
210}; 219};
211 220
221static struct resource irda_resources[] = {
222 [0] = {
223 .start = 0xE6D00000,
224 .end = 0xE6D01FD4 - 1,
225 .flags = IORESOURCE_MEM,
226 },
227 [1] = {
228 .start = evt2irq(0x480), /* IRDA */
229 .flags = IORESOURCE_IRQ,
230 },
231};
232
233static struct platform_device irda_device = {
234 .name = "sh_irda",
235 .id = -1,
236 .resource = irda_resources,
237 .num_resources = ARRAY_SIZE(irda_resources),
238};
239
212static struct platform_device *g3evm_devices[] __initdata = { 240static struct platform_device *g3evm_devices[] __initdata = {
213 &nor_flash_device, 241 &nor_flash_device,
214 &usb_host_device, 242 &usb_host_device,
215 &keysc_device, 243 &keysc_device,
216 &nand_flash_device, 244 &nand_flash_device,
245 &irda_device,
217}; 246};
218 247
219static struct map_desc g3evm_io_desc[] __initdata = { 248static struct map_desc g3evm_io_desc[] __initdata = {
@@ -232,9 +261,8 @@ static void __init g3evm_map_io(void)
232{ 261{
233 iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); 262 iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
234 263
235 /* setup early devices, clocks and console here as well */ 264 /* setup early devices and console here as well */
236 sh7367_add_early_devices(); 265 sh7367_add_early_devices();
237 sh7367_clock_init();
238 shmobile_setup_console(); 266 shmobile_setup_console();
239} 267}
240 268
@@ -271,9 +299,6 @@ static void __init g3evm_init(void)
271 gpio_request(GPIO_FN_EXTLP, NULL); 299 gpio_request(GPIO_FN_EXTLP, NULL);
272 gpio_request(GPIO_FN_IDIN, NULL); 300 gpio_request(GPIO_FN_IDIN, NULL);
273 301
274 /* enable clock in SYMSTPCR2 */
275 __raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048);
276
277 /* setup USB phy */ 302 /* setup USB phy */
278 __raw_writew(0x0300, 0xe605810a); /* USBCR1 */ 303 __raw_writew(0x0300, 0xe605810a); /* USBCR1 */
279 __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ 304 __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
@@ -318,16 +343,32 @@ static void __init g3evm_init(void)
318 /* FOE, FCDE, FSC on dedicated pins */ 343 /* FOE, FCDE, FSC on dedicated pins */
319 __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); 344 __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
320 345
346 /* IrDA */
347 gpio_request(GPIO_FN_IRDA_OUT, NULL);
348 gpio_request(GPIO_FN_IRDA_IN, NULL);
349 gpio_request(GPIO_FN_IRDA_FIRSEL, NULL);
350 set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW);
351
321 sh7367_add_standard_devices(); 352 sh7367_add_standard_devices();
322 353
323 platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); 354 platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
324} 355}
325 356
357static void __init g3evm_timer_init(void)
358{
359 sh7367_clock_init();
360 shmobile_timer.init();
361}
362
363static struct sys_timer g3evm_timer = {
364 .init = g3evm_timer_init,
365};
366
326MACHINE_START(G3EVM, "g3evm") 367MACHINE_START(G3EVM, "g3evm")
327 .phys_io = 0xe6000000, 368 .phys_io = 0xe6000000,
328 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, 369 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
329 .map_io = g3evm_map_io, 370 .map_io = g3evm_map_io,
330 .init_irq = sh7367_init_irq, 371 .init_irq = sh7367_init_irq,
331 .init_machine = g3evm_init, 372 .init_machine = g3evm_init,
332 .timer = &shmobile_timer, 373 .timer = &g3evm_timer,
333MACHINE_END 374MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 10673a90be52..2c3ff6f7f34c 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -30,12 +30,39 @@
30#include <linux/io.h> 30#include <linux/io.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/input/sh_keysc.h> 32#include <linux/input/sh_keysc.h>
33#include <linux/mfd/sh_mobile_sdhi.h>
33#include <linux/gpio.h> 34#include <linux/gpio.h>
34#include <mach/sh7377.h> 35#include <mach/sh7377.h>
35#include <mach/common.h> 36#include <mach/common.h>
36#include <asm/mach-types.h> 37#include <asm/mach-types.h>
37#include <asm/mach/arch.h> 38#include <asm/mach/arch.h>
38#include <asm/mach/map.h> 39#include <asm/mach/map.h>
40#include <asm/mach/time.h>
41
42/*
43 * SDHI
44 *
45 * SDHI0 : card detection is possible
46 * SDHI1 : card detection is impossible
47 *
48 * [G4-MAIN-BOARD]
49 * JP74 : short # DBG_2V8A for SDHI0
50 * JP75 : NC # DBG_3V3A for SDHI0
51 * JP76 : NC # DBG_3V3A_SD for SDHI0
52 * JP77 : NC # 3V3A_SDIO for SDHI1
53 * JP78 : short # DBG_2V8A for SDHI1
54 * JP79 : NC # DBG_3V3A for SDHI1
55 * JP80 : NC # DBG_3V3A_SD for SDHI1
56 *
57 * [G4-CORE-BOARD]
58 * S32 : all off # to dissever from G3-CORE_DBG board
59 * S33 : all off # to dissever from G3-CORE_DBG board
60 *
61 * [G3-CORE_DBG-BOARD]
62 * S1 : all off # to dissever from G3-CORE_DBG board
63 * S3 : all off # to dissever from G3-CORE_DBG board
64 * S4 : all off # to dissever from G3-CORE_DBG board
65 */
39 66
40static struct mtd_partition nor_flash_partitions[] = { 67static struct mtd_partition nor_flash_partitions[] = {
41 { 68 {
@@ -90,7 +117,7 @@ static struct platform_device nor_flash_device = {
90}; 117};
91 118
92/* USBHS */ 119/* USBHS */
93void usb_host_port_power(int port, int power) 120static void usb_host_port_power(int port, int power)
94{ 121{
95 if (!power) /* only power-on supported for now */ 122 if (!power) /* only power-on supported for now */
96 return; 123 return;
@@ -112,8 +139,7 @@ static struct resource usb_host_resources[] = {
112 .flags = IORESOURCE_MEM, 139 .flags = IORESOURCE_MEM,
113 }, 140 },
114 [1] = { 141 [1] = {
115 .start = 65, 142 .start = evt2irq(0x0a20), /* USBHS_USHI0 */
116 .end = 65,
117 .flags = IORESOURCE_IRQ, 143 .flags = IORESOURCE_IRQ,
118 }, 144 },
119}; 145};
@@ -154,7 +180,7 @@ static struct resource keysc_resources[] = {
154 .flags = IORESOURCE_MEM, 180 .flags = IORESOURCE_MEM,
155 }, 181 },
156 [1] = { 182 [1] = {
157 .start = 79, 183 .start = evt2irq(0x0be0), /* KEYSC_KEY */
158 .flags = IORESOURCE_IRQ, 184 .flags = IORESOURCE_IRQ,
159 }, 185 },
160}; 186};
@@ -169,10 +195,53 @@ static struct platform_device keysc_device = {
169 }, 195 },
170}; 196};
171 197
198/* SDHI */
199static struct resource sdhi0_resources[] = {
200 [0] = {
201 .name = "SDHI0",
202 .start = 0xe6d50000,
203 .end = 0xe6d501ff,
204 .flags = IORESOURCE_MEM,
205 },
206 [1] = {
207 .start = evt2irq(0x0e00), /* SDHI0 */
208 .flags = IORESOURCE_IRQ,
209 },
210};
211
212static struct platform_device sdhi0_device = {
213 .name = "sh_mobile_sdhi",
214 .num_resources = ARRAY_SIZE(sdhi0_resources),
215 .resource = sdhi0_resources,
216 .id = 0,
217};
218
219static struct resource sdhi1_resources[] = {
220 [0] = {
221 .name = "SDHI1",
222 .start = 0xe6d60000,
223 .end = 0xe6d601ff,
224 .flags = IORESOURCE_MEM,
225 },
226 [1] = {
227 .start = evt2irq(0x0e80), /* SDHI1 */
228 .flags = IORESOURCE_IRQ,
229 },
230};
231
232static struct platform_device sdhi1_device = {
233 .name = "sh_mobile_sdhi",
234 .num_resources = ARRAY_SIZE(sdhi1_resources),
235 .resource = sdhi1_resources,
236 .id = 1,
237};
238
172static struct platform_device *g4evm_devices[] __initdata = { 239static struct platform_device *g4evm_devices[] __initdata = {
173 &nor_flash_device, 240 &nor_flash_device,
174 &usb_host_device, 241 &usb_host_device,
175 &keysc_device, 242 &keysc_device,
243 &sdhi0_device,
244 &sdhi1_device,
176}; 245};
177 246
178static struct map_desc g4evm_io_desc[] __initdata = { 247static struct map_desc g4evm_io_desc[] __initdata = {
@@ -191,12 +260,41 @@ static void __init g4evm_map_io(void)
191{ 260{
192 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); 261 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
193 262
194 /* setup early devices, clocks and console here as well */ 263 /* setup early devices and console here as well */
195 sh7377_add_early_devices(); 264 sh7377_add_early_devices();
196 sh7367_clock_init(); /* use g3 clocks for now */
197 shmobile_setup_console(); 265 shmobile_setup_console();
198} 266}
199 267
268#define GPIO_SDHID0_D0 0xe60520fc
269#define GPIO_SDHID0_D1 0xe60520fd
270#define GPIO_SDHID0_D2 0xe60520fe
271#define GPIO_SDHID0_D3 0xe60520ff
272#define GPIO_SDHICMD0 0xe6052100
273
274#define GPIO_SDHID1_D0 0xe6052103
275#define GPIO_SDHID1_D1 0xe6052104
276#define GPIO_SDHID1_D2 0xe6052105
277#define GPIO_SDHID1_D3 0xe6052106
278#define GPIO_SDHICMD1 0xe6052107
279
280/*
281 * FIXME !!
282 *
283 * gpio_pull_up is quick_hack.
284 *
285 * current gpio frame work doesn't have
286 * the method to control only pull up/down/free.
287 * this function should be replaced by correct gpio function
288 */
289static void __init gpio_pull_up(u32 addr)
290{
291 u8 data = __raw_readb(addr);
292
293 data &= 0x0F;
294 data |= 0xC0;
295 __raw_writeb(data, addr);
296}
297
200static void __init g4evm_init(void) 298static void __init g4evm_init(void)
201{ 299{
202 sh7377_pinmux_init(); 300 sh7377_pinmux_init();
@@ -229,9 +327,6 @@ static void __init g4evm_init(void)
229 gpio_request(GPIO_FN_EXTLP, NULL); 327 gpio_request(GPIO_FN_EXTLP, NULL);
230 gpio_request(GPIO_FN_IDIN, NULL); 328 gpio_request(GPIO_FN_IDIN, NULL);
231 329
232 /* enable clock in SMSTPCR3 */
233 __raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c);
234
235 /* setup USB phy */ 330 /* setup USB phy */
236 __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ 331 __raw_writew(0x0200, 0xe605810a); /* USBCR1 */
237 __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ 332 __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
@@ -253,16 +348,54 @@ static void __init g4evm_init(void)
253 gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); 348 gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
254 gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); 349 gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
255 350
351 /* SDHI0 */
352 gpio_request(GPIO_FN_SDHICLK0, NULL);
353 gpio_request(GPIO_FN_SDHICD0, NULL);
354 gpio_request(GPIO_FN_SDHID0_0, NULL);
355 gpio_request(GPIO_FN_SDHID0_1, NULL);
356 gpio_request(GPIO_FN_SDHID0_2, NULL);
357 gpio_request(GPIO_FN_SDHID0_3, NULL);
358 gpio_request(GPIO_FN_SDHICMD0, NULL);
359 gpio_request(GPIO_FN_SDHIWP0, NULL);
360 gpio_pull_up(GPIO_SDHID0_D0);
361 gpio_pull_up(GPIO_SDHID0_D1);
362 gpio_pull_up(GPIO_SDHID0_D2);
363 gpio_pull_up(GPIO_SDHID0_D3);
364 gpio_pull_up(GPIO_SDHICMD0);
365
366 /* SDHI1 */
367 gpio_request(GPIO_FN_SDHICLK1, NULL);
368 gpio_request(GPIO_FN_SDHID1_0, NULL);
369 gpio_request(GPIO_FN_SDHID1_1, NULL);
370 gpio_request(GPIO_FN_SDHID1_2, NULL);
371 gpio_request(GPIO_FN_SDHID1_3, NULL);
372 gpio_request(GPIO_FN_SDHICMD1, NULL);
373 gpio_pull_up(GPIO_SDHID1_D0);
374 gpio_pull_up(GPIO_SDHID1_D1);
375 gpio_pull_up(GPIO_SDHID1_D2);
376 gpio_pull_up(GPIO_SDHID1_D3);
377 gpio_pull_up(GPIO_SDHICMD1);
378
256 sh7377_add_standard_devices(); 379 sh7377_add_standard_devices();
257 380
258 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); 381 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
259} 382}
260 383
384static void __init g4evm_timer_init(void)
385{
386 sh7377_clock_init();
387 shmobile_timer.init();
388}
389
390static struct sys_timer g4evm_timer = {
391 .init = g4evm_timer_init,
392};
393
261MACHINE_START(G4EVM, "g4evm") 394MACHINE_START(G4EVM, "g4evm")
262 .phys_io = 0xe6000000, 395 .phys_io = 0xe6000000,
263 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, 396 .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
264 .map_io = g4evm_map_io, 397 .map_io = g4evm_map_io,
265 .init_irq = sh7377_init_irq, 398 .init_irq = sh7377_init_irq,
266 .init_machine = g4evm_init, 399 .init_machine = g4evm_init,
267 .timer = &shmobile_timer, 400 .timer = &g4evm_timer,
268MACHINE_END 401MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index bb940c6e4e6c..b6454c9f2abb 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Preliminary clock framework support for sh7367 2 * SH7367 clock framework support
3 * 3 *
4 * Copyright (C) 2010 Magnus Damm 4 * Copyright (C) 2010 Magnus Damm
5 * 5 *
@@ -17,87 +17,342 @@
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */ 18 */
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/kernel.h> 20#include <linux/kernel.h>
22#include <linux/list.h> 21#include <linux/io.h>
23#include <linux/clk.h> 22#include <linux/sh_clk.h>
23#include <mach/common.h>
24#include <asm/clkdev.h>
25
26/* SH7367 registers */
27#define RTFRQCR 0xe6150000
28#define SYFRQCR 0xe6150004
29#define CMFRQCR 0xe61500E0
30#define VCLKCR1 0xe6150008
31#define VCLKCR2 0xe615000C
32#define VCLKCR3 0xe615001C
33#define SCLKACR 0xe6150010
34#define SCLKBCR 0xe6150014
35#define SUBUSBCKCR 0xe6158080
36#define SPUCKCR 0xe6150084
37#define MSUCKCR 0xe6150088
38#define MVI3CKCR 0xe6150090
39#define VOUCKCR 0xe6150094
40#define MFCK1CR 0xe6150098
41#define MFCK2CR 0xe615009C
42#define PLLC1CR 0xe6150028
43#define PLLC2CR 0xe615002C
44#define RTMSTPCR0 0xe6158030
45#define RTMSTPCR2 0xe6158038
46#define SYMSTPCR0 0xe6158040
47#define SYMSTPCR2 0xe6158048
48#define CMMSTPCR0 0xe615804c
24 49
25struct clk { 50/* Fixed 32 KHz root clock from EXTALR pin */
26 const char *name; 51static struct clk r_clk = {
27 unsigned long rate; 52 .rate = 32768,
28}; 53};
29 54
30#include <asm/clkdev.h> 55/*
56 * 26MHz default rate for the EXTALB1 root input clock.
57 * If needed, reset this with clk_set_rate() from the platform code.
58 */
59struct clk sh7367_extalb1_clk = {
60 .rate = 26666666,
61};
31 62
32int __clk_get(struct clk *clk) 63/*
33{ 64 * 48MHz default rate for the EXTAL2 root input clock.
34 return 1; 65 * If needed, reset this with clk_set_rate() from the platform code.
35} 66 */
36EXPORT_SYMBOL(__clk_get); 67struct clk sh7367_extal2_clk = {
68 .rate = 48000000,
69};
37 70
38void __clk_put(struct clk *clk) 71/* A fixed divide-by-2 block */
72static unsigned long div2_recalc(struct clk *clk)
39{ 73{
74 return clk->parent->rate / 2;
40} 75}
41EXPORT_SYMBOL(__clk_put);
42 76
77static struct clk_ops div2_clk_ops = {
78 .recalc = div2_recalc,
79};
80
81/* Divide extalb1 by two */
82static struct clk extalb1_div2_clk = {
83 .ops = &div2_clk_ops,
84 .parent = &sh7367_extalb1_clk,
85};
86
87/* Divide extal2 by two */
88static struct clk extal2_div2_clk = {
89 .ops = &div2_clk_ops,
90 .parent = &sh7367_extal2_clk,
91};
43 92
44int clk_enable(struct clk *clk) 93/* PLLC1 */
94static unsigned long pllc1_recalc(struct clk *clk)
45{ 95{
46 return 0; 96 unsigned long mult = 1;
97
98 if (__raw_readl(PLLC1CR) & (1 << 14))
99 mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
100
101 return clk->parent->rate * mult;
47} 102}
48EXPORT_SYMBOL(clk_enable);
49 103
50void clk_disable(struct clk *clk) 104static struct clk_ops pllc1_clk_ops = {
105 .recalc = pllc1_recalc,
106};
107
108static struct clk pllc1_clk = {
109 .ops = &pllc1_clk_ops,
110 .flags = CLK_ENABLE_ON_INIT,
111 .parent = &extalb1_div2_clk,
112};
113
114/* Divide PLLC1 by two */
115static struct clk pllc1_div2_clk = {
116 .ops = &div2_clk_ops,
117 .parent = &pllc1_clk,
118};
119
120/* PLLC2 */
121static unsigned long pllc2_recalc(struct clk *clk)
51{ 122{
123 unsigned long mult = 1;
124
125 if (__raw_readl(PLLC2CR) & (1 << 31))
126 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
127
128 return clk->parent->rate * mult;
52} 129}
53EXPORT_SYMBOL(clk_disable);
54 130
55unsigned long clk_get_rate(struct clk *clk) 131static struct clk_ops pllc2_clk_ops = {
132 .recalc = pllc2_recalc,
133};
134
135static struct clk pllc2_clk = {
136 .ops = &pllc2_clk_ops,
137 .flags = CLK_ENABLE_ON_INIT,
138 .parent = &extalb1_div2_clk,
139};
140
141static struct clk *main_clks[] = {
142 &r_clk,
143 &sh7367_extalb1_clk,
144 &sh7367_extal2_clk,
145 &extalb1_div2_clk,
146 &extal2_div2_clk,
147 &pllc1_clk,
148 &pllc1_div2_clk,
149 &pllc2_clk,
150};
151
152static void div4_kick(struct clk *clk)
56{ 153{
57 return clk ? clk->rate : 0; 154 unsigned long value;
155
156 /* set KICK bit in SYFRQCR to update hardware setting */
157 value = __raw_readl(SYFRQCR);
158 value |= (1 << 31);
159 __raw_writel(value, SYFRQCR);
58} 160}
59EXPORT_SYMBOL(clk_get_rate);
60 161
61/* a static peripheral clock for now - enough to get sh-sci working */ 162static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
62static struct clk peripheral_clk = { 163 24, 32, 36, 48, 0, 72, 0, 0 };
63 .name = "peripheral_clk", 164
64 .rate = 48000000, 165static struct clk_div_mult_table div4_div_mult_table = {
166 .divisors = divisors,
167 .nr_divisors = ARRAY_SIZE(divisors),
65}; 168};
66 169
67/* a static rclk for now - enough to get sh_cmt working */ 170static struct clk_div4_table div4_table = {
68static struct clk r_clk = { 171 .div_mult_table = &div4_div_mult_table,
69 .name = "r_clk", 172 .kick = div4_kick,
70 .rate = 32768, 173};
174
175enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B,
176 DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP,
177 DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
178
179#define DIV4(_reg, _bit, _mask, _flags) \
180 SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
181
182static struct clk div4_clks[DIV4_NR] = {
183 [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
184 [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
185 [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT),
186 [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
187 [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0),
188 [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
189 [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
190 [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0),
191 [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
192 [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
193 [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
194 [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
195 [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
71}; 196};
72 197
73/* a static usb0 for now - enough to get r8a66597 working */ 198enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU,
74static struct clk usb0_clk = { 199 DIV6_MVI3, DIV6_MF1, DIV6_MF2,
75 .name = "usb0", 200 DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU,
201 DIV6_NR };
202
203static struct clk div6_clks[DIV6_NR] = {
204 [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0),
205 [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0),
206 [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0),
207 [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
208 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
209 [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
210 [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
211 [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
212 [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
213 [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
214 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
215 [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
76}; 216};
77 217
78/* a static keysc0 clk for now - enough to get sh_keysc working */ 218enum { RTMSTP001,
79static struct clk keysc0_clk = { 219 RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226,
80 .name = "keysc0", 220 RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201,
221 SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004,
222 SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000,
223 SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222,
224 SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211,
225 CMMSTP003,
226 MSTP_NR };
227
228#define MSTP(_parent, _reg, _bit, _flags) \
229 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
230
231static struct clk mstp_clks[MSTP_NR] = {
232 [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */
233 [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */
234 [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */
235 [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */
236 [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */
237 [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */
238 [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */
239 [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */
240 [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */
241 [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */
242 [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */
243 [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */
244 [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */
245 [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */
246 [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */
247 [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */
248 [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */
249 [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */
250 [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */
251 [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */
252 [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */
253 [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */
254 [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */
255 [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */
256 [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */
257 [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */
258 [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */
259 [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */
81}; 260};
82 261
262#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
263#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
264
83static struct clk_lookup lookups[] = { 265static struct clk_lookup lookups[] = {
84 { 266 /* main clocks */
85 .clk = &peripheral_clk, 267 CLKDEV_CON_ID("r_clk", &r_clk),
86 }, { 268 CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk),
87 .clk = &r_clk, 269 CLKDEV_CON_ID("extal2", &sh7367_extal2_clk),
88 }, { 270 CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk),
89 .clk = &usb0_clk, 271 CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
90 }, { 272 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
91 .clk = &keysc0_clk, 273 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
92 } 274 CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
275
276 /* DIV4 clocks */
277 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
278 CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]),
279 CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
280 CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
281 CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
282 CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
283 CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]),
284 CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
285 CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
286 CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
287 CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
288 CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
289
290 /* DIV6 clocks */
291 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
292 CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]),
293 CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]),
294 CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
295 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
296 CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
297 CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
298 CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
299 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
300 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
301 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
302 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
303
304 /* MSTP32 clocks */
305 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */
306 CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */
307 CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */
308 CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */
309 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */
310 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */
311 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */
312 CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */
313 CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */
314 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */
315 CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */
316 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */
317 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */
318 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */
319 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */
320 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */
321 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
322 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
323 CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
324 CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */
325 CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
326 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
327 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
328 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */
329 CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */
330 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */
331 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */
332 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */
333 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */
93}; 334};
94 335
95void __init sh7367_clock_init(void) 336void __init sh7367_clock_init(void)
96{ 337{
97 int i; 338 int k, ret = 0;
339
340 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
341 ret = clk_register(main_clks[k]);
342
343 if (!ret)
344 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
345
346 if (!ret)
347 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
348
349 if (!ret)
350 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
351
352 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
98 353
99 for (i = 0; i < ARRAY_SIZE(lookups); i++) { 354 if (!ret)
100 lookups[i].con_id = lookups[i].clk->name; 355 clk_init();
101 clkdev_add(&lookups[i]); 356 else
102 } 357 panic("failed to setup sh7367 clocks\n");
103} 358}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
new file mode 100644
index 000000000000..fb4e9b1d788e
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -0,0 +1,560 @@
1/*
2 * SH7372 clock framework support
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
23#include <mach/common.h>
24#include <asm/clkdev.h>
25
26/* SH7372 registers */
27#define FRQCRA 0xe6150000
28#define FRQCRB 0xe6150004
29#define FRQCRC 0xe61500e0
30#define FRQCRD 0xe61500e4
31#define VCLKCR1 0xe6150008
32#define VCLKCR2 0xe615000c
33#define VCLKCR3 0xe615001c
34#define FMSICKCR 0xe6150010
35#define FMSOCKCR 0xe6150014
36#define FSIACKCR 0xe6150018
37#define FSIBCKCR 0xe6150090
38#define SUBCKCR 0xe6150080
39#define SPUCKCR 0xe6150084
40#define VOUCKCR 0xe6150088
41#define HDMICKCR 0xe6150094
42#define DSITCKCR 0xe6150060
43#define DSI0PCKCR 0xe6150064
44#define DSI1PCKCR 0xe6150098
45#define PLLC01CR 0xe6150028
46#define PLLC2CR 0xe615002c
47#define SMSTPCR0 0xe6150130
48#define SMSTPCR1 0xe6150134
49#define SMSTPCR2 0xe6150138
50#define SMSTPCR3 0xe615013c
51#define SMSTPCR4 0xe6150140
52
53/* Platforms must set frequency on their DV_CLKI pin */
54struct clk dv_clki_clk = {
55};
56
57/* Fixed 32 KHz root clock from EXTALR pin */
58static struct clk r_clk = {
59 .rate = 32768,
60};
61
62/*
63 * 26MHz default rate for the EXTAL1 root input clock.
64 * If needed, reset this with clk_set_rate() from the platform code.
65 */
66struct clk sh7372_extal1_clk = {
67 .rate = 26000000,
68};
69
70/*
71 * 48MHz default rate for the EXTAL2 root input clock.
72 * If needed, reset this with clk_set_rate() from the platform code.
73 */
74struct clk sh7372_extal2_clk = {
75 .rate = 48000000,
76};
77
78/* A fixed divide-by-2 block */
79static unsigned long div2_recalc(struct clk *clk)
80{
81 return clk->parent->rate / 2;
82}
83
84static struct clk_ops div2_clk_ops = {
85 .recalc = div2_recalc,
86};
87
88/* Divide dv_clki by two */
89struct clk dv_clki_div2_clk = {
90 .ops = &div2_clk_ops,
91 .parent = &dv_clki_clk,
92};
93
94/* Divide extal1 by two */
95static struct clk extal1_div2_clk = {
96 .ops = &div2_clk_ops,
97 .parent = &sh7372_extal1_clk,
98};
99
100/* Divide extal2 by two */
101static struct clk extal2_div2_clk = {
102 .ops = &div2_clk_ops,
103 .parent = &sh7372_extal2_clk,
104};
105
106/* Divide extal2 by four */
107static struct clk extal2_div4_clk = {
108 .ops = &div2_clk_ops,
109 .parent = &extal2_div2_clk,
110};
111
112/* PLLC0 and PLLC1 */
113static unsigned long pllc01_recalc(struct clk *clk)
114{
115 unsigned long mult = 1;
116
117 if (__raw_readl(PLLC01CR) & (1 << 14))
118 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
119
120 return clk->parent->rate * mult;
121}
122
123static struct clk_ops pllc01_clk_ops = {
124 .recalc = pllc01_recalc,
125};
126
127static struct clk pllc0_clk = {
128 .ops = &pllc01_clk_ops,
129 .flags = CLK_ENABLE_ON_INIT,
130 .parent = &extal1_div2_clk,
131 .enable_reg = (void __iomem *)FRQCRC,
132};
133
134static struct clk pllc1_clk = {
135 .ops = &pllc01_clk_ops,
136 .flags = CLK_ENABLE_ON_INIT,
137 .parent = &extal1_div2_clk,
138 .enable_reg = (void __iomem *)FRQCRA,
139};
140
141/* Divide PLLC1 by two */
142static struct clk pllc1_div2_clk = {
143 .ops = &div2_clk_ops,
144 .parent = &pllc1_clk,
145};
146
147/* PLLC2 */
148
149/* Indices are important - they are the actual src selecting values */
150static struct clk *pllc2_parent[] = {
151 [0] = &extal1_div2_clk,
152 [1] = &extal2_div2_clk,
153 [2] = &dv_clki_div2_clk,
154};
155
156/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
157static struct cpufreq_frequency_table pllc2_freq_table[29];
158
159static void pllc2_table_rebuild(struct clk *clk)
160{
161 int i;
162
163 /* Initialise PLLC2 frequency table */
164 for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
165 pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
166 pllc2_freq_table[i].index = i;
167 }
168
169 /* This is a special entry - switching PLL off makes it a repeater */
170 pllc2_freq_table[i].frequency = clk->parent->rate;
171 pllc2_freq_table[i].index = i;
172
173 pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
174 pllc2_freq_table[i].index = i;
175}
176
177static unsigned long pllc2_recalc(struct clk *clk)
178{
179 unsigned long mult = 1;
180
181 pllc2_table_rebuild(clk);
182
183 /*
184 * If the PLL is off, mult == 1, clk->rate will be updated in
185 * pllc2_enable().
186 */
187 if (__raw_readl(PLLC2CR) & (1 << 31))
188 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
189
190 return clk->parent->rate * mult;
191}
192
193static long pllc2_round_rate(struct clk *clk, unsigned long rate)
194{
195 return clk_rate_table_round(clk, clk->freq_table, rate);
196}
197
198static int pllc2_enable(struct clk *clk)
199{
200 int i;
201
202 __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
203
204 for (i = 0; i < 100; i++)
205 if (__raw_readl(PLLC2CR) & 0x80000000) {
206 clk->rate = pllc2_recalc(clk);
207 return 0;
208 }
209
210 pr_err("%s(): timeout!\n", __func__);
211
212 return -ETIMEDOUT;
213}
214
215static void pllc2_disable(struct clk *clk)
216{
217 __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
218}
219
220static int pllc2_set_rate(struct clk *clk,
221 unsigned long rate, int algo_id)
222{
223 unsigned long value;
224 int idx;
225
226 idx = clk_rate_table_find(clk, clk->freq_table, rate);
227 if (idx < 0)
228 return idx;
229
230 if (rate == clk->parent->rate) {
231 pllc2_disable(clk);
232 return 0;
233 }
234
235 value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
236
237 if (value & 0x80000000)
238 pllc2_disable(clk);
239
240 __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
241
242 if (value & 0x80000000)
243 return pllc2_enable(clk);
244
245 return 0;
246}
247
248static int pllc2_set_parent(struct clk *clk, struct clk *parent)
249{
250 u32 value;
251 int ret, i;
252
253 if (!clk->parent_table || !clk->parent_num)
254 return -EINVAL;
255
256 /* Search the parent */
257 for (i = 0; i < clk->parent_num; i++)
258 if (clk->parent_table[i] == parent)
259 break;
260
261 if (i == clk->parent_num)
262 return -ENODEV;
263
264 ret = clk_reparent(clk, parent);
265 if (ret < 0)
266 return ret;
267
268 value = __raw_readl(PLLC2CR) & ~(3 << 6);
269
270 __raw_writel(value | (i << 6), PLLC2CR);
271
272 /* Rebiuld the frequency table */
273 pllc2_table_rebuild(clk);
274
275 return 0;
276}
277
278static struct clk_ops pllc2_clk_ops = {
279 .recalc = pllc2_recalc,
280 .round_rate = pllc2_round_rate,
281 .set_rate = pllc2_set_rate,
282 .enable = pllc2_enable,
283 .disable = pllc2_disable,
284 .set_parent = pllc2_set_parent,
285};
286
287struct clk pllc2_clk = {
288 .ops = &pllc2_clk_ops,
289 .flags = CLK_ENABLE_ON_INIT,
290 .parent = &extal1_div2_clk,
291 .freq_table = pllc2_freq_table,
292 .parent_table = pllc2_parent,
293 .parent_num = ARRAY_SIZE(pllc2_parent),
294};
295
296static struct clk *main_clks[] = {
297 &dv_clki_clk,
298 &r_clk,
299 &sh7372_extal1_clk,
300 &sh7372_extal2_clk,
301 &dv_clki_div2_clk,
302 &extal1_div2_clk,
303 &extal2_div2_clk,
304 &extal2_div4_clk,
305 &pllc0_clk,
306 &pllc1_clk,
307 &pllc1_div2_clk,
308 &pllc2_clk,
309};
310
311static void div4_kick(struct clk *clk)
312{
313 unsigned long value;
314
315 /* set KICK bit in FRQCRB to update hardware setting */
316 value = __raw_readl(FRQCRB);
317 value |= (1 << 31);
318 __raw_writel(value, FRQCRB);
319}
320
321static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
322 24, 32, 36, 48, 0, 72, 96, 0 };
323
324static struct clk_div_mult_table div4_div_mult_table = {
325 .divisors = divisors,
326 .nr_divisors = ARRAY_SIZE(divisors),
327};
328
329static struct clk_div4_table div4_table = {
330 .div_mult_table = &div4_div_mult_table,
331 .kick = div4_kick,
332};
333
334enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
335 DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
336 DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
337 DIV4_DDRP, DIV4_NR };
338
339#define DIV4(_reg, _bit, _mask, _flags) \
340 SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
341
342static struct clk div4_clks[DIV4_NR] = {
343 [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
344 [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
345 [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
346 [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
347 [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
348 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
349 [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
350 [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
351 [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
352 [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
353 [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
354 [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
355 [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
356 [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
357 [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
358};
359
360enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
361 DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
362 DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
363 DIV6_NR };
364
365static struct clk div6_clks[DIV6_NR] = {
366 [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
367 [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
368 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
369 [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
370 [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
371 [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
372 [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
373 [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
374 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
375 [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
376 [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
377 [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
378 [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
379};
380
381enum { DIV6_HDMI, DIV6_REPARENT_NR };
382
383/* Indices are important - they are the actual src selecting values */
384static struct clk *hdmi_parent[] = {
385 [0] = &pllc1_div2_clk,
386 [1] = &pllc2_clk,
387 [2] = &dv_clki_clk,
388 [3] = NULL, /* pllc2_div4 not implemented yet */
389};
390
391static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
392 [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
393 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
394};
395
396enum { MSTP001,
397 MSTP131, MSTP130,
398 MSTP129, MSTP128,
399 MSTP118, MSTP117, MSTP116,
400 MSTP106, MSTP101, MSTP100,
401 MSTP223,
402 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
403 MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
404 MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
405 MSTP_NR };
406
407#define MSTP(_parent, _reg, _bit, _flags) \
408 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
409
410static struct clk mstp_clks[MSTP_NR] = {
411 [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
412 [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
413 [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
414 [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
415 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
416 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
417 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
418 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
419 [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
420 [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
421 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
422 [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
423 [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
424 [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
425 [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
426 [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
427 [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
428 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
429 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
430 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
431 [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */
432 [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
433 [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
434 [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
435 [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
436 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
437 [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
438 [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
439 [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
440 [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
441 [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
442 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
443};
444
445#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
446#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
447
448static struct clk_lookup lookups[] = {
449 /* main clocks */
450 CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk),
451 CLKDEV_CON_ID("r_clk", &r_clk),
452 CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
453 CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
454 CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
455 CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
456 CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
457 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
458 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
459 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
460 CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
461
462 /* DIV4 clocks */
463 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
464 CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
465 CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
466 CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
467 CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
468 CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
469 CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
470 CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
471 CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
472 CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
473 CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
474 CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
475 CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
476 CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
477 CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
478
479 /* DIV6 clocks */
480 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
481 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
482 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
483 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
484 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
485 CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
486 CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
487 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
488 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
489 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
490 CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
491 CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
492 CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
493 CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
494
495 /* MSTP32 clocks */
496 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
497 CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
498 CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
499 CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
500 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
501 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
502 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
503 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
504 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
505 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
506 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
507 CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
508 CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
509 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
510 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
511 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
512 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
513 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
514 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
515 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
516 CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
517 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
518 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
519 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
520 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
521 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
522 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
523 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
524 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
525 CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
526 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
527 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
528 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
529 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
530 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
531 {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]},
532};
533
534void __init sh7372_clock_init(void)
535{
536 int k, ret = 0;
537
538 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
539 ret = clk_register(main_clks[k]);
540
541 if (!ret)
542 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
543
544 if (!ret)
545 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
546
547 if (!ret)
548 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR);
549
550 if (!ret)
551 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
552
553 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
554
555 if (!ret)
556 clk_init();
557 else
558 panic("failed to setup sh7372 clocks\n");
559
560}
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
new file mode 100644
index 000000000000..e007c28cf0a8
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -0,0 +1,369 @@
1/*
2 * SH7377 clock framework support
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
23#include <mach/common.h>
24#include <asm/clkdev.h>
25
26/* SH7377 registers */
27#define RTFRQCR 0xe6150000
28#define SYFRQCR 0xe6150004
29#define CMFRQCR 0xe61500E0
30#define VCLKCR1 0xe6150008
31#define VCLKCR2 0xe615000C
32#define VCLKCR3 0xe615001C
33#define FMSICKCR 0xe6150010
34#define FMSOCKCR 0xe6150014
35#define FSICKCR 0xe6150018
36#define PLLC1CR 0xe6150028
37#define PLLC2CR 0xe615002C
38#define SUBUSBCKCR 0xe6150080
39#define SPUCKCR 0xe6150084
40#define MSUCKCR 0xe6150088
41#define MVI3CKCR 0xe6150090
42#define HDMICKCR 0xe6150094
43#define MFCK1CR 0xe6150098
44#define MFCK2CR 0xe615009C
45#define DSITCKCR 0xe6150060
46#define DSIPCKCR 0xe6150064
47#define SMSTPCR0 0xe6150130
48#define SMSTPCR1 0xe6150134
49#define SMSTPCR2 0xe6150138
50#define SMSTPCR3 0xe615013C
51#define SMSTPCR4 0xe6150140
52
53/* Fixed 32 KHz root clock from EXTALR pin */
54static struct clk r_clk = {
55 .rate = 32768,
56};
57
58/*
59 * 26MHz default rate for the EXTALC1 root input clock.
60 * If needed, reset this with clk_set_rate() from the platform code.
61 */
62struct clk sh7377_extalc1_clk = {
63 .rate = 26666666,
64};
65
66/*
67 * 48MHz default rate for the EXTAL2 root input clock.
68 * If needed, reset this with clk_set_rate() from the platform code.
69 */
70struct clk sh7377_extal2_clk = {
71 .rate = 48000000,
72};
73
74/* A fixed divide-by-2 block */
75static unsigned long div2_recalc(struct clk *clk)
76{
77 return clk->parent->rate / 2;
78}
79
80static struct clk_ops div2_clk_ops = {
81 .recalc = div2_recalc,
82};
83
84/* Divide extalc1 by two */
85static struct clk extalc1_div2_clk = {
86 .ops = &div2_clk_ops,
87 .parent = &sh7377_extalc1_clk,
88};
89
90/* Divide extal2 by two */
91static struct clk extal2_div2_clk = {
92 .ops = &div2_clk_ops,
93 .parent = &sh7377_extal2_clk,
94};
95
96/* Divide extal2 by four */
97static struct clk extal2_div4_clk = {
98 .ops = &div2_clk_ops,
99 .parent = &extal2_div2_clk,
100};
101
102/* PLLC1 */
103static unsigned long pllc1_recalc(struct clk *clk)
104{
105 unsigned long mult = 1;
106
107 if (__raw_readl(PLLC1CR) & (1 << 14))
108 mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
109
110 return clk->parent->rate * mult;
111}
112
113static struct clk_ops pllc1_clk_ops = {
114 .recalc = pllc1_recalc,
115};
116
117static struct clk pllc1_clk = {
118 .ops = &pllc1_clk_ops,
119 .flags = CLK_ENABLE_ON_INIT,
120 .parent = &extalc1_div2_clk,
121};
122
123/* Divide PLLC1 by two */
124static struct clk pllc1_div2_clk = {
125 .ops = &div2_clk_ops,
126 .parent = &pllc1_clk,
127};
128
129/* PLLC2 */
130static unsigned long pllc2_recalc(struct clk *clk)
131{
132 unsigned long mult = 1;
133
134 if (__raw_readl(PLLC2CR) & (1 << 31))
135 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
136
137 return clk->parent->rate * mult;
138}
139
140static struct clk_ops pllc2_clk_ops = {
141 .recalc = pllc2_recalc,
142};
143
144static struct clk pllc2_clk = {
145 .ops = &pllc2_clk_ops,
146 .flags = CLK_ENABLE_ON_INIT,
147 .parent = &extalc1_div2_clk,
148};
149
150static struct clk *main_clks[] = {
151 &r_clk,
152 &sh7377_extalc1_clk,
153 &sh7377_extal2_clk,
154 &extalc1_div2_clk,
155 &extal2_div2_clk,
156 &extal2_div4_clk,
157 &pllc1_clk,
158 &pllc1_div2_clk,
159 &pllc2_clk,
160};
161
162static void div4_kick(struct clk *clk)
163{
164 unsigned long value;
165
166 /* set KICK bit in SYFRQCR to update hardware setting */
167 value = __raw_readl(SYFRQCR);
168 value |= (1 << 31);
169 __raw_writel(value, SYFRQCR);
170}
171
172static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
173 24, 32, 36, 48, 0, 72, 96, 0 };
174
175static struct clk_div_mult_table div4_div_mult_table = {
176 .divisors = divisors,
177 .nr_divisors = ARRAY_SIZE(divisors),
178};
179
180static struct clk_div4_table div4_table = {
181 .div_mult_table = &div4_div_mult_table,
182 .kick = div4_kick,
183};
184
185enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
186 DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP,
187 DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
188
189#define DIV4(_reg, _bit, _mask, _flags) \
190 SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
191
192static struct clk div4_clks[DIV4_NR] = {
193 [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
194 [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
195 [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
196 [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT),
197 [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0),
198 [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0),
199 [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
200 [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
201 [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
202 [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
203 [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
204 [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
205 [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
206};
207
208enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
209 DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI,
210 DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP,
211 DIV6_NR };
212
213static struct clk div6_clks[] = {
214 [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
215 [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
216 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
217 [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
218 [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
219 [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0),
220 [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0),
221 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
222 [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
223 [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
224 [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
225 [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
226 [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
227 [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
228 [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0),
229};
230
231enum { MSTP001,
232 MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101,
233 MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
234 MSTP331, MSTP329, MSTP325, MSTP323, MSTP322,
235 MSTP315, MSTP314, MSTP313,
236 MSTP403,
237 MSTP_NR };
238
239#define MSTP(_parent, _reg, _bit, _flags) \
240 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
241
242static struct clk mstp_clks[] = {
243 [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
244 [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
245 [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
246 [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
247 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
248 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
249 [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
250 [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
251 [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
252 [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
253 [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
254 [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
255 [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
256 [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
257 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
258 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
259 [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
260 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
261 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */
262 [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
263 [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
264 [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */
265 [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
266 [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
267 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
268};
269
270#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
271#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
272
273static struct clk_lookup lookups[] = {
274 /* main clocks */
275 CLKDEV_CON_ID("r_clk", &r_clk),
276 CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk),
277 CLKDEV_CON_ID("extal2", &sh7377_extal2_clk),
278 CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk),
279 CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
280 CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
281 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
282 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
283 CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
284
285 /* DIV4 clocks */
286 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
287 CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
288 CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
289 CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
290 CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
291 CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
292 CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
293 CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
294 CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
295 CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
296 CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
297 CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
298 CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
299
300 /* DIV6 clocks */
301 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
302 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
303 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
304 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
305 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
306 CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]),
307 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
308 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
309 CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
310 CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
311 CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
312 CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
313 CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
314 CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
315 CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]),
316
317 /* MSTP32 clocks */
318 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
319 CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
320 CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
321 CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
322 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
323 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
324 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
325 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
326 CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
327 CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
328 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
329 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */
330 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
331 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
332 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
333 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
334 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
335 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
336 CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
337 CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
338 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
339 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
340 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */
341 CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */
342 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
343 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
344 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
345};
346
347void __init sh7377_clock_init(void)
348{
349 int k, ret = 0;
350
351 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
352 ret = clk_register(main_clks[k]);
353
354 if (!ret)
355 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
356
357 if (!ret)
358 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
359
360 if (!ret)
361 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
362
363 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
364
365 if (!ret)
366 clk_init();
367 else
368 panic("failed to setup sh7377 clocks\n");
369}
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c
new file mode 100644
index 000000000000..b7c705a213a2
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock.c
@@ -0,0 +1,44 @@
1/*
2 * SH-Mobile Timer
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/sh_clk.h>
23
24int __init clk_init(void)
25{
26 /* Kick the child clocks.. */
27 recalculate_root_clocks();
28
29 /* Enable the necessary init clocks */
30 clk_enable_init_clocks();
31
32 return 0;
33}
34
35int __clk_get(struct clk *clk)
36{
37 return 1;
38}
39EXPORT_SYMBOL(__clk_get);
40
41void __clk_put(struct clk *clk)
42{
43}
44EXPORT_SYMBOL(__clk_put);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 57903605cc51..efeef778a875 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -3,21 +3,31 @@
3 3
4extern struct sys_timer shmobile_timer; 4extern struct sys_timer shmobile_timer;
5extern void shmobile_setup_console(void); 5extern void shmobile_setup_console(void);
6struct clk;
7extern int clk_init(void);
6 8
7extern void sh7367_init_irq(void); 9extern void sh7367_init_irq(void);
8extern void sh7367_add_early_devices(void); 10extern void sh7367_add_early_devices(void);
9extern void sh7367_add_standard_devices(void); 11extern void sh7367_add_standard_devices(void);
10extern void sh7367_clock_init(void); 12extern void sh7367_clock_init(void);
11extern void sh7367_pinmux_init(void); 13extern void sh7367_pinmux_init(void);
14extern struct clk sh7367_extalb1_clk;
15extern struct clk sh7367_extal2_clk;
12 16
13extern void sh7377_init_irq(void); 17extern void sh7377_init_irq(void);
14extern void sh7377_add_early_devices(void); 18extern void sh7377_add_early_devices(void);
15extern void sh7377_add_standard_devices(void); 19extern void sh7377_add_standard_devices(void);
20extern void sh7377_clock_init(void);
16extern void sh7377_pinmux_init(void); 21extern void sh7377_pinmux_init(void);
22extern struct clk sh7377_extalc1_clk;
23extern struct clk sh7377_extal2_clk;
17 24
18extern void sh7372_init_irq(void); 25extern void sh7372_init_irq(void);
19extern void sh7372_add_early_devices(void); 26extern void sh7372_add_early_devices(void);
20extern void sh7372_add_standard_devices(void); 27extern void sh7372_add_standard_devices(void);
28extern void sh7372_clock_init(void);
21extern void sh7372_pinmux_init(void); 29extern void sh7372_pinmux_init(void);
30extern struct clk sh7372_extal1_clk;
31extern struct clk sh7372_extal2_clk;
22 32
23#endif /* __ARCH_MACH_COMMON_H */ 33#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index 132256bb8c81..fa15b5f8a001 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -3,7 +3,13 @@
3 3
4#define NR_IRQS 512 4#define NR_IRQS 512
5 5
6/* INTCA */
6#define evt2irq(evt) (((evt) >> 5) - 16) 7#define evt2irq(evt) (((evt) >> 5) - 16)
7#define irq2evt(irq) (((irq) + 16) << 5) 8#define irq2evt(irq) (((irq) + 16) << 5)
8 9
10/* INTCS */
11#define INTCS_VECT_BASE 0x2200
12#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
13#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
14
9#endif /* __ASM_MACH_IRQS_H */ 15#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h
index e188183f4dce..377584e57e03 100644
--- a/arch/arm/mach-shmobile/include/mach/memory.h
+++ b/arch/arm/mach-shmobile/include/mach/memory.h
@@ -4,4 +4,7 @@
4#define PHYS_OFFSET UL(CONFIG_MEMORY_START) 4#define PHYS_OFFSET UL(CONFIG_MEMORY_START)
5#define MEM_SIZE UL(CONFIG_MEMORY_SIZE) 5#define MEM_SIZE UL(CONFIG_MEMORY_SIZE)
6 6
7/* DMA memory at 0xf6000000 - 0xffdfffff */
8#define CONSISTENT_DMA_SIZE (158 << 20)
9
7#endif /* __ASM_MACH_MEMORY_H */ 10#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index dc34f00c56b8..33e9700ded7e 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -11,6 +11,8 @@
11#ifndef __ASM_SH7372_H__ 11#ifndef __ASM_SH7372_H__
12#define __ASM_SH7372_H__ 12#define __ASM_SH7372_H__
13 13
14#include <linux/sh_clk.h>
15
14/* 16/*
15 * Pin Function Controller: 17 * Pin Function Controller:
16 * GPIO_FN_xx - GPIO used to select pin function 18 * GPIO_FN_xx - GPIO used to select pin function
@@ -431,4 +433,32 @@ enum {
431 GPIO_FN_SDENC_DV_CLKI, 433 GPIO_FN_SDENC_DV_CLKI,
432}; 434};
433 435
436/* DMA slave IDs */
437enum {
438 SHDMA_SLAVE_SCIF0_TX,
439 SHDMA_SLAVE_SCIF0_RX,
440 SHDMA_SLAVE_SCIF1_TX,
441 SHDMA_SLAVE_SCIF1_RX,
442 SHDMA_SLAVE_SCIF2_TX,
443 SHDMA_SLAVE_SCIF2_RX,
444 SHDMA_SLAVE_SCIF3_TX,
445 SHDMA_SLAVE_SCIF3_RX,
446 SHDMA_SLAVE_SCIF4_TX,
447 SHDMA_SLAVE_SCIF4_RX,
448 SHDMA_SLAVE_SCIF5_TX,
449 SHDMA_SLAVE_SCIF5_RX,
450 SHDMA_SLAVE_SCIF6_TX,
451 SHDMA_SLAVE_SCIF6_RX,
452 SHDMA_SLAVE_SDHI0_RX,
453 SHDMA_SLAVE_SDHI0_TX,
454 SHDMA_SLAVE_SDHI1_RX,
455 SHDMA_SLAVE_SDHI1_TX,
456 SHDMA_SLAVE_SDHI2_RX,
457 SHDMA_SLAVE_SDHI2_TX,
458};
459
460extern struct clk dv_clki_clk;
461extern struct clk dv_clki_div2_clk;
462extern struct clk pllc2_clk;
463
434#endif /* __ASM_SH7372_H__ */ 464#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
index fb3c4f1ab252..4aecf6e3a859 100644
--- a/arch/arm/mach-shmobile/include/mach/vmalloc.h
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -1,6 +1,7 @@
1#ifndef __ASM_MACH_VMALLOC_H 1#ifndef __ASM_MACH_VMALLOC_H
2#define __ASM_MACH_VMALLOC_H 2#define __ASM_MACH_VMALLOC_H
3 3
4#define VMALLOC_END (PAGE_OFFSET + 0x24000000) 4/* Vmalloc at ... - 0xe5ffffff */
5#define VMALLOC_END 0xe6000000
5 6
6#endif /* __ASM_MACH_VMALLOC_H */ 7#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
index 5ff70cadfc32..1a20c489b20d 100644
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -75,7 +75,7 @@ enum {
75 ETM11, ARM11, USBHS, FLCTL, IIC1 75 ETM11, ARM11, USBHS, FLCTL, IIC1
76}; 76};
77 77
78static struct intc_vect intca_vectors[] = { 78static struct intc_vect intca_vectors[] __initdata = {
79 INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), 79 INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
80 INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), 80 INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
81 INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), 81 INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
@@ -162,7 +162,7 @@ static struct intc_group intca_groups[] __initdata = {
162 INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), 162 INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
163}; 163};
164 164
165static struct intc_mask_reg intca_mask_registers[] = { 165static struct intc_mask_reg intca_mask_registers[] __initdata = {
166 { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ 166 { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
167 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, 167 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
168 { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ 168 { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
@@ -211,7 +211,7 @@ static struct intc_mask_reg intca_mask_registers[] = {
211 MISTY, CMT3, RWDT1, RWDT0 } }, 211 MISTY, CMT3, RWDT1, RWDT0 } },
212}; 212};
213 213
214static struct intc_prio_reg intca_prio_registers[] = { 214static struct intc_prio_reg intca_prio_registers[] __initdata = {
215 { 0xe6900010, 0, 32, 4, /* INTPRI00A */ 215 { 0xe6900010, 0, 32, 4, /* INTPRI00A */
216 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, 216 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
217 { 0xe6900014, 0, 32, 4, /* INTPRI10A */ 217 { 0xe6900014, 0, 32, 4, /* INTPRI10A */
@@ -263,8 +263,178 @@ static struct intc_desc intca_desc __initdata = {
263 intca_sense_registers, intca_ack_registers), 263 intca_sense_registers, intca_ack_registers),
264}; 264};
265 265
266enum {
267 UNUSED_INTCS = 0,
268
269 INTCS,
270
271 /* interrupt sources INTCS */
272 VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3,
273 VIO3_VOU,
274 RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
275 VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2,
276 VPU,
277 SGX530,
278 _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3,
279 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
280 IPMMU_IPMMUB, IPMMU_IPMMUS,
281 RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
282 MSIOF,
283 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
284 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
285 CMT,
286 TSIF,
287 IPMMUI,
288 MVI3,
289 ICB,
290 PEP,
291 ASA,
292 BEM,
293 VE2HO,
294 HQE,
295 JPEG,
296 LCDC,
297
298 /* interrupt groups INTCS */
299 _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
300};
301
302static struct intc_vect intcs_vectors[] = {
303 INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720),
304 INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760),
305 INTCS_VECT(VIO3_VOU, 0x780),
306 INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
307 INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
308 INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0),
309 INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0),
310 INTCS_VECT(VPU, 0x980),
311 INTCS_VECT(SGX530, 0x9e0),
312 INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20),
313 INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60),
314 INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
315 INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
316 INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60),
317 INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
318 INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
319 INTCS_VECT(MSIOF, 0xd20),
320 INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
321 INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
322 INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
323 INTCS_VECT(TMU_TUNI2, 0xec0),
324 INTCS_VECT(CMT, 0xf00),
325 INTCS_VECT(TSIF, 0xf20),
326 INTCS_VECT(IPMMUI, 0xf60),
327 INTCS_VECT(MVI3, 0x420),
328 INTCS_VECT(ICB, 0x480),
329 INTCS_VECT(PEP, 0x4a0),
330 INTCS_VECT(ASA, 0x4c0),
331 INTCS_VECT(BEM, 0x4e0),
332 INTCS_VECT(VE2HO, 0x520),
333 INTCS_VECT(HQE, 0x540),
334 INTCS_VECT(JPEG, 0x560),
335 INTCS_VECT(LCDC, 0x580),
336
337 INTC_VECT(INTCS, 0xf80),
338};
339
340static struct intc_group intcs_groups[] __initdata = {
341 INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1,
342 _2DDMAC_2DDM2, _2DDMAC_2DDM3),
343 INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
344 RTDMAC_1_DEI2, RTDMAC_1_DEI3),
345 INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
346 INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3),
347 INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2),
348 INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
349 INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB),
350 INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
351};
352
353static struct intc_mask_reg intcs_mask_registers[] = {
354 { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
355 { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU,
356 VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } },
357 { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
358 { VIO3_VOU, 0, VE2HO, VPU,
359 0, 0, 0, 0 } },
360 { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
361 { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0,
362 BEM, ASA, PEP, ICB } },
363 { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
364 { 0, 0, MVI3, 0,
365 JPEG, HQE, 0, LCDC } },
366 { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
367 { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
368 RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
369 { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
370 { 0, 0, MSIOF, 0,
371 SGX530, 0, 0, 0 } },
372 { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
373 { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
374 0, 0, 0, 0 } },
375 { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
376 { 0, 0, 0, CMT,
377 IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
378 { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
379 { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0,
380 0, 0, 0, 0 } },
381 { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
382 { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
383 0, 0, IPMMUI, TSIF } },
384 { 0xffd20104, 0, 16, /* INTAMASK */
385 { 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, INTCS } },
387};
388
389/* Priority is needed for INTCA to receive the INTCS interrupt */
390static struct intc_prio_reg intcs_prio_registers[] = {
391 { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } },
392 { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } },
393 { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
394 { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } },
395 { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } },
396 { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
397 TMU_TUNI2, 0 } },
398 { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } },
399 { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } },
400 { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } },
401 { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } },
402 { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } },
403 { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
404};
405
406static struct resource intcs_resources[] __initdata = {
407 [0] = {
408 .start = 0xffd20000,
409 .end = 0xffd2ffff,
410 .flags = IORESOURCE_MEM,
411 }
412};
413
414static struct intc_desc intcs_desc __initdata = {
415 .name = "sh7367-intcs",
416 .resource = intcs_resources,
417 .num_resources = ARRAY_SIZE(intcs_resources),
418 .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
419 intcs_prio_registers, NULL, NULL),
420};
421
422static void intcs_demux(unsigned int irq, struct irq_desc *desc)
423{
424 void __iomem *reg = (void *)get_irq_data(irq);
425 unsigned int evtcodeas = ioread32(reg);
426
427 generic_handle_irq(intcs_evt2irq(evtcodeas));
428}
429
266void __init sh7367_init_irq(void) 430void __init sh7367_init_irq(void)
267{ 431{
268 /* INTCA */ 432 void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
433
269 register_intc_controller(&intca_desc); 434 register_intc_controller(&intca_desc);
435 register_intc_controller(&intcs_desc);
436
437 /* demux using INTEVTSA */
438 set_irq_data(evt2irq(0xf80), (void *)intevtsa);
439 set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
270} 440}
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 3ce9d9bd5899..e3551b56cd03 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -319,17 +319,17 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
319 { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, 319 { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
320 { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, 320 { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
321 CMT14, CMT15 } }, 321 CMT14, CMT15 } },
322 { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, 322 { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0,
323 MMC_MMC_ERR, MMC_MMC_NOR } }, 323 MMC_MMC_ERR, MMC_MMC_NOR } },
324 { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, 324 { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
325 IIC4_WAITI4, IIC4_DTEI4 } }, 325 IIC4_WAITI4, IIC4_DTEI4 } },
326 { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, 326 { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
327 IIC3_WAITI3, IIC3_DTEI3 } }, 327 IIC3_WAITI3, IIC3_DTEI3 } },
328 { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, 328 { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
329 0/*TXI*/, 0/*TEI*/} }, 329 0/*TXI*/, 0/*TEI*/} },
330 { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, 330 { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
331 USB1_USB1I1, USB1_USB1I0 } }, 331 USB1_USB1I1, USB1_USB1I0 } },
332 { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, 332 { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
333}; 333};
334 334
335static struct intc_sense_reg intca_sense_registers[] __initdata = { 335static struct intc_sense_reg intca_sense_registers[] __initdata = {
@@ -363,7 +363,227 @@ static struct intc_desc intca_desc __initdata = {
363 intca_sense_registers, intca_ack_registers), 363 intca_sense_registers, intca_ack_registers),
364}; 364};
365 365
366enum {
367 UNUSED_INTCS = 0,
368
369 INTCS,
370
371 /* interrupt sources INTCS */
372 VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
373 RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
374 CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
375 VPU,
376 TSIF1,
377 _3DG_SGX530,
378 _2DDMAC,
379 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
380 IPMMU_IPMMUR, IPMMU_IPMMUR2,
381 RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
382 MSIOF,
383 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
384 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
385 CMT0,
386 TSIF0,
387 LMB,
388 CTI,
389 ICB,
390 JPU_JPEG,
391 LCDC,
392 LCRC,
393 RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
394 RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
395 ISP,
396 LCDC1,
397 CSIRX,
398 DSITX_DSITX0,
399 DSITX_DSITX1,
400 TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
401 CMT4,
402 DSITX1_DSITX1_0,
403 DSITX1_DSITX1_1,
404 CPORTS2R,
405 JPU6E,
406
407 /* interrupt groups INTCS */
408 RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
409 RTDMAC2_1, RTDMAC2_2, TMU1, DSITX,
410};
411
412static struct intc_vect intcs_vectors[] = {
413 INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
414 INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
415 INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
416 INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
417 INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
418 INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
419 INTCS_VECT(VPU, 0x980),
420 INTCS_VECT(TSIF1, 0x9a0),
421 INTCS_VECT(_3DG_SGX530, 0x9e0),
422 INTCS_VECT(_2DDMAC, 0xa00),
423 INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
424 INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
425 INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
426 INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
427 INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
428 INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
429 INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
430 INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
431 INTCS_VECT(TMU_TUNI2, 0xec0),
432 INTCS_VECT(CMT0, 0xf00),
433 INTCS_VECT(TSIF0, 0xf20),
434 INTCS_VECT(LMB, 0xf60),
435 INTCS_VECT(CTI, 0x400),
436 INTCS_VECT(ICB, 0x480),
437 INTCS_VECT(JPU_JPEG, 0x560),
438 INTCS_VECT(LCDC, 0x580),
439 INTCS_VECT(LCRC, 0x5a0),
440 INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
441 INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
442 INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0),
443 INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0),
444 INTCS_VECT(ISP, 0x1720),
445 INTCS_VECT(LCDC1, 0x1780),
446 INTCS_VECT(CSIRX, 0x17a0),
447 INTCS_VECT(DSITX_DSITX0, 0x17c0),
448 INTCS_VECT(DSITX_DSITX1, 0x17e0),
449 INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
450 INTCS_VECT(TMU1_TUNI2, 0x1940),
451 INTCS_VECT(CMT4, 0x1980),
452 INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
453 INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
454 INTCS_VECT(CPORTS2R, 0x1a20),
455 INTCS_VECT(JPU6E, 0x1a80),
456
457 INTC_VECT(INTCS, 0xf80),
458};
459
460static struct intc_group intcs_groups[] __initdata = {
461 INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
462 RTDMAC_1_DEI2, RTDMAC_1_DEI3),
463 INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
464 INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
465 INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
466 INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
467 INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
468 INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
469 INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
470 RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
471 INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4,
472 RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
473 INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0),
474 INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
475};
476
477static struct intc_mask_reg intcs_mask_registers[] = {
478 { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
479 { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
480 VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
481 { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
482 { 0, 0, 0, VPU,
483 0, 0, 0, 0 } },
484 { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
485 { 0, 0, 0, _2DDMAC,
486 0, 0, 0, ICB } },
487 { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
488 { 0, 0, 0, CTI,
489 JPU_JPEG, 0, LCRC, LCDC } },
490 { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
491 { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
492 RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
493 { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
494 { 0, 0, MSIOF, 0,
495 _3DG_SGX530, 0, 0, 0 } },
496 { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
497 { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
498 0, 0, 0, 0 } },
499 { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
500 { 0, 0, 0, CMT0,
501 IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
502 { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
503 { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR,
504 0, 0, 0, 0 } },
505 { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
506 { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
507 0, TSIF1, LMB, TSIF0 } },
508 { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
509 { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4,
510 RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } },
511 { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
512 { 0, ISP, 0, 0,
513 LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
514 { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
515 { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
516 CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } },
517 { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
518 { 0, CPORTS2R, 0, 0,
519 JPU6E, 0, 0, 0 } },
520 { 0xffd20104, 0, 16, /* INTAMASK */
521 { 0, 0, 0, 0, 0, 0, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, INTCS } },
523};
524
525/* Priority is needed for INTCA to receive the INTCS interrupt */
526static struct intc_prio_reg intcs_prio_registers[] = {
527 { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } },
528 { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
529 { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } },
530 { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } },
531 { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
532 TMU_TUNI2, TSIF1 } },
533 { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } },
534 { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } },
535 { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } },
536 { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } },
537 { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } },
538 { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
539 { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } },
540 { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } },
541 { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } },
542 { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } },
543 { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } },
544 { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0,
545 DSITX1_DSITX1_1, 0 } },
546 { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } },
547 { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } },
548};
549
550static struct resource intcs_resources[] __initdata = {
551 [0] = {
552 .start = 0xffd20000,
553 .end = 0xffd201ff,
554 .flags = IORESOURCE_MEM,
555 },
556 [1] = {
557 .start = 0xffd50000,
558 .end = 0xffd501ff,
559 .flags = IORESOURCE_MEM,
560 }
561};
562
563static struct intc_desc intcs_desc __initdata = {
564 .name = "sh7372-intcs",
565 .resource = intcs_resources,
566 .num_resources = ARRAY_SIZE(intcs_resources),
567 .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
568 intcs_prio_registers, NULL, NULL),
569};
570
571static void intcs_demux(unsigned int irq, struct irq_desc *desc)
572{
573 void __iomem *reg = (void *)get_irq_data(irq);
574 unsigned int evtcodeas = ioread32(reg);
575
576 generic_handle_irq(intcs_evt2irq(evtcodeas));
577}
578
366void __init sh7372_init_irq(void) 579void __init sh7372_init_irq(void)
367{ 580{
581 void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
582
368 register_intc_controller(&intca_desc); 583 register_intc_controller(&intca_desc);
584 register_intc_controller(&intcs_desc);
585
586 /* demux using INTEVTSA */
587 set_irq_data(evt2irq(0xf80), (void *)intevtsa);
588 set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
369} 589}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
index 5c781e2d1897..2cdeb8ccd821 100644
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -90,7 +90,7 @@ enum {
90 ICUSB, ICUDMC 90 ICUSB, ICUDMC
91}; 91};
92 92
93static struct intc_vect intca_vectors[] = { 93static struct intc_vect intca_vectors[] __initdata = {
94 INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), 94 INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
95 INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), 95 INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
96 INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), 96 INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
@@ -202,7 +202,7 @@ static struct intc_group intca_groups[] __initdata = {
202 INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), 202 INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
203}; 203};
204 204
205static struct intc_mask_reg intca_mask_registers[] = { 205static struct intc_mask_reg intca_mask_registers[] __initdata = {
206 { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ 206 { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
207 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, 207 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
208 { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ 208 { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
@@ -272,7 +272,7 @@ static struct intc_mask_reg intca_mask_registers[] = {
272 SCIFA6, 0, 0, 0 } }, 272 SCIFA6, 0, 0, 0 } },
273}; 273};
274 274
275static struct intc_prio_reg intca_prio_registers[] = { 275static struct intc_prio_reg intca_prio_registers[] __initdata = {
276 { 0xe6900010, 0, 32, 4, /* INTPRI00A */ 276 { 0xe6900010, 0, 32, 4, /* INTPRI00A */
277 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, 277 { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
278 { 0xe6900014, 0, 32, 4, /* INTPRI10A */ 278 { 0xe6900014, 0, 32, 4, /* INTPRI10A */
@@ -346,7 +346,301 @@ static struct intc_desc intca_desc __initdata = {
346 intca_sense_registers, intca_ack_registers), 346 intca_sense_registers, intca_ack_registers),
347}; 347};
348 348
349/* this macro ignore entry which is also in INTCA */
350#define __IGNORE(a...)
351#define __IGNORE0(a...) 0
352
353enum {
354 UNUSED_INTCS = 0,
355
356 INTCS,
357
358 /* interrupt sources INTCS */
359 VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
360 RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3,
361 CEU,
362 BEU_BEU0, BEU_BEU1, BEU_BEU2,
363 __IGNORE(MFI)
364 __IGNORE(BBIF2)
365 VPU,
366 TSIF1,
367 __IGNORE(SGX540)
368 _2DDMAC,
369 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
370 IPMMU_IPMMUR, IPMMU_IPMMUR2,
371 RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR,
372 __IGNORE(KEYSC)
373 __IGNORE(TTI20)
374 __IGNORE(MSIOF)
375 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
376 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
377 CMT0,
378 TSIF0,
379 __IGNORE(CMT2)
380 LMB,
381 __IGNORE(MSUG)
382 __IGNORE(MSU_MSU, MSU_MSU2)
383 __IGNORE(CTI)
384 MVI3,
385 __IGNORE(RWDT0)
386 __IGNORE(RWDT1)
387 ICB,
388 PEP,
389 ASA,
390 __IGNORE(_2DG)
391 HQE,
392 JPU,
393 LCDC0,
394 __IGNORE(LCRC)
395 RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
396 RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
397 FRC,
398 LCDC1,
399 CSIRX,
400 DSITX_DSITX0, DSITX_DSITX1,
401 __IGNORE(SPU2_SPU0, SPU2_SPU1)
402 __IGNORE(FSI)
403 __IGNORE(FMSI)
404 __IGNORE(SCUV)
405 TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
406 TSIF2,
407 CMT4,
408 __IGNORE(MFIS2)
409 CPORTS2R,
410
411 /* interrupt groups INTCS */
412 RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU,
413 IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1,
414};
415
416#define INTCS_INTVECT 0x0F80
417static struct intc_vect intcs_vectors[] __initdata = {
418 INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720),
419 INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760),
420 INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820),
421 INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860),
422 INTCS_VECT(CEU, 0x0880),
423 INTCS_VECT(BEU_BEU0, 0x08A0),
424 INTCS_VECT(BEU_BEU1, 0x08C0),
425 INTCS_VECT(BEU_BEU2, 0x08E0),
426 __IGNORE(INTCS_VECT(MFI, 0x0900))
427 __IGNORE(INTCS_VECT(BBIF2, 0x0960))
428 INTCS_VECT(VPU, 0x0980),
429 INTCS_VECT(TSIF1, 0x09A0),
430 __IGNORE(INTCS_VECT(SGX540, 0x09E0))
431 INTCS_VECT(_2DDMAC, 0x0A00),
432 INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0),
433 INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0),
434 INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20),
435 INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80),
436 INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0),
437 INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0),
438 __IGNORE(INTCS_VECT(KEYSC 0x0BE0))
439 __IGNORE(INTCS_VECT(TTI20, 0x0C80))
440 __IGNORE(INTCS_VECT(MSIOF, 0x0D20))
441 INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20),
442 INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60),
443 INTCS_VECT(TMU_TUNI0, 0x0E80),
444 INTCS_VECT(TMU_TUNI1, 0x0EA0),
445 INTCS_VECT(TMU_TUNI2, 0x0EC0),
446 INTCS_VECT(CMT0, 0x0F00),
447 INTCS_VECT(TSIF0, 0x0F20),
448 __IGNORE(INTCS_VECT(CMT2, 0x0F40))
449 INTCS_VECT(LMB, 0x0F60),
450 __IGNORE(INTCS_VECT(MSUG, 0x0F80))
451 __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0))
452 __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0))
453 __IGNORE(INTCS_VECT(CTI, 0x0400))
454 INTCS_VECT(MVI3, 0x0420),
455 __IGNORE(INTCS_VECT(RWDT0, 0x0440))
456 __IGNORE(INTCS_VECT(RWDT1, 0x0460))
457 INTCS_VECT(ICB, 0x0480),
458 INTCS_VECT(PEP, 0x04A0),
459 INTCS_VECT(ASA, 0x04C0),
460 __IGNORE(INTCS_VECT(_2DG, 0x04E0))
461 INTCS_VECT(HQE, 0x0540),
462 INTCS_VECT(JPU, 0x0560),
463 INTCS_VECT(LCDC0, 0x0580),
464 __IGNORE(INTCS_VECT(LCRC, 0x05A0))
465 INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
466 INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
467 INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0),
468 INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0),
469 INTCS_VECT(FRC, 0x1700),
470 INTCS_VECT(LCDC1, 0x1780),
471 INTCS_VECT(CSIRX, 0x17A0),
472 INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0),
473 __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800))
474 __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820))
475 __IGNORE(INTCS_VECT(FSI, 0x1840))
476 __IGNORE(INTCS_VECT(FMSI, 0x1860))
477 __IGNORE(INTCS_VECT(SCUV, 0x1880))
478 INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
479 INTCS_VECT(TMU1_TUNI12, 0x1940),
480 INTCS_VECT(TSIF2, 0x1960),
481 INTCS_VECT(CMT4, 0x1980),
482 __IGNORE(INTCS_VECT(MFIS2, 0x1A00))
483 INTCS_VECT(CPORTS2R, 0x1A20),
484
485 INTC_VECT(INTCS, INTCS_INTVECT),
486};
487
488static struct intc_group intcs_groups[] __initdata = {
489 INTC_GROUP(RTDMAC1_1,
490 RTDMAC1_1_DEI0, RTDMAC1_1_DEI1,
491 RTDMAC1_1_DEI2, RTDMAC1_1_DEI3),
492 INTC_GROUP(RTDMAC1_2,
493 RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR),
494 INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
495 INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
496 INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
497 __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2))
498 INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
499 INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
500 INTC_GROUP(RTDMAC2_1,
501 RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
502 RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
503 INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
504 INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
505 __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1))
506 INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12),
507};
508
509static struct intc_mask_reg intcs_mask_registers[] __initdata = {
510 { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */
511 { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
512 VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
513 { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */
514 { 0, 0, 0, VPU,
515 __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } },
516 { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */
517 { 0, 0, 0, _2DDMAC,
518 __IGNORE0(_2DG), ASA, PEP, ICB } },
519 { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */
520 { 0, 0, MVI3, __IGNORE0(CTI),
521 JPU, HQE, __IGNORE0(LCRC), LCDC0 } },
522 { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */
523 { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4,
524 RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } },
525 __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */
526 { 0, 0, MSIOF, 0,
527 SGX540, 0, TTI20, 0 } })
528 { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */
529 { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
530 0, 0, 0, 0 } },
531 __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */
532 { 0, 0, 0, 0,
533 0, MSU_MSU, MSU_MSU2, MSUG } })
534 { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */
535 { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0,
536 IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
537 { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */
538 { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2,
539 0, 0, 0, 0 } },
540 { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */
541 { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
542 0, TSIF1, LMB, TSIF0 } },
543 { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */
544 { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
545 RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } },
546 { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */
547 { FRC, 0, 0, 0,
548 LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
549 __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */
550 {SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
551 SCUV, 0, 0, 0 } })
552 { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */
553 { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2,
554 CMT4, 0, 0, 0 } },
555 { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */
556 { __IGNORE0(MFIS2), CPORTS2R, 0, 0,
557 0, 0, 0, 0 } },
558 { 0xFFD20104, 0, 16, /* INTAMASK */
559 { 0, 0, 0, 0, 0, 0, 0, 0,
560 0, 0, 0, 0, 0, 0, 0, INTCS } }
561};
562
563static struct intc_prio_reg intcs_prio_registers[] __initdata = {
564 /* IPRAS */
565 { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } },
566 /* IPRBS */
567 { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } },
568 /* IPRCS */
569 __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } })
570 /* IPRES */
571 { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } },
572 /* IPRFS */
573 { 0xFFD20014, 0, 16, 4,
574 { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } },
575 /* IPRGS */
576 { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } },
577 /* IPRHS */
578 { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } },
579 /* IPRIS */
580 { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } },
581 /* IPRJS */
582 __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } })
583 /* IPRKS */
584 { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } },
585 /* IPRLS */
586 { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } },
587 /* IPRMS */
588 { 0xFFD20030, 0, 16, 4,
589 { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } },
590 /* IPRAS3 */
591 { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } },
592 /* IPRBS3 */
593 { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } },
594 /* IPRIS3 */
595 { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } },
596 /* IPRJS3 */
597 { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } },
598 /* IPRKS3 */
599 __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } })
600 /* IPRLS3 */
601 __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } })
602 /* IPRMS3 */
603 { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } },
604 /* IPRNS3 */
605 { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } },
606 /* IPROS3 */
607 { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } },
608};
609
610static struct resource intcs_resources[] __initdata = {
611 [0] = {
612 .start = 0xffd20000,
613 .end = 0xffd500ff,
614 .flags = IORESOURCE_MEM,
615 }
616};
617
618static struct intc_desc intcs_desc __initdata = {
619 .name = "sh7377-intcs",
620 .resource = intcs_resources,
621 .num_resources = ARRAY_SIZE(intcs_resources),
622 .hw = INTC_HW_DESC(intcs_vectors, intcs_groups,
623 intcs_mask_registers, intcs_prio_registers,
624 NULL, NULL),
625};
626
627static void intcs_demux(unsigned int irq, struct irq_desc *desc)
628{
629 void __iomem *reg = (void *)get_irq_data(irq);
630 unsigned int evtcodeas = ioread32(reg);
631
632 generic_handle_irq(intcs_evt2irq(evtcodeas));
633}
634
635#define INTEVTSA 0xFFD20100
349void __init sh7377_init_irq(void) 636void __init sh7377_init_irq(void)
350{ 637{
638 void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE);
639
351 register_intc_controller(&intca_desc); 640 register_intc_controller(&intca_desc);
641 register_intc_controller(&intcs_desc);
642
643 /* demux using INTEVTSA */
644 set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
645 set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
352} 646}
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
index 9557d0964d73..ec420353f8e3 100644
--- a/arch/arm/mach-shmobile/pfc-sh7372.c
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -1160,6 +1160,9 @@ static struct pinmux_gpio pinmux_gpios[] = {
1160 GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20), 1160 GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20),
1161 GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23), 1161 GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23),
1162 1162
1163 GPIO_FN(LCDC0_SELECT),
1164 GPIO_FN(LCDC1_SELECT),
1165
1163 /* IRDA */ 1166 /* IRDA */
1164 GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL), 1167 GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
1165 GPIO_FN(IROUT_139), GPIO_FN(IROUT_140), 1168 GPIO_FN(IROUT_139), GPIO_FN(IROUT_140),
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index eca90716140e..3148c11a550e 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -31,11 +31,13 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
33 33
34/* SCIFA0 */
34static struct plat_sci_port scif0_platform_data = { 35static struct plat_sci_port scif0_platform_data = {
35 .mapbase = 0xe6c40000, 36 .mapbase = 0xe6c40000,
36 .flags = UPF_BOOT_AUTOCONF, 37 .flags = UPF_BOOT_AUTOCONF,
37 .type = PORT_SCIF, 38 .type = PORT_SCIF,
38 .irqs = { 80, 80, 80, 80 }, 39 .irqs = { evt2irq(0xc00), evt2irq(0xc00),
40 evt2irq(0xc00), evt2irq(0xc00) },
39}; 41};
40 42
41static struct platform_device scif0_device = { 43static struct platform_device scif0_device = {
@@ -46,11 +48,13 @@ static struct platform_device scif0_device = {
46 }, 48 },
47}; 49};
48 50
51/* SCIFA1 */
49static struct plat_sci_port scif1_platform_data = { 52static struct plat_sci_port scif1_platform_data = {
50 .mapbase = 0xe6c50000, 53 .mapbase = 0xe6c50000,
51 .flags = UPF_BOOT_AUTOCONF, 54 .flags = UPF_BOOT_AUTOCONF,
52 .type = PORT_SCIF, 55 .type = PORT_SCIF,
53 .irqs = { 81, 81, 81, 81 }, 56 .irqs = { evt2irq(0xc20), evt2irq(0xc20),
57 evt2irq(0xc20), evt2irq(0xc20) },
54}; 58};
55 59
56static struct platform_device scif1_device = { 60static struct platform_device scif1_device = {
@@ -61,11 +65,13 @@ static struct platform_device scif1_device = {
61 }, 65 },
62}; 66};
63 67
68/* SCIFA2 */
64static struct plat_sci_port scif2_platform_data = { 69static struct plat_sci_port scif2_platform_data = {
65 .mapbase = 0xe6c60000, 70 .mapbase = 0xe6c60000,
66 .flags = UPF_BOOT_AUTOCONF, 71 .flags = UPF_BOOT_AUTOCONF,
67 .type = PORT_SCIF, 72 .type = PORT_SCIF,
68 .irqs = { 82, 82, 82, 82 }, 73 .irqs = { evt2irq(0xc40), evt2irq(0xc40),
74 evt2irq(0xc40), evt2irq(0xc40) },
69}; 75};
70 76
71static struct platform_device scif2_device = { 77static struct platform_device scif2_device = {
@@ -76,11 +82,13 @@ static struct platform_device scif2_device = {
76 }, 82 },
77}; 83};
78 84
85/* SCIFA3 */
79static struct plat_sci_port scif3_platform_data = { 86static struct plat_sci_port scif3_platform_data = {
80 .mapbase = 0xe6c70000, 87 .mapbase = 0xe6c70000,
81 .flags = UPF_BOOT_AUTOCONF, 88 .flags = UPF_BOOT_AUTOCONF,
82 .type = PORT_SCIF, 89 .type = PORT_SCIF,
83 .irqs = { 83, 83, 83, 83 }, 90 .irqs = { evt2irq(0xc60), evt2irq(0xc60),
91 evt2irq(0xc60), evt2irq(0xc60) },
84}; 92};
85 93
86static struct platform_device scif3_device = { 94static struct platform_device scif3_device = {
@@ -91,11 +99,13 @@ static struct platform_device scif3_device = {
91 }, 99 },
92}; 100};
93 101
102/* SCIFA4 */
94static struct plat_sci_port scif4_platform_data = { 103static struct plat_sci_port scif4_platform_data = {
95 .mapbase = 0xe6c80000, 104 .mapbase = 0xe6c80000,
96 .flags = UPF_BOOT_AUTOCONF, 105 .flags = UPF_BOOT_AUTOCONF,
97 .type = PORT_SCIF, 106 .type = PORT_SCIF,
98 .irqs = { 89, 89, 89, 89 }, 107 .irqs = { evt2irq(0xd20), evt2irq(0xd20),
108 evt2irq(0xd20), evt2irq(0xd20) },
99}; 109};
100 110
101static struct platform_device scif4_device = { 111static struct platform_device scif4_device = {
@@ -106,11 +116,13 @@ static struct platform_device scif4_device = {
106 }, 116 },
107}; 117};
108 118
119/* SCIFA5 */
109static struct plat_sci_port scif5_platform_data = { 120static struct plat_sci_port scif5_platform_data = {
110 .mapbase = 0xe6cb0000, 121 .mapbase = 0xe6cb0000,
111 .flags = UPF_BOOT_AUTOCONF, 122 .flags = UPF_BOOT_AUTOCONF,
112 .type = PORT_SCIF, 123 .type = PORT_SCIF,
113 .irqs = { 90, 90, 90, 90 }, 124 .irqs = { evt2irq(0xd40), evt2irq(0xd40),
125 evt2irq(0xd40), evt2irq(0xd40) },
114}; 126};
115 127
116static struct platform_device scif5_device = { 128static struct platform_device scif5_device = {
@@ -121,11 +133,13 @@ static struct platform_device scif5_device = {
121 }, 133 },
122}; 134};
123 135
136/* SCIFB */
124static struct plat_sci_port scif6_platform_data = { 137static struct plat_sci_port scif6_platform_data = {
125 .mapbase = 0xe6c30000, 138 .mapbase = 0xe6c30000,
126 .flags = UPF_BOOT_AUTOCONF, 139 .flags = UPF_BOOT_AUTOCONF,
127 .type = PORT_SCIF, 140 .type = PORT_SCIF,
128 .irqs = { 91, 91, 91, 91 }, 141 .irqs = { evt2irq(0xd60), evt2irq(0xd60),
142 evt2irq(0xd60), evt2irq(0xd60) },
129}; 143};
130 144
131static struct platform_device scif6_device = { 145static struct platform_device scif6_device = {
@@ -153,7 +167,7 @@ static struct resource cmt10_resources[] = {
153 .flags = IORESOURCE_MEM, 167 .flags = IORESOURCE_MEM,
154 }, 168 },
155 [1] = { 169 [1] = {
156 .start = 72, 170 .start = evt2irq(0xb00), /* CMT1_CMT10 */
157 .flags = IORESOURCE_IRQ, 171 .flags = IORESOURCE_IRQ,
158 }, 172 },
159}; 173};
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 1d1153290f59..e26686c9d0b6 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -26,17 +26,21 @@
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/serial_sci.h> 28#include <linux/serial_sci.h>
29#include <linux/sh_dma.h>
29#include <linux/sh_intc.h> 30#include <linux/sh_intc.h>
30#include <linux/sh_timer.h> 31#include <linux/sh_timer.h>
31#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/sh7372.h>
32#include <asm/mach-types.h> 34#include <asm/mach-types.h>
33#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
34 36
37/* SCIFA0 */
35static struct plat_sci_port scif0_platform_data = { 38static struct plat_sci_port scif0_platform_data = {
36 .mapbase = 0xe6c40000, 39 .mapbase = 0xe6c40000,
37 .flags = UPF_BOOT_AUTOCONF, 40 .flags = UPF_BOOT_AUTOCONF,
38 .type = PORT_SCIF, 41 .type = PORT_SCIFA,
39 .irqs = { 80, 80, 80, 80 }, 42 .irqs = { evt2irq(0x0c00), evt2irq(0x0c00),
43 evt2irq(0x0c00), evt2irq(0x0c00) },
40}; 44};
41 45
42static struct platform_device scif0_device = { 46static struct platform_device scif0_device = {
@@ -47,11 +51,13 @@ static struct platform_device scif0_device = {
47 }, 51 },
48}; 52};
49 53
54/* SCIFA1 */
50static struct plat_sci_port scif1_platform_data = { 55static struct plat_sci_port scif1_platform_data = {
51 .mapbase = 0xe6c50000, 56 .mapbase = 0xe6c50000,
52 .flags = UPF_BOOT_AUTOCONF, 57 .flags = UPF_BOOT_AUTOCONF,
53 .type = PORT_SCIF, 58 .type = PORT_SCIFA,
54 .irqs = { 81, 81, 81, 81 }, 59 .irqs = { evt2irq(0x0c20), evt2irq(0x0c20),
60 evt2irq(0x0c20), evt2irq(0x0c20) },
55}; 61};
56 62
57static struct platform_device scif1_device = { 63static struct platform_device scif1_device = {
@@ -62,11 +68,13 @@ static struct platform_device scif1_device = {
62 }, 68 },
63}; 69};
64 70
71/* SCIFA2 */
65static struct plat_sci_port scif2_platform_data = { 72static struct plat_sci_port scif2_platform_data = {
66 .mapbase = 0xe6c60000, 73 .mapbase = 0xe6c60000,
67 .flags = UPF_BOOT_AUTOCONF, 74 .flags = UPF_BOOT_AUTOCONF,
68 .type = PORT_SCIF, 75 .type = PORT_SCIFA,
69 .irqs = { 82, 82, 82, 82 }, 76 .irqs = { evt2irq(0x0c40), evt2irq(0x0c40),
77 evt2irq(0x0c40), evt2irq(0x0c40) },
70}; 78};
71 79
72static struct platform_device scif2_device = { 80static struct platform_device scif2_device = {
@@ -77,11 +85,13 @@ static struct platform_device scif2_device = {
77 }, 85 },
78}; 86};
79 87
88/* SCIFA3 */
80static struct plat_sci_port scif3_platform_data = { 89static struct plat_sci_port scif3_platform_data = {
81 .mapbase = 0xe6c70000, 90 .mapbase = 0xe6c70000,
82 .flags = UPF_BOOT_AUTOCONF, 91 .flags = UPF_BOOT_AUTOCONF,
83 .type = PORT_SCIF, 92 .type = PORT_SCIFA,
84 .irqs = { 83, 83, 83, 83 }, 93 .irqs = { evt2irq(0x0c60), evt2irq(0x0c60),
94 evt2irq(0x0c60), evt2irq(0x0c60) },
85}; 95};
86 96
87static struct platform_device scif3_device = { 97static struct platform_device scif3_device = {
@@ -92,11 +102,13 @@ static struct platform_device scif3_device = {
92 }, 102 },
93}; 103};
94 104
105/* SCIFA4 */
95static struct plat_sci_port scif4_platform_data = { 106static struct plat_sci_port scif4_platform_data = {
96 .mapbase = 0xe6c80000, 107 .mapbase = 0xe6c80000,
97 .flags = UPF_BOOT_AUTOCONF, 108 .flags = UPF_BOOT_AUTOCONF,
98 .type = PORT_SCIF, 109 .type = PORT_SCIFA,
99 .irqs = { 89, 89, 89, 89 }, 110 .irqs = { evt2irq(0x0d20), evt2irq(0x0d20),
111 evt2irq(0x0d20), evt2irq(0x0d20) },
100}; 112};
101 113
102static struct platform_device scif4_device = { 114static struct platform_device scif4_device = {
@@ -107,11 +119,13 @@ static struct platform_device scif4_device = {
107 }, 119 },
108}; 120};
109 121
122/* SCIFA5 */
110static struct plat_sci_port scif5_platform_data = { 123static struct plat_sci_port scif5_platform_data = {
111 .mapbase = 0xe6cb0000, 124 .mapbase = 0xe6cb0000,
112 .flags = UPF_BOOT_AUTOCONF, 125 .flags = UPF_BOOT_AUTOCONF,
113 .type = PORT_SCIF, 126 .type = PORT_SCIFA,
114 .irqs = { 90, 90, 90, 90 }, 127 .irqs = { evt2irq(0x0d40), evt2irq(0x0d40),
128 evt2irq(0x0d40), evt2irq(0x0d40) },
115}; 129};
116 130
117static struct platform_device scif5_device = { 131static struct platform_device scif5_device = {
@@ -122,11 +136,13 @@ static struct platform_device scif5_device = {
122 }, 136 },
123}; 137};
124 138
139/* SCIFB */
125static struct plat_sci_port scif6_platform_data = { 140static struct plat_sci_port scif6_platform_data = {
126 .mapbase = 0xe6c30000, 141 .mapbase = 0xe6c30000,
127 .flags = UPF_BOOT_AUTOCONF, 142 .flags = UPF_BOOT_AUTOCONF,
128 .type = PORT_SCIF, 143 .type = PORT_SCIFB,
129 .irqs = { 91, 91, 91, 91 }, 144 .irqs = { evt2irq(0x0d60), evt2irq(0x0d60),
145 evt2irq(0x0d60), evt2irq(0x0d60) },
130}; 146};
131 147
132static struct platform_device scif6_device = { 148static struct platform_device scif6_device = {
@@ -137,11 +153,12 @@ static struct platform_device scif6_device = {
137 }, 153 },
138}; 154};
139 155
156/* CMT */
140static struct sh_timer_config cmt10_platform_data = { 157static struct sh_timer_config cmt10_platform_data = {
141 .name = "CMT10", 158 .name = "CMT10",
142 .channel_offset = 0x10, 159 .channel_offset = 0x10,
143 .timer_bit = 0, 160 .timer_bit = 0,
144 .clk = "r_clk", 161 .clk = "cmt1",
145 .clockevent_rating = 125, 162 .clockevent_rating = 125,
146 .clocksource_rating = 125, 163 .clocksource_rating = 125,
147}; 164};
@@ -154,7 +171,7 @@ static struct resource cmt10_resources[] = {
154 .flags = IORESOURCE_MEM, 171 .flags = IORESOURCE_MEM,
155 }, 172 },
156 [1] = { 173 [1] = {
157 .start = 72, 174 .start = evt2irq(0x0b00), /* CMT1_CMT10 */
158 .flags = IORESOURCE_IRQ, 175 .flags = IORESOURCE_IRQ,
159 }, 176 },
160}; 177};
@@ -169,6 +186,337 @@ static struct platform_device cmt10_device = {
169 .num_resources = ARRAY_SIZE(cmt10_resources), 186 .num_resources = ARRAY_SIZE(cmt10_resources),
170}; 187};
171 188
189/* I2C */
190static struct resource iic0_resources[] = {
191 [0] = {
192 .name = "IIC0",
193 .start = 0xFFF20000,
194 .end = 0xFFF20425 - 1,
195 .flags = IORESOURCE_MEM,
196 },
197 [1] = {
198 .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */
199 .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */
200 .flags = IORESOURCE_IRQ,
201 },
202};
203
204static struct platform_device iic0_device = {
205 .name = "i2c-sh_mobile",
206 .id = 0, /* "i2c0" clock */
207 .num_resources = ARRAY_SIZE(iic0_resources),
208 .resource = iic0_resources,
209};
210
211static struct resource iic1_resources[] = {
212 [0] = {
213 .name = "IIC1",
214 .start = 0xE6C20000,
215 .end = 0xE6C20425 - 1,
216 .flags = IORESOURCE_MEM,
217 },
218 [1] = {
219 .start = evt2irq(0x780), /* IIC1_ALI1 */
220 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
221 .flags = IORESOURCE_IRQ,
222 },
223};
224
225static struct platform_device iic1_device = {
226 .name = "i2c-sh_mobile",
227 .id = 1, /* "i2c1" clock */
228 .num_resources = ARRAY_SIZE(iic1_resources),
229 .resource = iic1_resources,
230};
231
232/* DMA */
233/* Transmit sizes and respective CHCR register values */
234enum {
235 XMIT_SZ_8BIT = 0,
236 XMIT_SZ_16BIT = 1,
237 XMIT_SZ_32BIT = 2,
238 XMIT_SZ_64BIT = 7,
239 XMIT_SZ_128BIT = 3,
240 XMIT_SZ_256BIT = 4,
241 XMIT_SZ_512BIT = 5,
242};
243
244/* log2(size / 8) - used to calculate number of transfers */
245#define TS_SHIFT { \
246 [XMIT_SZ_8BIT] = 0, \
247 [XMIT_SZ_16BIT] = 1, \
248 [XMIT_SZ_32BIT] = 2, \
249 [XMIT_SZ_64BIT] = 3, \
250 [XMIT_SZ_128BIT] = 4, \
251 [XMIT_SZ_256BIT] = 5, \
252 [XMIT_SZ_512BIT] = 6, \
253}
254
255#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \
256 (((i) & 0xc) << (20 - 2)))
257
258static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
259 {
260 .slave_id = SHDMA_SLAVE_SCIF0_TX,
261 .addr = 0xe6c40020,
262 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
263 .mid_rid = 0x21,
264 }, {
265 .slave_id = SHDMA_SLAVE_SCIF0_RX,
266 .addr = 0xe6c40024,
267 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
268 .mid_rid = 0x22,
269 }, {
270 .slave_id = SHDMA_SLAVE_SCIF1_TX,
271 .addr = 0xe6c50020,
272 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
273 .mid_rid = 0x25,
274 }, {
275 .slave_id = SHDMA_SLAVE_SCIF1_RX,
276 .addr = 0xe6c50024,
277 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
278 .mid_rid = 0x26,
279 }, {
280 .slave_id = SHDMA_SLAVE_SCIF2_TX,
281 .addr = 0xe6c60020,
282 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
283 .mid_rid = 0x29,
284 }, {
285 .slave_id = SHDMA_SLAVE_SCIF2_RX,
286 .addr = 0xe6c60024,
287 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
288 .mid_rid = 0x2a,
289 }, {
290 .slave_id = SHDMA_SLAVE_SCIF3_TX,
291 .addr = 0xe6c70020,
292 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
293 .mid_rid = 0x2d,
294 }, {
295 .slave_id = SHDMA_SLAVE_SCIF3_RX,
296 .addr = 0xe6c70024,
297 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
298 .mid_rid = 0x2e,
299 }, {
300 .slave_id = SHDMA_SLAVE_SCIF4_TX,
301 .addr = 0xe6c80020,
302 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
303 .mid_rid = 0x39,
304 }, {
305 .slave_id = SHDMA_SLAVE_SCIF4_RX,
306 .addr = 0xe6c80024,
307 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
308 .mid_rid = 0x3a,
309 }, {
310 .slave_id = SHDMA_SLAVE_SCIF5_TX,
311 .addr = 0xe6cb0020,
312 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
313 .mid_rid = 0x35,
314 }, {
315 .slave_id = SHDMA_SLAVE_SCIF5_RX,
316 .addr = 0xe6cb0024,
317 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
318 .mid_rid = 0x36,
319 }, {
320 .slave_id = SHDMA_SLAVE_SCIF6_TX,
321 .addr = 0xe6c30040,
322 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
323 .mid_rid = 0x3d,
324 }, {
325 .slave_id = SHDMA_SLAVE_SCIF6_RX,
326 .addr = 0xe6c30060,
327 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
328 .mid_rid = 0x3e,
329 }, {
330 .slave_id = SHDMA_SLAVE_SDHI0_TX,
331 .addr = 0xe6850030,
332 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
333 .mid_rid = 0xc1,
334 }, {
335 .slave_id = SHDMA_SLAVE_SDHI0_RX,
336 .addr = 0xe6850030,
337 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
338 .mid_rid = 0xc2,
339 }, {
340 .slave_id = SHDMA_SLAVE_SDHI1_TX,
341 .addr = 0xe6860030,
342 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
343 .mid_rid = 0xc9,
344 }, {
345 .slave_id = SHDMA_SLAVE_SDHI1_RX,
346 .addr = 0xe6860030,
347 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
348 .mid_rid = 0xca,
349 }, {
350 .slave_id = SHDMA_SLAVE_SDHI2_TX,
351 .addr = 0xe6870030,
352 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
353 .mid_rid = 0xcd,
354 }, {
355 .slave_id = SHDMA_SLAVE_SDHI2_RX,
356 .addr = 0xe6870030,
357 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
358 .mid_rid = 0xce,
359 },
360};
361
362static const struct sh_dmae_channel sh7372_dmae_channels[] = {
363 {
364 .offset = 0,
365 .dmars = 0,
366 .dmars_bit = 0,
367 }, {
368 .offset = 0x10,
369 .dmars = 0,
370 .dmars_bit = 8,
371 }, {
372 .offset = 0x20,
373 .dmars = 4,
374 .dmars_bit = 0,
375 }, {
376 .offset = 0x30,
377 .dmars = 4,
378 .dmars_bit = 8,
379 }, {
380 .offset = 0x50,
381 .dmars = 8,
382 .dmars_bit = 0,
383 }, {
384 .offset = 0x60,
385 .dmars = 8,
386 .dmars_bit = 8,
387 }
388};
389
390static const unsigned int ts_shift[] = TS_SHIFT;
391
392static struct sh_dmae_pdata dma_platform_data = {
393 .slave = sh7372_dmae_slaves,
394 .slave_num = ARRAY_SIZE(sh7372_dmae_slaves),
395 .channel = sh7372_dmae_channels,
396 .channel_num = ARRAY_SIZE(sh7372_dmae_channels),
397 .ts_low_shift = 3,
398 .ts_low_mask = 0x18,
399 .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
400 .ts_high_mask = 0x00300000,
401 .ts_shift = ts_shift,
402 .ts_shift_num = ARRAY_SIZE(ts_shift),
403 .dmaor_init = DMAOR_DME,
404};
405
406/* Resource order important! */
407static struct resource sh7372_dmae0_resources[] = {
408 {
409 /* Channel registers and DMAOR */
410 .start = 0xfe008020,
411 .end = 0xfe00808f,
412 .flags = IORESOURCE_MEM,
413 },
414 {
415 /* DMARSx */
416 .start = 0xfe009000,
417 .end = 0xfe00900b,
418 .flags = IORESOURCE_MEM,
419 },
420 {
421 /* DMA error IRQ */
422 .start = 246,
423 .end = 246,
424 .flags = IORESOURCE_IRQ,
425 },
426 {
427 /* IRQ for channels 0-5 */
428 .start = 240,
429 .end = 245,
430 .flags = IORESOURCE_IRQ,
431 },
432};
433
434/* Resource order important! */
435static struct resource sh7372_dmae1_resources[] = {
436 {
437 /* Channel registers and DMAOR */
438 .start = 0xfe018020,
439 .end = 0xfe01808f,
440 .flags = IORESOURCE_MEM,
441 },
442 {
443 /* DMARSx */
444 .start = 0xfe019000,
445 .end = 0xfe01900b,
446 .flags = IORESOURCE_MEM,
447 },
448 {
449 /* DMA error IRQ */
450 .start = 254,
451 .end = 254,
452 .flags = IORESOURCE_IRQ,
453 },
454 {
455 /* IRQ for channels 0-5 */
456 .start = 248,
457 .end = 253,
458 .flags = IORESOURCE_IRQ,
459 },
460};
461
462/* Resource order important! */
463static struct resource sh7372_dmae2_resources[] = {
464 {
465 /* Channel registers and DMAOR */
466 .start = 0xfe028020,
467 .end = 0xfe02808f,
468 .flags = IORESOURCE_MEM,
469 },
470 {
471 /* DMARSx */
472 .start = 0xfe029000,
473 .end = 0xfe02900b,
474 .flags = IORESOURCE_MEM,
475 },
476 {
477 /* DMA error IRQ */
478 .start = 262,
479 .end = 262,
480 .flags = IORESOURCE_IRQ,
481 },
482 {
483 /* IRQ for channels 0-5 */
484 .start = 256,
485 .end = 261,
486 .flags = IORESOURCE_IRQ,
487 },
488};
489
490static struct platform_device dma0_device = {
491 .name = "sh-dma-engine",
492 .id = 0,
493 .resource = sh7372_dmae0_resources,
494 .num_resources = ARRAY_SIZE(sh7372_dmae0_resources),
495 .dev = {
496 .platform_data = &dma_platform_data,
497 },
498};
499
500static struct platform_device dma1_device = {
501 .name = "sh-dma-engine",
502 .id = 1,
503 .resource = sh7372_dmae1_resources,
504 .num_resources = ARRAY_SIZE(sh7372_dmae1_resources),
505 .dev = {
506 .platform_data = &dma_platform_data,
507 },
508};
509
510static struct platform_device dma2_device = {
511 .name = "sh-dma-engine",
512 .id = 2,
513 .resource = sh7372_dmae2_resources,
514 .num_resources = ARRAY_SIZE(sh7372_dmae2_resources),
515 .dev = {
516 .platform_data = &dma_platform_data,
517 },
518};
519
172static struct platform_device *sh7372_early_devices[] __initdata = { 520static struct platform_device *sh7372_early_devices[] __initdata = {
173 &scif0_device, 521 &scif0_device,
174 &scif1_device, 522 &scif1_device,
@@ -178,6 +526,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
178 &scif5_device, 526 &scif5_device,
179 &scif6_device, 527 &scif6_device,
180 &cmt10_device, 528 &cmt10_device,
529 &iic0_device,
530 &iic1_device,
531 &dma0_device,
532 &dma1_device,
533 &dma2_device,
181}; 534};
182 535
183void __init sh7372_add_standard_devices(void) 536void __init sh7372_add_standard_devices(void)
@@ -186,14 +539,8 @@ void __init sh7372_add_standard_devices(void)
186 ARRAY_SIZE(sh7372_early_devices)); 539 ARRAY_SIZE(sh7372_early_devices));
187} 540}
188 541
189#define SMSTPCR3 0xe615013c
190#define SMSTPCR3_CMT1 (1 << 29)
191
192void __init sh7372_add_early_devices(void) 542void __init sh7372_add_early_devices(void)
193{ 543{
194 /* enable clock to CMT1 */
195 __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
196
197 early_platform_add_devices(sh7372_early_devices, 544 early_platform_add_devices(sh7372_early_devices,
198 ARRAY_SIZE(sh7372_early_devices)); 545 ARRAY_SIZE(sh7372_early_devices));
199} 546}
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index 60e37774c35c..bb4adf17dbf4 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -32,11 +32,13 @@
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
34 34
35/* SCIFA0 */
35static struct plat_sci_port scif0_platform_data = { 36static struct plat_sci_port scif0_platform_data = {
36 .mapbase = 0xe6c40000, 37 .mapbase = 0xe6c40000,
37 .flags = UPF_BOOT_AUTOCONF, 38 .flags = UPF_BOOT_AUTOCONF,
38 .type = PORT_SCIF, 39 .type = PORT_SCIF,
39 .irqs = { 80, 80, 80, 80 }, 40 .irqs = { evt2irq(0xc00), evt2irq(0xc00),
41 evt2irq(0xc00), evt2irq(0xc00) },
40}; 42};
41 43
42static struct platform_device scif0_device = { 44static struct platform_device scif0_device = {
@@ -47,11 +49,13 @@ static struct platform_device scif0_device = {
47 }, 49 },
48}; 50};
49 51
52/* SCIFA1 */
50static struct plat_sci_port scif1_platform_data = { 53static struct plat_sci_port scif1_platform_data = {
51 .mapbase = 0xe6c50000, 54 .mapbase = 0xe6c50000,
52 .flags = UPF_BOOT_AUTOCONF, 55 .flags = UPF_BOOT_AUTOCONF,
53 .type = PORT_SCIF, 56 .type = PORT_SCIF,
54 .irqs = { 81, 81, 81, 81 }, 57 .irqs = { evt2irq(0xc20), evt2irq(0xc20),
58 evt2irq(0xc20), evt2irq(0xc20) },
55}; 59};
56 60
57static struct platform_device scif1_device = { 61static struct platform_device scif1_device = {
@@ -62,11 +66,13 @@ static struct platform_device scif1_device = {
62 }, 66 },
63}; 67};
64 68
69/* SCIFA2 */
65static struct plat_sci_port scif2_platform_data = { 70static struct plat_sci_port scif2_platform_data = {
66 .mapbase = 0xe6c60000, 71 .mapbase = 0xe6c60000,
67 .flags = UPF_BOOT_AUTOCONF, 72 .flags = UPF_BOOT_AUTOCONF,
68 .type = PORT_SCIF, 73 .type = PORT_SCIF,
69 .irqs = { 82, 82, 82, 82 }, 74 .irqs = { evt2irq(0xc40), evt2irq(0xc40),
75 evt2irq(0xc40), evt2irq(0xc40) },
70}; 76};
71 77
72static struct platform_device scif2_device = { 78static struct platform_device scif2_device = {
@@ -77,11 +83,13 @@ static struct platform_device scif2_device = {
77 }, 83 },
78}; 84};
79 85
86/* SCIFA3 */
80static struct plat_sci_port scif3_platform_data = { 87static struct plat_sci_port scif3_platform_data = {
81 .mapbase = 0xe6c70000, 88 .mapbase = 0xe6c70000,
82 .flags = UPF_BOOT_AUTOCONF, 89 .flags = UPF_BOOT_AUTOCONF,
83 .type = PORT_SCIF, 90 .type = PORT_SCIF,
84 .irqs = { 83, 83, 83, 83 }, 91 .irqs = { evt2irq(0xc60), evt2irq(0xc60),
92 evt2irq(0xc60), evt2irq(0xc60) },
85}; 93};
86 94
87static struct platform_device scif3_device = { 95static struct platform_device scif3_device = {
@@ -92,11 +100,13 @@ static struct platform_device scif3_device = {
92 }, 100 },
93}; 101};
94 102
103/* SCIFA4 */
95static struct plat_sci_port scif4_platform_data = { 104static struct plat_sci_port scif4_platform_data = {
96 .mapbase = 0xe6c80000, 105 .mapbase = 0xe6c80000,
97 .flags = UPF_BOOT_AUTOCONF, 106 .flags = UPF_BOOT_AUTOCONF,
98 .type = PORT_SCIF, 107 .type = PORT_SCIF,
99 .irqs = { 89, 89, 89, 89 }, 108 .irqs = { evt2irq(0xd20), evt2irq(0xd20),
109 evt2irq(0xd20), evt2irq(0xd20) },
100}; 110};
101 111
102static struct platform_device scif4_device = { 112static struct platform_device scif4_device = {
@@ -107,11 +117,13 @@ static struct platform_device scif4_device = {
107 }, 117 },
108}; 118};
109 119
120/* SCIFA5 */
110static struct plat_sci_port scif5_platform_data = { 121static struct plat_sci_port scif5_platform_data = {
111 .mapbase = 0xe6cb0000, 122 .mapbase = 0xe6cb0000,
112 .flags = UPF_BOOT_AUTOCONF, 123 .flags = UPF_BOOT_AUTOCONF,
113 .type = PORT_SCIF, 124 .type = PORT_SCIF,
114 .irqs = { 90, 90, 90, 90 }, 125 .irqs = { evt2irq(0xd40), evt2irq(0xd40),
126 evt2irq(0xd40), evt2irq(0xd40) },
115}; 127};
116 128
117static struct platform_device scif5_device = { 129static struct platform_device scif5_device = {
@@ -122,11 +134,13 @@ static struct platform_device scif5_device = {
122 }, 134 },
123}; 135};
124 136
137/* SCIFA6 */
125static struct plat_sci_port scif6_platform_data = { 138static struct plat_sci_port scif6_platform_data = {
126 .mapbase = 0xe6cc0000, 139 .mapbase = 0xe6cc0000,
127 .flags = UPF_BOOT_AUTOCONF, 140 .flags = UPF_BOOT_AUTOCONF,
128 .type = PORT_SCIF, 141 .type = PORT_SCIF,
129 .irqs = { 196, 196, 196, 196 }, 142 .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
143 intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
130}; 144};
131 145
132static struct platform_device scif6_device = { 146static struct platform_device scif6_device = {
@@ -137,11 +151,13 @@ static struct platform_device scif6_device = {
137 }, 151 },
138}; 152};
139 153
154/* SCIFB */
140static struct plat_sci_port scif7_platform_data = { 155static struct plat_sci_port scif7_platform_data = {
141 .mapbase = 0xe6c30000, 156 .mapbase = 0xe6c30000,
142 .flags = UPF_BOOT_AUTOCONF, 157 .flags = UPF_BOOT_AUTOCONF,
143 .type = PORT_SCIF, 158 .type = PORT_SCIF,
144 .irqs = { 91, 91, 91, 91 }, 159 .irqs = { evt2irq(0xd60), evt2irq(0xd60),
160 evt2irq(0xd60), evt2irq(0xd60) },
145}; 161};
146 162
147static struct platform_device scif7_device = { 163static struct platform_device scif7_device = {
@@ -169,7 +185,7 @@ static struct resource cmt10_resources[] = {
169 .flags = IORESOURCE_MEM, 185 .flags = IORESOURCE_MEM,
170 }, 186 },
171 [1] = { 187 [1] = {
172 .start = 72, 188 .start = evt2irq(0xb00), /* CMT1_CMT10 */
173 .flags = IORESOURCE_IRQ, 189 .flags = IORESOURCE_IRQ,
174 }, 190 },
175}; 191};