|
@@ -510,3 +510,170 @@ static struct sh_dmae_pdata usb_dma_platform_data = {
|
|
.slave_only = 1,
|
|
.slave_only = 1,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static struct resource r8a7740_usb_dma_resources[] = {
|
|
|
|
+ {
|
|
|
|
+ /* Channel registers and DMAOR */
|
|
|
|
+ .start = 0xe68a0020,
|
|
|
|
+ .end = 0xe68a0064 - 1,
|
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ /* VCR/SWR/DMICR */
|
|
|
|
+ .start = 0xe68a0000,
|
|
|
|
+ .end = 0xe68a0014 - 1,
|
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ /* IRQ for channels */
|
|
|
|
+ .start = evt2irq(0x0a00),
|
|
|
|
+ .end = evt2irq(0x0a00),
|
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device usb_dma_device = {
|
|
|
|
+ .name = "sh-dma-engine",
|
|
|
|
+ .id = 3,
|
|
|
|
+ .resource = r8a7740_usb_dma_resources,
|
|
|
|
+ .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources),
|
|
|
|
+ .dev = {
|
|
|
|
+ .platform_data = &usb_dma_platform_data,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* I2C */
|
|
|
|
+static struct resource i2c0_resources[] = {
|
|
|
|
+ [0] = {
|
|
|
|
+ .name = "IIC0",
|
|
|
|
+ .start = 0xfff20000,
|
|
|
|
+ .end = 0xfff20425 - 1,
|
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
|
+ },
|
|
|
|
+ [1] = {
|
|
|
|
+ .start = intcs_evt2irq(0xe00),
|
|
|
|
+ .end = intcs_evt2irq(0xe60),
|
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct resource i2c1_resources[] = {
|
|
|
|
+ [0] = {
|
|
|
|
+ .name = "IIC1",
|
|
|
|
+ .start = 0xe6c20000,
|
|
|
|
+ .end = 0xe6c20425 - 1,
|
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
|
+ },
|
|
|
|
+ [1] = {
|
|
|
|
+ .start = evt2irq(0x780), /* IIC1_ALI1 */
|
|
|
|
+ .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
|
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device i2c0_device = {
|
|
|
|
+ .name = "i2c-sh_mobile",
|
|
|
|
+ .id = 0,
|
|
|
|
+ .resource = i2c0_resources,
|
|
|
|
+ .num_resources = ARRAY_SIZE(i2c0_resources),
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device i2c1_device = {
|
|
|
|
+ .name = "i2c-sh_mobile",
|
|
|
|
+ .id = 1,
|
|
|
|
+ .resource = i2c1_resources,
|
|
|
|
+ .num_resources = ARRAY_SIZE(i2c1_resources),
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct resource pmu_resources[] = {
|
|
|
|
+ [0] = {
|
|
|
|
+ .start = evt2irq(0x19a0),
|
|
|
|
+ .end = evt2irq(0x19a0),
|
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device pmu_device = {
|
|
|
|
+ .name = "arm-pmu",
|
|
|
|
+ .id = -1,
|
|
|
|
+ .num_resources = ARRAY_SIZE(pmu_resources),
|
|
|
|
+ .resource = pmu_resources,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device *r8a7740_late_devices[] __initdata = {
|
|
|
|
+ &i2c0_device,
|
|
|
|
+ &i2c1_device,
|
|
|
|
+ &dma0_device,
|
|
|
|
+ &dma1_device,
|
|
|
|
+ &dma2_device,
|
|
|
|
+ &usb_dma_device,
|
|
|
|
+ &pmu_device,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * r8a7740 chip has lasting errata on MERAM buffer.
|
|
|
|
+ * this is work-around for it.
|
|
|
|
+ * see
|
|
|
|
+ * "Media RAM (MERAM)" on r8a7740 documentation
|
|
|
|
+ */
|
|
|
|
+#define MEBUFCNTR 0xFE950098
|
|
|
|
+void r8a7740_meram_workaround(void)
|
|
|
|
+{
|
|
|
|
+ void __iomem *reg;
|
|
|
|
+
|
|
|
|
+ reg = ioremap_nocache(MEBUFCNTR, 4);
|
|
|
|
+ if (reg) {
|
|
|
|
+ iowrite32(0x01600164, reg);
|
|
|
|
+ iounmap(reg);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define ICCR 0x0004
|
|
|
|
+#define ICSTART 0x0070
|
|
|
|
+
|
|
|
|
+#define i2c_read(reg, offset) ioread8(reg + offset)
|
|
|
|
+#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * r8a7740 chip has lasting errata on I2C I/O pad reset.
|
|
|
|
+ * this is work-around for it.
|
|
|
|
+ */
|
|
|
|
+static void r8a7740_i2c_workaround(struct platform_device *pdev)
|
|
|
|
+{
|
|
|
|
+ struct resource *res;
|
|
|
|
+ void __iomem *reg;
|
|
|
|
+
|
|
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
|
+ if (unlikely(!res)) {
|
|
|
|
+ pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ reg = ioremap(res->start, resource_size(res));
|
|
|
|
+ if (unlikely(!reg)) {
|
|
|
|
+ pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
|
|
|
|
+ i2c_read(reg, ICCR); /* dummy read */
|
|
|
|
+
|
|
|
|
+ i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
|
|
|
|
+ i2c_read(reg, ICSTART); /* dummy read */
|
|
|
|
+
|
|
|
|
+ udelay(10);
|
|
|
|
+
|
|
|
|
+ i2c_write(reg, ICCR, 0x01);
|
|
|
|
+ i2c_write(reg, ICSTART, 0x00);
|
|
|
|
+
|
|
|
|
+ udelay(10);
|
|
|
|
+
|
|
|
|
+ i2c_write(reg, ICCR, 0x10);
|
|
|
|
+ udelay(10);
|
|
|
|
+ i2c_write(reg, ICCR, 0x00);
|
|
|
|
+ udelay(10);
|
|
|
|
+ i2c_write(reg, ICCR, 0x10);
|
|
|
|
+ udelay(10);
|
|
|
|
+
|
|
|
|
+ iounmap(reg);
|
|
|
|
+}
|
|
|
|
+
|