aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 18:33:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 18:33:25 -0400
commit4e8a780ed6e1fdb8af203f61718212d5739bc4a0 (patch)
tree2f3b28f400932d72c3940ff360a1be1fed8b0f87 /arch/arm
parent90ff1f30c0f401e325d6b2747618b7e3a0addaf8 (diff)
parent66ee3bef3ce0bab155de082805388bd6ec2785f8 (diff)
Merge branch 'rmobile-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* 'rmobile-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (34 commits) ARM: mach-shmobile: mackerel: add renesas_usbhs support for USB1 ARM: mach-shmobile: Correct the G4EVM SDHI0 I/O range. ARM: arch-shmobile: sh7372: add renesas_usbhs irq support ARM: mach-shmobile: sh73a0: mark DMA slave ID 0 as invalid ARM: mach-shmobile: mark DMA slave ID 0 as invalid ARM: mach-shmobile: Enable DMAEngine for SDHI on AG5EVM ARM: mach-shmobile: Enable DMAEngine for MMCIF on AG5EVM ARM: mach-shmobile: sh73a0 DMA Engine support for SY-DMAC dmaengine: shdma: Update SH_DMAC_MAX_CHANNELS to 20 dmaengine: shdma: Fix SH_DMAC_MAX_CHANNELS handling dmaengine: shdma: Make second memory window optional ARM: mach-shmobile: Tidy up after SH7372 pm changes. ARM: mach-shmobile: sh7372 Core Standby CPUIdle ARM: mach-shmobile: CPUIdle support ARM: mach-shmobile: sh7372 Core Standby Suspend-to-RAM ARM: mach-shmobile: Suspend-to-RAM support mailmap: Add entry for Damian Hobson-Garcia. ARM: switch mackerel to dynamically manage the platform camera ARM: mach-shmobile: Add SDHI support for AG5EVM and sh73a0 ARM: arch-shmobile: Use multiple irq vectors for SDHI ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-shmobile/Makefile5
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c118
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c30
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c2
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c272
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c21
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c19
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c92
-rw-r--r--arch/arm/mach-shmobile/headsmp.S2
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-ap4evb.txt3
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-mackerel.txt3
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h30
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c46
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c108
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c223
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c217
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c239
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c244
-rw-r--r--arch/arm/mach-shmobile/sleep-sh7372.S260
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c9
-rw-r--r--arch/arm/mach-shmobile/suspend.c47
23 files changed, 1909 insertions, 89 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e2507f66f9d5..612b27000c3e 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -30,6 +30,11 @@ obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
30obj-$(CONFIG_ARCH_SH7372) += entry-intc.o 30obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
31obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o 31obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o
32 32
33# PM objects
34obj-$(CONFIG_SUSPEND) += suspend.o
35obj-$(CONFIG_CPU_IDLE) += cpuidle.o
36obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
37
33# Board objects 38# Board objects
34obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o 39obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
35obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o 40obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 3e6f0aab460b..c95258c274c1 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -34,6 +34,8 @@
34#include <linux/input/sh_keysc.h> 34#include <linux/input/sh_keysc.h>
35#include <linux/mmc/host.h> 35#include <linux/mmc/host.h>
36#include <linux/mmc/sh_mmcif.h> 36#include <linux/mmc/sh_mmcif.h>
37#include <linux/mmc/sh_mobile_sdhi.h>
38#include <linux/mfd/tmio.h>
37#include <linux/sh_clk.h> 39#include <linux/sh_clk.h>
38#include <video/sh_mobile_lcdc.h> 40#include <video/sh_mobile_lcdc.h>
39#include <video/sh_mipi_dsi.h> 41#include <video/sh_mipi_dsi.h>
@@ -156,10 +158,19 @@ static struct resource sh_mmcif_resources[] = {
156 }, 158 },
157}; 159};
158 160
161static struct sh_mmcif_dma sh_mmcif_dma = {
162 .chan_priv_rx = {
163 .slave_id = SHDMA_SLAVE_MMCIF_RX,
164 },
165 .chan_priv_tx = {
166 .slave_id = SHDMA_SLAVE_MMCIF_TX,
167 },
168};
159static struct sh_mmcif_plat_data sh_mmcif_platdata = { 169static struct sh_mmcif_plat_data sh_mmcif_platdata = {
160 .sup_pclk = 0, 170 .sup_pclk = 0,
161 .ocr = MMC_VDD_165_195, 171 .ocr = MMC_VDD_165_195,
162 .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, 172 .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
173 .dma = &sh_mmcif_dma,
163}; 174};
164 175
165static struct platform_device mmc_device = { 176static struct platform_device mmc_device = {
@@ -296,11 +307,13 @@ static struct platform_device lcdc0_device = {
296/* MIPI-DSI */ 307/* MIPI-DSI */
297static struct resource mipidsi0_resources[] = { 308static struct resource mipidsi0_resources[] = {
298 [0] = { 309 [0] = {
310 .name = "DSI0",
299 .start = 0xfeab0000, 311 .start = 0xfeab0000,
300 .end = 0xfeab3fff, 312 .end = 0xfeab3fff,
301 .flags = IORESOURCE_MEM, 313 .flags = IORESOURCE_MEM,
302 }, 314 },
303 [1] = { 315 [1] = {
316 .name = "DSI0",
304 .start = 0xfeab4000, 317 .start = 0xfeab4000,
305 .end = 0xfeab7fff, 318 .end = 0xfeab7fff,
306 .flags = IORESOURCE_MEM, 319 .flags = IORESOURCE_MEM,
@@ -325,6 +338,89 @@ static struct platform_device mipidsi0_device = {
325 }, 338 },
326}; 339};
327 340
341static struct sh_mobile_sdhi_info sdhi0_info = {
342 .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
343 .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
344 .tmio_caps = MMC_CAP_SD_HIGHSPEED,
345 .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
346};
347
348static struct resource sdhi0_resources[] = {
349 [0] = {
350 .name = "SDHI0",
351 .start = 0xee100000,
352 .end = 0xee1000ff,
353 .flags = IORESOURCE_MEM,
354 },
355 [1] = {
356 .start = gic_spi(83),
357 .flags = IORESOURCE_IRQ,
358 },
359 [2] = {
360 .start = gic_spi(84),
361 .flags = IORESOURCE_IRQ,
362 },
363 [3] = {
364 .start = gic_spi(85),
365 .flags = IORESOURCE_IRQ,
366 },
367};
368
369static struct platform_device sdhi0_device = {
370 .name = "sh_mobile_sdhi",
371 .id = 0,
372 .num_resources = ARRAY_SIZE(sdhi0_resources),
373 .resource = sdhi0_resources,
374 .dev = {
375 .platform_data = &sdhi0_info,
376 },
377};
378
379void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
380{
381 gpio_set_value(GPIO_PORT114, state);
382}
383
384static struct sh_mobile_sdhi_info sh_sdhi1_platdata = {
385 .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
386 .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
387 .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
388 .tmio_caps = MMC_CAP_NONREMOVABLE,
389 .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
390 .set_pwr = ag5evm_sdhi1_set_pwr,
391};
392
393static struct resource sdhi1_resources[] = {
394 [0] = {
395 .name = "SDHI1",
396 .start = 0xee120000,
397 .end = 0xee1200ff,
398 .flags = IORESOURCE_MEM,
399 },
400 [1] = {
401 .start = gic_spi(87),
402 .flags = IORESOURCE_IRQ,
403 },
404 [2] = {
405 .start = gic_spi(88),
406 .flags = IORESOURCE_IRQ,
407 },
408 [3] = {
409 .start = gic_spi(89),
410 .flags = IORESOURCE_IRQ,
411 },
412};
413
414static struct platform_device sdhi1_device = {
415 .name = "sh_mobile_sdhi",
416 .id = 1,
417 .dev = {
418 .platform_data = &sh_sdhi1_platdata,
419 },
420 .num_resources = ARRAY_SIZE(sdhi1_resources),
421 .resource = sdhi1_resources,
422};
423
328static struct platform_device *ag5evm_devices[] __initdata = { 424static struct platform_device *ag5evm_devices[] __initdata = {
329 &eth_device, 425 &eth_device,
330 &keysc_device, 426 &keysc_device,
@@ -333,6 +429,8 @@ static struct platform_device *ag5evm_devices[] __initdata = {
333 &irda_device, 429 &irda_device,
334 &lcdc0_device, 430 &lcdc0_device,
335 &mipidsi0_device, 431 &mipidsi0_device,
432 &sdhi0_device,
433 &sdhi1_device,
336}; 434};
337 435
338static struct map_desc ag5evm_io_desc[] __initdata = { 436static struct map_desc ag5evm_io_desc[] __initdata = {
@@ -454,6 +552,26 @@ static void __init ag5evm_init(void)
454 /* MIPI-DSI clock setup */ 552 /* MIPI-DSI clock setup */
455 __raw_writel(0x2a809010, DSI0PHYCR); 553 __raw_writel(0x2a809010, DSI0PHYCR);
456 554
555 /* enable SDHI0 on CN15 [SD I/F] */
556 gpio_request(GPIO_FN_SDHICD0, NULL);
557 gpio_request(GPIO_FN_SDHIWP0, NULL);
558 gpio_request(GPIO_FN_SDHICMD0, NULL);
559 gpio_request(GPIO_FN_SDHICLK0, NULL);
560 gpio_request(GPIO_FN_SDHID0_3, NULL);
561 gpio_request(GPIO_FN_SDHID0_2, NULL);
562 gpio_request(GPIO_FN_SDHID0_1, NULL);
563 gpio_request(GPIO_FN_SDHID0_0, NULL);
564
565 /* enable SDHI1 on CN4 [WLAN I/F] */
566 gpio_request(GPIO_FN_SDHICLK1, NULL);
567 gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
568 gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
569 gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
570 gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
571 gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
572 gpio_request(GPIO_PORT114, "sdhi1_power");
573 gpio_direction_output(GPIO_PORT114, 0);
574
457#ifdef CONFIG_CACHE_L2X0 575#ifdef CONFIG_CACHE_L2X0
458 /* Shared attribute override enable, 64K*8way */ 576 /* Shared attribute override enable, 64K*8way */
459 l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff); 577 l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 1e35fa976d64..08acb6ec8139 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -316,8 +316,16 @@ static struct resource sdhi0_resources[] = {
316 .flags = IORESOURCE_MEM, 316 .flags = IORESOURCE_MEM,
317 }, 317 },
318 [1] = { 318 [1] = {
319 .start = evt2irq(0x0e00) /* SDHI0 */, 319 .start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
320 .flags = IORESOURCE_IRQ, 320 .flags = IORESOURCE_IRQ,
321 },
322 [2] = {
323 .start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
324 .flags = IORESOURCE_IRQ,
325 },
326 [3] = {
327 .start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
328 .flags = IORESOURCE_IRQ,
321 }, 329 },
322}; 330};
323 331
@@ -349,8 +357,16 @@ static struct resource sdhi1_resources[] = {
349 .flags = IORESOURCE_MEM, 357 .flags = IORESOURCE_MEM,
350 }, 358 },
351 [1] = { 359 [1] = {
352 .start = evt2irq(0x0e80), 360 .start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
353 .flags = IORESOURCE_IRQ, 361 .flags = IORESOURCE_IRQ,
362 },
363 [2] = {
364 .start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
365 .flags = IORESOURCE_IRQ,
366 },
367 [3] = {
368 .start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
369 .flags = IORESOURCE_IRQ,
354 }, 370 },
355}; 371};
356 372
@@ -980,11 +996,6 @@ static void __init hdmi_init_pm_clock(void)
980 goto out; 996 goto out;
981 } 997 }
982 998
983 ret = clk_enable(&sh7372_pllc2_clk);
984 if (ret < 0) {
985 pr_err("Cannot enable pllc2 clock\n");
986 goto out;
987 }
988 pr_debug("PLLC2 set frequency %lu\n", rate); 999 pr_debug("PLLC2 set frequency %lu\n", rate);
989 1000
990 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 1001 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -1343,6 +1354,7 @@ static void __init ap4evb_init(void)
1343 1354
1344 hdmi_init_pm_clock(); 1355 hdmi_init_pm_clock();
1345 fsi_init_pm_clock(); 1356 fsi_init_pm_clock();
1357 sh7372_pm_init();
1346} 1358}
1347 1359
1348static void __init ap4evb_timer_init(void) 1360static void __init ap4evb_timer_init(void)
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index c87a7b7c5832..8e3c5559f27f 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -205,7 +205,7 @@ static struct resource sdhi0_resources[] = {
205 [0] = { 205 [0] = {
206 .name = "SDHI0", 206 .name = "SDHI0",
207 .start = 0xe6d50000, 207 .start = 0xe6d50000,
208 .end = 0xe6d50nff, 208 .end = 0xe6d500ff,
209 .flags = IORESOURCE_MEM, 209 .flags = IORESOURCE_MEM,
210 }, 210 },
211 [1] = { 211 [1] = {
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 7da2ca24229d..448ddbe43335 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -43,6 +43,7 @@
43#include <linux/sh_intc.h> 43#include <linux/sh_intc.h>
44#include <linux/tca6416_keypad.h> 44#include <linux/tca6416_keypad.h>
45#include <linux/usb/r8a66597.h> 45#include <linux/usb/r8a66597.h>
46#include <linux/usb/renesas_usbhs.h>
46 47
47#include <video/sh_mobile_hdmi.h> 48#include <video/sh_mobile_hdmi.h>
48#include <video/sh_mobile_lcdc.h> 49#include <video/sh_mobile_lcdc.h>
@@ -143,7 +144,30 @@
143 * open | external VBUS | Function 144 * open | external VBUS | Function
144 * 145 *
145 * *1 146 * *1
146 * CN31 is used as Host in Linux. 147 * CN31 is used as
148 * CONFIG_USB_R8A66597_HCD Host
149 * CONFIG_USB_RENESAS_USBHS Function
150 *
151 * CAUTION
152 *
153 * renesas_usbhs driver can use external interrupt mode
154 * (which come from USB-PHY) or autonomy mode (it use own interrupt)
155 * for detecting connection/disconnection when Function.
156 * USB will be power OFF while it has been disconnecting
157 * if external interrupt mode, and it is always power ON if autonomy mode,
158 *
159 * mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
160 * because Touchscreen is using IRQ7-PORT40.
161 * It is impossible to use IRQ7 demux on this board.
162 *
163 * We can use external interrupt mode USB-Function on "USB1".
164 * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
165 * But don't select both drivers in same time.
166 * These uses same IRQ number for request_irq(), and aren't supporting
167 * IRQF_SHARD / IORESOURCE_IRQ_SHAREABLE.
168 *
169 * Actually these are old/new version of USB driver.
170 * This mean its register will be broken if it supports SHARD IRQ,
147 */ 171 */
148 172
149/* 173/*
@@ -185,6 +209,7 @@
185 * FIXME !! 209 * FIXME !!
186 * 210 *
187 * gpio_no_direction 211 * gpio_no_direction
212 * gpio_pull_down
188 * are quick_hack. 213 * are quick_hack.
189 * 214 *
190 * current gpio frame work doesn't have 215 * current gpio frame work doesn't have
@@ -196,6 +221,16 @@ static void __init gpio_no_direction(u32 addr)
196 __raw_writeb(0x00, addr); 221 __raw_writeb(0x00, addr);
197} 222}
198 223
224static void __init gpio_pull_down(u32 addr)
225{
226 u8 data = __raw_readb(addr);
227
228 data &= 0x0F;
229 data |= 0xA0;
230
231 __raw_writeb(data, addr);
232}
233
199/* MTD */ 234/* MTD */
200static struct mtd_partition nor_flash_partitions[] = { 235static struct mtd_partition nor_flash_partitions[] = {
201 { 236 {
@@ -458,12 +493,6 @@ static void __init hdmi_init_pm_clock(void)
458 goto out; 493 goto out;
459 } 494 }
460 495
461 ret = clk_enable(&sh7372_pllc2_clk);
462 if (ret < 0) {
463 pr_err("Cannot enable pllc2 clock\n");
464 goto out;
465 }
466
467 pr_debug("PLLC2 set frequency %lu\n", rate); 496 pr_debug("PLLC2 set frequency %lu\n", rate);
468 497
469 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 498 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -515,6 +544,157 @@ static struct platform_device usb1_host_device = {
515 .resource = usb1_host_resources, 544 .resource = usb1_host_resources,
516}; 545};
517 546
547/* USB1 (Function) */
548#define USB_PHY_MODE (1 << 4)
549#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
550#define USB_PHY_ON (1 << 1)
551#define USB_PHY_OFF (1 << 0)
552#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
553
554struct usbhs_private {
555 unsigned int irq;
556 unsigned int usbphyaddr;
557 unsigned int usbcrcaddr;
558 struct renesas_usbhs_platform_info info;
559};
560
561#define usbhs_get_priv(pdev) \
562 container_of(renesas_usbhs_get_info(pdev), \
563 struct usbhs_private, info)
564
565#define usbhs_is_connected(priv) \
566 (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
567
568static int usbhs1_get_id(struct platform_device *pdev)
569{
570 return USBHS_GADGET;
571}
572
573static int usbhs1_get_vbus(struct platform_device *pdev)
574{
575 return usbhs_is_connected(usbhs_get_priv(pdev));
576}
577
578static irqreturn_t usbhs1_interrupt(int irq, void *data)
579{
580 struct platform_device *pdev = data;
581 struct usbhs_private *priv = usbhs_get_priv(pdev);
582
583 dev_dbg(&pdev->dev, "%s\n", __func__);
584
585 renesas_usbhs_call_notify_hotplug(pdev);
586
587 /* clear status */
588 __raw_writew(__raw_readw(priv->usbphyaddr) | USB_PHY_INT_CLR,
589 priv->usbphyaddr);
590
591 return IRQ_HANDLED;
592}
593
594static int usbhs1_hardware_init(struct platform_device *pdev)
595{
596 struct usbhs_private *priv = usbhs_get_priv(pdev);
597 int ret;
598
599 irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
600
601 /* clear interrupt status */
602 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
603
604 ret = request_irq(priv->irq, usbhs1_interrupt, 0,
605 dev_name(&pdev->dev), pdev);
606 if (ret) {
607 dev_err(&pdev->dev, "request_irq err\n");
608 return ret;
609 }
610
611 /* enable USB phy interrupt */
612 __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->usbphyaddr);
613
614 return 0;
615}
616
617static void usbhs1_hardware_exit(struct platform_device *pdev)
618{
619 struct usbhs_private *priv = usbhs_get_priv(pdev);
620
621 /* clear interrupt status */
622 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
623
624 free_irq(priv->irq, pdev);
625}
626
627static void usbhs1_phy_reset(struct platform_device *pdev)
628{
629 struct usbhs_private *priv = usbhs_get_priv(pdev);
630
631 /* init phy */
632 __raw_writew(0x8a0a, priv->usbcrcaddr);
633}
634
635static u32 usbhs1_pipe_cfg[] = {
636 USB_ENDPOINT_XFER_CONTROL,
637 USB_ENDPOINT_XFER_ISOC,
638 USB_ENDPOINT_XFER_ISOC,
639 USB_ENDPOINT_XFER_BULK,
640 USB_ENDPOINT_XFER_BULK,
641 USB_ENDPOINT_XFER_BULK,
642 USB_ENDPOINT_XFER_INT,
643 USB_ENDPOINT_XFER_INT,
644 USB_ENDPOINT_XFER_INT,
645 USB_ENDPOINT_XFER_BULK,
646 USB_ENDPOINT_XFER_BULK,
647 USB_ENDPOINT_XFER_BULK,
648 USB_ENDPOINT_XFER_BULK,
649 USB_ENDPOINT_XFER_BULK,
650 USB_ENDPOINT_XFER_BULK,
651 USB_ENDPOINT_XFER_BULK,
652};
653
654static struct usbhs_private usbhs1_private = {
655 .irq = evt2irq(0x0300), /* IRQ8 */
656 .usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */
657 .usbcrcaddr = 0xE6058130, /* USBCR4 */
658 .info = {
659 .platform_callback = {
660 .hardware_init = usbhs1_hardware_init,
661 .hardware_exit = usbhs1_hardware_exit,
662 .phy_reset = usbhs1_phy_reset,
663 .get_id = usbhs1_get_id,
664 .get_vbus = usbhs1_get_vbus,
665 },
666 .driver_param = {
667 .buswait_bwait = 4,
668 .pipe_type = usbhs1_pipe_cfg,
669 .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg),
670 },
671 },
672};
673
674static struct resource usbhs1_resources[] = {
675 [0] = {
676 .name = "USBHS",
677 .start = 0xE68B0000,
678 .end = 0xE68B00E6 - 1,
679 .flags = IORESOURCE_MEM,
680 },
681 [1] = {
682 .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
683 .flags = IORESOURCE_IRQ,
684 },
685};
686
687static struct platform_device usbhs1_device = {
688 .name = "renesas_usbhs",
689 .id = 1,
690 .dev = {
691 .platform_data = &usbhs1_private.info,
692 },
693 .num_resources = ARRAY_SIZE(usbhs1_resources),
694 .resource = usbhs1_resources,
695};
696
697
518/* LED */ 698/* LED */
519static struct gpio_led mackerel_leds[] = { 699static struct gpio_led mackerel_leds[] = {
520 { 700 {
@@ -690,7 +870,15 @@ static struct resource sdhi0_resources[] = {
690 .flags = IORESOURCE_MEM, 870 .flags = IORESOURCE_MEM,
691 }, 871 },
692 [1] = { 872 [1] = {
693 .start = evt2irq(0x0e00) /* SDHI0 */, 873 .start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
874 .flags = IORESOURCE_IRQ,
875 },
876 [2] = {
877 .start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
878 .flags = IORESOURCE_IRQ,
879 },
880 [3] = {
881 .start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
694 .flags = IORESOURCE_IRQ, 882 .flags = IORESOURCE_IRQ,
695 }, 883 },
696}; 884};
@@ -705,7 +893,7 @@ static struct platform_device sdhi0_device = {
705 }, 893 },
706}; 894};
707 895
708#if !defined(CONFIG_MMC_SH_MMCIF) 896#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
709/* SDHI1 */ 897/* SDHI1 */
710static struct sh_mobile_sdhi_info sdhi1_info = { 898static struct sh_mobile_sdhi_info sdhi1_info = {
711 .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, 899 .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
@@ -725,7 +913,15 @@ static struct resource sdhi1_resources[] = {
725 .flags = IORESOURCE_MEM, 913 .flags = IORESOURCE_MEM,
726 }, 914 },
727 [1] = { 915 [1] = {
728 .start = evt2irq(0x0e80), 916 .start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
917 .flags = IORESOURCE_IRQ,
918 },
919 [2] = {
920 .start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
921 .flags = IORESOURCE_IRQ,
922 },
923 [3] = {
924 .start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
729 .flags = IORESOURCE_IRQ, 925 .flags = IORESOURCE_IRQ,
730 }, 926 },
731}; 927};
@@ -768,7 +964,15 @@ static struct resource sdhi2_resources[] = {
768 .flags = IORESOURCE_MEM, 964 .flags = IORESOURCE_MEM,
769 }, 965 },
770 [1] = { 966 [1] = {
771 .start = evt2irq(0x1200), 967 .start = evt2irq(0x1200), /* SDHI2_SDHI2I0 */
968 .flags = IORESOURCE_IRQ,
969 },
970 [2] = {
971 .start = evt2irq(0x1220), /* SDHI2_SDHI2I1 */
972 .flags = IORESOURCE_IRQ,
973 },
974 [3] = {
975 .start = evt2irq(0x1240), /* SDHI2_SDHI2I2 */
772 .flags = IORESOURCE_IRQ, 976 .flags = IORESOURCE_IRQ,
773 }, 977 },
774}; 978};
@@ -803,6 +1007,15 @@ static struct resource sh_mmcif_resources[] = {
803 }, 1007 },
804}; 1008};
805 1009
1010static struct sh_mmcif_dma sh_mmcif_dma = {
1011 .chan_priv_rx = {
1012 .slave_id = SHDMA_SLAVE_MMCIF_RX,
1013 },
1014 .chan_priv_tx = {
1015 .slave_id = SHDMA_SLAVE_MMCIF_TX,
1016 },
1017};
1018
806static struct sh_mmcif_plat_data sh_mmcif_plat = { 1019static struct sh_mmcif_plat_data sh_mmcif_plat = {
807 .sup_pclk = 0, 1020 .sup_pclk = 0,
808 .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 1021 .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -810,6 +1023,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
810 MMC_CAP_8_BIT_DATA | 1023 MMC_CAP_8_BIT_DATA |
811 MMC_CAP_NEEDS_POLL, 1024 MMC_CAP_NEEDS_POLL,
812 .get_cd = slot_cn7_get_cd, 1025 .get_cd = slot_cn7_get_cd,
1026 .dma = &sh_mmcif_dma,
813}; 1027};
814 1028
815static struct platform_device sh_mmcif_device = { 1029static struct platform_device sh_mmcif_device = {
@@ -858,37 +1072,23 @@ static struct soc_camera_link camera_link = {
858 .priv = &camera_info, 1072 .priv = &camera_info,
859}; 1073};
860 1074
861static void dummy_release(struct device *dev) 1075static struct platform_device *camera_device;
1076
1077static void mackerel_camera_release(struct device *dev)
862{ 1078{
1079 soc_camera_platform_release(&camera_device);
863} 1080}
864 1081
865static struct platform_device camera_device = {
866 .name = "soc_camera_platform",
867 .dev = {
868 .platform_data = &camera_info,
869 .release = dummy_release,
870 },
871};
872
873static int mackerel_camera_add(struct soc_camera_link *icl, 1082static int mackerel_camera_add(struct soc_camera_link *icl,
874 struct device *dev) 1083 struct device *dev)
875{ 1084{
876 if (icl != &camera_link) 1085 return soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
877 return -ENODEV; 1086 mackerel_camera_release, 0);
878
879 camera_info.dev = dev;
880
881 return platform_device_register(&camera_device);
882} 1087}
883 1088
884static void mackerel_camera_del(struct soc_camera_link *icl) 1089static void mackerel_camera_del(struct soc_camera_link *icl)
885{ 1090{
886 if (icl != &camera_link) 1091 soc_camera_platform_del(icl, camera_device, &camera_link);
887 return;
888
889 platform_device_unregister(&camera_device);
890 memset(&camera_device.dev.kobj, 0,
891 sizeof(camera_device.dev.kobj));
892} 1092}
893 1093
894static struct sh_mobile_ceu_info sh_mobile_ceu_info = { 1094static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
@@ -935,12 +1135,13 @@ static struct platform_device *mackerel_devices[] __initdata = {
935 &smc911x_device, 1135 &smc911x_device,
936 &lcdc_device, 1136 &lcdc_device,
937 &usb1_host_device, 1137 &usb1_host_device,
1138 &usbhs1_device,
938 &leds_device, 1139 &leds_device,
939 &fsi_device, 1140 &fsi_device,
940 &fsi_ak4643_device, 1141 &fsi_ak4643_device,
941 &fsi_hdmi_device, 1142 &fsi_hdmi_device,
942 &sdhi0_device, 1143 &sdhi0_device,
943#if !defined(CONFIG_MMC_SH_MMCIF) 1144#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
944 &sdhi1_device, 1145 &sdhi1_device,
945#endif 1146#endif
946 &sdhi2_device, 1147 &sdhi2_device,
@@ -1030,6 +1231,7 @@ static void __init mackerel_map_io(void)
1030 1231
1031#define GPIO_PORT9CR 0xE6051009 1232#define GPIO_PORT9CR 0xE6051009
1032#define GPIO_PORT10CR 0xE605100A 1233#define GPIO_PORT10CR 0xE605100A
1234#define GPIO_PORT168CR 0xE60520A8
1033#define SRCR4 0xe61580bc 1235#define SRCR4 0xe61580bc
1034#define USCCR1 0xE6058144 1236#define USCCR1 0xE6058144
1035static void __init mackerel_init(void) 1237static void __init mackerel_init(void)
@@ -1088,6 +1290,7 @@ static void __init mackerel_init(void)
1088 gpio_request(GPIO_FN_OVCN_1_114, NULL); 1290 gpio_request(GPIO_FN_OVCN_1_114, NULL);
1089 gpio_request(GPIO_FN_EXTLP_1, NULL); 1291 gpio_request(GPIO_FN_EXTLP_1, NULL);
1090 gpio_request(GPIO_FN_OVCN2_1, NULL); 1292 gpio_request(GPIO_FN_OVCN2_1, NULL);
1293 gpio_pull_down(GPIO_PORT168CR);
1091 1294
1092 /* setup USB phy */ 1295 /* setup USB phy */
1093 __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */ 1296 __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
@@ -1140,7 +1343,7 @@ static void __init mackerel_init(void)
1140 gpio_request(GPIO_FN_SDHID0_1, NULL); 1343 gpio_request(GPIO_FN_SDHID0_1, NULL);
1141 gpio_request(GPIO_FN_SDHID0_0, NULL); 1344 gpio_request(GPIO_FN_SDHID0_0, NULL);
1142 1345
1143#if !defined(CONFIG_MMC_SH_MMCIF) 1346#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
1144 /* enable SDHI1 */ 1347 /* enable SDHI1 */
1145 gpio_request(GPIO_FN_SDHICMD1, NULL); 1348 gpio_request(GPIO_FN_SDHICMD1, NULL);
1146 gpio_request(GPIO_FN_SDHICLK1, NULL); 1349 gpio_request(GPIO_FN_SDHICLK1, NULL);
@@ -1216,6 +1419,7 @@ static void __init mackerel_init(void)
1216 platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); 1419 platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
1217 1420
1218 hdmi_init_pm_clock(); 1421 hdmi_init_pm_clock();
1422 sh7372_pm_init();
1219} 1423}
1220 1424
1221static void __init mackerel_timer_init(void) 1425static void __init mackerel_timer_init(void)
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index e9731b5a73ed..d17eb66f4ac2 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -44,6 +44,11 @@
44#define DSI1PCKCR 0xe6150098 44#define DSI1PCKCR 0xe6150098
45#define PLLC01CR 0xe6150028 45#define PLLC01CR 0xe6150028
46#define PLLC2CR 0xe615002c 46#define PLLC2CR 0xe615002c
47#define RMSTPCR0 0xe6150110
48#define RMSTPCR1 0xe6150114
49#define RMSTPCR2 0xe6150118
50#define RMSTPCR3 0xe615011c
51#define RMSTPCR4 0xe6150120
47#define SMSTPCR0 0xe6150130 52#define SMSTPCR0 0xe6150130
48#define SMSTPCR1 0xe6150134 53#define SMSTPCR1 0xe6150134
49#define SMSTPCR2 0xe6150138 54#define SMSTPCR2 0xe6150138
@@ -421,9 +426,6 @@ static unsigned long fsidiv_recalc(struct clk *clk)
421 426
422 value = __raw_readl(clk->mapping->base); 427 value = __raw_readl(clk->mapping->base);
423 428
424 if ((value & 0x3) != 0x3)
425 return 0;
426
427 value >>= 16; 429 value >>= 16;
428 if (value < 2) 430 if (value < 2)
429 return 0; 431 return 0;
@@ -504,7 +506,7 @@ static struct clk *late_main_clks[] = {
504enum { MSTP001, 506enum { MSTP001,
505 MSTP131, MSTP130, 507 MSTP131, MSTP130,
506 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, 508 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
507 MSTP118, MSTP117, MSTP116, 509 MSTP118, MSTP117, MSTP116, MSTP113,
508 MSTP106, MSTP101, MSTP100, 510 MSTP106, MSTP101, MSTP100,
509 MSTP223, 511 MSTP223,
510 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, 512 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
@@ -527,6 +529,7 @@ static struct clk mstp_clks[MSTP_NR] = {
527 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ 529 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
528 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ 530 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
529 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ 531 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
532 [MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
530 [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ 533 [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
531 [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ 534 [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
532 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ 535 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
@@ -617,6 +620,7 @@ static struct clk_lookup lookups[] = {
617 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ 620 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
618 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ 621 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
619 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ 622 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
623 CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
620 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ 624 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
621 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ 625 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
622 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ 626 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
@@ -634,6 +638,7 @@ static struct clk_lookup lookups[] = {
634 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 638 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
635 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ 639 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
636 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ 640 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
641 CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
637 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ 642 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
638 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 643 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
639 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ 644 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
@@ -644,6 +649,7 @@ static struct clk_lookup lookups[] = {
644 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ 649 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
645 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ 650 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
646 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ 651 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
652 CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
647 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 653 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
648 654
649 CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), 655 CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
@@ -655,6 +661,13 @@ void __init sh7372_clock_init(void)
655{ 661{
656 int k, ret = 0; 662 int k, ret = 0;
657 663
664 /* make sure MSTP bits on the RT/SH4AL-DSP side are off */
665 __raw_writel(0xe4ef8087, RMSTPCR0);
666 __raw_writel(0xffffffff, RMSTPCR1);
667 __raw_writel(0x37c7f7ff, RMSTPCR2);
668 __raw_writel(0xffffffff, RMSTPCR3);
669 __raw_writel(0xffe0fffd, RMSTPCR4);
670
658 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) 671 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
659 ret = clk_register(main_clks[k]); 672 ret = clk_register(main_clks[k]);
660 673
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 7e58904c1c8c..bcacb1e8cf85 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -266,7 +266,8 @@ enum { MSTP001,
266 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, 266 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
267 MSTP219, 267 MSTP219,
268 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, 268 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
269 MSTP331, MSTP329, MSTP325, MSTP323, MSTP312, 269 MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
270 MSTP314, MSTP313, MSTP312, MSTP311,
270 MSTP411, MSTP410, MSTP403, 271 MSTP411, MSTP410, MSTP403,
271 MSTP_NR }; 272 MSTP_NR };
272 273
@@ -295,7 +296,11 @@ static struct clk mstp_clks[MSTP_NR] = {
295 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ 296 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
296 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ 297 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
297 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ 298 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
299 [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
300 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
301 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
298 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ 302 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
303 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
299 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */ 304 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
300 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */ 305 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
301 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ 306 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
@@ -313,6 +318,9 @@ static struct clk_lookup lookups[] = {
313 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), 318 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
314 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), 319 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
315 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), 320 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
321 CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
322 CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
323 CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
316 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), 324 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
317 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), 325 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
318 CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), 326 CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
@@ -341,7 +349,11 @@ static struct clk_lookup lookups[] = {
341 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ 349 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
342 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ 350 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
343 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ 351 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
352 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
353 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
354 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
344 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ 355 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
356 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
345 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ 357 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
346 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ 358 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
347 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 359 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
@@ -351,6 +363,11 @@ void __init sh73a0_clock_init(void)
351{ 363{
352 int k, ret = 0; 364 int k, ret = 0;
353 365
366 /* Set SDHI clocks to a known state */
367 __raw_writel(0x108, SD0CKCR);
368 __raw_writel(0x108, SD1CKCR);
369 __raw_writel(0x108, SD2CKCR);
370
354 /* detect main clock parent */ 371 /* detect main clock parent */
355 switch ((__raw_readl(CKSCR) >> 24) & 0x03) { 372 switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
356 case 0: 373 case 0:
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
new file mode 100644
index 000000000000..2e44f11f592e
--- /dev/null
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -0,0 +1,92 @@
1/*
2 * CPUIdle support code for SH-Mobile ARM
3 *
4 * Copyright (C) 2011 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/pm.h>
12#include <linux/cpuidle.h>
13#include <linux/suspend.h>
14#include <linux/module.h>
15#include <linux/err.h>
16#include <asm/system.h>
17#include <asm/io.h>
18
19static void shmobile_enter_wfi(void)
20{
21 cpu_do_idle();
22}
23
24void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
25 shmobile_enter_wfi, /* regular sleep mode */
26};
27
28static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
29 struct cpuidle_state *state)
30{
31 ktime_t before, after;
32 int requested_state = state - &dev->states[0];
33
34 dev->last_state = &dev->states[requested_state];
35 before = ktime_get();
36
37 local_irq_disable();
38 local_fiq_disable();
39
40 shmobile_cpuidle_modes[requested_state]();
41
42 local_irq_enable();
43 local_fiq_enable();
44
45 after = ktime_get();
46 return ktime_to_ns(ktime_sub(after, before)) >> 10;
47}
48
49static struct cpuidle_device shmobile_cpuidle_dev;
50static struct cpuidle_driver shmobile_cpuidle_driver = {
51 .name = "shmobile_cpuidle",
52 .owner = THIS_MODULE,
53};
54
55void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
56
57static int shmobile_cpuidle_init(void)
58{
59 struct cpuidle_device *dev = &shmobile_cpuidle_dev;
60 struct cpuidle_state *state;
61 int i;
62
63 cpuidle_register_driver(&shmobile_cpuidle_driver);
64
65 for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
66 dev->states[i].name[0] = '\0';
67 dev->states[i].desc[0] = '\0';
68 dev->states[i].enter = shmobile_cpuidle_enter;
69 }
70
71 i = CPUIDLE_DRIVER_STATE_START;
72
73 state = &dev->states[i++];
74 snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
75 strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
76 state->exit_latency = 1;
77 state->target_residency = 1 * 2;
78 state->power_usage = 3;
79 state->flags = 0;
80 state->flags |= CPUIDLE_FLAG_TIME_VALID;
81
82 dev->safe_state = state;
83 dev->state_count = i;
84
85 if (shmobile_cpuidle_setup)
86 shmobile_cpuidle_setup(dev);
87
88 cpuidle_register_device(dev);
89
90 return 0;
91}
92late_initcall(shmobile_cpuidle_init);
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index d4cec6b4c7d9..26079d933d91 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -24,4 +24,4 @@
24 .align 12 24 .align 12
25ENTRY(shmobile_secondary_vector) 25ENTRY(shmobile_secondary_vector)
26 ldr pc, 1f 26 ldr pc, 1f
271: .long secondary_startup - PAGE_OFFSET + PHYS_OFFSET 271: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 013ac0ee8256..06aecb31d9c7 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -8,6 +8,10 @@ struct clk;
8extern int clk_init(void); 8extern int clk_init(void);
9extern void shmobile_handle_irq_intc(struct pt_regs *); 9extern void shmobile_handle_irq_intc(struct pt_regs *);
10extern void shmobile_handle_irq_gic(struct pt_regs *); 10extern void shmobile_handle_irq_gic(struct pt_regs *);
11extern struct platform_suspend_ops shmobile_suspend_ops;
12struct cpuidle_device;
13extern void (*shmobile_cpuidle_modes[])(void);
14extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
11 15
12extern void sh7367_init_irq(void); 16extern void sh7367_init_irq(void);
13extern void sh7367_add_early_devices(void); 17extern void sh7367_add_early_devices(void);
@@ -30,6 +34,9 @@ extern void sh7372_add_early_devices(void);
30extern void sh7372_add_standard_devices(void); 34extern void sh7372_add_standard_devices(void);
31extern void sh7372_clock_init(void); 35extern void sh7372_clock_init(void);
32extern void sh7372_pinmux_init(void); 36extern void sh7372_pinmux_init(void);
37extern void sh7372_pm_init(void);
38extern void sh7372_cpu_suspend(void);
39extern void sh7372_cpu_resume(void);
33extern struct clk sh7372_extal1_clk; 40extern struct clk sh7372_extal1_clk;
34extern struct clk sh7372_extal2_clk; 41extern struct clk sh7372_extal2_clk;
35 42
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
index 3029aba38688..9f134dfeffdc 100644
--- a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
+++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
@@ -87,8 +87,7 @@ WAIT 1, 0xFE40009C
87ED 0xFE400354, 0x01AD8002 87ED 0xFE400354, 0x01AD8002
88 88
89LIST "SCIF0 - Serial port for earlyprintk" 89LIST "SCIF0 - Serial port for earlyprintk"
90EB 0xE6053098, 0x11
91EB 0xE6053098, 0xe1 90EB 0xE6053098, 0xe1
92EW 0xE6C40000, 0x0000 91EW 0xE6C40000, 0x0000
93EB 0xE6C40004, 0x19 92EB 0xE6C40004, 0x19
94EW 0xE6C40008, 0x3000 93EW 0xE6C40008, 0x0030
diff --git a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
index 3029aba38688..9f134dfeffdc 100644
--- a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
+++ b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
@@ -87,8 +87,7 @@ WAIT 1, 0xFE40009C
87ED 0xFE400354, 0x01AD8002 87ED 0xFE400354, 0x01AD8002
88 88
89LIST "SCIF0 - Serial port for earlyprintk" 89LIST "SCIF0 - Serial port for earlyprintk"
90EB 0xE6053098, 0x11
91EB 0xE6053098, 0xe1 90EB 0xE6053098, 0xe1
92EW 0xE6C40000, 0x0000 91EW 0xE6C40000, 0x0000
93EB 0xE6C40004, 0x19 92EB 0xE6C40004, 0x19
94EW 0xE6C40008, 0x3000 93EW 0xE6C40008, 0x0030
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 5736efcca60c..df20d7670172 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -435,6 +435,7 @@ enum {
435 435
436/* DMA slave IDs */ 436/* DMA slave IDs */
437enum { 437enum {
438 SHDMA_SLAVE_INVALID,
438 SHDMA_SLAVE_SCIF0_TX, 439 SHDMA_SLAVE_SCIF0_TX,
439 SHDMA_SLAVE_SCIF0_RX, 440 SHDMA_SLAVE_SCIF0_RX,
440 SHDMA_SLAVE_SCIF1_TX, 441 SHDMA_SLAVE_SCIF1_TX,
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index ceb2cdc92bf9..216c3d695ef1 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -463,5 +463,35 @@ enum {
463 GPIO_FN_FSIAIBT_PU, 463 GPIO_FN_FSIAIBT_PU,
464 GPIO_FN_FSIAISLD_PU, 464 GPIO_FN_FSIAISLD_PU,
465}; 465};
466/* DMA slave IDs */
467enum {
468 SHDMA_SLAVE_INVALID,
469 SHDMA_SLAVE_SCIF0_TX,
470 SHDMA_SLAVE_SCIF0_RX,
471 SHDMA_SLAVE_SCIF1_TX,
472 SHDMA_SLAVE_SCIF1_RX,
473 SHDMA_SLAVE_SCIF2_TX,
474 SHDMA_SLAVE_SCIF2_RX,
475 SHDMA_SLAVE_SCIF3_TX,
476 SHDMA_SLAVE_SCIF3_RX,
477 SHDMA_SLAVE_SCIF4_TX,
478 SHDMA_SLAVE_SCIF4_RX,
479 SHDMA_SLAVE_SCIF5_TX,
480 SHDMA_SLAVE_SCIF5_RX,
481 SHDMA_SLAVE_SCIF6_TX,
482 SHDMA_SLAVE_SCIF6_RX,
483 SHDMA_SLAVE_SCIF7_TX,
484 SHDMA_SLAVE_SCIF7_RX,
485 SHDMA_SLAVE_SCIF8_TX,
486 SHDMA_SLAVE_SCIF8_RX,
487 SHDMA_SLAVE_SDHI0_TX,
488 SHDMA_SLAVE_SDHI0_RX,
489 SHDMA_SLAVE_SDHI1_TX,
490 SHDMA_SLAVE_SDHI1_RX,
491 SHDMA_SLAVE_SDHI2_TX,
492 SHDMA_SLAVE_SDHI2_RX,
493 SHDMA_SLAVE_MMCIF_TX,
494 SHDMA_SLAVE_MMCIF_RX,
495};
466 496
467#endif /* __ASM_SH73A0_H__ */ 497#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 7a4960f9c1e3..3b28743c77eb 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -27,8 +27,6 @@
27 27
28enum { 28enum {
29 UNUSED_INTCA = 0, 29 UNUSED_INTCA = 0,
30 ENABLED,
31 DISABLED,
32 30
33 /* interrupt sources INTCA */ 31 /* interrupt sources INTCA */
34 IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A, 32 IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
@@ -49,14 +47,14 @@ enum {
49 MSIOF2, MSIOF1, 47 MSIOF2, MSIOF1,
50 SCIFA4, SCIFA5, SCIFB, 48 SCIFA4, SCIFA5, SCIFB,
51 FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, 49 FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
52 SDHI0, 50 SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
53 SDHI1, 51 SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2,
54 IRREM, 52 IRREM,
55 IRDA, 53 IRDA,
56 TPU0, 54 TPU0,
57 TTI20, 55 TTI20,
58 DDM, 56 DDM,
59 SDHI2, 57 SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
60 RWDT0, 58 RWDT0,
61 DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3, 59 DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
62 DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR, 60 DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
@@ -84,7 +82,7 @@ enum {
84 82
85 /* interrupt groups INTCA */ 83 /* interrupt groups INTCA */
86 DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT, 84 DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
87 AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1 85 AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2
88}; 86};
89 87
90static struct intc_vect intca_vectors[] __initdata = { 88static struct intc_vect intca_vectors[] __initdata = {
@@ -125,17 +123,17 @@ static struct intc_vect intca_vectors[] __initdata = {
125 INTC_VECT(SCIFB, 0x0d60), 123 INTC_VECT(SCIFB, 0x0d60),
126 INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0), 124 INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
127 INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0), 125 INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
128 INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20), 126 INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
129 INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60), 127 INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
130 INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0), 128 INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
131 INTC_VECT(SDHI1, 0x0ec0), 129 INTC_VECT(SDHI1_SDHI1I2, 0x0ec0),
132 INTC_VECT(IRREM, 0x0f60), 130 INTC_VECT(IRREM, 0x0f60),
133 INTC_VECT(IRDA, 0x0480), 131 INTC_VECT(IRDA, 0x0480),
134 INTC_VECT(TPU0, 0x04a0), 132 INTC_VECT(TPU0, 0x04a0),
135 INTC_VECT(TTI20, 0x1100), 133 INTC_VECT(TTI20, 0x1100),
136 INTC_VECT(DDM, 0x1140), 134 INTC_VECT(DDM, 0x1140),
137 INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220), 135 INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
138 INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260), 136 INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260),
139 INTC_VECT(RWDT0, 0x1280), 137 INTC_VECT(RWDT0, 0x1280),
140 INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020), 138 INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
141 INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060), 139 INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
@@ -195,6 +193,12 @@ static struct intc_group intca_groups[] __initdata = {
195 INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, 193 INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
196 FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), 194 FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
197 INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), 195 INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
196 INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
197 SDHI0_SDHI0I2, SDHI0_SDHI0I3),
198 INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
199 SDHI1_SDHI1I2),
200 INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
201 SDHI2_SDHI2I2, SDHI2_SDHI2I3),
198 INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM), 202 INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
199}; 203};
200 204
@@ -230,10 +234,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
230 { SCIFB, SCIFA5, SCIFA4, MSIOF1, 234 { SCIFB, SCIFA5, SCIFA4, MSIOF1,
231 0, 0, MSIOF2, 0 } }, 235 0, 0, MSIOF2, 0 } },
232 { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ 236 { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
233 { DISABLED, ENABLED, ENABLED, ENABLED, 237 { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
234 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, 238 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
235 { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ 239 { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
236 { 0, ENABLED, ENABLED, ENABLED, 240 { 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
237 TTI20, USBHSDMAC0_USHDMI, 0, 0 } }, 241 TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
238 { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ 242 { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
239 { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, 243 { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
@@ -248,7 +252,7 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
248 { 0, 0, TPU0, 0, 252 { 0, 0, TPU0, 0,
249 0, 0, 0, 0 } }, 253 0, 0, 0, 0 } },
250 { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */ 254 { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
251 { DISABLED, DISABLED, ENABLED, ENABLED, 255 { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
252 0, CMT3, 0, RWDT0 } }, 256 0, CMT3, 0, RWDT0 } },
253 { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */ 257 { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
254 { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0, 258 { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
@@ -354,14 +358,10 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = {
354 { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } }, 358 { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
355}; 359};
356 360
357static struct intc_desc intca_desc __initdata = { 361static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
358 .name = "sh7372-intca", 362 intca_vectors, intca_groups,
359 .force_enable = ENABLED, 363 intca_mask_registers, intca_prio_registers,
360 .force_disable = DISABLED, 364 intca_sense_registers, intca_ack_registers);
361 .hw = INTC_HW_DESC(intca_vectors, intca_groups,
362 intca_mask_registers, intca_prio_registers,
363 intca_sense_registers, intca_ack_registers),
364};
365 365
366enum { 366enum {
367 UNUSED_INTCS = 0, 367 UNUSED_INTCS = 0,
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
new file mode 100644
index 000000000000..8e4aadf14c9f
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -0,0 +1,108 @@
1/*
2 * sh7372 Power management support
3 *
4 * Copyright (C) 2011 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/pm.h>
12#include <linux/suspend.h>
13#include <linux/cpuidle.h>
14#include <linux/module.h>
15#include <linux/list.h>
16#include <linux/err.h>
17#include <linux/slab.h>
18#include <asm/system.h>
19#include <asm/io.h>
20#include <asm/tlbflush.h>
21#include <mach/common.h>
22
23#define SMFRAM 0xe6a70000
24#define SYSTBCR 0xe6150024
25#define SBAR 0xe6180020
26#define APARMBAREA 0xe6f10020
27
28static void sh7372_enter_core_standby(void)
29{
30 void __iomem *smfram = (void __iomem *)SMFRAM;
31
32 __raw_writel(0, APARMBAREA); /* translate 4k */
33 __raw_writel(__pa(sh7372_cpu_resume), SBAR); /* set reset vector */
34 __raw_writel(0x10, SYSTBCR); /* enable core standby */
35
36 __raw_writel(0, smfram + 0x3c); /* clear page table address */
37
38 sh7372_cpu_suspend();
39 cpu_init();
40
41 /* if page table address is non-NULL then we have been powered down */
42 if (__raw_readl(smfram + 0x3c)) {
43 __raw_writel(__raw_readl(smfram + 0x40),
44 __va(__raw_readl(smfram + 0x3c)));
45
46 flush_tlb_all();
47 set_cr(__raw_readl(smfram + 0x38));
48 }
49
50 __raw_writel(0, SYSTBCR); /* disable core standby */
51 __raw_writel(0, SBAR); /* disable reset vector translation */
52}
53
54#ifdef CONFIG_CPU_IDLE
55static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
56{
57 struct cpuidle_state *state;
58 int i = dev->state_count;
59
60 state = &dev->states[i];
61 snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
62 strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
63 state->exit_latency = 10;
64 state->target_residency = 20 + 10;
65 state->power_usage = 1; /* perhaps not */
66 state->flags = 0;
67 state->flags |= CPUIDLE_FLAG_TIME_VALID;
68 shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
69
70 dev->state_count = i + 1;
71}
72
73static void sh7372_cpuidle_init(void)
74{
75 shmobile_cpuidle_setup = sh7372_cpuidle_setup;
76}
77#else
78static void sh7372_cpuidle_init(void) {}
79#endif
80
81#ifdef CONFIG_SUSPEND
82static int sh7372_enter_suspend(suspend_state_t suspend_state)
83{
84 sh7372_enter_core_standby();
85 return 0;
86}
87
88static void sh7372_suspend_init(void)
89{
90 shmobile_suspend_ops.enter = sh7372_enter_suspend;
91}
92#else
93static void sh7372_suspend_init(void) {}
94#endif
95
96#define DBGREG1 0xe6100020
97#define DBGREG9 0xe6100040
98
99void __init sh7372_pm_init(void)
100{
101 /* enable DBG hardware block to kick SYSC */
102 __raw_writel(0x0000a500, DBGREG9);
103 __raw_writel(0x0000a501, DBGREG9);
104 __raw_writel(0x00000000, DBGREG1);
105
106 sh7372_suspend_init();
107 sh7372_cpuidle_init();
108}
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index ce28141662da..2c10190dbb55 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/uio_driver.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/input.h> 27#include <linux/input.h>
27#include <linux/io.h> 28#include <linux/io.h>
@@ -195,6 +196,214 @@ static struct platform_device cmt10_device = {
195 .num_resources = ARRAY_SIZE(cmt10_resources), 196 .num_resources = ARRAY_SIZE(cmt10_resources),
196}; 197};
197 198
199/* VPU */
200static struct uio_info vpu_platform_data = {
201 .name = "VPU5",
202 .version = "0",
203 .irq = intcs_evt2irq(0x980),
204};
205
206static struct resource vpu_resources[] = {
207 [0] = {
208 .name = "VPU",
209 .start = 0xfe900000,
210 .end = 0xfe902807,
211 .flags = IORESOURCE_MEM,
212 },
213};
214
215static struct platform_device vpu_device = {
216 .name = "uio_pdrv_genirq",
217 .id = 0,
218 .dev = {
219 .platform_data = &vpu_platform_data,
220 },
221 .resource = vpu_resources,
222 .num_resources = ARRAY_SIZE(vpu_resources),
223};
224
225/* VEU0 */
226static struct uio_info veu0_platform_data = {
227 .name = "VEU0",
228 .version = "0",
229 .irq = intcs_evt2irq(0x700),
230};
231
232static struct resource veu0_resources[] = {
233 [0] = {
234 .name = "VEU0",
235 .start = 0xfe920000,
236 .end = 0xfe9200b7,
237 .flags = IORESOURCE_MEM,
238 },
239};
240
241static struct platform_device veu0_device = {
242 .name = "uio_pdrv_genirq",
243 .id = 1,
244 .dev = {
245 .platform_data = &veu0_platform_data,
246 },
247 .resource = veu0_resources,
248 .num_resources = ARRAY_SIZE(veu0_resources),
249};
250
251/* VEU1 */
252static struct uio_info veu1_platform_data = {
253 .name = "VEU1",
254 .version = "0",
255 .irq = intcs_evt2irq(0x720),
256};
257
258static struct resource veu1_resources[] = {
259 [0] = {
260 .name = "VEU1",
261 .start = 0xfe924000,
262 .end = 0xfe9240b7,
263 .flags = IORESOURCE_MEM,
264 },
265};
266
267static struct platform_device veu1_device = {
268 .name = "uio_pdrv_genirq",
269 .id = 2,
270 .dev = {
271 .platform_data = &veu1_platform_data,
272 },
273 .resource = veu1_resources,
274 .num_resources = ARRAY_SIZE(veu1_resources),
275};
276
277/* VEU2 */
278static struct uio_info veu2_platform_data = {
279 .name = "VEU2",
280 .version = "0",
281 .irq = intcs_evt2irq(0x740),
282};
283
284static struct resource veu2_resources[] = {
285 [0] = {
286 .name = "VEU2",
287 .start = 0xfe928000,
288 .end = 0xfe9280b7,
289 .flags = IORESOURCE_MEM,
290 },
291};
292
293static struct platform_device veu2_device = {
294 .name = "uio_pdrv_genirq",
295 .id = 3,
296 .dev = {
297 .platform_data = &veu2_platform_data,
298 },
299 .resource = veu2_resources,
300 .num_resources = ARRAY_SIZE(veu2_resources),
301};
302
303/* VEU3 */
304static struct uio_info veu3_platform_data = {
305 .name = "VEU3",
306 .version = "0",
307 .irq = intcs_evt2irq(0x760),
308};
309
310static struct resource veu3_resources[] = {
311 [0] = {
312 .name = "VEU3",
313 .start = 0xfe92c000,
314 .end = 0xfe92c0b7,
315 .flags = IORESOURCE_MEM,
316 },
317};
318
319static struct platform_device veu3_device = {
320 .name = "uio_pdrv_genirq",
321 .id = 4,
322 .dev = {
323 .platform_data = &veu3_platform_data,
324 },
325 .resource = veu3_resources,
326 .num_resources = ARRAY_SIZE(veu3_resources),
327};
328
329/* VEU2H */
330static struct uio_info veu2h_platform_data = {
331 .name = "VEU2H",
332 .version = "0",
333 .irq = intcs_evt2irq(0x520),
334};
335
336static struct resource veu2h_resources[] = {
337 [0] = {
338 .name = "VEU2H",
339 .start = 0xfe93c000,
340 .end = 0xfe93c27b,
341 .flags = IORESOURCE_MEM,
342 },
343};
344
345static struct platform_device veu2h_device = {
346 .name = "uio_pdrv_genirq",
347 .id = 5,
348 .dev = {
349 .platform_data = &veu2h_platform_data,
350 },
351 .resource = veu2h_resources,
352 .num_resources = ARRAY_SIZE(veu2h_resources),
353};
354
355/* JPU */
356static struct uio_info jpu_platform_data = {
357 .name = "JPU",
358 .version = "0",
359 .irq = intcs_evt2irq(0x560),
360};
361
362static struct resource jpu_resources[] = {
363 [0] = {
364 .name = "JPU",
365 .start = 0xfe980000,
366 .end = 0xfe9902d3,
367 .flags = IORESOURCE_MEM,
368 },
369};
370
371static struct platform_device jpu_device = {
372 .name = "uio_pdrv_genirq",
373 .id = 6,
374 .dev = {
375 .platform_data = &jpu_platform_data,
376 },
377 .resource = jpu_resources,
378 .num_resources = ARRAY_SIZE(jpu_resources),
379};
380
381/* SPU1 */
382static struct uio_info spu1_platform_data = {
383 .name = "SPU1",
384 .version = "0",
385 .irq = evt2irq(0xfc0),
386};
387
388static struct resource spu1_resources[] = {
389 [0] = {
390 .name = "SPU1",
391 .start = 0xfe300000,
392 .end = 0xfe3fffff,
393 .flags = IORESOURCE_MEM,
394 },
395};
396
397static struct platform_device spu1_device = {
398 .name = "uio_pdrv_genirq",
399 .id = 7,
400 .dev = {
401 .platform_data = &spu1_platform_data,
402 },
403 .resource = spu1_resources,
404 .num_resources = ARRAY_SIZE(spu1_resources),
405};
406
198static struct platform_device *sh7367_early_devices[] __initdata = { 407static struct platform_device *sh7367_early_devices[] __initdata = {
199 &scif0_device, 408 &scif0_device,
200 &scif1_device, 409 &scif1_device,
@@ -206,10 +415,24 @@ static struct platform_device *sh7367_early_devices[] __initdata = {
206 &cmt10_device, 415 &cmt10_device,
207}; 416};
208 417
418static struct platform_device *sh7367_devices[] __initdata = {
419 &vpu_device,
420 &veu0_device,
421 &veu1_device,
422 &veu2_device,
423 &veu3_device,
424 &veu2h_device,
425 &jpu_device,
426 &spu1_device,
427};
428
209void __init sh7367_add_standard_devices(void) 429void __init sh7367_add_standard_devices(void)
210{ 430{
211 platform_add_devices(sh7367_early_devices, 431 platform_add_devices(sh7367_early_devices,
212 ARRAY_SIZE(sh7367_early_devices)); 432 ARRAY_SIZE(sh7367_early_devices));
433
434 platform_add_devices(sh7367_devices,
435 ARRAY_SIZE(sh7367_devices));
213} 436}
214 437
215#define SYMSTPCR2 0xe6158048 438#define SYMSTPCR2 0xe6158048
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index ff0494f3d00c..cd807eea69e2 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/uio_driver.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/input.h> 27#include <linux/input.h>
27#include <linux/io.h> 28#include <linux/io.h>
@@ -601,6 +602,214 @@ static struct platform_device dma2_device = {
601 }, 602 },
602}; 603};
603 604
605/* VPU */
606static struct uio_info vpu_platform_data = {
607 .name = "VPU5HG",
608 .version = "0",
609 .irq = intcs_evt2irq(0x980),
610};
611
612static struct resource vpu_resources[] = {
613 [0] = {
614 .name = "VPU",
615 .start = 0xfe900000,
616 .end = 0xfe900157,
617 .flags = IORESOURCE_MEM,
618 },
619};
620
621static struct platform_device vpu_device = {
622 .name = "uio_pdrv_genirq",
623 .id = 0,
624 .dev = {
625 .platform_data = &vpu_platform_data,
626 },
627 .resource = vpu_resources,
628 .num_resources = ARRAY_SIZE(vpu_resources),
629};
630
631/* VEU0 */
632static struct uio_info veu0_platform_data = {
633 .name = "VEU0",
634 .version = "0",
635 .irq = intcs_evt2irq(0x700),
636};
637
638static struct resource veu0_resources[] = {
639 [0] = {
640 .name = "VEU0",
641 .start = 0xfe920000,
642 .end = 0xfe9200cb,
643 .flags = IORESOURCE_MEM,
644 },
645};
646
647static struct platform_device veu0_device = {
648 .name = "uio_pdrv_genirq",
649 .id = 1,
650 .dev = {
651 .platform_data = &veu0_platform_data,
652 },
653 .resource = veu0_resources,
654 .num_resources = ARRAY_SIZE(veu0_resources),
655};
656
657/* VEU1 */
658static struct uio_info veu1_platform_data = {
659 .name = "VEU1",
660 .version = "0",
661 .irq = intcs_evt2irq(0x720),
662};
663
664static struct resource veu1_resources[] = {
665 [0] = {
666 .name = "VEU1",
667 .start = 0xfe924000,
668 .end = 0xfe9240cb,
669 .flags = IORESOURCE_MEM,
670 },
671};
672
673static struct platform_device veu1_device = {
674 .name = "uio_pdrv_genirq",
675 .id = 2,
676 .dev = {
677 .platform_data = &veu1_platform_data,
678 },
679 .resource = veu1_resources,
680 .num_resources = ARRAY_SIZE(veu1_resources),
681};
682
683/* VEU2 */
684static struct uio_info veu2_platform_data = {
685 .name = "VEU2",
686 .version = "0",
687 .irq = intcs_evt2irq(0x740),
688};
689
690static struct resource veu2_resources[] = {
691 [0] = {
692 .name = "VEU2",
693 .start = 0xfe928000,
694 .end = 0xfe928307,
695 .flags = IORESOURCE_MEM,
696 },
697};
698
699static struct platform_device veu2_device = {
700 .name = "uio_pdrv_genirq",
701 .id = 3,
702 .dev = {
703 .platform_data = &veu2_platform_data,
704 },
705 .resource = veu2_resources,
706 .num_resources = ARRAY_SIZE(veu2_resources),
707};
708
709/* VEU3 */
710static struct uio_info veu3_platform_data = {
711 .name = "VEU3",
712 .version = "0",
713 .irq = intcs_evt2irq(0x760),
714};
715
716static struct resource veu3_resources[] = {
717 [0] = {
718 .name = "VEU3",
719 .start = 0xfe92c000,
720 .end = 0xfe92c307,
721 .flags = IORESOURCE_MEM,
722 },
723};
724
725static struct platform_device veu3_device = {
726 .name = "uio_pdrv_genirq",
727 .id = 4,
728 .dev = {
729 .platform_data = &veu3_platform_data,
730 },
731 .resource = veu3_resources,
732 .num_resources = ARRAY_SIZE(veu3_resources),
733};
734
735/* JPU */
736static struct uio_info jpu_platform_data = {
737 .name = "JPU",
738 .version = "0",
739 .irq = intcs_evt2irq(0x560),
740};
741
742static struct resource jpu_resources[] = {
743 [0] = {
744 .name = "JPU",
745 .start = 0xfe980000,
746 .end = 0xfe9902d3,
747 .flags = IORESOURCE_MEM,
748 },
749};
750
751static struct platform_device jpu_device = {
752 .name = "uio_pdrv_genirq",
753 .id = 5,
754 .dev = {
755 .platform_data = &jpu_platform_data,
756 },
757 .resource = jpu_resources,
758 .num_resources = ARRAY_SIZE(jpu_resources),
759};
760
761/* SPU2DSP0 */
762static struct uio_info spu0_platform_data = {
763 .name = "SPU2DSP0",
764 .version = "0",
765 .irq = evt2irq(0x1800),
766};
767
768static struct resource spu0_resources[] = {
769 [0] = {
770 .name = "SPU2DSP0",
771 .start = 0xfe200000,
772 .end = 0xfe2fffff,
773 .flags = IORESOURCE_MEM,
774 },
775};
776
777static struct platform_device spu0_device = {
778 .name = "uio_pdrv_genirq",
779 .id = 6,
780 .dev = {
781 .platform_data = &spu0_platform_data,
782 },
783 .resource = spu0_resources,
784 .num_resources = ARRAY_SIZE(spu0_resources),
785};
786
787/* SPU2DSP1 */
788static struct uio_info spu1_platform_data = {
789 .name = "SPU2DSP1",
790 .version = "0",
791 .irq = evt2irq(0x1820),
792};
793
794static struct resource spu1_resources[] = {
795 [0] = {
796 .name = "SPU2DSP1",
797 .start = 0xfe300000,
798 .end = 0xfe3fffff,
799 .flags = IORESOURCE_MEM,
800 },
801};
802
803static struct platform_device spu1_device = {
804 .name = "uio_pdrv_genirq",
805 .id = 7,
806 .dev = {
807 .platform_data = &spu1_platform_data,
808 },
809 .resource = spu1_resources,
810 .num_resources = ARRAY_SIZE(spu1_resources),
811};
812
604static struct platform_device *sh7372_early_devices[] __initdata = { 813static struct platform_device *sh7372_early_devices[] __initdata = {
605 &scif0_device, 814 &scif0_device,
606 &scif1_device, 815 &scif1_device,
@@ -620,6 +829,14 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
620 &dma0_device, 829 &dma0_device,
621 &dma1_device, 830 &dma1_device,
622 &dma2_device, 831 &dma2_device,
832 &vpu_device,
833 &veu0_device,
834 &veu1_device,
835 &veu2_device,
836 &veu3_device,
837 &jpu_device,
838 &spu0_device,
839 &spu1_device,
623}; 840};
624 841
625void __init sh7372_add_standard_devices(void) 842void __init sh7372_add_standard_devices(void)
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index 8099b0b8a934..bb405b8e459b 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/uio_driver.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/input.h> 27#include <linux/input.h>
27#include <linux/io.h> 28#include <linux/io.h>
@@ -38,7 +39,7 @@ static struct plat_sci_port scif0_platform_data = {
38 .flags = UPF_BOOT_AUTOCONF, 39 .flags = UPF_BOOT_AUTOCONF,
39 .scscr = SCSCR_RE | SCSCR_TE, 40 .scscr = SCSCR_RE | SCSCR_TE,
40 .scbrr_algo_id = SCBRR_ALGO_4, 41 .scbrr_algo_id = SCBRR_ALGO_4,
41 .type = PORT_SCIF, 42 .type = PORT_SCIFA,
42 .irqs = { evt2irq(0xc00), evt2irq(0xc00), 43 .irqs = { evt2irq(0xc00), evt2irq(0xc00),
43 evt2irq(0xc00), evt2irq(0xc00) }, 44 evt2irq(0xc00), evt2irq(0xc00) },
44}; 45};
@@ -57,7 +58,7 @@ static struct plat_sci_port scif1_platform_data = {
57 .flags = UPF_BOOT_AUTOCONF, 58 .flags = UPF_BOOT_AUTOCONF,
58 .scscr = SCSCR_RE | SCSCR_TE, 59 .scscr = SCSCR_RE | SCSCR_TE,
59 .scbrr_algo_id = SCBRR_ALGO_4, 60 .scbrr_algo_id = SCBRR_ALGO_4,
60 .type = PORT_SCIF, 61 .type = PORT_SCIFA,
61 .irqs = { evt2irq(0xc20), evt2irq(0xc20), 62 .irqs = { evt2irq(0xc20), evt2irq(0xc20),
62 evt2irq(0xc20), evt2irq(0xc20) }, 63 evt2irq(0xc20), evt2irq(0xc20) },
63}; 64};
@@ -76,7 +77,7 @@ static struct plat_sci_port scif2_platform_data = {
76 .flags = UPF_BOOT_AUTOCONF, 77 .flags = UPF_BOOT_AUTOCONF,
77 .scscr = SCSCR_RE | SCSCR_TE, 78 .scscr = SCSCR_RE | SCSCR_TE,
78 .scbrr_algo_id = SCBRR_ALGO_4, 79 .scbrr_algo_id = SCBRR_ALGO_4,
79 .type = PORT_SCIF, 80 .type = PORT_SCIFA,
80 .irqs = { evt2irq(0xc40), evt2irq(0xc40), 81 .irqs = { evt2irq(0xc40), evt2irq(0xc40),
81 evt2irq(0xc40), evt2irq(0xc40) }, 82 evt2irq(0xc40), evt2irq(0xc40) },
82}; 83};
@@ -95,7 +96,7 @@ static struct plat_sci_port scif3_platform_data = {
95 .flags = UPF_BOOT_AUTOCONF, 96 .flags = UPF_BOOT_AUTOCONF,
96 .scscr = SCSCR_RE | SCSCR_TE, 97 .scscr = SCSCR_RE | SCSCR_TE,
97 .scbrr_algo_id = SCBRR_ALGO_4, 98 .scbrr_algo_id = SCBRR_ALGO_4,
98 .type = PORT_SCIF, 99 .type = PORT_SCIFA,
99 .irqs = { evt2irq(0xc60), evt2irq(0xc60), 100 .irqs = { evt2irq(0xc60), evt2irq(0xc60),
100 evt2irq(0xc60), evt2irq(0xc60) }, 101 evt2irq(0xc60), evt2irq(0xc60) },
101}; 102};
@@ -114,7 +115,7 @@ static struct plat_sci_port scif4_platform_data = {
114 .flags = UPF_BOOT_AUTOCONF, 115 .flags = UPF_BOOT_AUTOCONF,
115 .scscr = SCSCR_RE | SCSCR_TE, 116 .scscr = SCSCR_RE | SCSCR_TE,
116 .scbrr_algo_id = SCBRR_ALGO_4, 117 .scbrr_algo_id = SCBRR_ALGO_4,
117 .type = PORT_SCIF, 118 .type = PORT_SCIFA,
118 .irqs = { evt2irq(0xd20), evt2irq(0xd20), 119 .irqs = { evt2irq(0xd20), evt2irq(0xd20),
119 evt2irq(0xd20), evt2irq(0xd20) }, 120 evt2irq(0xd20), evt2irq(0xd20) },
120}; 121};
@@ -133,7 +134,7 @@ static struct plat_sci_port scif5_platform_data = {
133 .flags = UPF_BOOT_AUTOCONF, 134 .flags = UPF_BOOT_AUTOCONF,
134 .scscr = SCSCR_RE | SCSCR_TE, 135 .scscr = SCSCR_RE | SCSCR_TE,
135 .scbrr_algo_id = SCBRR_ALGO_4, 136 .scbrr_algo_id = SCBRR_ALGO_4,
136 .type = PORT_SCIF, 137 .type = PORT_SCIFA,
137 .irqs = { evt2irq(0xd40), evt2irq(0xd40), 138 .irqs = { evt2irq(0xd40), evt2irq(0xd40),
138 evt2irq(0xd40), evt2irq(0xd40) }, 139 evt2irq(0xd40), evt2irq(0xd40) },
139}; 140};
@@ -152,7 +153,7 @@ static struct plat_sci_port scif6_platform_data = {
152 .flags = UPF_BOOT_AUTOCONF, 153 .flags = UPF_BOOT_AUTOCONF,
153 .scscr = SCSCR_RE | SCSCR_TE, 154 .scscr = SCSCR_RE | SCSCR_TE,
154 .scbrr_algo_id = SCBRR_ALGO_4, 155 .scbrr_algo_id = SCBRR_ALGO_4,
155 .type = PORT_SCIF, 156 .type = PORT_SCIFA,
156 .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), 157 .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
157 intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, 158 intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
158}; 159};
@@ -171,7 +172,7 @@ static struct plat_sci_port scif7_platform_data = {
171 .flags = UPF_BOOT_AUTOCONF, 172 .flags = UPF_BOOT_AUTOCONF,
172 .scscr = SCSCR_RE | SCSCR_TE, 173 .scscr = SCSCR_RE | SCSCR_TE,
173 .scbrr_algo_id = SCBRR_ALGO_4, 174 .scbrr_algo_id = SCBRR_ALGO_4,
174 .type = PORT_SCIF, 175 .type = PORT_SCIFB,
175 .irqs = { evt2irq(0xd60), evt2irq(0xd60), 176 .irqs = { evt2irq(0xd60), evt2irq(0xd60),
176 evt2irq(0xd60), evt2irq(0xd60) }, 177 evt2irq(0xd60), evt2irq(0xd60) },
177}; 178};
@@ -215,6 +216,214 @@ static struct platform_device cmt10_device = {
215 .num_resources = ARRAY_SIZE(cmt10_resources), 216 .num_resources = ARRAY_SIZE(cmt10_resources),
216}; 217};
217 218
219/* VPU */
220static struct uio_info vpu_platform_data = {
221 .name = "VPU5HG",
222 .version = "0",
223 .irq = intcs_evt2irq(0x980),
224};
225
226static struct resource vpu_resources[] = {
227 [0] = {
228 .name = "VPU",
229 .start = 0xfe900000,
230 .end = 0xfe900157,
231 .flags = IORESOURCE_MEM,
232 },
233};
234
235static struct platform_device vpu_device = {
236 .name = "uio_pdrv_genirq",
237 .id = 0,
238 .dev = {
239 .platform_data = &vpu_platform_data,
240 },
241 .resource = vpu_resources,
242 .num_resources = ARRAY_SIZE(vpu_resources),
243};
244
245/* VEU0 */
246static struct uio_info veu0_platform_data = {
247 .name = "VEU0",
248 .version = "0",
249 .irq = intcs_evt2irq(0x700),
250};
251
252static struct resource veu0_resources[] = {
253 [0] = {
254 .name = "VEU0",
255 .start = 0xfe920000,
256 .end = 0xfe9200cb,
257 .flags = IORESOURCE_MEM,
258 },
259};
260
261static struct platform_device veu0_device = {
262 .name = "uio_pdrv_genirq",
263 .id = 1,
264 .dev = {
265 .platform_data = &veu0_platform_data,
266 },
267 .resource = veu0_resources,
268 .num_resources = ARRAY_SIZE(veu0_resources),
269};
270
271/* VEU1 */
272static struct uio_info veu1_platform_data = {
273 .name = "VEU1",
274 .version = "0",
275 .irq = intcs_evt2irq(0x720),
276};
277
278static struct resource veu1_resources[] = {
279 [0] = {
280 .name = "VEU1",
281 .start = 0xfe924000,
282 .end = 0xfe9240cb,
283 .flags = IORESOURCE_MEM,
284 },
285};
286
287static struct platform_device veu1_device = {
288 .name = "uio_pdrv_genirq",
289 .id = 2,
290 .dev = {
291 .platform_data = &veu1_platform_data,
292 },
293 .resource = veu1_resources,
294 .num_resources = ARRAY_SIZE(veu1_resources),
295};
296
297/* VEU2 */
298static struct uio_info veu2_platform_data = {
299 .name = "VEU2",
300 .version = "0",
301 .irq = intcs_evt2irq(0x740),
302};
303
304static struct resource veu2_resources[] = {
305 [0] = {
306 .name = "VEU2",
307 .start = 0xfe928000,
308 .end = 0xfe928307,
309 .flags = IORESOURCE_MEM,
310 },
311};
312
313static struct platform_device veu2_device = {
314 .name = "uio_pdrv_genirq",
315 .id = 3,
316 .dev = {
317 .platform_data = &veu2_platform_data,
318 },
319 .resource = veu2_resources,
320 .num_resources = ARRAY_SIZE(veu2_resources),
321};
322
323/* VEU3 */
324static struct uio_info veu3_platform_data = {
325 .name = "VEU3",
326 .version = "0",
327 .irq = intcs_evt2irq(0x760),
328};
329
330static struct resource veu3_resources[] = {
331 [0] = {
332 .name = "VEU3",
333 .start = 0xfe92c000,
334 .end = 0xfe92c307,
335 .flags = IORESOURCE_MEM,
336 },
337};
338
339static struct platform_device veu3_device = {
340 .name = "uio_pdrv_genirq",
341 .id = 4,
342 .dev = {
343 .platform_data = &veu3_platform_data,
344 },
345 .resource = veu3_resources,
346 .num_resources = ARRAY_SIZE(veu3_resources),
347};
348
349/* JPU */
350static struct uio_info jpu_platform_data = {
351 .name = "JPU",
352 .version = "0",
353 .irq = intcs_evt2irq(0x560),
354};
355
356static struct resource jpu_resources[] = {
357 [0] = {
358 .name = "JPU",
359 .start = 0xfe980000,
360 .end = 0xfe9902d3,
361 .flags = IORESOURCE_MEM,
362 },
363};
364
365static struct platform_device jpu_device = {
366 .name = "uio_pdrv_genirq",
367 .id = 5,
368 .dev = {
369 .platform_data = &jpu_platform_data,
370 },
371 .resource = jpu_resources,
372 .num_resources = ARRAY_SIZE(jpu_resources),
373};
374
375/* SPU2DSP0 */
376static struct uio_info spu0_platform_data = {
377 .name = "SPU2DSP0",
378 .version = "0",
379 .irq = evt2irq(0x1800),
380};
381
382static struct resource spu0_resources[] = {
383 [0] = {
384 .name = "SPU2DSP0",
385 .start = 0xfe200000,
386 .end = 0xfe2fffff,
387 .flags = IORESOURCE_MEM,
388 },
389};
390
391static struct platform_device spu0_device = {
392 .name = "uio_pdrv_genirq",
393 .id = 6,
394 .dev = {
395 .platform_data = &spu0_platform_data,
396 },
397 .resource = spu0_resources,
398 .num_resources = ARRAY_SIZE(spu0_resources),
399};
400
401/* SPU2DSP1 */
402static struct uio_info spu1_platform_data = {
403 .name = "SPU2DSP1",
404 .version = "0",
405 .irq = evt2irq(0x1820),
406};
407
408static struct resource spu1_resources[] = {
409 [0] = {
410 .name = "SPU2DSP1",
411 .start = 0xfe300000,
412 .end = 0xfe3fffff,
413 .flags = IORESOURCE_MEM,
414 },
415};
416
417static struct platform_device spu1_device = {
418 .name = "uio_pdrv_genirq",
419 .id = 7,
420 .dev = {
421 .platform_data = &spu1_platform_data,
422 },
423 .resource = spu1_resources,
424 .num_resources = ARRAY_SIZE(spu1_resources),
425};
426
218static struct platform_device *sh7377_early_devices[] __initdata = { 427static struct platform_device *sh7377_early_devices[] __initdata = {
219 &scif0_device, 428 &scif0_device,
220 &scif1_device, 429 &scif1_device,
@@ -227,10 +436,24 @@ static struct platform_device *sh7377_early_devices[] __initdata = {
227 &cmt10_device, 436 &cmt10_device,
228}; 437};
229 438
439static struct platform_device *sh7377_devices[] __initdata = {
440 &vpu_device,
441 &veu0_device,
442 &veu1_device,
443 &veu2_device,
444 &veu3_device,
445 &jpu_device,
446 &spu0_device,
447 &spu1_device,
448};
449
230void __init sh7377_add_standard_devices(void) 450void __init sh7377_add_standard_devices(void)
231{ 451{
232 platform_add_devices(sh7377_early_devices, 452 platform_add_devices(sh7377_early_devices,
233 ARRAY_SIZE(sh7377_early_devices)); 453 ARRAY_SIZE(sh7377_early_devices));
454
455 platform_add_devices(sh7377_devices,
456 ARRAY_SIZE(sh7377_devices));
234} 457}
235 458
236#define SMSTPCR3 0xe615013c 459#define SMSTPCR3 0xe615013c
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 685c40a2f5e6..e46821c0a62e 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -27,9 +27,11 @@
27#include <linux/input.h> 27#include <linux/input.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/serial_sci.h> 29#include <linux/serial_sci.h>
30#include <linux/sh_dma.h>
30#include <linux/sh_intc.h> 31#include <linux/sh_intc.h>
31#include <linux/sh_timer.h> 32#include <linux/sh_timer.h>
32#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <mach/sh73a0.h>
33#include <asm/mach-types.h> 35#include <asm/mach-types.h>
34#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
35 37
@@ -392,6 +394,242 @@ static struct platform_device i2c4_device = {
392 .num_resources = ARRAY_SIZE(i2c4_resources), 394 .num_resources = ARRAY_SIZE(i2c4_resources),
393}; 395};
394 396
397/* Transmit sizes and respective CHCR register values */
398enum {
399 XMIT_SZ_8BIT = 0,
400 XMIT_SZ_16BIT = 1,
401 XMIT_SZ_32BIT = 2,
402 XMIT_SZ_64BIT = 7,
403 XMIT_SZ_128BIT = 3,
404 XMIT_SZ_256BIT = 4,
405 XMIT_SZ_512BIT = 5,
406};
407
408/* log2(size / 8) - used to calculate number of transfers */
409#define TS_SHIFT { \
410 [XMIT_SZ_8BIT] = 0, \
411 [XMIT_SZ_16BIT] = 1, \
412 [XMIT_SZ_32BIT] = 2, \
413 [XMIT_SZ_64BIT] = 3, \
414 [XMIT_SZ_128BIT] = 4, \
415 [XMIT_SZ_256BIT] = 5, \
416 [XMIT_SZ_512BIT] = 6, \
417}
418
419#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
420#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
421#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
422
423static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
424 {
425 .slave_id = SHDMA_SLAVE_SCIF0_TX,
426 .addr = 0xe6c40020,
427 .chcr = CHCR_TX(XMIT_SZ_8BIT),
428 .mid_rid = 0x21,
429 }, {
430 .slave_id = SHDMA_SLAVE_SCIF0_RX,
431 .addr = 0xe6c40024,
432 .chcr = CHCR_RX(XMIT_SZ_8BIT),
433 .mid_rid = 0x22,
434 }, {
435 .slave_id = SHDMA_SLAVE_SCIF1_TX,
436 .addr = 0xe6c50020,
437 .chcr = CHCR_TX(XMIT_SZ_8BIT),
438 .mid_rid = 0x25,
439 }, {
440 .slave_id = SHDMA_SLAVE_SCIF1_RX,
441 .addr = 0xe6c50024,
442 .chcr = CHCR_RX(XMIT_SZ_8BIT),
443 .mid_rid = 0x26,
444 }, {
445 .slave_id = SHDMA_SLAVE_SCIF2_TX,
446 .addr = 0xe6c60020,
447 .chcr = CHCR_TX(XMIT_SZ_8BIT),
448 .mid_rid = 0x29,
449 }, {
450 .slave_id = SHDMA_SLAVE_SCIF2_RX,
451 .addr = 0xe6c60024,
452 .chcr = CHCR_RX(XMIT_SZ_8BIT),
453 .mid_rid = 0x2a,
454 }, {
455 .slave_id = SHDMA_SLAVE_SCIF3_TX,
456 .addr = 0xe6c70020,
457 .chcr = CHCR_TX(XMIT_SZ_8BIT),
458 .mid_rid = 0x2d,
459 }, {
460 .slave_id = SHDMA_SLAVE_SCIF3_RX,
461 .addr = 0xe6c70024,
462 .chcr = CHCR_RX(XMIT_SZ_8BIT),
463 .mid_rid = 0x2e,
464 }, {
465 .slave_id = SHDMA_SLAVE_SCIF4_TX,
466 .addr = 0xe6c80020,
467 .chcr = CHCR_TX(XMIT_SZ_8BIT),
468 .mid_rid = 0x39,
469 }, {
470 .slave_id = SHDMA_SLAVE_SCIF4_RX,
471 .addr = 0xe6c80024,
472 .chcr = CHCR_RX(XMIT_SZ_8BIT),
473 .mid_rid = 0x3a,
474 }, {
475 .slave_id = SHDMA_SLAVE_SCIF5_TX,
476 .addr = 0xe6cb0020,
477 .chcr = CHCR_TX(XMIT_SZ_8BIT),
478 .mid_rid = 0x35,
479 }, {
480 .slave_id = SHDMA_SLAVE_SCIF5_RX,
481 .addr = 0xe6cb0024,
482 .chcr = CHCR_RX(XMIT_SZ_8BIT),
483 .mid_rid = 0x36,
484 }, {
485 .slave_id = SHDMA_SLAVE_SCIF6_TX,
486 .addr = 0xe6cc0020,
487 .chcr = CHCR_TX(XMIT_SZ_8BIT),
488 .mid_rid = 0x1d,
489 }, {
490 .slave_id = SHDMA_SLAVE_SCIF6_RX,
491 .addr = 0xe6cc0024,
492 .chcr = CHCR_RX(XMIT_SZ_8BIT),
493 .mid_rid = 0x1e,
494 }, {
495 .slave_id = SHDMA_SLAVE_SCIF7_TX,
496 .addr = 0xe6cd0020,
497 .chcr = CHCR_TX(XMIT_SZ_8BIT),
498 .mid_rid = 0x19,
499 }, {
500 .slave_id = SHDMA_SLAVE_SCIF7_RX,
501 .addr = 0xe6cd0024,
502 .chcr = CHCR_RX(XMIT_SZ_8BIT),
503 .mid_rid = 0x1a,
504 }, {
505 .slave_id = SHDMA_SLAVE_SCIF8_TX,
506 .addr = 0xe6c30040,
507 .chcr = CHCR_TX(XMIT_SZ_8BIT),
508 .mid_rid = 0x3d,
509 }, {
510 .slave_id = SHDMA_SLAVE_SCIF8_RX,
511 .addr = 0xe6c30060,
512 .chcr = CHCR_RX(XMIT_SZ_8BIT),
513 .mid_rid = 0x3e,
514 }, {
515 .slave_id = SHDMA_SLAVE_SDHI0_TX,
516 .addr = 0xee100030,
517 .chcr = CHCR_TX(XMIT_SZ_16BIT),
518 .mid_rid = 0xc1,
519 }, {
520 .slave_id = SHDMA_SLAVE_SDHI0_RX,
521 .addr = 0xee100030,
522 .chcr = CHCR_RX(XMIT_SZ_16BIT),
523 .mid_rid = 0xc2,
524 }, {
525 .slave_id = SHDMA_SLAVE_SDHI1_TX,
526 .addr = 0xee120030,
527 .chcr = CHCR_TX(XMIT_SZ_16BIT),
528 .mid_rid = 0xc9,
529 }, {
530 .slave_id = SHDMA_SLAVE_SDHI1_RX,
531 .addr = 0xee120030,
532 .chcr = CHCR_RX(XMIT_SZ_16BIT),
533 .mid_rid = 0xca,
534 }, {
535 .slave_id = SHDMA_SLAVE_SDHI2_TX,
536 .addr = 0xee140030,
537 .chcr = CHCR_TX(XMIT_SZ_16BIT),
538 .mid_rid = 0xcd,
539 }, {
540 .slave_id = SHDMA_SLAVE_SDHI2_RX,
541 .addr = 0xee140030,
542 .chcr = CHCR_RX(XMIT_SZ_16BIT),
543 .mid_rid = 0xce,
544 }, {
545 .slave_id = SHDMA_SLAVE_MMCIF_TX,
546 .addr = 0xe6bd0034,
547 .chcr = CHCR_TX(XMIT_SZ_32BIT),
548 .mid_rid = 0xd1,
549 }, {
550 .slave_id = SHDMA_SLAVE_MMCIF_RX,
551 .addr = 0xe6bd0034,
552 .chcr = CHCR_RX(XMIT_SZ_32BIT),
553 .mid_rid = 0xd2,
554 },
555};
556
557#define DMAE_CHANNEL(_offset) \
558 { \
559 .offset = _offset - 0x20, \
560 .dmars = _offset - 0x20 + 0x40, \
561 }
562
563static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
564 DMAE_CHANNEL(0x8000),
565 DMAE_CHANNEL(0x8080),
566 DMAE_CHANNEL(0x8100),
567 DMAE_CHANNEL(0x8180),
568 DMAE_CHANNEL(0x8200),
569 DMAE_CHANNEL(0x8280),
570 DMAE_CHANNEL(0x8300),
571 DMAE_CHANNEL(0x8380),
572 DMAE_CHANNEL(0x8400),
573 DMAE_CHANNEL(0x8480),
574 DMAE_CHANNEL(0x8500),
575 DMAE_CHANNEL(0x8580),
576 DMAE_CHANNEL(0x8600),
577 DMAE_CHANNEL(0x8680),
578 DMAE_CHANNEL(0x8700),
579 DMAE_CHANNEL(0x8780),
580 DMAE_CHANNEL(0x8800),
581 DMAE_CHANNEL(0x8880),
582 DMAE_CHANNEL(0x8900),
583 DMAE_CHANNEL(0x8980),
584};
585
586static const unsigned int ts_shift[] = TS_SHIFT;
587
588static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
589 .slave = sh73a0_dmae_slaves,
590 .slave_num = ARRAY_SIZE(sh73a0_dmae_slaves),
591 .channel = sh73a0_dmae_channels,
592 .channel_num = ARRAY_SIZE(sh73a0_dmae_channels),
593 .ts_low_shift = 3,
594 .ts_low_mask = 0x18,
595 .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
596 .ts_high_mask = 0x00300000,
597 .ts_shift = ts_shift,
598 .ts_shift_num = ARRAY_SIZE(ts_shift),
599 .dmaor_init = DMAOR_DME,
600};
601
602static struct resource sh73a0_dmae_resources[] = {
603 {
604 /* Registers including DMAOR and channels including DMARSx */
605 .start = 0xfe000020,
606 .end = 0xfe008a00 - 1,
607 .flags = IORESOURCE_MEM,
608 },
609 {
610 /* DMA error IRQ */
611 .start = gic_spi(129),
612 .end = gic_spi(129),
613 .flags = IORESOURCE_IRQ,
614 },
615 {
616 /* IRQ for channels 0-19 */
617 .start = gic_spi(109),
618 .end = gic_spi(128),
619 .flags = IORESOURCE_IRQ,
620 },
621};
622
623static struct platform_device dma0_device = {
624 .name = "sh-dma-engine",
625 .id = 0,
626 .resource = sh73a0_dmae_resources,
627 .num_resources = ARRAY_SIZE(sh73a0_dmae_resources),
628 .dev = {
629 .platform_data = &sh73a0_dmae_platform_data,
630 },
631};
632
395static struct platform_device *sh73a0_early_devices[] __initdata = { 633static struct platform_device *sh73a0_early_devices[] __initdata = {
396 &scif0_device, 634 &scif0_device,
397 &scif1_device, 635 &scif1_device,
@@ -413,10 +651,16 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
413 &i2c2_device, 651 &i2c2_device,
414 &i2c3_device, 652 &i2c3_device,
415 &i2c4_device, 653 &i2c4_device,
654 &dma0_device,
416}; 655};
417 656
657#define SRCR2 0xe61580b0
658
418void __init sh73a0_add_standard_devices(void) 659void __init sh73a0_add_standard_devices(void)
419{ 660{
661 /* Clear software reset bit on SY-DMAC module */
662 __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
663
420 platform_add_devices(sh73a0_early_devices, 664 platform_add_devices(sh73a0_early_devices,
421 ARRAY_SIZE(sh73a0_early_devices)); 665 ARRAY_SIZE(sh73a0_early_devices));
422 platform_add_devices(sh73a0_late_devices, 666 platform_add_devices(sh73a0_late_devices,
diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S
new file mode 100644
index 000000000000..d37d3ca4d18f
--- /dev/null
+++ b/arch/arm/mach-shmobile/sleep-sh7372.S
@@ -0,0 +1,260 @@
1/*
2 * sh7372 lowlevel sleep code for "Core Standby Mode"
3 *
4 * Copyright (C) 2011 Magnus Damm
5 *
6 * In "Core Standby Mode" the ARM core is off, but L2 cache is still on
7 *
8 * Based on mach-omap2/sleep34xx.S
9 *
10 * (C) Copyright 2007 Texas Instruments
11 * Karthik Dasu <karthik-dp@ti.com>
12 *
13 * (C) Copyright 2004 Texas Instruments, <www.ti.com>
14 * Richard Woodruff <r-woodruff2@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 */
31
32#include <linux/linkage.h>
33#include <asm/assembler.h>
34
35#define SMFRAM 0xe6a70000
36
37 .align
38kernel_flush:
39 .word v7_flush_dcache_all
40
41 .align 3
42ENTRY(sh7372_cpu_suspend)
43 stmfd sp!, {r0-r12, lr} @ save registers on stack
44
45 ldr r8, =SMFRAM
46
47 mov r4, sp @ Store sp
48 mrs r5, spsr @ Store spsr
49 mov r6, lr @ Store lr
50 stmia r8!, {r4-r6}
51
52 mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register
53 mrc p15, 0, r5, c2, c0, 0 @ TTBR0
54 mrc p15, 0, r6, c2, c0, 1 @ TTBR1
55 mrc p15, 0, r7, c2, c0, 2 @ TTBCR
56 stmia r8!, {r4-r7}
57
58 mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register
59 mrc p15, 0, r5, c10, c2, 0 @ PRRR
60 mrc p15, 0, r6, c10, c2, 1 @ NMRR
61 stmia r8!,{r4-r6}
62
63 mrc p15, 0, r4, c13, c0, 1 @ Context ID
64 mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
65 mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
66 mrs r7, cpsr @ Store current cpsr
67 stmia r8!, {r4-r7}
68
69 mrc p15, 0, r4, c1, c0, 0 @ save control register
70 stmia r8!, {r4}
71
72 /*
73 * jump out to kernel flush routine
74 * - reuse that code is better
75 * - it executes in a cached space so is faster than refetch per-block
76 * - should be faster and will change with kernel
77 * - 'might' have to copy address, load and jump to it
78 * Flush all data from the L1 data cache before disabling
79 * SCTLR.C bit.
80 */
81 ldr r1, kernel_flush
82 mov lr, pc
83 bx r1
84
85 /*
86 * Clear the SCTLR.C bit to prevent further data cache
87 * allocation. Clearing SCTLR.C would make all the data accesses
88 * strongly ordered and would not hit the cache.
89 */
90 mrc p15, 0, r0, c1, c0, 0
91 bic r0, r0, #(1 << 2) @ Disable the C bit
92 mcr p15, 0, r0, c1, c0, 0
93 isb
94
95 /*
96 * Invalidate L1 data cache. Even though only invalidate is
97 * necessary exported flush API is used here. Doing clean
98 * on already clean cache would be almost NOP.
99 */
100 ldr r1, kernel_flush
101 blx r1
102 /*
103 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
104 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
105 * This sequence switches back to ARM. Note that .align may insert a
106 * nop: bx pc needs to be word-aligned in order to work.
107 */
108 THUMB( .thumb )
109 THUMB( .align )
110 THUMB( bx pc )
111 THUMB( nop )
112 .arm
113
114 /* Data memory barrier and Data sync barrier */
115 dsb
116 dmb
117
118/*
119 * ===================================
120 * == WFI instruction => Enter idle ==
121 * ===================================
122 */
123 wfi @ wait for interrupt
124
125/*
126 * ===================================
127 * == Resume path for non-OFF modes ==
128 * ===================================
129 */
130 mrc p15, 0, r0, c1, c0, 0
131 tst r0, #(1 << 2) @ Check C bit enabled?
132 orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
133 mcreq p15, 0, r0, c1, c0, 0
134 isb
135
136/*
137 * ===================================
138 * == Exit point from non-OFF modes ==
139 * ===================================
140 */
141 ldmfd sp!, {r0-r12, pc} @ restore regs and return
142
143 .pool
144
145 .align 12
146 .text
147 .global sh7372_cpu_resume
148sh7372_cpu_resume:
149
150 mov r1, #0
151 /*
152 * Invalidate all instruction caches to PoU
153 * and flush branch target cache
154 */
155 mcr p15, 0, r1, c7, c5, 0
156
157 ldr r3, =SMFRAM
158
159 ldmia r3!, {r4-r6}
160 mov sp, r4 @ Restore sp
161 msr spsr_cxsf, r5 @ Restore spsr
162 mov lr, r6 @ Restore lr
163
164 ldmia r3!, {r4-r7}
165 mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register
166 mcr p15, 0, r5, c2, c0, 0 @ TTBR0
167 mcr p15, 0, r6, c2, c0, 1 @ TTBR1
168 mcr p15, 0, r7, c2, c0, 2 @ TTBCR
169
170 ldmia r3!,{r4-r6}
171 mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register
172 mcr p15, 0, r5, c10, c2, 0 @ PRRR
173 mcr p15, 0, r6, c10, c2, 1 @ NMRR
174
175 ldmia r3!,{r4-r7}
176 mcr p15, 0, r4, c13, c0, 1 @ Context ID
177 mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
178 mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
179 msr cpsr, r7 @ store cpsr
180
181 /* Starting to enable MMU here */
182 mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
183 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
184 and r7, #0x7
185 cmp r7, #0x0
186 beq usettbr0
187ttbr_error:
188 /*
189 * More work needs to be done to support N[0:2] value other than 0
190 * So looping here so that the error can be detected
191 */
192 b ttbr_error
193
194 .align
195cache_pred_disable_mask:
196 .word 0xFFFFE7FB
197ttbrbit_mask:
198 .word 0xFFFFC000
199table_index_mask:
200 .word 0xFFF00000
201table_entry:
202 .word 0x00000C02
203usettbr0:
204
205 mrc p15, 0, r2, c2, c0, 0
206 ldr r5, ttbrbit_mask
207 and r2, r5
208 mov r4, pc
209 ldr r5, table_index_mask
210 and r4, r5 @ r4 = 31 to 20 bits of pc
211 /* Extract the value to be written to table entry */
212 ldr r6, table_entry
213 /* r6 has the value to be written to table entry */
214 add r6, r6, r4
215 /* Getting the address of table entry to modify */
216 lsr r4, #18
217 /* r2 has the location which needs to be modified */
218 add r2, r4
219 ldr r4, [r2]
220 str r6, [r2] /* modify the table entry */
221
222 mov r7, r6
223 mov r5, r2
224 mov r6, r4
225 /* r5 = original page table address */
226 /* r6 = original page table data */
227
228 mov r0, #0
229 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
230 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
231 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
232 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
233
234 /*
235 * Restore control register. This enables the MMU.
236 * The caches and prediction are not enabled here, they
237 * will be enabled after restoring the MMU table entry.
238 */
239 ldmia r3!, {r4}
240 stmia r3!, {r5} /* save original page table address */
241 stmia r3!, {r6} /* save original page table data */
242 stmia r3!, {r7} /* save modified page table data */
243
244 ldr r2, cache_pred_disable_mask
245 and r4, r2
246 mcr p15, 0, r4, c1, c0, 0
247 dsb
248 isb
249
250 ldr r0, =restoremmu_on
251 bx r0
252
253/*
254 * ==============================
255 * == Exit point from OFF mode ==
256 * ==============================
257 */
258restoremmu_on:
259
260 ldmfd sp!, {r0-r12, pc} @ restore regs and return
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index a156d2108df1..3ffdbc92ba82 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -59,6 +59,11 @@ unsigned int __init sh73a0_get_core_count(void)
59{ 59{
60 void __iomem *scu_base = scu_base_addr(); 60 void __iomem *scu_base = scu_base_addr();
61 61
62#ifdef CONFIG_HAVE_ARM_TWD
63 /* twd_base needs to be initialized before percpu_timer_setup() */
64 twd_base = (void __iomem *)0xf0000600;
65#endif
66
62 return scu_get_core_count(scu_base); 67 return scu_get_core_count(scu_base);
63} 68}
64 69
@@ -82,10 +87,6 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
82 87
83void __init sh73a0_smp_prepare_cpus(void) 88void __init sh73a0_smp_prepare_cpus(void)
84{ 89{
85#ifdef CONFIG_HAVE_ARM_TWD
86 twd_base = (void __iomem *)0xf0000600;
87#endif
88
89 scu_enable(scu_base_addr()); 90 scu_enable(scu_base_addr());
90 91
91 /* Map the reset vector (in headsmp.S) */ 92 /* Map the reset vector (in headsmp.S) */
diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
new file mode 100644
index 000000000000..c1febe13f709
--- /dev/null
+++ b/arch/arm/mach-shmobile/suspend.c
@@ -0,0 +1,47 @@
1/*
2 * Suspend-to-RAM support code for SH-Mobile ARM
3 *
4 * Copyright (C) 2011 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/pm.h>
12#include <linux/suspend.h>
13#include <linux/module.h>
14#include <linux/err.h>
15#include <asm/system.h>
16#include <asm/io.h>
17
18static int shmobile_suspend_default_enter(suspend_state_t suspend_state)
19{
20 cpu_do_idle();
21 return 0;
22}
23
24static int shmobile_suspend_begin(suspend_state_t state)
25{
26 disable_hlt();
27 return 0;
28}
29
30static void shmobile_suspend_end(void)
31{
32 enable_hlt();
33}
34
35struct platform_suspend_ops shmobile_suspend_ops = {
36 .begin = shmobile_suspend_begin,
37 .end = shmobile_suspend_end,
38 .enter = shmobile_suspend_default_enter,
39 .valid = suspend_valid_only_mem,
40};
41
42static int __init shmobile_suspend_init(void)
43{
44 suspend_set_ops(&shmobile_suspend_ops);
45 return 0;
46}
47late_initcall(shmobile_suspend_init);