mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-12 16:58:53 +00:00
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 ...
This commit is contained in:
commit
4e8a780ed6
1
.mailmap
1
.mailmap
@ -32,6 +32,7 @@ Brian Avery <b.avery@hp.com>
|
||||
Brian King <brking@us.ibm.com>
|
||||
Christoph Hellwig <hch@lst.de>
|
||||
Corey Minyard <minyard@acm.org>
|
||||
Damian Hobson-Garcia <dhobsong@igel.co.jp>
|
||||
David Brownell <david-b@pacbell.net>
|
||||
David Woodhouse <dwmw2@shinybook.infradead.org>
|
||||
Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
|
||||
|
@ -30,6 +30,11 @@ obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
|
||||
obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o
|
||||
|
||||
# PM objects
|
||||
obj-$(CONFIG_SUSPEND) += suspend.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
|
||||
|
||||
# Board objects
|
||||
obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
|
||||
obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <linux/input/sh_keysc.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sh_mmcif.h>
|
||||
#include <linux/mmc/sh_mobile_sdhi.h>
|
||||
#include <linux/mfd/tmio.h>
|
||||
#include <linux/sh_clk.h>
|
||||
#include <video/sh_mobile_lcdc.h>
|
||||
#include <video/sh_mipi_dsi.h>
|
||||
@ -156,10 +158,19 @@ static struct resource sh_mmcif_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_mmcif_dma sh_mmcif_dma = {
|
||||
.chan_priv_rx = {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_RX,
|
||||
},
|
||||
.chan_priv_tx = {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_TX,
|
||||
},
|
||||
};
|
||||
static struct sh_mmcif_plat_data sh_mmcif_platdata = {
|
||||
.sup_pclk = 0,
|
||||
.ocr = MMC_VDD_165_195,
|
||||
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
|
||||
.dma = &sh_mmcif_dma,
|
||||
};
|
||||
|
||||
static struct platform_device mmc_device = {
|
||||
@ -296,11 +307,13 @@ static struct platform_device lcdc0_device = {
|
||||
/* MIPI-DSI */
|
||||
static struct resource mipidsi0_resources[] = {
|
||||
[0] = {
|
||||
.name = "DSI0",
|
||||
.start = 0xfeab0000,
|
||||
.end = 0xfeab3fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.name = "DSI0",
|
||||
.start = 0xfeab4000,
|
||||
.end = 0xfeab7fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
@ -325,6 +338,89 @@ static struct platform_device mipidsi0_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_mobile_sdhi_info sdhi0_info = {
|
||||
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
|
||||
.dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
|
||||
.tmio_caps = MMC_CAP_SD_HIGHSPEED,
|
||||
.tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
|
||||
};
|
||||
|
||||
static struct resource sdhi0_resources[] = {
|
||||
[0] = {
|
||||
.name = "SDHI0",
|
||||
.start = 0xee100000,
|
||||
.end = 0xee1000ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = gic_spi(83),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = gic_spi(84),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = gic_spi(85),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device sdhi0_device = {
|
||||
.name = "sh_mobile_sdhi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(sdhi0_resources),
|
||||
.resource = sdhi0_resources,
|
||||
.dev = {
|
||||
.platform_data = &sdhi0_info,
|
||||
},
|
||||
};
|
||||
|
||||
void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
|
||||
{
|
||||
gpio_set_value(GPIO_PORT114, state);
|
||||
}
|
||||
|
||||
static struct sh_mobile_sdhi_info sh_sdhi1_platdata = {
|
||||
.dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
|
||||
.dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
|
||||
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
|
||||
.tmio_caps = MMC_CAP_NONREMOVABLE,
|
||||
.tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
|
||||
.set_pwr = ag5evm_sdhi1_set_pwr,
|
||||
};
|
||||
|
||||
static struct resource sdhi1_resources[] = {
|
||||
[0] = {
|
||||
.name = "SDHI1",
|
||||
.start = 0xee120000,
|
||||
.end = 0xee1200ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = gic_spi(87),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = gic_spi(88),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = gic_spi(89),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device sdhi1_device = {
|
||||
.name = "sh_mobile_sdhi",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &sh_sdhi1_platdata,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(sdhi1_resources),
|
||||
.resource = sdhi1_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *ag5evm_devices[] __initdata = {
|
||||
ð_device,
|
||||
&keysc_device,
|
||||
@ -333,6 +429,8 @@ static struct platform_device *ag5evm_devices[] __initdata = {
|
||||
&irda_device,
|
||||
&lcdc0_device,
|
||||
&mipidsi0_device,
|
||||
&sdhi0_device,
|
||||
&sdhi1_device,
|
||||
};
|
||||
|
||||
static struct map_desc ag5evm_io_desc[] __initdata = {
|
||||
@ -454,6 +552,26 @@ static void __init ag5evm_init(void)
|
||||
/* MIPI-DSI clock setup */
|
||||
__raw_writel(0x2a809010, DSI0PHYCR);
|
||||
|
||||
/* enable SDHI0 on CN15 [SD I/F] */
|
||||
gpio_request(GPIO_FN_SDHICD0, NULL);
|
||||
gpio_request(GPIO_FN_SDHIWP0, NULL);
|
||||
gpio_request(GPIO_FN_SDHICMD0, NULL);
|
||||
gpio_request(GPIO_FN_SDHICLK0, NULL);
|
||||
gpio_request(GPIO_FN_SDHID0_3, NULL);
|
||||
gpio_request(GPIO_FN_SDHID0_2, NULL);
|
||||
gpio_request(GPIO_FN_SDHID0_1, NULL);
|
||||
gpio_request(GPIO_FN_SDHID0_0, NULL);
|
||||
|
||||
/* enable SDHI1 on CN4 [WLAN I/F] */
|
||||
gpio_request(GPIO_FN_SDHICLK1, NULL);
|
||||
gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
|
||||
gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
|
||||
gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
|
||||
gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
|
||||
gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
|
||||
gpio_request(GPIO_PORT114, "sdhi1_power");
|
||||
gpio_direction_output(GPIO_PORT114, 0);
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
/* Shared attribute override enable, 64K*8way */
|
||||
l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
|
||||
|
@ -316,8 +316,16 @@ static struct resource sdhi0_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x0e00) /* SDHI0 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
.start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
@ -349,8 +357,16 @@ static struct resource sdhi1_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x0e80),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
.start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
@ -980,11 +996,6 @@ static void __init hdmi_init_pm_clock(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = clk_enable(&sh7372_pllc2_clk);
|
||||
if (ret < 0) {
|
||||
pr_err("Cannot enable pllc2 clock\n");
|
||||
goto out;
|
||||
}
|
||||
pr_debug("PLLC2 set frequency %lu\n", rate);
|
||||
|
||||
ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
|
||||
@ -1343,6 +1354,7 @@ static void __init ap4evb_init(void)
|
||||
|
||||
hdmi_init_pm_clock();
|
||||
fsi_init_pm_clock();
|
||||
sh7372_pm_init();
|
||||
}
|
||||
|
||||
static void __init ap4evb_timer_init(void)
|
||||
|
@ -205,7 +205,7 @@ static struct resource sdhi0_resources[] = {
|
||||
[0] = {
|
||||
.name = "SDHI0",
|
||||
.start = 0xe6d50000,
|
||||
.end = 0xe6d50nff,
|
||||
.end = 0xe6d500ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <linux/sh_intc.h>
|
||||
#include <linux/tca6416_keypad.h>
|
||||
#include <linux/usb/r8a66597.h>
|
||||
#include <linux/usb/renesas_usbhs.h>
|
||||
|
||||
#include <video/sh_mobile_hdmi.h>
|
||||
#include <video/sh_mobile_lcdc.h>
|
||||
@ -143,7 +144,30 @@
|
||||
* open | external VBUS | Function
|
||||
*
|
||||
* *1
|
||||
* CN31 is used as Host in Linux.
|
||||
* CN31 is used as
|
||||
* CONFIG_USB_R8A66597_HCD Host
|
||||
* CONFIG_USB_RENESAS_USBHS Function
|
||||
*
|
||||
* CAUTION
|
||||
*
|
||||
* renesas_usbhs driver can use external interrupt mode
|
||||
* (which come from USB-PHY) or autonomy mode (it use own interrupt)
|
||||
* for detecting connection/disconnection when Function.
|
||||
* USB will be power OFF while it has been disconnecting
|
||||
* if external interrupt mode, and it is always power ON if autonomy mode,
|
||||
*
|
||||
* mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
|
||||
* because Touchscreen is using IRQ7-PORT40.
|
||||
* It is impossible to use IRQ7 demux on this board.
|
||||
*
|
||||
* We can use external interrupt mode USB-Function on "USB1".
|
||||
* USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
|
||||
* But don't select both drivers in same time.
|
||||
* These uses same IRQ number for request_irq(), and aren't supporting
|
||||
* IRQF_SHARD / IORESOURCE_IRQ_SHAREABLE.
|
||||
*
|
||||
* Actually these are old/new version of USB driver.
|
||||
* This mean its register will be broken if it supports SHARD IRQ,
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -185,6 +209,7 @@
|
||||
* FIXME !!
|
||||
*
|
||||
* gpio_no_direction
|
||||
* gpio_pull_down
|
||||
* are quick_hack.
|
||||
*
|
||||
* current gpio frame work doesn't have
|
||||
@ -196,6 +221,16 @@ static void __init gpio_no_direction(u32 addr)
|
||||
__raw_writeb(0x00, addr);
|
||||
}
|
||||
|
||||
static void __init gpio_pull_down(u32 addr)
|
||||
{
|
||||
u8 data = __raw_readb(addr);
|
||||
|
||||
data &= 0x0F;
|
||||
data |= 0xA0;
|
||||
|
||||
__raw_writeb(data, addr);
|
||||
}
|
||||
|
||||
/* MTD */
|
||||
static struct mtd_partition nor_flash_partitions[] = {
|
||||
{
|
||||
@ -458,12 +493,6 @@ static void __init hdmi_init_pm_clock(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = clk_enable(&sh7372_pllc2_clk);
|
||||
if (ret < 0) {
|
||||
pr_err("Cannot enable pllc2 clock\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_debug("PLLC2 set frequency %lu\n", rate);
|
||||
|
||||
ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
|
||||
@ -515,6 +544,157 @@ static struct platform_device usb1_host_device = {
|
||||
.resource = usb1_host_resources,
|
||||
};
|
||||
|
||||
/* USB1 (Function) */
|
||||
#define USB_PHY_MODE (1 << 4)
|
||||
#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
|
||||
#define USB_PHY_ON (1 << 1)
|
||||
#define USB_PHY_OFF (1 << 0)
|
||||
#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
|
||||
|
||||
struct usbhs_private {
|
||||
unsigned int irq;
|
||||
unsigned int usbphyaddr;
|
||||
unsigned int usbcrcaddr;
|
||||
struct renesas_usbhs_platform_info info;
|
||||
};
|
||||
|
||||
#define usbhs_get_priv(pdev) \
|
||||
container_of(renesas_usbhs_get_info(pdev), \
|
||||
struct usbhs_private, info)
|
||||
|
||||
#define usbhs_is_connected(priv) \
|
||||
(!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
|
||||
|
||||
static int usbhs1_get_id(struct platform_device *pdev)
|
||||
{
|
||||
return USBHS_GADGET;
|
||||
}
|
||||
|
||||
static int usbhs1_get_vbus(struct platform_device *pdev)
|
||||
{
|
||||
return usbhs_is_connected(usbhs_get_priv(pdev));
|
||||
}
|
||||
|
||||
static irqreturn_t usbhs1_interrupt(int irq, void *data)
|
||||
{
|
||||
struct platform_device *pdev = data;
|
||||
struct usbhs_private *priv = usbhs_get_priv(pdev);
|
||||
|
||||
dev_dbg(&pdev->dev, "%s\n", __func__);
|
||||
|
||||
renesas_usbhs_call_notify_hotplug(pdev);
|
||||
|
||||
/* clear status */
|
||||
__raw_writew(__raw_readw(priv->usbphyaddr) | USB_PHY_INT_CLR,
|
||||
priv->usbphyaddr);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int usbhs1_hardware_init(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_private *priv = usbhs_get_priv(pdev);
|
||||
int ret;
|
||||
|
||||
irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
|
||||
/* clear interrupt status */
|
||||
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
|
||||
|
||||
ret = request_irq(priv->irq, usbhs1_interrupt, 0,
|
||||
dev_name(&pdev->dev), pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request_irq err\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* enable USB phy interrupt */
|
||||
__raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->usbphyaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbhs1_hardware_exit(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_private *priv = usbhs_get_priv(pdev);
|
||||
|
||||
/* clear interrupt status */
|
||||
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
|
||||
|
||||
free_irq(priv->irq, pdev);
|
||||
}
|
||||
|
||||
static void usbhs1_phy_reset(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_private *priv = usbhs_get_priv(pdev);
|
||||
|
||||
/* init phy */
|
||||
__raw_writew(0x8a0a, priv->usbcrcaddr);
|
||||
}
|
||||
|
||||
static u32 usbhs1_pipe_cfg[] = {
|
||||
USB_ENDPOINT_XFER_CONTROL,
|
||||
USB_ENDPOINT_XFER_ISOC,
|
||||
USB_ENDPOINT_XFER_ISOC,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_INT,
|
||||
USB_ENDPOINT_XFER_INT,
|
||||
USB_ENDPOINT_XFER_INT,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usbhs_private usbhs1_private = {
|
||||
.irq = evt2irq(0x0300), /* IRQ8 */
|
||||
.usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */
|
||||
.usbcrcaddr = 0xE6058130, /* USBCR4 */
|
||||
.info = {
|
||||
.platform_callback = {
|
||||
.hardware_init = usbhs1_hardware_init,
|
||||
.hardware_exit = usbhs1_hardware_exit,
|
||||
.phy_reset = usbhs1_phy_reset,
|
||||
.get_id = usbhs1_get_id,
|
||||
.get_vbus = usbhs1_get_vbus,
|
||||
},
|
||||
.driver_param = {
|
||||
.buswait_bwait = 4,
|
||||
.pipe_type = usbhs1_pipe_cfg,
|
||||
.pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource usbhs1_resources[] = {
|
||||
[0] = {
|
||||
.name = "USBHS",
|
||||
.start = 0xE68B0000,
|
||||
.end = 0xE68B00E6 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device usbhs1_device = {
|
||||
.name = "renesas_usbhs",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &usbhs1_private.info,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(usbhs1_resources),
|
||||
.resource = usbhs1_resources,
|
||||
};
|
||||
|
||||
|
||||
/* LED */
|
||||
static struct gpio_led mackerel_leds[] = {
|
||||
{
|
||||
@ -690,7 +870,15 @@ static struct resource sdhi0_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x0e00) /* SDHI0 */,
|
||||
.start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
@ -705,7 +893,7 @@ static struct platform_device sdhi0_device = {
|
||||
},
|
||||
};
|
||||
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF)
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
|
||||
/* SDHI1 */
|
||||
static struct sh_mobile_sdhi_info sdhi1_info = {
|
||||
.dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
|
||||
@ -725,7 +913,15 @@ static struct resource sdhi1_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x0e80),
|
||||
.start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
@ -768,7 +964,15 @@ static struct resource sdhi2_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = evt2irq(0x1200),
|
||||
.start = evt2irq(0x1200), /* SDHI2_SDHI2I0 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = evt2irq(0x1220), /* SDHI2_SDHI2I1 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = evt2irq(0x1240), /* SDHI2_SDHI2I2 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
@ -803,6 +1007,15 @@ static struct resource sh_mmcif_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_mmcif_dma sh_mmcif_dma = {
|
||||
.chan_priv_rx = {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_RX,
|
||||
},
|
||||
.chan_priv_tx = {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_TX,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_mmcif_plat_data sh_mmcif_plat = {
|
||||
.sup_pclk = 0,
|
||||
.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 = {
|
||||
MMC_CAP_8_BIT_DATA |
|
||||
MMC_CAP_NEEDS_POLL,
|
||||
.get_cd = slot_cn7_get_cd,
|
||||
.dma = &sh_mmcif_dma,
|
||||
};
|
||||
|
||||
static struct platform_device sh_mmcif_device = {
|
||||
@ -858,37 +1072,23 @@ static struct soc_camera_link camera_link = {
|
||||
.priv = &camera_info,
|
||||
};
|
||||
|
||||
static void dummy_release(struct device *dev)
|
||||
{
|
||||
}
|
||||
static struct platform_device *camera_device;
|
||||
|
||||
static struct platform_device camera_device = {
|
||||
.name = "soc_camera_platform",
|
||||
.dev = {
|
||||
.platform_data = &camera_info,
|
||||
.release = dummy_release,
|
||||
},
|
||||
};
|
||||
static void mackerel_camera_release(struct device *dev)
|
||||
{
|
||||
soc_camera_platform_release(&camera_device);
|
||||
}
|
||||
|
||||
static int mackerel_camera_add(struct soc_camera_link *icl,
|
||||
struct device *dev)
|
||||
{
|
||||
if (icl != &camera_link)
|
||||
return -ENODEV;
|
||||
|
||||
camera_info.dev = dev;
|
||||
|
||||
return platform_device_register(&camera_device);
|
||||
return soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
|
||||
mackerel_camera_release, 0);
|
||||
}
|
||||
|
||||
static void mackerel_camera_del(struct soc_camera_link *icl)
|
||||
{
|
||||
if (icl != &camera_link)
|
||||
return;
|
||||
|
||||
platform_device_unregister(&camera_device);
|
||||
memset(&camera_device.dev.kobj, 0,
|
||||
sizeof(camera_device.dev.kobj));
|
||||
soc_camera_platform_del(icl, camera_device, &camera_link);
|
||||
}
|
||||
|
||||
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
|
||||
@ -935,12 +1135,13 @@ static struct platform_device *mackerel_devices[] __initdata = {
|
||||
&smc911x_device,
|
||||
&lcdc_device,
|
||||
&usb1_host_device,
|
||||
&usbhs1_device,
|
||||
&leds_device,
|
||||
&fsi_device,
|
||||
&fsi_ak4643_device,
|
||||
&fsi_hdmi_device,
|
||||
&sdhi0_device,
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF)
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
|
||||
&sdhi1_device,
|
||||
#endif
|
||||
&sdhi2_device,
|
||||
@ -1030,6 +1231,7 @@ static void __init mackerel_map_io(void)
|
||||
|
||||
#define GPIO_PORT9CR 0xE6051009
|
||||
#define GPIO_PORT10CR 0xE605100A
|
||||
#define GPIO_PORT168CR 0xE60520A8
|
||||
#define SRCR4 0xe61580bc
|
||||
#define USCCR1 0xE6058144
|
||||
static void __init mackerel_init(void)
|
||||
@ -1088,6 +1290,7 @@ static void __init mackerel_init(void)
|
||||
gpio_request(GPIO_FN_OVCN_1_114, NULL);
|
||||
gpio_request(GPIO_FN_EXTLP_1, NULL);
|
||||
gpio_request(GPIO_FN_OVCN2_1, NULL);
|
||||
gpio_pull_down(GPIO_PORT168CR);
|
||||
|
||||
/* setup USB phy */
|
||||
__raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
|
||||
@ -1140,7 +1343,7 @@ static void __init mackerel_init(void)
|
||||
gpio_request(GPIO_FN_SDHID0_1, NULL);
|
||||
gpio_request(GPIO_FN_SDHID0_0, NULL);
|
||||
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF)
|
||||
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
|
||||
/* enable SDHI1 */
|
||||
gpio_request(GPIO_FN_SDHICMD1, NULL);
|
||||
gpio_request(GPIO_FN_SDHICLK1, NULL);
|
||||
@ -1216,6 +1419,7 @@ static void __init mackerel_init(void)
|
||||
platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
|
||||
|
||||
hdmi_init_pm_clock();
|
||||
sh7372_pm_init();
|
||||
}
|
||||
|
||||
static void __init mackerel_timer_init(void)
|
||||
|
@ -44,6 +44,11 @@
|
||||
#define DSI1PCKCR 0xe6150098
|
||||
#define PLLC01CR 0xe6150028
|
||||
#define PLLC2CR 0xe615002c
|
||||
#define RMSTPCR0 0xe6150110
|
||||
#define RMSTPCR1 0xe6150114
|
||||
#define RMSTPCR2 0xe6150118
|
||||
#define RMSTPCR3 0xe615011c
|
||||
#define RMSTPCR4 0xe6150120
|
||||
#define SMSTPCR0 0xe6150130
|
||||
#define SMSTPCR1 0xe6150134
|
||||
#define SMSTPCR2 0xe6150138
|
||||
@ -421,9 +426,6 @@ static unsigned long fsidiv_recalc(struct clk *clk)
|
||||
|
||||
value = __raw_readl(clk->mapping->base);
|
||||
|
||||
if ((value & 0x3) != 0x3)
|
||||
return 0;
|
||||
|
||||
value >>= 16;
|
||||
if (value < 2)
|
||||
return 0;
|
||||
@ -504,7 +506,7 @@ static struct clk *late_main_clks[] = {
|
||||
enum { MSTP001,
|
||||
MSTP131, MSTP130,
|
||||
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
|
||||
MSTP118, MSTP117, MSTP116,
|
||||
MSTP118, MSTP117, MSTP116, MSTP113,
|
||||
MSTP106, MSTP101, MSTP100,
|
||||
MSTP223,
|
||||
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
|
||||
@ -527,6 +529,7 @@ static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
|
||||
[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
|
||||
[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
|
||||
[MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
|
||||
[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
|
||||
[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
|
||||
[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
|
||||
@ -617,6 +620,7 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
|
||||
@ -634,6 +638,7 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
|
||||
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
|
||||
@ -644,6 +649,7 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
|
||||
CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
|
||||
|
||||
CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
|
||||
@ -655,6 +661,13 @@ void __init sh7372_clock_init(void)
|
||||
{
|
||||
int k, ret = 0;
|
||||
|
||||
/* make sure MSTP bits on the RT/SH4AL-DSP side are off */
|
||||
__raw_writel(0xe4ef8087, RMSTPCR0);
|
||||
__raw_writel(0xffffffff, RMSTPCR1);
|
||||
__raw_writel(0x37c7f7ff, RMSTPCR2);
|
||||
__raw_writel(0xffffffff, RMSTPCR3);
|
||||
__raw_writel(0xffe0fffd, RMSTPCR4);
|
||||
|
||||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
|
@ -266,7 +266,8 @@ enum { MSTP001,
|
||||
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
|
||||
MSTP219,
|
||||
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
|
||||
MSTP331, MSTP329, MSTP325, MSTP323, MSTP312,
|
||||
MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
|
||||
MSTP314, MSTP313, MSTP312, MSTP311,
|
||||
MSTP411, MSTP410, MSTP403,
|
||||
MSTP_NR };
|
||||
|
||||
@ -295,7 +296,11 @@ static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
|
||||
[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
|
||||
[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
|
||||
[MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
|
||||
[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
|
||||
[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
|
||||
[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
|
||||
[MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
|
||||
[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
|
||||
[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
|
||||
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
|
||||
@ -313,6 +318,9 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
|
||||
CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
|
||||
CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
|
||||
CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
|
||||
CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
|
||||
CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
|
||||
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
|
||||
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
|
||||
CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
|
||||
@ -341,7 +349,11 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
|
||||
CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
|
||||
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
|
||||
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
|
||||
@ -351,6 +363,11 @@ void __init sh73a0_clock_init(void)
|
||||
{
|
||||
int k, ret = 0;
|
||||
|
||||
/* Set SDHI clocks to a known state */
|
||||
__raw_writel(0x108, SD0CKCR);
|
||||
__raw_writel(0x108, SD1CKCR);
|
||||
__raw_writel(0x108, SD2CKCR);
|
||||
|
||||
/* detect main clock parent */
|
||||
switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
|
||||
case 0:
|
||||
|
92
arch/arm/mach-shmobile/cpuidle.c
Normal file
92
arch/arm/mach-shmobile/cpuidle.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* CPUIdle support code for SH-Mobile ARM
|
||||
*
|
||||
* Copyright (C) 2011 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static void shmobile_enter_wfi(void)
|
||||
{
|
||||
cpu_do_idle();
|
||||
}
|
||||
|
||||
void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
|
||||
shmobile_enter_wfi, /* regular sleep mode */
|
||||
};
|
||||
|
||||
static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_state *state)
|
||||
{
|
||||
ktime_t before, after;
|
||||
int requested_state = state - &dev->states[0];
|
||||
|
||||
dev->last_state = &dev->states[requested_state];
|
||||
before = ktime_get();
|
||||
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
shmobile_cpuidle_modes[requested_state]();
|
||||
|
||||
local_irq_enable();
|
||||
local_fiq_enable();
|
||||
|
||||
after = ktime_get();
|
||||
return ktime_to_ns(ktime_sub(after, before)) >> 10;
|
||||
}
|
||||
|
||||
static struct cpuidle_device shmobile_cpuidle_dev;
|
||||
static struct cpuidle_driver shmobile_cpuidle_driver = {
|
||||
.name = "shmobile_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
|
||||
|
||||
static int shmobile_cpuidle_init(void)
|
||||
{
|
||||
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
|
||||
struct cpuidle_state *state;
|
||||
int i;
|
||||
|
||||
cpuidle_register_driver(&shmobile_cpuidle_driver);
|
||||
|
||||
for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
|
||||
dev->states[i].name[0] = '\0';
|
||||
dev->states[i].desc[0] = '\0';
|
||||
dev->states[i].enter = shmobile_cpuidle_enter;
|
||||
}
|
||||
|
||||
i = CPUIDLE_DRIVER_STATE_START;
|
||||
|
||||
state = &dev->states[i++];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
|
||||
strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = 1;
|
||||
state->target_residency = 1 * 2;
|
||||
state->power_usage = 3;
|
||||
state->flags = 0;
|
||||
state->flags |= CPUIDLE_FLAG_TIME_VALID;
|
||||
|
||||
dev->safe_state = state;
|
||||
dev->state_count = i;
|
||||
|
||||
if (shmobile_cpuidle_setup)
|
||||
shmobile_cpuidle_setup(dev);
|
||||
|
||||
cpuidle_register_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(shmobile_cpuidle_init);
|
@ -24,4 +24,4 @@
|
||||
.align 12
|
||||
ENTRY(shmobile_secondary_vector)
|
||||
ldr pc, 1f
|
||||
1: .long secondary_startup - PAGE_OFFSET + PHYS_OFFSET
|
||||
1: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET
|
||||
|
@ -8,6 +8,10 @@ struct clk;
|
||||
extern int clk_init(void);
|
||||
extern void shmobile_handle_irq_intc(struct pt_regs *);
|
||||
extern void shmobile_handle_irq_gic(struct pt_regs *);
|
||||
extern struct platform_suspend_ops shmobile_suspend_ops;
|
||||
struct cpuidle_device;
|
||||
extern void (*shmobile_cpuidle_modes[])(void);
|
||||
extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
|
||||
|
||||
extern void sh7367_init_irq(void);
|
||||
extern void sh7367_add_early_devices(void);
|
||||
@ -30,6 +34,9 @@ extern void sh7372_add_early_devices(void);
|
||||
extern void sh7372_add_standard_devices(void);
|
||||
extern void sh7372_clock_init(void);
|
||||
extern void sh7372_pinmux_init(void);
|
||||
extern void sh7372_pm_init(void);
|
||||
extern void sh7372_cpu_suspend(void);
|
||||
extern void sh7372_cpu_resume(void);
|
||||
extern struct clk sh7372_extal1_clk;
|
||||
extern struct clk sh7372_extal2_clk;
|
||||
|
||||
|
@ -87,8 +87,7 @@ WAIT 1, 0xFE40009C
|
||||
ED 0xFE400354, 0x01AD8002
|
||||
|
||||
LIST "SCIF0 - Serial port for earlyprintk"
|
||||
EB 0xE6053098, 0x11
|
||||
EB 0xE6053098, 0xe1
|
||||
EW 0xE6C40000, 0x0000
|
||||
EB 0xE6C40004, 0x19
|
||||
EW 0xE6C40008, 0x3000
|
||||
EW 0xE6C40008, 0x0030
|
||||
|
@ -87,8 +87,7 @@ WAIT 1, 0xFE40009C
|
||||
ED 0xFE400354, 0x01AD8002
|
||||
|
||||
LIST "SCIF0 - Serial port for earlyprintk"
|
||||
EB 0xE6053098, 0x11
|
||||
EB 0xE6053098, 0xe1
|
||||
EW 0xE6C40000, 0x0000
|
||||
EB 0xE6C40004, 0x19
|
||||
EW 0xE6C40008, 0x3000
|
||||
EW 0xE6C40008, 0x0030
|
||||
|
@ -435,6 +435,7 @@ enum {
|
||||
|
||||
/* DMA slave IDs */
|
||||
enum {
|
||||
SHDMA_SLAVE_INVALID,
|
||||
SHDMA_SLAVE_SCIF0_TX,
|
||||
SHDMA_SLAVE_SCIF0_RX,
|
||||
SHDMA_SLAVE_SCIF1_TX,
|
||||
|
@ -463,5 +463,35 @@ enum {
|
||||
GPIO_FN_FSIAIBT_PU,
|
||||
GPIO_FN_FSIAISLD_PU,
|
||||
};
|
||||
/* DMA slave IDs */
|
||||
enum {
|
||||
SHDMA_SLAVE_INVALID,
|
||||
SHDMA_SLAVE_SCIF0_TX,
|
||||
SHDMA_SLAVE_SCIF0_RX,
|
||||
SHDMA_SLAVE_SCIF1_TX,
|
||||
SHDMA_SLAVE_SCIF1_RX,
|
||||
SHDMA_SLAVE_SCIF2_TX,
|
||||
SHDMA_SLAVE_SCIF2_RX,
|
||||
SHDMA_SLAVE_SCIF3_TX,
|
||||
SHDMA_SLAVE_SCIF3_RX,
|
||||
SHDMA_SLAVE_SCIF4_TX,
|
||||
SHDMA_SLAVE_SCIF4_RX,
|
||||
SHDMA_SLAVE_SCIF5_TX,
|
||||
SHDMA_SLAVE_SCIF5_RX,
|
||||
SHDMA_SLAVE_SCIF6_TX,
|
||||
SHDMA_SLAVE_SCIF6_RX,
|
||||
SHDMA_SLAVE_SCIF7_TX,
|
||||
SHDMA_SLAVE_SCIF7_RX,
|
||||
SHDMA_SLAVE_SCIF8_TX,
|
||||
SHDMA_SLAVE_SCIF8_RX,
|
||||
SHDMA_SLAVE_SDHI0_TX,
|
||||
SHDMA_SLAVE_SDHI0_RX,
|
||||
SHDMA_SLAVE_SDHI1_TX,
|
||||
SHDMA_SLAVE_SDHI1_RX,
|
||||
SHDMA_SLAVE_SDHI2_TX,
|
||||
SHDMA_SLAVE_SDHI2_RX,
|
||||
SHDMA_SLAVE_MMCIF_TX,
|
||||
SHDMA_SLAVE_MMCIF_RX,
|
||||
};
|
||||
|
||||
#endif /* __ASM_SH73A0_H__ */
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
enum {
|
||||
UNUSED_INTCA = 0,
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
|
||||
/* interrupt sources INTCA */
|
||||
IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
|
||||
@ -49,14 +47,14 @@ enum {
|
||||
MSIOF2, MSIOF1,
|
||||
SCIFA4, SCIFA5, SCIFB,
|
||||
FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
|
||||
SDHI0,
|
||||
SDHI1,
|
||||
SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
|
||||
SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2,
|
||||
IRREM,
|
||||
IRDA,
|
||||
TPU0,
|
||||
TTI20,
|
||||
DDM,
|
||||
SDHI2,
|
||||
SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
|
||||
RWDT0,
|
||||
DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
|
||||
DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
|
||||
@ -84,7 +82,7 @@ enum {
|
||||
|
||||
/* interrupt groups INTCA */
|
||||
DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
|
||||
AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1
|
||||
AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2
|
||||
};
|
||||
|
||||
static struct intc_vect intca_vectors[] __initdata = {
|
||||
@ -125,17 +123,17 @@ static struct intc_vect intca_vectors[] __initdata = {
|
||||
INTC_VECT(SCIFB, 0x0d60),
|
||||
INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
|
||||
INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
|
||||
INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
|
||||
INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
|
||||
INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
|
||||
INTC_VECT(SDHI1, 0x0ec0),
|
||||
INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
|
||||
INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
|
||||
INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
|
||||
INTC_VECT(SDHI1_SDHI1I2, 0x0ec0),
|
||||
INTC_VECT(IRREM, 0x0f60),
|
||||
INTC_VECT(IRDA, 0x0480),
|
||||
INTC_VECT(TPU0, 0x04a0),
|
||||
INTC_VECT(TTI20, 0x1100),
|
||||
INTC_VECT(DDM, 0x1140),
|
||||
INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
|
||||
INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
|
||||
INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
|
||||
INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260),
|
||||
INTC_VECT(RWDT0, 0x1280),
|
||||
INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
|
||||
INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
|
||||
@ -195,6 +193,12 @@ static struct intc_group intca_groups[] __initdata = {
|
||||
INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
|
||||
FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
|
||||
INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
|
||||
INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
|
||||
SDHI0_SDHI0I2, SDHI0_SDHI0I3),
|
||||
INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
|
||||
SDHI1_SDHI1I2),
|
||||
INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
|
||||
SDHI2_SDHI2I2, SDHI2_SDHI2I3),
|
||||
INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
|
||||
};
|
||||
|
||||
@ -230,10 +234,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
|
||||
{ SCIFB, SCIFA5, SCIFA4, MSIOF1,
|
||||
0, 0, MSIOF2, 0 } },
|
||||
{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
|
||||
{ DISABLED, ENABLED, ENABLED, ENABLED,
|
||||
{ SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
|
||||
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
|
||||
{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
|
||||
{ 0, ENABLED, ENABLED, ENABLED,
|
||||
{ 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
|
||||
TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
|
||||
{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
|
||||
{ CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
|
||||
@ -248,7 +252,7 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
|
||||
{ 0, 0, TPU0, 0,
|
||||
0, 0, 0, 0 } },
|
||||
{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
|
||||
{ DISABLED, DISABLED, ENABLED, ENABLED,
|
||||
{ SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
|
||||
0, CMT3, 0, RWDT0 } },
|
||||
{ 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
|
||||
{ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
|
||||
@ -354,14 +358,10 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = {
|
||||
{ IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
|
||||
};
|
||||
|
||||
static struct intc_desc intca_desc __initdata = {
|
||||
.name = "sh7372-intca",
|
||||
.force_enable = ENABLED,
|
||||
.force_disable = DISABLED,
|
||||
.hw = INTC_HW_DESC(intca_vectors, intca_groups,
|
||||
intca_mask_registers, intca_prio_registers,
|
||||
intca_sense_registers, intca_ack_registers),
|
||||
};
|
||||
static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
|
||||
intca_vectors, intca_groups,
|
||||
intca_mask_registers, intca_prio_registers,
|
||||
intca_sense_registers, intca_ack_registers);
|
||||
|
||||
enum {
|
||||
UNUSED_INTCS = 0,
|
||||
|
108
arch/arm/mach-shmobile/pm-sh7372.c
Normal file
108
arch/arm/mach-shmobile/pm-sh7372.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* sh7372 Power management support
|
||||
*
|
||||
* Copyright (C) 2011 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#define SMFRAM 0xe6a70000
|
||||
#define SYSTBCR 0xe6150024
|
||||
#define SBAR 0xe6180020
|
||||
#define APARMBAREA 0xe6f10020
|
||||
|
||||
static void sh7372_enter_core_standby(void)
|
||||
{
|
||||
void __iomem *smfram = (void __iomem *)SMFRAM;
|
||||
|
||||
__raw_writel(0, APARMBAREA); /* translate 4k */
|
||||
__raw_writel(__pa(sh7372_cpu_resume), SBAR); /* set reset vector */
|
||||
__raw_writel(0x10, SYSTBCR); /* enable core standby */
|
||||
|
||||
__raw_writel(0, smfram + 0x3c); /* clear page table address */
|
||||
|
||||
sh7372_cpu_suspend();
|
||||
cpu_init();
|
||||
|
||||
/* if page table address is non-NULL then we have been powered down */
|
||||
if (__raw_readl(smfram + 0x3c)) {
|
||||
__raw_writel(__raw_readl(smfram + 0x40),
|
||||
__va(__raw_readl(smfram + 0x3c)));
|
||||
|
||||
flush_tlb_all();
|
||||
set_cr(__raw_readl(smfram + 0x38));
|
||||
}
|
||||
|
||||
__raw_writel(0, SYSTBCR); /* disable core standby */
|
||||
__raw_writel(0, SBAR); /* disable reset vector translation */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
|
||||
{
|
||||
struct cpuidle_state *state;
|
||||
int i = dev->state_count;
|
||||
|
||||
state = &dev->states[i];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
|
||||
strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = 10;
|
||||
state->target_residency = 20 + 10;
|
||||
state->power_usage = 1; /* perhaps not */
|
||||
state->flags = 0;
|
||||
state->flags |= CPUIDLE_FLAG_TIME_VALID;
|
||||
shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
|
||||
|
||||
dev->state_count = i + 1;
|
||||
}
|
||||
|
||||
static void sh7372_cpuidle_init(void)
|
||||
{
|
||||
shmobile_cpuidle_setup = sh7372_cpuidle_setup;
|
||||
}
|
||||
#else
|
||||
static void sh7372_cpuidle_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int sh7372_enter_suspend(suspend_state_t suspend_state)
|
||||
{
|
||||
sh7372_enter_core_standby();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh7372_suspend_init(void)
|
||||
{
|
||||
shmobile_suspend_ops.enter = sh7372_enter_suspend;
|
||||
}
|
||||
#else
|
||||
static void sh7372_suspend_init(void) {}
|
||||
#endif
|
||||
|
||||
#define DBGREG1 0xe6100020
|
||||
#define DBGREG9 0xe6100040
|
||||
|
||||
void __init sh7372_pm_init(void)
|
||||
{
|
||||
/* enable DBG hardware block to kick SYSC */
|
||||
__raw_writel(0x0000a500, DBGREG9);
|
||||
__raw_writel(0x0000a501, DBGREG9);
|
||||
__raw_writel(0x00000000, DBGREG1);
|
||||
|
||||
sh7372_suspend_init();
|
||||
sh7372_cpuidle_init();
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uio_driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
@ -195,6 +196,214 @@ static struct platform_device cmt10_device = {
|
||||
.num_resources = ARRAY_SIZE(cmt10_resources),
|
||||
};
|
||||
|
||||
/* VPU */
|
||||
static struct uio_info vpu_platform_data = {
|
||||
.name = "VPU5",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x980),
|
||||
};
|
||||
|
||||
static struct resource vpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "VPU",
|
||||
.start = 0xfe900000,
|
||||
.end = 0xfe902807,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device vpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &vpu_platform_data,
|
||||
},
|
||||
.resource = vpu_resources,
|
||||
.num_resources = ARRAY_SIZE(vpu_resources),
|
||||
};
|
||||
|
||||
/* VEU0 */
|
||||
static struct uio_info veu0_platform_data = {
|
||||
.name = "VEU0",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x700),
|
||||
};
|
||||
|
||||
static struct resource veu0_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU0",
|
||||
.start = 0xfe920000,
|
||||
.end = 0xfe9200b7,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu0_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &veu0_platform_data,
|
||||
},
|
||||
.resource = veu0_resources,
|
||||
.num_resources = ARRAY_SIZE(veu0_resources),
|
||||
};
|
||||
|
||||
/* VEU1 */
|
||||
static struct uio_info veu1_platform_data = {
|
||||
.name = "VEU1",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x720),
|
||||
};
|
||||
|
||||
static struct resource veu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU1",
|
||||
.start = 0xfe924000,
|
||||
.end = 0xfe9240b7,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.platform_data = &veu1_platform_data,
|
||||
},
|
||||
.resource = veu1_resources,
|
||||
.num_resources = ARRAY_SIZE(veu1_resources),
|
||||
};
|
||||
|
||||
/* VEU2 */
|
||||
static struct uio_info veu2_platform_data = {
|
||||
.name = "VEU2",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x740),
|
||||
};
|
||||
|
||||
static struct resource veu2_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU2",
|
||||
.start = 0xfe928000,
|
||||
.end = 0xfe9280b7,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu2_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 3,
|
||||
.dev = {
|
||||
.platform_data = &veu2_platform_data,
|
||||
},
|
||||
.resource = veu2_resources,
|
||||
.num_resources = ARRAY_SIZE(veu2_resources),
|
||||
};
|
||||
|
||||
/* VEU3 */
|
||||
static struct uio_info veu3_platform_data = {
|
||||
.name = "VEU3",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x760),
|
||||
};
|
||||
|
||||
static struct resource veu3_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU3",
|
||||
.start = 0xfe92c000,
|
||||
.end = 0xfe92c0b7,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu3_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 4,
|
||||
.dev = {
|
||||
.platform_data = &veu3_platform_data,
|
||||
},
|
||||
.resource = veu3_resources,
|
||||
.num_resources = ARRAY_SIZE(veu3_resources),
|
||||
};
|
||||
|
||||
/* VEU2H */
|
||||
static struct uio_info veu2h_platform_data = {
|
||||
.name = "VEU2H",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x520),
|
||||
};
|
||||
|
||||
static struct resource veu2h_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU2H",
|
||||
.start = 0xfe93c000,
|
||||
.end = 0xfe93c27b,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu2h_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 5,
|
||||
.dev = {
|
||||
.platform_data = &veu2h_platform_data,
|
||||
},
|
||||
.resource = veu2h_resources,
|
||||
.num_resources = ARRAY_SIZE(veu2h_resources),
|
||||
};
|
||||
|
||||
/* JPU */
|
||||
static struct uio_info jpu_platform_data = {
|
||||
.name = "JPU",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x560),
|
||||
};
|
||||
|
||||
static struct resource jpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "JPU",
|
||||
.start = 0xfe980000,
|
||||
.end = 0xfe9902d3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device jpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 6,
|
||||
.dev = {
|
||||
.platform_data = &jpu_platform_data,
|
||||
},
|
||||
.resource = jpu_resources,
|
||||
.num_resources = ARRAY_SIZE(jpu_resources),
|
||||
};
|
||||
|
||||
/* SPU1 */
|
||||
static struct uio_info spu1_platform_data = {
|
||||
.name = "SPU1",
|
||||
.version = "0",
|
||||
.irq = evt2irq(0xfc0),
|
||||
};
|
||||
|
||||
static struct resource spu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "SPU1",
|
||||
.start = 0xfe300000,
|
||||
.end = 0xfe3fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device spu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 7,
|
||||
.dev = {
|
||||
.platform_data = &spu1_platform_data,
|
||||
},
|
||||
.resource = spu1_resources,
|
||||
.num_resources = ARRAY_SIZE(spu1_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *sh7367_early_devices[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
@ -206,10 +415,24 @@ static struct platform_device *sh7367_early_devices[] __initdata = {
|
||||
&cmt10_device,
|
||||
};
|
||||
|
||||
static struct platform_device *sh7367_devices[] __initdata = {
|
||||
&vpu_device,
|
||||
&veu0_device,
|
||||
&veu1_device,
|
||||
&veu2_device,
|
||||
&veu3_device,
|
||||
&veu2h_device,
|
||||
&jpu_device,
|
||||
&spu1_device,
|
||||
};
|
||||
|
||||
void __init sh7367_add_standard_devices(void)
|
||||
{
|
||||
platform_add_devices(sh7367_early_devices,
|
||||
ARRAY_SIZE(sh7367_early_devices));
|
||||
|
||||
platform_add_devices(sh7367_devices,
|
||||
ARRAY_SIZE(sh7367_devices));
|
||||
}
|
||||
|
||||
#define SYMSTPCR2 0xe6158048
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uio_driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
@ -601,6 +602,214 @@ static struct platform_device dma2_device = {
|
||||
},
|
||||
};
|
||||
|
||||
/* VPU */
|
||||
static struct uio_info vpu_platform_data = {
|
||||
.name = "VPU5HG",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x980),
|
||||
};
|
||||
|
||||
static struct resource vpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "VPU",
|
||||
.start = 0xfe900000,
|
||||
.end = 0xfe900157,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device vpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &vpu_platform_data,
|
||||
},
|
||||
.resource = vpu_resources,
|
||||
.num_resources = ARRAY_SIZE(vpu_resources),
|
||||
};
|
||||
|
||||
/* VEU0 */
|
||||
static struct uio_info veu0_platform_data = {
|
||||
.name = "VEU0",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x700),
|
||||
};
|
||||
|
||||
static struct resource veu0_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU0",
|
||||
.start = 0xfe920000,
|
||||
.end = 0xfe9200cb,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu0_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &veu0_platform_data,
|
||||
},
|
||||
.resource = veu0_resources,
|
||||
.num_resources = ARRAY_SIZE(veu0_resources),
|
||||
};
|
||||
|
||||
/* VEU1 */
|
||||
static struct uio_info veu1_platform_data = {
|
||||
.name = "VEU1",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x720),
|
||||
};
|
||||
|
||||
static struct resource veu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU1",
|
||||
.start = 0xfe924000,
|
||||
.end = 0xfe9240cb,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.platform_data = &veu1_platform_data,
|
||||
},
|
||||
.resource = veu1_resources,
|
||||
.num_resources = ARRAY_SIZE(veu1_resources),
|
||||
};
|
||||
|
||||
/* VEU2 */
|
||||
static struct uio_info veu2_platform_data = {
|
||||
.name = "VEU2",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x740),
|
||||
};
|
||||
|
||||
static struct resource veu2_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU2",
|
||||
.start = 0xfe928000,
|
||||
.end = 0xfe928307,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu2_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 3,
|
||||
.dev = {
|
||||
.platform_data = &veu2_platform_data,
|
||||
},
|
||||
.resource = veu2_resources,
|
||||
.num_resources = ARRAY_SIZE(veu2_resources),
|
||||
};
|
||||
|
||||
/* VEU3 */
|
||||
static struct uio_info veu3_platform_data = {
|
||||
.name = "VEU3",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x760),
|
||||
};
|
||||
|
||||
static struct resource veu3_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU3",
|
||||
.start = 0xfe92c000,
|
||||
.end = 0xfe92c307,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu3_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 4,
|
||||
.dev = {
|
||||
.platform_data = &veu3_platform_data,
|
||||
},
|
||||
.resource = veu3_resources,
|
||||
.num_resources = ARRAY_SIZE(veu3_resources),
|
||||
};
|
||||
|
||||
/* JPU */
|
||||
static struct uio_info jpu_platform_data = {
|
||||
.name = "JPU",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x560),
|
||||
};
|
||||
|
||||
static struct resource jpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "JPU",
|
||||
.start = 0xfe980000,
|
||||
.end = 0xfe9902d3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device jpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 5,
|
||||
.dev = {
|
||||
.platform_data = &jpu_platform_data,
|
||||
},
|
||||
.resource = jpu_resources,
|
||||
.num_resources = ARRAY_SIZE(jpu_resources),
|
||||
};
|
||||
|
||||
/* SPU2DSP0 */
|
||||
static struct uio_info spu0_platform_data = {
|
||||
.name = "SPU2DSP0",
|
||||
.version = "0",
|
||||
.irq = evt2irq(0x1800),
|
||||
};
|
||||
|
||||
static struct resource spu0_resources[] = {
|
||||
[0] = {
|
||||
.name = "SPU2DSP0",
|
||||
.start = 0xfe200000,
|
||||
.end = 0xfe2fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device spu0_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 6,
|
||||
.dev = {
|
||||
.platform_data = &spu0_platform_data,
|
||||
},
|
||||
.resource = spu0_resources,
|
||||
.num_resources = ARRAY_SIZE(spu0_resources),
|
||||
};
|
||||
|
||||
/* SPU2DSP1 */
|
||||
static struct uio_info spu1_platform_data = {
|
||||
.name = "SPU2DSP1",
|
||||
.version = "0",
|
||||
.irq = evt2irq(0x1820),
|
||||
};
|
||||
|
||||
static struct resource spu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "SPU2DSP1",
|
||||
.start = 0xfe300000,
|
||||
.end = 0xfe3fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device spu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 7,
|
||||
.dev = {
|
||||
.platform_data = &spu1_platform_data,
|
||||
},
|
||||
.resource = spu1_resources,
|
||||
.num_resources = ARRAY_SIZE(spu1_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *sh7372_early_devices[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
@ -620,6 +829,14 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
|
||||
&dma0_device,
|
||||
&dma1_device,
|
||||
&dma2_device,
|
||||
&vpu_device,
|
||||
&veu0_device,
|
||||
&veu1_device,
|
||||
&veu2_device,
|
||||
&veu3_device,
|
||||
&jpu_device,
|
||||
&spu0_device,
|
||||
&spu1_device,
|
||||
};
|
||||
|
||||
void __init sh7372_add_standard_devices(void)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uio_driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
@ -38,7 +39,7 @@ static struct plat_sci_port scif0_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc00), evt2irq(0xc00),
|
||||
evt2irq(0xc00), evt2irq(0xc00) },
|
||||
};
|
||||
@ -57,7 +58,7 @@ static struct plat_sci_port scif1_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc20), evt2irq(0xc20),
|
||||
evt2irq(0xc20), evt2irq(0xc20) },
|
||||
};
|
||||
@ -76,7 +77,7 @@ static struct plat_sci_port scif2_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc40), evt2irq(0xc40),
|
||||
evt2irq(0xc40), evt2irq(0xc40) },
|
||||
};
|
||||
@ -95,7 +96,7 @@ static struct plat_sci_port scif3_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc60), evt2irq(0xc60),
|
||||
evt2irq(0xc60), evt2irq(0xc60) },
|
||||
};
|
||||
@ -114,7 +115,7 @@ static struct plat_sci_port scif4_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xd20), evt2irq(0xd20),
|
||||
evt2irq(0xd20), evt2irq(0xd20) },
|
||||
};
|
||||
@ -133,7 +134,7 @@ static struct plat_sci_port scif5_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xd40), evt2irq(0xd40),
|
||||
evt2irq(0xd40), evt2irq(0xd40) },
|
||||
};
|
||||
@ -152,7 +153,7 @@ static struct plat_sci_port scif6_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
|
||||
intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
|
||||
};
|
||||
@ -171,7 +172,7 @@ static struct plat_sci_port scif7_platform_data = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFB,
|
||||
.irqs = { evt2irq(0xd60), evt2irq(0xd60),
|
||||
evt2irq(0xd60), evt2irq(0xd60) },
|
||||
};
|
||||
@ -215,6 +216,214 @@ static struct platform_device cmt10_device = {
|
||||
.num_resources = ARRAY_SIZE(cmt10_resources),
|
||||
};
|
||||
|
||||
/* VPU */
|
||||
static struct uio_info vpu_platform_data = {
|
||||
.name = "VPU5HG",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x980),
|
||||
};
|
||||
|
||||
static struct resource vpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "VPU",
|
||||
.start = 0xfe900000,
|
||||
.end = 0xfe900157,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device vpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &vpu_platform_data,
|
||||
},
|
||||
.resource = vpu_resources,
|
||||
.num_resources = ARRAY_SIZE(vpu_resources),
|
||||
};
|
||||
|
||||
/* VEU0 */
|
||||
static struct uio_info veu0_platform_data = {
|
||||
.name = "VEU0",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x700),
|
||||
};
|
||||
|
||||
static struct resource veu0_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU0",
|
||||
.start = 0xfe920000,
|
||||
.end = 0xfe9200cb,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu0_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &veu0_platform_data,
|
||||
},
|
||||
.resource = veu0_resources,
|
||||
.num_resources = ARRAY_SIZE(veu0_resources),
|
||||
};
|
||||
|
||||
/* VEU1 */
|
||||
static struct uio_info veu1_platform_data = {
|
||||
.name = "VEU1",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x720),
|
||||
};
|
||||
|
||||
static struct resource veu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU1",
|
||||
.start = 0xfe924000,
|
||||
.end = 0xfe9240cb,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.platform_data = &veu1_platform_data,
|
||||
},
|
||||
.resource = veu1_resources,
|
||||
.num_resources = ARRAY_SIZE(veu1_resources),
|
||||
};
|
||||
|
||||
/* VEU2 */
|
||||
static struct uio_info veu2_platform_data = {
|
||||
.name = "VEU2",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x740),
|
||||
};
|
||||
|
||||
static struct resource veu2_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU2",
|
||||
.start = 0xfe928000,
|
||||
.end = 0xfe928307,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu2_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 3,
|
||||
.dev = {
|
||||
.platform_data = &veu2_platform_data,
|
||||
},
|
||||
.resource = veu2_resources,
|
||||
.num_resources = ARRAY_SIZE(veu2_resources),
|
||||
};
|
||||
|
||||
/* VEU3 */
|
||||
static struct uio_info veu3_platform_data = {
|
||||
.name = "VEU3",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x760),
|
||||
};
|
||||
|
||||
static struct resource veu3_resources[] = {
|
||||
[0] = {
|
||||
.name = "VEU3",
|
||||
.start = 0xfe92c000,
|
||||
.end = 0xfe92c307,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device veu3_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 4,
|
||||
.dev = {
|
||||
.platform_data = &veu3_platform_data,
|
||||
},
|
||||
.resource = veu3_resources,
|
||||
.num_resources = ARRAY_SIZE(veu3_resources),
|
||||
};
|
||||
|
||||
/* JPU */
|
||||
static struct uio_info jpu_platform_data = {
|
||||
.name = "JPU",
|
||||
.version = "0",
|
||||
.irq = intcs_evt2irq(0x560),
|
||||
};
|
||||
|
||||
static struct resource jpu_resources[] = {
|
||||
[0] = {
|
||||
.name = "JPU",
|
||||
.start = 0xfe980000,
|
||||
.end = 0xfe9902d3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device jpu_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 5,
|
||||
.dev = {
|
||||
.platform_data = &jpu_platform_data,
|
||||
},
|
||||
.resource = jpu_resources,
|
||||
.num_resources = ARRAY_SIZE(jpu_resources),
|
||||
};
|
||||
|
||||
/* SPU2DSP0 */
|
||||
static struct uio_info spu0_platform_data = {
|
||||
.name = "SPU2DSP0",
|
||||
.version = "0",
|
||||
.irq = evt2irq(0x1800),
|
||||
};
|
||||
|
||||
static struct resource spu0_resources[] = {
|
||||
[0] = {
|
||||
.name = "SPU2DSP0",
|
||||
.start = 0xfe200000,
|
||||
.end = 0xfe2fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device spu0_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 6,
|
||||
.dev = {
|
||||
.platform_data = &spu0_platform_data,
|
||||
},
|
||||
.resource = spu0_resources,
|
||||
.num_resources = ARRAY_SIZE(spu0_resources),
|
||||
};
|
||||
|
||||
/* SPU2DSP1 */
|
||||
static struct uio_info spu1_platform_data = {
|
||||
.name = "SPU2DSP1",
|
||||
.version = "0",
|
||||
.irq = evt2irq(0x1820),
|
||||
};
|
||||
|
||||
static struct resource spu1_resources[] = {
|
||||
[0] = {
|
||||
.name = "SPU2DSP1",
|
||||
.start = 0xfe300000,
|
||||
.end = 0xfe3fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device spu1_device = {
|
||||
.name = "uio_pdrv_genirq",
|
||||
.id = 7,
|
||||
.dev = {
|
||||
.platform_data = &spu1_platform_data,
|
||||
},
|
||||
.resource = spu1_resources,
|
||||
.num_resources = ARRAY_SIZE(spu1_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *sh7377_early_devices[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
@ -227,10 +436,24 @@ static struct platform_device *sh7377_early_devices[] __initdata = {
|
||||
&cmt10_device,
|
||||
};
|
||||
|
||||
static struct platform_device *sh7377_devices[] __initdata = {
|
||||
&vpu_device,
|
||||
&veu0_device,
|
||||
&veu1_device,
|
||||
&veu2_device,
|
||||
&veu3_device,
|
||||
&jpu_device,
|
||||
&spu0_device,
|
||||
&spu1_device,
|
||||
};
|
||||
|
||||
void __init sh7377_add_standard_devices(void)
|
||||
{
|
||||
platform_add_devices(sh7377_early_devices,
|
||||
ARRAY_SIZE(sh7377_early_devices));
|
||||
|
||||
platform_add_devices(sh7377_devices,
|
||||
ARRAY_SIZE(sh7377_devices));
|
||||
}
|
||||
|
||||
#define SMSTPCR3 0xe615013c
|
||||
|
@ -27,9 +27,11 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/sh_intc.h>
|
||||
#include <linux/sh_timer.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/sh73a0.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
@ -392,6 +394,242 @@ static struct platform_device i2c4_device = {
|
||||
.num_resources = ARRAY_SIZE(i2c4_resources),
|
||||
};
|
||||
|
||||
/* Transmit sizes and respective CHCR register values */
|
||||
enum {
|
||||
XMIT_SZ_8BIT = 0,
|
||||
XMIT_SZ_16BIT = 1,
|
||||
XMIT_SZ_32BIT = 2,
|
||||
XMIT_SZ_64BIT = 7,
|
||||
XMIT_SZ_128BIT = 3,
|
||||
XMIT_SZ_256BIT = 4,
|
||||
XMIT_SZ_512BIT = 5,
|
||||
};
|
||||
|
||||
/* log2(size / 8) - used to calculate number of transfers */
|
||||
#define TS_SHIFT { \
|
||||
[XMIT_SZ_8BIT] = 0, \
|
||||
[XMIT_SZ_16BIT] = 1, \
|
||||
[XMIT_SZ_32BIT] = 2, \
|
||||
[XMIT_SZ_64BIT] = 3, \
|
||||
[XMIT_SZ_128BIT] = 4, \
|
||||
[XMIT_SZ_256BIT] = 5, \
|
||||
[XMIT_SZ_512BIT] = 6, \
|
||||
}
|
||||
|
||||
#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
|
||||
#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
|
||||
#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
|
||||
|
||||
static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
|
||||
{
|
||||
.slave_id = SHDMA_SLAVE_SCIF0_TX,
|
||||
.addr = 0xe6c40020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x21,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF0_RX,
|
||||
.addr = 0xe6c40024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x22,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF1_TX,
|
||||
.addr = 0xe6c50020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x25,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF1_RX,
|
||||
.addr = 0xe6c50024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x26,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF2_TX,
|
||||
.addr = 0xe6c60020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x29,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF2_RX,
|
||||
.addr = 0xe6c60024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x2a,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF3_TX,
|
||||
.addr = 0xe6c70020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x2d,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF3_RX,
|
||||
.addr = 0xe6c70024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x2e,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF4_TX,
|
||||
.addr = 0xe6c80020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x39,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF4_RX,
|
||||
.addr = 0xe6c80024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x3a,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF5_TX,
|
||||
.addr = 0xe6cb0020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x35,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF5_RX,
|
||||
.addr = 0xe6cb0024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x36,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF6_TX,
|
||||
.addr = 0xe6cc0020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x1d,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF6_RX,
|
||||
.addr = 0xe6cc0024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x1e,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF7_TX,
|
||||
.addr = 0xe6cd0020,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x19,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF7_RX,
|
||||
.addr = 0xe6cd0024,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x1a,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF8_TX,
|
||||
.addr = 0xe6c30040,
|
||||
.chcr = CHCR_TX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x3d,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SCIF8_RX,
|
||||
.addr = 0xe6c30060,
|
||||
.chcr = CHCR_RX(XMIT_SZ_8BIT),
|
||||
.mid_rid = 0x3e,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI0_TX,
|
||||
.addr = 0xee100030,
|
||||
.chcr = CHCR_TX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xc1,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI0_RX,
|
||||
.addr = 0xee100030,
|
||||
.chcr = CHCR_RX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xc2,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI1_TX,
|
||||
.addr = 0xee120030,
|
||||
.chcr = CHCR_TX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xc9,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI1_RX,
|
||||
.addr = 0xee120030,
|
||||
.chcr = CHCR_RX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xca,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI2_TX,
|
||||
.addr = 0xee140030,
|
||||
.chcr = CHCR_TX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xcd,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_SDHI2_RX,
|
||||
.addr = 0xee140030,
|
||||
.chcr = CHCR_RX(XMIT_SZ_16BIT),
|
||||
.mid_rid = 0xce,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_TX,
|
||||
.addr = 0xe6bd0034,
|
||||
.chcr = CHCR_TX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xd1,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF_RX,
|
||||
.addr = 0xe6bd0034,
|
||||
.chcr = CHCR_RX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xd2,
|
||||
},
|
||||
};
|
||||
|
||||
#define DMAE_CHANNEL(_offset) \
|
||||
{ \
|
||||
.offset = _offset - 0x20, \
|
||||
.dmars = _offset - 0x20 + 0x40, \
|
||||
}
|
||||
|
||||
static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
|
||||
DMAE_CHANNEL(0x8000),
|
||||
DMAE_CHANNEL(0x8080),
|
||||
DMAE_CHANNEL(0x8100),
|
||||
DMAE_CHANNEL(0x8180),
|
||||
DMAE_CHANNEL(0x8200),
|
||||
DMAE_CHANNEL(0x8280),
|
||||
DMAE_CHANNEL(0x8300),
|
||||
DMAE_CHANNEL(0x8380),
|
||||
DMAE_CHANNEL(0x8400),
|
||||
DMAE_CHANNEL(0x8480),
|
||||
DMAE_CHANNEL(0x8500),
|
||||
DMAE_CHANNEL(0x8580),
|
||||
DMAE_CHANNEL(0x8600),
|
||||
DMAE_CHANNEL(0x8680),
|
||||
DMAE_CHANNEL(0x8700),
|
||||
DMAE_CHANNEL(0x8780),
|
||||
DMAE_CHANNEL(0x8800),
|
||||
DMAE_CHANNEL(0x8880),
|
||||
DMAE_CHANNEL(0x8900),
|
||||
DMAE_CHANNEL(0x8980),
|
||||
};
|
||||
|
||||
static const unsigned int ts_shift[] = TS_SHIFT;
|
||||
|
||||
static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
|
||||
.slave = sh73a0_dmae_slaves,
|
||||
.slave_num = ARRAY_SIZE(sh73a0_dmae_slaves),
|
||||
.channel = sh73a0_dmae_channels,
|
||||
.channel_num = ARRAY_SIZE(sh73a0_dmae_channels),
|
||||
.ts_low_shift = 3,
|
||||
.ts_low_mask = 0x18,
|
||||
.ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
|
||||
.ts_high_mask = 0x00300000,
|
||||
.ts_shift = ts_shift,
|
||||
.ts_shift_num = ARRAY_SIZE(ts_shift),
|
||||
.dmaor_init = DMAOR_DME,
|
||||
};
|
||||
|
||||
static struct resource sh73a0_dmae_resources[] = {
|
||||
{
|
||||
/* Registers including DMAOR and channels including DMARSx */
|
||||
.start = 0xfe000020,
|
||||
.end = 0xfe008a00 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
/* DMA error IRQ */
|
||||
.start = gic_spi(129),
|
||||
.end = gic_spi(129),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
/* IRQ for channels 0-19 */
|
||||
.start = gic_spi(109),
|
||||
.end = gic_spi(128),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device dma0_device = {
|
||||
.name = "sh-dma-engine",
|
||||
.id = 0,
|
||||
.resource = sh73a0_dmae_resources,
|
||||
.num_resources = ARRAY_SIZE(sh73a0_dmae_resources),
|
||||
.dev = {
|
||||
.platform_data = &sh73a0_dmae_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh73a0_early_devices[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
@ -413,10 +651,16 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
|
||||
&i2c2_device,
|
||||
&i2c3_device,
|
||||
&i2c4_device,
|
||||
&dma0_device,
|
||||
};
|
||||
|
||||
#define SRCR2 0xe61580b0
|
||||
|
||||
void __init sh73a0_add_standard_devices(void)
|
||||
{
|
||||
/* Clear software reset bit on SY-DMAC module */
|
||||
__raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
|
||||
|
||||
platform_add_devices(sh73a0_early_devices,
|
||||
ARRAY_SIZE(sh73a0_early_devices));
|
||||
platform_add_devices(sh73a0_late_devices,
|
||||
|
260
arch/arm/mach-shmobile/sleep-sh7372.S
Normal file
260
arch/arm/mach-shmobile/sleep-sh7372.S
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* sh7372 lowlevel sleep code for "Core Standby Mode"
|
||||
*
|
||||
* Copyright (C) 2011 Magnus Damm
|
||||
*
|
||||
* In "Core Standby Mode" the ARM core is off, but L2 cache is still on
|
||||
*
|
||||
* Based on mach-omap2/sleep34xx.S
|
||||
*
|
||||
* (C) Copyright 2007 Texas Instruments
|
||||
* Karthik Dasu <karthik-dp@ti.com>
|
||||
*
|
||||
* (C) Copyright 2004 Texas Instruments, <www.ti.com>
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#define SMFRAM 0xe6a70000
|
||||
|
||||
.align
|
||||
kernel_flush:
|
||||
.word v7_flush_dcache_all
|
||||
|
||||
.align 3
|
||||
ENTRY(sh7372_cpu_suspend)
|
||||
stmfd sp!, {r0-r12, lr} @ save registers on stack
|
||||
|
||||
ldr r8, =SMFRAM
|
||||
|
||||
mov r4, sp @ Store sp
|
||||
mrs r5, spsr @ Store spsr
|
||||
mov r6, lr @ Store lr
|
||||
stmia r8!, {r4-r6}
|
||||
|
||||
mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register
|
||||
mrc p15, 0, r5, c2, c0, 0 @ TTBR0
|
||||
mrc p15, 0, r6, c2, c0, 1 @ TTBR1
|
||||
mrc p15, 0, r7, c2, c0, 2 @ TTBCR
|
||||
stmia r8!, {r4-r7}
|
||||
|
||||
mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register
|
||||
mrc p15, 0, r5, c10, c2, 0 @ PRRR
|
||||
mrc p15, 0, r6, c10, c2, 1 @ NMRR
|
||||
stmia r8!,{r4-r6}
|
||||
|
||||
mrc p15, 0, r4, c13, c0, 1 @ Context ID
|
||||
mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
|
||||
mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
|
||||
mrs r7, cpsr @ Store current cpsr
|
||||
stmia r8!, {r4-r7}
|
||||
|
||||
mrc p15, 0, r4, c1, c0, 0 @ save control register
|
||||
stmia r8!, {r4}
|
||||
|
||||
/*
|
||||
* jump out to kernel flush routine
|
||||
* - reuse that code is better
|
||||
* - it executes in a cached space so is faster than refetch per-block
|
||||
* - should be faster and will change with kernel
|
||||
* - 'might' have to copy address, load and jump to it
|
||||
* Flush all data from the L1 data cache before disabling
|
||||
* SCTLR.C bit.
|
||||
*/
|
||||
ldr r1, kernel_flush
|
||||
mov lr, pc
|
||||
bx r1
|
||||
|
||||
/*
|
||||
* Clear the SCTLR.C bit to prevent further data cache
|
||||
* allocation. Clearing SCTLR.C would make all the data accesses
|
||||
* strongly ordered and would not hit the cache.
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #(1 << 2) @ Disable the C bit
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
isb
|
||||
|
||||
/*
|
||||
* Invalidate L1 data cache. Even though only invalidate is
|
||||
* necessary exported flush API is used here. Doing clean
|
||||
* on already clean cache would be almost NOP.
|
||||
*/
|
||||
ldr r1, kernel_flush
|
||||
blx r1
|
||||
/*
|
||||
* The kernel doesn't interwork: v7_flush_dcache_all in particluar will
|
||||
* always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
|
||||
* This sequence switches back to ARM. Note that .align may insert a
|
||||
* nop: bx pc needs to be word-aligned in order to work.
|
||||
*/
|
||||
THUMB( .thumb )
|
||||
THUMB( .align )
|
||||
THUMB( bx pc )
|
||||
THUMB( nop )
|
||||
.arm
|
||||
|
||||
/* Data memory barrier and Data sync barrier */
|
||||
dsb
|
||||
dmb
|
||||
|
||||
/*
|
||||
* ===================================
|
||||
* == WFI instruction => Enter idle ==
|
||||
* ===================================
|
||||
*/
|
||||
wfi @ wait for interrupt
|
||||
|
||||
/*
|
||||
* ===================================
|
||||
* == Resume path for non-OFF modes ==
|
||||
* ===================================
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
tst r0, #(1 << 2) @ Check C bit enabled?
|
||||
orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
|
||||
mcreq p15, 0, r0, c1, c0, 0
|
||||
isb
|
||||
|
||||
/*
|
||||
* ===================================
|
||||
* == Exit point from non-OFF modes ==
|
||||
* ===================================
|
||||
*/
|
||||
ldmfd sp!, {r0-r12, pc} @ restore regs and return
|
||||
|
||||
.pool
|
||||
|
||||
.align 12
|
||||
.text
|
||||
.global sh7372_cpu_resume
|
||||
sh7372_cpu_resume:
|
||||
|
||||
mov r1, #0
|
||||
/*
|
||||
* Invalidate all instruction caches to PoU
|
||||
* and flush branch target cache
|
||||
*/
|
||||
mcr p15, 0, r1, c7, c5, 0
|
||||
|
||||
ldr r3, =SMFRAM
|
||||
|
||||
ldmia r3!, {r4-r6}
|
||||
mov sp, r4 @ Restore sp
|
||||
msr spsr_cxsf, r5 @ Restore spsr
|
||||
mov lr, r6 @ Restore lr
|
||||
|
||||
ldmia r3!, {r4-r7}
|
||||
mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register
|
||||
mcr p15, 0, r5, c2, c0, 0 @ TTBR0
|
||||
mcr p15, 0, r6, c2, c0, 1 @ TTBR1
|
||||
mcr p15, 0, r7, c2, c0, 2 @ TTBCR
|
||||
|
||||
ldmia r3!,{r4-r6}
|
||||
mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register
|
||||
mcr p15, 0, r5, c10, c2, 0 @ PRRR
|
||||
mcr p15, 0, r6, c10, c2, 1 @ NMRR
|
||||
|
||||
ldmia r3!,{r4-r7}
|
||||
mcr p15, 0, r4, c13, c0, 1 @ Context ID
|
||||
mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
|
||||
mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
|
||||
msr cpsr, r7 @ store cpsr
|
||||
|
||||
/* Starting to enable MMU here */
|
||||
mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
|
||||
/* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
|
||||
and r7, #0x7
|
||||
cmp r7, #0x0
|
||||
beq usettbr0
|
||||
ttbr_error:
|
||||
/*
|
||||
* More work needs to be done to support N[0:2] value other than 0
|
||||
* So looping here so that the error can be detected
|
||||
*/
|
||||
b ttbr_error
|
||||
|
||||
.align
|
||||
cache_pred_disable_mask:
|
||||
.word 0xFFFFE7FB
|
||||
ttbrbit_mask:
|
||||
.word 0xFFFFC000
|
||||
table_index_mask:
|
||||
.word 0xFFF00000
|
||||
table_entry:
|
||||
.word 0x00000C02
|
||||
usettbr0:
|
||||
|
||||
mrc p15, 0, r2, c2, c0, 0
|
||||
ldr r5, ttbrbit_mask
|
||||
and r2, r5
|
||||
mov r4, pc
|
||||
ldr r5, table_index_mask
|
||||
and r4, r5 @ r4 = 31 to 20 bits of pc
|
||||
/* Extract the value to be written to table entry */
|
||||
ldr r6, table_entry
|
||||
/* r6 has the value to be written to table entry */
|
||||
add r6, r6, r4
|
||||
/* Getting the address of table entry to modify */
|
||||
lsr r4, #18
|
||||
/* r2 has the location which needs to be modified */
|
||||
add r2, r4
|
||||
ldr r4, [r2]
|
||||
str r6, [r2] /* modify the table entry */
|
||||
|
||||
mov r7, r6
|
||||
mov r5, r2
|
||||
mov r6, r4
|
||||
/* r5 = original page table address */
|
||||
/* r6 = original page table data */
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
|
||||
mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
|
||||
mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
|
||||
mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
|
||||
|
||||
/*
|
||||
* Restore control register. This enables the MMU.
|
||||
* The caches and prediction are not enabled here, they
|
||||
* will be enabled after restoring the MMU table entry.
|
||||
*/
|
||||
ldmia r3!, {r4}
|
||||
stmia r3!, {r5} /* save original page table address */
|
||||
stmia r3!, {r6} /* save original page table data */
|
||||
stmia r3!, {r7} /* save modified page table data */
|
||||
|
||||
ldr r2, cache_pred_disable_mask
|
||||
and r4, r2
|
||||
mcr p15, 0, r4, c1, c0, 0
|
||||
dsb
|
||||
isb
|
||||
|
||||
ldr r0, =restoremmu_on
|
||||
bx r0
|
||||
|
||||
/*
|
||||
* ==============================
|
||||
* == Exit point from OFF mode ==
|
||||
* ==============================
|
||||
*/
|
||||
restoremmu_on:
|
||||
|
||||
ldmfd sp!, {r0-r12, pc} @ restore regs and return
|
@ -59,6 +59,11 @@ unsigned int __init sh73a0_get_core_count(void)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
/* twd_base needs to be initialized before percpu_timer_setup() */
|
||||
twd_base = (void __iomem *)0xf0000600;
|
||||
#endif
|
||||
|
||||
return scu_get_core_count(scu_base);
|
||||
}
|
||||
|
||||
@ -82,10 +87,6 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
|
||||
|
||||
void __init sh73a0_smp_prepare_cpus(void)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
twd_base = (void __iomem *)0xf0000600;
|
||||
#endif
|
||||
|
||||
scu_enable(scu_base_addr());
|
||||
|
||||
/* Map the reset vector (in headsmp.S) */
|
||||
|
47
arch/arm/mach-shmobile/suspend.c
Normal file
47
arch/arm/mach-shmobile/suspend.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Suspend-to-RAM support code for SH-Mobile ARM
|
||||
*
|
||||
* Copyright (C) 2011 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static int shmobile_suspend_default_enter(suspend_state_t suspend_state)
|
||||
{
|
||||
cpu_do_idle();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shmobile_suspend_begin(suspend_state_t state)
|
||||
{
|
||||
disable_hlt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void shmobile_suspend_end(void)
|
||||
{
|
||||
enable_hlt();
|
||||
}
|
||||
|
||||
struct platform_suspend_ops shmobile_suspend_ops = {
|
||||
.begin = shmobile_suspend_begin,
|
||||
.end = shmobile_suspend_end,
|
||||
.enter = shmobile_suspend_default_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init shmobile_suspend_init(void)
|
||||
{
|
||||
suspend_set_ops(&shmobile_suspend_ops);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(shmobile_suspend_init);
|
@ -213,12 +213,17 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
|
||||
struct sh_dmae_device, common);
|
||||
struct sh_dmae_pdata *pdata = shdev->pdata;
|
||||
const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
|
||||
u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
|
||||
u16 __iomem *addr = shdev->dmars;
|
||||
int shift = chan_pdata->dmars_bit;
|
||||
|
||||
if (dmae_is_busy(sh_chan))
|
||||
return -EBUSY;
|
||||
|
||||
/* in the case of a missing DMARS resource use first memory window */
|
||||
if (!addr)
|
||||
addr = (u16 __iomem *)shdev->chan_reg;
|
||||
addr += chan_pdata->dmars / sizeof(u16);
|
||||
|
||||
__raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
|
||||
addr);
|
||||
|
||||
@ -1078,7 +1083,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
unsigned long irqflags = IRQF_DISABLED,
|
||||
chan_flag[SH_DMAC_MAX_CHANNELS] = {};
|
||||
int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
|
||||
int err, i, irq_cnt = 0, irqres = 0;
|
||||
int err, i, irq_cnt = 0, irqres = 0, irq_cap = 0;
|
||||
struct sh_dmae_device *shdev;
|
||||
struct resource *chan, *dmars, *errirq_res, *chanirq_res;
|
||||
|
||||
@ -1087,7 +1092,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
|
||||
chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
/* DMARS area is optional, if absent, this controller cannot do slave DMA */
|
||||
/* DMARS area is optional */
|
||||
dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
/*
|
||||
* IRQ resources:
|
||||
@ -1154,7 +1159,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
INIT_LIST_HEAD(&shdev->common.channels);
|
||||
|
||||
dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
|
||||
if (dmars)
|
||||
if (pdata->slave && pdata->slave_num)
|
||||
dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
|
||||
|
||||
shdev->common.device_alloc_chan_resources
|
||||
@ -1203,8 +1208,13 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
!platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
|
||||
/* Special case - all multiplexed */
|
||||
for (; irq_cnt < pdata->channel_num; irq_cnt++) {
|
||||
chan_irq[irq_cnt] = chanirq_res->start;
|
||||
chan_flag[irq_cnt] = IRQF_SHARED;
|
||||
if (irq_cnt < SH_DMAC_MAX_CHANNELS) {
|
||||
chan_irq[irq_cnt] = chanirq_res->start;
|
||||
chan_flag[irq_cnt] = IRQF_SHARED;
|
||||
} else {
|
||||
irq_cap = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
@ -1218,22 +1228,32 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
"Found IRQ %d for channel %d\n",
|
||||
i, irq_cnt);
|
||||
chan_irq[irq_cnt++] = i;
|
||||
|
||||
if (irq_cnt >= SH_DMAC_MAX_CHANNELS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (irq_cnt >= SH_DMAC_MAX_CHANNELS) {
|
||||
irq_cap = 1;
|
||||
break;
|
||||
}
|
||||
chanirq_res = platform_get_resource(pdev,
|
||||
IORESOURCE_IRQ, ++irqres);
|
||||
} while (irq_cnt < pdata->channel_num && chanirq_res);
|
||||
}
|
||||
|
||||
if (irq_cnt < pdata->channel_num)
|
||||
goto eirqres;
|
||||
|
||||
/* Create DMA Channel */
|
||||
for (i = 0; i < pdata->channel_num; i++) {
|
||||
for (i = 0; i < irq_cnt; i++) {
|
||||
err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
|
||||
if (err)
|
||||
goto chan_probe_err;
|
||||
}
|
||||
|
||||
if (irq_cap)
|
||||
dev_notice(&pdev->dev, "Attempting to register %d DMA "
|
||||
"channels when a maximum of %d are supported.\n",
|
||||
pdata->channel_num, SH_DMAC_MAX_CHANNELS);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
platform_set_drvdata(pdev, shdev);
|
||||
@ -1243,7 +1263,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||
|
||||
chan_probe_err:
|
||||
sh_dmae_chan_remove(shdev);
|
||||
eirqres:
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
|
||||
free_irq(errirq, shdev);
|
||||
eirq_err:
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#define SH_DMAC_MAX_CHANNELS 6
|
||||
#define SH_DMAC_MAX_CHANNELS 20
|
||||
#define SH_DMA_SLAVE_NUMBER 256
|
||||
#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user