2013-07-23 10:51:04

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 00/15] ARM: shmobile: move DMAC configuration data in the driver

An updated version of an shdma driver platform driver conversion and Device
Tree support. No functional changes since v2/v3, just made some structs
const, updated documentation, removed an unused generic DT match entry,
adjusted file order in the Makefile.

Patch 9 "DMA: shdma: support referencing specific DMACs within a
multiplexer in DT" is actually an RFC. It proposes a method to support
referencing a specific DMAC ninstance within a multiplexer DT node from
slave DT nodes. As described in the documentation, the idea is to add a
"#dma-cells" property to DMAC instances, that has to be made available
for such targeted channel allocation. AFAICS, this is the only way to
support both muxed and targeted referencing without core code
modifications.

Cc: Guennadi Liakhovetski <[email protected]>

Guennadi Liakhovetski (15):
DMA: shdma: add support for DMAC configuration data, supplied via
device ID
DMA: shdma: add r8a7740 DMAC data to the device ID table
DMA: shdma: add r8a73a4 DMAC data to the device ID table
DMA: shdma: make a pointer const
DMA: shdma: pass SoC-specific configuration to the driver via OF
matching
DMA: shdma: make multiplexer platform data optional
DMA: shdma: add sh73a0 DMAC data to the device ID table
DMA: shdma: move two macros to a header
DMA: shdma: support referencing specific DMACs within a multiplexer
in DT
ARM: shmobile: r8a73a4: add a DMAC platform device and clock for it
ARM: shmobile: r8a7740: switch DMAC controllers to using device ID
data
ARM: shmobile: r8a7740: add DT nodes and clock aliases for three DMAC
instances
ARM: shmobile: r8a73a4: add a DT node and a clock alias for the DMAC
ARM: shmobile: sh73a0: switch DMAC controllers to using device ID
data
ARM: shmobile: r8a7740: add support for 2 RTDMACs

Documentation/devicetree/bindings/dma/shdma.txt | 23 +++-
arch/arm/boot/dts/r8a73a4.dtsi | 43 ++++++
arch/arm/boot/dts/r8a7740.dtsi | 95 ++++++++++++
arch/arm/mach-shmobile/clock-r8a73a4.c | 5 +-
arch/arm/mach-shmobile/clock-r8a7740.c | 17 ++-
arch/arm/mach-shmobile/clock-sh73a0.c | 2 +-
arch/arm/mach-shmobile/include/mach/r8a73a4.h | 9 +
arch/arm/mach-shmobile/setup-r8a73a4.c | 17 ++
arch/arm/mach-shmobile/setup-r8a7740.c | 178 +++++++++-------------
arch/arm/mach-shmobile/setup-sh73a0.c | 182 +----------------------
drivers/dma/sh/Kconfig | 12 ++
drivers/dma/sh/Makefile | 5 +
drivers/dma/sh/shdma-base.c | 3 -
drivers/dma/sh/shdma-of.c | 5 -
drivers/dma/sh/shdma-r8a73a4.c | 75 +++++++++
drivers/dma/sh/shdma-r8a7740.c | 95 ++++++++++++
drivers/dma/sh/shdma-sh73a0.c | 181 ++++++++++++++++++++++
drivers/dma/sh/shdma.h | 30 ++++-
drivers/dma/sh/{shdma.c => shdmac.c} | 104 ++++++++++++-
include/linux/shdma-base.h | 3 +
20 files changed, 775 insertions(+), 309 deletions(-)
create mode 100644 drivers/dma/sh/shdma-r8a73a4.c
create mode 100644 drivers/dma/sh/shdma-r8a7740.c
create mode 100644 drivers/dma/sh/shdma-sh73a0.c
rename drivers/dma/sh/{shdma.c => shdmac.c} (89%)

--
1.7.2.5

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/


2013-07-23 10:50:17

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 01/15] DMA: shdma: add support for DMAC configuration data, supplied via device ID

This is going to facilitate DT support by eliminating the need in AUXDATA
and avoiding creating complex DT data. This also fits well with DMAC
devices, because SoCs with them often have multiple identical DMAC
instances and it is perfectly valid to use a single configuration data set
for all of them.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
drivers/dma/sh/Makefile | 2 ++
drivers/dma/sh/{shdma.c => shdmac.c} | 11 ++++++++++-
2 files changed, 12 insertions(+), 1 deletions(-)
rename drivers/dma/sh/{shdma.c => shdmac.c} (98%)

diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index c962138..893ee09 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o
obj-$(CONFIG_SH_DMAE) += shdma.o
+shdma-y := shdmac.o
+shdma-objs := $(shdma-y)
obj-$(CONFIG_SUDMAC) += sudmac.o
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdmac.c
similarity index 98%
rename from drivers/dma/sh/shdma.c
rename to drivers/dma/sh/shdmac.c
index 5153af1..751a4e3 100644
--- a/drivers/dma/sh/shdma.c
+++ b/drivers/dma/sh/shdmac.c
@@ -665,7 +665,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {

static int sh_dmae_probe(struct platform_device *pdev)
{
- struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
+ struct sh_dmae_pdata *pdata;
unsigned long irqflags = IRQF_DISABLED,
chan_flag[SH_DMAE_MAX_CHANNELS] = {};
int errirq, chan_irq[SH_DMAE_MAX_CHANNELS];
@@ -674,6 +674,8 @@ static int sh_dmae_probe(struct platform_device *pdev)
struct dma_device *dma_dev;
struct resource *chan, *dmars, *errirq_res, *chanirq_res;

+ pdata = (void *)pdev->id_entry->driver_data ? : pdev->dev.platform_data;
+
/* get platform data */
if (!pdata || !pdata->channel_num)
return -ENODEV;
@@ -903,6 +905,12 @@ static const struct of_device_id sh_dmae_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sh_dmae_of_match);

+const struct platform_device_id sh_dmae_id_table[] = {
+ {.name = SH_DMAE_DRV_NAME,},
+ {}
+};
+MODULE_DEVICE_TABLE(platform, sh_dmae_id_table);
+
static struct platform_driver sh_dmae_driver = {
.driver = {
.owner = THIS_MODULE,
@@ -912,6 +920,7 @@ static struct platform_driver sh_dmae_driver = {
},
.remove = sh_dmae_remove,
.shutdown = sh_dmae_shutdown,
+ .id_table = sh_dmae_id_table,
};

static int __init sh_dmae_init(void)
--
1.7.2.5

2013-07-23 10:51:08

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 07/15] DMA: shdma: add sh73a0 DMAC data to the device ID table

This configuration data will be re-used, when DMAC DT support is added to
sh73a0, DMAC platform data in setup-sh73a0.c will be removed.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

v4: add documentation

Documentation/devicetree/bindings/dma/shdma.txt | 1 +
drivers/dma/sh/Kconfig | 4 +
drivers/dma/sh/Makefile | 1 +
drivers/dma/sh/shdma-sh73a0.c | 181 +++++++++++++++++++++++
drivers/dma/sh/shdma.h | 7 +
drivers/dma/sh/shdmac.c | 2 +
6 files changed, 196 insertions(+), 0 deletions(-)
create mode 100644 drivers/dma/sh/shdma-sh73a0.c

diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt
index be0f82b..6b015d6 100644
--- a/Documentation/devicetree/bindings/dma/shdma.txt
+++ b/Documentation/devicetree/bindings/dma/shdma.txt
@@ -25,6 +25,7 @@ Required properties:
- compatible: should be one of
"renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC
"renesas,shdma-r8a7740" for the DMACs (not RTDMAC) on r8a7740
+ "renesas,shdma-sh73a0" for the DMACs on sh73a0

Example:
dmac: dma-mux0 {
diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 6921ba2..040d780 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -30,3 +30,7 @@ config SHDMA_R8A73A4
config SHDMA_R8A7740
def_bool y
depends on ARCH_R8A7740 && SH_DMAE != n
+
+config SHDMA_SH73A0
+ def_bool y
+ depends on ARCH_SH73A0 && SH_DMAE != n
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index 8352bfb..4facc1f 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -3,5 +3,6 @@ obj-$(CONFIG_SH_DMAE) += shdma.o
shdma-y := shdmac.o
shdma-$(CONFIG_SHDMA_R8A73A4) += shdma-r8a73a4.o
shdma-$(CONFIG_SHDMA_R8A7740) += shdma-r8a7740.o
+shdma-$(CONFIG_SHDMA_SH73A0) += shdma-sh73a0.o
shdma-objs := $(shdma-y)
obj-$(CONFIG_SUDMAC) += sudmac.o
diff --git a/drivers/dma/sh/shdma-sh73a0.c b/drivers/dma/sh/shdma-sh73a0.c
new file mode 100644
index 0000000..59b311e
--- /dev/null
+++ b/drivers/dma/sh/shdma-sh73a0.c
@@ -0,0 +1,181 @@
+#include <linux/sh_dma.h>
+
+#include <mach/dma-register.h>
+#include <mach/sh73a0.h>
+
+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),
+};
+
+const struct sh_dmae_pdata sh73a0_dma_pdata = {
+ .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 = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+};
diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
index ae0c65f..8394424 100644
--- a/drivers/dma/sh/shdma.h
+++ b/drivers/dma/sh/shdma.h
@@ -75,4 +75,11 @@ extern struct sh_dmae_pdata r8a7740_dma_pdata;
#define r8a7740_shdma_devid NULL
#endif

+#ifdef CONFIG_SHDMA_SH73A0
+extern const struct sh_dmae_pdata sh73a0_dma_pdata;
+#define sh73a0_shdma_devid &sh73a0_dma_pdata
+#else
+#define sh73a0_shdma_devid NULL
+#endif
+
#endif /* __DMA_SHDMA_H */
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index aa90ea2..9ee3c28 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -668,6 +668,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
static const struct of_device_id sh_dmae_of_match[] = {
{.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,},
{.compatible = "renesas,shdma-r8a7740", .data = r8a7740_shdma_devid,},
+ {.compatible = "renesas,shdma-sh73a0", .data = sh73a0_shdma_devid,},
{}
};
MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
@@ -916,6 +917,7 @@ const struct platform_device_id sh_dmae_id_table[] = {
{.name = SH_DMAE_DRV_NAME,},
{.name = "shdma-r8a73a4", .driver_data = (kernel_ulong_t)r8a73a4_shdma_devid,},
{.name = "shdma-r8a7740", .driver_data = (kernel_ulong_t)r8a7740_shdma_devid,},
+ {.name = "shdma-sh73a0", .driver_data = (kernel_ulong_t)sh73a0_shdma_devid,},
{}
};
MODULE_DEVICE_TABLE(platform, sh_dmae_id_table);
--
1.7.2.5

2013-07-23 10:51:14

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 13/15] ARM: shmobile: r8a73a4: add a DT node and a clock alias for the DMAC

Add a DT node for the only system DMAC instance on r8a73a4. The RT DMAC
can be added later under the same multiplexer, because they can serve the
same slaves and use the same MID-RID values. Configuration data is
supplied to the driver, using a compatibility match string.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
arch/arm/boot/dts/r8a73a4.dtsi | 43 ++++++++++++++++++++++++++++++++
arch/arm/mach-shmobile/clock-r8a73a4.c | 1 +
2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
index e344b10..3c9c7f2 100644
--- a/arch/arm/boot/dts/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -78,6 +78,49 @@
<0 56 4>, <0 57 4>;
};

+ dmac: dma-multiplexer@0 {
+ compatible = "renesas,shdma-mux";
+ #dma-cells = <1>;
+ dma-channels = <20>;
+ dma-requests = <256>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ dma0: dma-controller@e6700020 {
+ compatible = "renesas,shdma-r8a73a4";
+ reg = <0 0xe6700020 0 0x89e0>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 220 4
+ 0 200 4
+ 0 201 4
+ 0 202 4
+ 0 203 4
+ 0 204 4
+ 0 205 4
+ 0 206 4
+ 0 207 4
+ 0 208 4
+ 0 209 4
+ 0 210 4
+ 0 211 4
+ 0 212 4
+ 0 213 4
+ 0 214 4
+ 0 215 4
+ 0 216 4
+ 0 217 4
+ 0 218 4
+ 0 219 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19";
+ };
+ };
+
thermal@e61f0000 {
compatible = "renesas,rcar-thermal";
reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index cd62b11..7d6d2a3 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -580,6 +580,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
CLKDEV_DEV_ID("shdma-r8a73a4.0", &mstp_clks[MSTP218]),
+ CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]),
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
--
1.7.2.5

2013-07-23 10:51:15

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 10/15] ARM: shmobile: r8a73a4: add a DMAC platform device and clock for it

Add a DMAC platform device and clock definitions for it on r8a73a4.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
arch/arm/mach-shmobile/clock-r8a73a4.c | 4 +++-
arch/arm/mach-shmobile/include/mach/r8a73a4.h | 9 +++++++++
arch/arm/mach-shmobile/setup-r8a73a4.c | 17 +++++++++++++++++
3 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 8ea5ef6..cd62b11 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = {

/* MSTP */
enum {
- MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
+ MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
MSTP329, MSTP323, MSTP318, MSTP317, MSTP316,
MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300,
MSTP411, MSTP410, MSTP409,
@@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */
[MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */
[MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */
+ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */
[MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */
[MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */
[MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */
@@ -578,6 +579,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("shdma-r8a73a4.0", &mstp_clks[MSTP218]),
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h
index f3a9b70..3a0ea48 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h
@@ -1,6 +1,15 @@
#ifndef __ASM_R8A73A4_H__
#define __ASM_R8A73A4_H__

+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_INVALID,
+ SHDMA_SLAVE_MMCIF0_TX,
+ SHDMA_SLAVE_MMCIF0_RX,
+ SHDMA_SLAVE_MMCIF1_TX,
+ SHDMA_SLAVE_MMCIF1_RX,
+};
+
void r8a73a4_add_standard_devices(void);
void r8a73a4_add_dt_devices(void);
void r8a73a4_clock_init(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
index 630ea4e..ad7180e 100644
--- a/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -199,12 +199,29 @@ void __init r8a73a4_add_dt_devices(void)
r8a7790_register_cmt(10);
}

+/* DMA */
+static struct resource dma_resources[] = {
+ DEFINE_RES_MEM(0xe6700020, 0x89e0),
+ DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"),
+ {
+ /* IRQ for channels 0-19 */
+ .start = gic_spi(200),
+ .end = gic_spi(219),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define r8a73a4_register_dmac() \
+ platform_device_register_simple("shdma-r8a73a4", 0, \
+ dma_resources, ARRAY_SIZE(dma_resources))
+
void __init r8a73a4_add_standard_devices(void)
{
r8a73a4_add_dt_devices();
r8a73a4_register_irqc(0);
r8a73a4_register_irqc(1);
r8a73a4_register_thermal();
+ r8a73a4_register_dmac();
}

void __init r8a73a4_init_delay(void)
--
1.7.2.5

2013-07-23 10:51:18

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 06/15] DMA: shdma: make multiplexer platform data optional

Instead of supplying platform data to the shdma dmaengine driver via
AUXDATA in the DT case, we now support platform data via an OF match table.
Make platform data optional.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
drivers/dma/sh/shdma-of.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c
index 11bcb05..2acf7b6 100644
--- a/drivers/dma/sh/shdma-of.c
+++ b/drivers/dma/sh/shdma-of.c
@@ -45,9 +45,6 @@ static int shdma_of_probe(struct platform_device *pdev)
const struct of_dev_auxdata *lookup = pdev->dev.platform_data;
int ret;

- if (!lookup)
- return -EINVAL;
-
ret = of_dma_controller_register(pdev->dev.of_node,
shdma_of_xlate, pdev);
if (ret < 0)
--
1.7.2.5

2013-07-23 10:51:12

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 04/15] DMA: shdma: make a pointer const

Platform data shouldn't be changed at run-time, so, pointers to it should
be const.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
drivers/dma/sh/shdma.h | 2 +-
drivers/dma/sh/shdmac.c | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
index 82a83f8..ae0c65f 100644
--- a/drivers/dma/sh/shdma.h
+++ b/drivers/dma/sh/shdma.h
@@ -36,7 +36,7 @@ struct sh_dmae_chan {
struct sh_dmae_device {
struct shdma_dev shdma_dev;
struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS];
- struct sh_dmae_pdata *pdata;
+ const struct sh_dmae_pdata *pdata;
struct list_head node;
void __iomem *chan_reg;
void __iomem *dmars;
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index 6546bf9..859ddbe 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -177,7 +177,7 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
{
struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
- struct sh_dmae_pdata *pdata = shdev->pdata;
+ const struct sh_dmae_pdata *pdata = shdev->pdata;
int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);

@@ -190,7 +190,7 @@ static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
{
struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
- struct sh_dmae_pdata *pdata = shdev->pdata;
+ const struct sh_dmae_pdata *pdata = shdev->pdata;
int i;

for (i = 0; i < pdata->ts_shift_num; i++)
@@ -250,7 +250,7 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
{
struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
- struct sh_dmae_pdata *pdata = shdev->pdata;
+ const struct sh_dmae_pdata *pdata = shdev->pdata;
const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->shdma_chan.id];
void __iomem *addr = shdev->dmars;
unsigned int shift = chan_pdata->dmars_bit;
@@ -319,7 +319,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave(
struct sh_dmae_chan *sh_chan, int match)
{
struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
- struct sh_dmae_pdata *pdata = shdev->pdata;
+ const struct sh_dmae_pdata *pdata = shdev->pdata;
const struct sh_dmae_slave_config *cfg;
int i;

@@ -665,7 +665,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {

static int sh_dmae_probe(struct platform_device *pdev)
{
- struct sh_dmae_pdata *pdata;
+ const struct sh_dmae_pdata *pdata;
unsigned long irqflags = IRQF_DISABLED,
chan_flag[SH_DMAE_MAX_CHANNELS] = {};
int errirq, chan_irq[SH_DMAE_MAX_CHANNELS];
--
1.7.2.5

2013-07-23 10:51:10

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 12/15] ARM: shmobile: r8a7740: add DT nodes and clock aliases for three DMAC instances

This patch adds Device Tree support for the three generic DMA controller
instances on r8a7740 in a DMA multiplexer node.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
arch/arm/boot/dts/r8a7740.dtsi | 61 ++++++++++++++++++++++++++++++++
arch/arm/mach-shmobile/clock-r8a7740.c | 3 ++
2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index e18a195..4797f1e 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -116,6 +116,67 @@
0 149 0x4>;
};

+ dmac: dma-multiplexer@0 {
+ compatible = "renesas,shdma-mux";
+ #dma-cells = <1>;
+ dma-channels = <6>;
+ dma-requests = <256>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma0: dma-controller@fe008020 {
+ compatible = "renesas,shdma-r8a7740";
+ reg = <0xfe008020 0x270>,
+ <0xfe009000 0xc>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 34 4
+ 0 28 4
+ 0 29 4
+ 0 30 4
+ 0 31 4
+ 0 32 4
+ 0 33 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5";
+ };
+
+ dma1: dma-controller@fe018020 {
+ compatible = "renesas,shdma-r8a7740";
+ reg = <0xfe018020 0x270>,
+ <0xfe019000 0xc>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 41 4
+ 0 35 4
+ 0 36 4
+ 0 37 4
+ 0 38 4
+ 0 39 4
+ 0 40 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5";
+ };
+
+ dma2: dma-controller@fe028020 {
+ compatible = "renesas,shdma-r8a7740";
+ reg = <0xfe028020 0x270>,
+ <0xfe029000 0xc>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 48 4
+ 0 42 4
+ 0 43 4
+ 0 44 4
+ 0 45 4
+ 0 46 4
+ 0 47 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5";
+ };
+ };
+
i2c0: i2c@fff20000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index f32a22d..b355018 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -576,8 +576,11 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("e6cb0000.sci", &mstp_clks[MSTP207]),
CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
CLKDEV_DEV_ID("shdma-r8a7740.2", &mstp_clks[MSTP216]),
+ CLKDEV_DEV_ID("fe028020.dma-controller",&mstp_clks[MSTP216]),
CLKDEV_DEV_ID("shdma-r8a7740.1", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("fe018020.dma-controller",&mstp_clks[MSTP217]),
CLKDEV_DEV_ID("shdma-r8a7740.0", &mstp_clks[MSTP218]),
+ CLKDEV_DEV_ID("fe008020.dma-controller",&mstp_clks[MSTP218]),
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
CLKDEV_DEV_ID("e6cd0000.sci", &mstp_clks[MSTP222]),
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
--
1.7.2.5

2013-07-23 10:51:06

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH/RFC v4 09/15] DMA: shdma: support referencing specific DMACs within a multiplexer in DT

Currently shdma DT nodes have to be placed under a multiplexer node. DMA
slave DT nodes then use that multiplexer's phandle in their "dmas"
properties. However, sometimes it can be necessary to let DMA slaves only
use a specific DMAC instance. In this case it would be logical to just use
the respective phandle in that slave's "dmas" property. For this to work
the referenced DMAC has to register a struct of_dma instance, which isn't
presently done. Instead the driver currently only registers one struct
of_dma for the multiplexer. This patch adds support for such
configurations. To enable this option a "#dma-cells" property also must be
added to the respective DMAC DT node.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

As mentioned in the cover letter patch, this is an RFC. We are certain,
that we want to be able to reference specific DMACs within multiplexers.
However, with the current implementation this cannot work, because single
DMAC DT nodes don't have of_dma objects associated with them, currently
there is only one such object per multiplexer. The proposal is to
implement such direct referencing by adding a "#dma-cells" property to
respective DT nodes, in which case an of_dma object will be allocated for
them too.

Documentation/devicetree/bindings/dma/shdma.txt | 16 ++++++
drivers/dma/sh/shdma.h | 7 +++
drivers/dma/sh/shdmac.c | 66 +++++++++++++++++++++++
3 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt
index 6b015d6..aeed9b8 100644
--- a/Documentation/devicetree/bindings/dma/shdma.txt
+++ b/Documentation/devicetree/bindings/dma/shdma.txt
@@ -27,6 +27,22 @@ Required properties:
"renesas,shdma-r8a7740" for the DMACs (not RTDMAC) on r8a7740
"renesas,shdma-sh73a0" for the DMACs on sh73a0

+Optional properties:
+- #dma-cells: this property is only needed in one specific case: if DMA slaves
+ have to be able to request channels specifically from this DMAC,
+ not from anyone from the multiplexer. In such a case the board
+ .dts file can contain code, similar to this:
+
+&dma1 {
+ #dma-cells = <1>;
+};
+
+&mmc0 {
+ dmas = <&dma1 0xd1
+ &dma1 0xd2>;
+ dma-names = "tx", "rx";
+};
+
Example:
dmac: dma-mux0 {
compatible = "renesas,shdma-mux";
diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
index 8394424..991316f 100644
--- a/drivers/dma/sh/shdma.h
+++ b/drivers/dma/sh/shdma.h
@@ -23,6 +23,7 @@
#define SH_DMAE_TCR_MAX 0x00FFFFFF /* 16MB */

struct device;
+struct device_node;

struct sh_dmae_chan {
struct shdma_chan shdma_chan;
@@ -33,6 +34,11 @@ struct sh_dmae_chan {
int pm_error;
};

+struct sh_dmae_filter_info {
+ u32 hw_req;
+ struct device_node *of_node;
+};
+
struct sh_dmae_device {
struct shdma_dev shdma_dev;
struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS];
@@ -42,6 +48,7 @@ struct sh_dmae_device {
void __iomem *dmars;
unsigned int chcr_offset;
u32 chcr_ie_bit;
+ struct sh_dmae_filter_info filter_info;
};

struct sh_dmae_regs {
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index 9ee3c28..fcaed8d 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_dma.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
@@ -665,6 +666,63 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
.get_partial = sh_dmae_get_partial,
};

+static bool sh_dmae_chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct sh_dmae_filter_info *info = arg;
+ struct shdma_chan *schan = to_shdma_chan(chan);
+ int match = info->hw_req;
+
+ if (match < 0)
+ /* No slave requested - arbitrary channel */
+ return true;
+
+ dev_dbg(schan->dev, "%s(): trying %s for 0x%x\n", __func__,
+ info->of_node->full_name, match);
+
+ if (schan->dev->of_node != info->of_node)
+ return false;
+
+ return !sh_dmae_set_slave(schan, match, true);
+}
+
+static struct dma_chan *sh_dmae_of_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct sh_dmae_filter_info *info = ofdma->of_dma_data;
+ u32 id = dma_spec->args[0];
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+
+ if (dma_spec->args_count != 1)
+ return NULL;
+
+ dma_cap_zero(mask);
+ /* Only slave DMA channels can be allocated via DT */
+ dma_cap_set(DMA_SLAVE, mask);
+
+ info->hw_req = id;
+ info->of_node = dma_spec->np;
+
+ chan = dma_request_channel(mask, sh_dmae_chan_filter, info);
+ if (chan)
+ to_shdma_chan(chan)->hw_req = id;
+
+ return chan;
+}
+
+static int sh_dmae_of_add(struct device *dev, struct sh_dmae_device *shdev)
+{
+ u32 cells;
+ int ret = of_property_read_u32(dev->of_node, "#dma-cells", &cells);
+
+ dev_dbg(dev, "%s(): %u (%d)\n", __func__, cells, ret);
+ if (ret < 0 || !cells)
+ return 0;
+
+ return of_dma_controller_register(dev->of_node,
+ sh_dmae_of_xlate, &shdev->filter_info);
+}
+
static const struct of_device_id sh_dmae_of_match[] = {
{.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,},
{.compatible = "renesas,shdma-r8a7740", .data = r8a7740_shdma_devid,},
@@ -845,6 +903,10 @@ static int sh_dmae_probe(struct platform_device *pdev)
} while (irq_cnt < pdata->channel_num && chanirq_res);
}

+ err = sh_dmae_of_add(&pdev->dev, shdev);
+ if (err < 0)
+ goto of_add_err;
+
/* Create DMA Channel */
for (i = 0; i < irq_cnt; i++) {
err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
@@ -869,6 +931,8 @@ edmadevreg:
pm_runtime_get(&pdev->dev);

chan_probe_err:
+ of_dma_controller_free(pdev->dev.of_node);
+of_add_err:
sh_dmae_chan_remove(shdev);

#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
@@ -895,6 +959,8 @@ static int sh_dmae_remove(struct platform_device *pdev)
struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev;

+ of_dma_controller_free(pdev->dev.of_node);
+
dma_async_device_unregister(dma_dev);

spin_lock_irq(&sh_dmae_lock);
--
1.7.2.5

2013-07-23 10:51:01

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 05/15] DMA: shdma: pass SoC-specific configuration to the driver via OF matching

Similar to the non-DT case, this patch passes SoC-specific configuration
to the driver via device ID matching, instead of platform data. Since the
controller configuration shall now always be passed via a device ID
table, we can remove the generic "renesas,shdma" entry, we always need a
specific SoC match.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

v4: remove generic "renesas,shdma" compatibility option

Documentation/devicetree/bindings/dma/shdma.txt | 6 ++++--
drivers/dma/sh/shdmac.c | 21 ++++++++++++++-------
2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt
index c15994a..be0f82b 100644
--- a/Documentation/devicetree/bindings/dma/shdma.txt
+++ b/Documentation/devicetree/bindings/dma/shdma.txt
@@ -22,7 +22,9 @@ Optional properties (currently unused):
* DMA controller

Required properties:
-- compatible: should be "renesas,shdma"
+- compatible: should be one of
+ "renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC
+ "renesas,shdma-r8a7740" for the DMACs (not RTDMAC) on r8a7740

Example:
dmac: dma-mux0 {
@@ -36,7 +38,7 @@ Example:
ranges;

dma0: shdma@fe008020 {
- compatible = "renesas,shdma";
+ compatible = "renesas,shdma-r8a7740";
reg = <0xfe008020 0x270>,
<0xfe009000 0xc>;
interrupt-parent = <&gic>;
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index 859ddbe..aa90ea2 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -20,6 +20,8 @@

#include <linux/init.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
@@ -663,6 +665,13 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
.get_partial = sh_dmae_get_partial,
};

+static const struct of_device_id sh_dmae_of_match[] = {
+ {.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,},
+ {.compatible = "renesas,shdma-r8a7740", .data = r8a7740_shdma_devid,},
+ {}
+};
+MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
+
static int sh_dmae_probe(struct platform_device *pdev)
{
const struct sh_dmae_pdata *pdata;
@@ -674,7 +683,11 @@ static int sh_dmae_probe(struct platform_device *pdev)
struct dma_device *dma_dev;
struct resource *chan, *dmars, *errirq_res, *chanirq_res;

- pdata = (void *)pdev->id_entry->driver_data ? : pdev->dev.platform_data;
+ if (pdev->dev.of_node)
+ pdata = of_match_device(sh_dmae_of_match, &pdev->dev)->data;
+ else
+ pdata = (void *)pdev->id_entry->driver_data ? :
+ pdev->dev.platform_data;

/* get platform data */
if (!pdata || !pdata->channel_num)
@@ -899,12 +912,6 @@ static int sh_dmae_remove(struct platform_device *pdev)
return 0;
}

-static const struct of_device_id sh_dmae_of_match[] = {
- { .compatible = "renesas,shdma", },
- { }
-};
-MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
-
const struct platform_device_id sh_dmae_id_table[] = {
{.name = SH_DMAE_DRV_NAME,},
{.name = "shdma-r8a73a4", .driver_data = (kernel_ulong_t)r8a73a4_shdma_devid,},
--
1.7.2.5

2013-07-23 10:51:00

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 15/15] ARM: shmobile: r8a7740: add support for 2 RTDMACs

In addition to 3 SYS-DMACs, r817740 SoCs also have 2 RT-DMACs. This patch
adds support for them in both DT- amd non-DT-modes.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

v4: update documentation

Documentation/devicetree/bindings/dma/shdma.txt | 2 +-
arch/arm/boot/dts/r8a7740.dtsi | 34 +++++++++++
arch/arm/mach-shmobile/clock-r8a7740.c | 8 +++
arch/arm/mach-shmobile/setup-r8a7740.c | 72 +++++++++++++++++++++++
4 files changed, 115 insertions(+), 1 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt
index aeed9b8..5ff154d 100644
--- a/Documentation/devicetree/bindings/dma/shdma.txt
+++ b/Documentation/devicetree/bindings/dma/shdma.txt
@@ -24,7 +24,7 @@ Optional properties (currently unused):
Required properties:
- compatible: should be one of
"renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC
- "renesas,shdma-r8a7740" for the DMACs (not RTDMAC) on r8a7740
+ "renesas,shdma-r8a7740" for the DMACs and RTDMACs on r8a7740
"renesas,shdma-sh73a0" for the DMACs on sh73a0

Optional properties:
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index 4797f1e..638ada2 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -175,6 +175,40 @@
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5";
};
+
+ dma3: dma-controller@ffc18020 {
+ compatible = "renesas,shdma-r8a7740";
+ reg = <0xffc18020 0x270>,
+ <0xffc19000 0xc>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 196 4
+ 0 190 4
+ 0 191 4
+ 0 192 4
+ 0 193 4
+ 0 194 4
+ 0 195 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5";
+ };
+
+ dma4: dma-controller@ffc28020 {
+ compatible = "renesas,shdma-r8a7740";
+ reg = <0xffc28020 0x270>,
+ <0xffc29000 0xc>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 158 4
+ 0 152 4
+ 0 153 4
+ 0 154 4
+ 0 155 4
+ 0 156 4
+ 0 157 4>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5";
+ };
};

i2c0: i2c@fff20000 {
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index b355018..c4a8309 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -451,6 +451,8 @@ static struct clk fsidivs[] = {

/* MSTP */
enum {
+ MSTP023, MSTP021,
+
MSTP128, MSTP127, MSTP125,
MSTP116, MSTP111, MSTP100, MSTP117,

@@ -469,6 +471,8 @@ enum {
};

static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR0, 21, 0), /* RT-DMAC1 */
+ [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR0, 23, 0), /* RT-DMAC2 */
[MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */
[MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */
[MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
@@ -547,6 +551,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),

/* MSTP32 clocks */
+ CLKDEV_DEV_ID("shdma-r8a7740.4", &mstp_clks[MSTP021]),
+ CLKDEV_DEV_ID("ffc18020.dma-controller",&mstp_clks[MSTP021]),
+ CLKDEV_DEV_ID("shdma-r8a7740.5", &mstp_clks[MSTP023]),
+ CLKDEV_DEV_ID("ffc28020.dma-controller",&mstp_clks[MSTP023]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
CLKDEV_DEV_ID("sh_tmu.3", &mstp_clks[MSTP111]),
CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 01dcb3b..2dc2d652 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -626,6 +626,62 @@ static struct resource r8a7740_dmae2_resources[] = {
},
};

+/* Resource order important! */
+static struct resource r8a7740_rtdma0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xffc18020,
+ .end = 0xffc1828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xffc19000,
+ .end = 0xffc1900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(196),
+ .end = gic_spi(196),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(190),
+ .end = gic_spi(195),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource r8a7740_rtdma1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xffc28020,
+ .end = 0xffc2828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xffc29000,
+ .end = 0xffc2900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(158),
+ .end = gic_spi(158),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(152),
+ .end = gic_spi(157),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct platform_device dma0_device = {
.name = "shdma-r8a7740",
.id = 0,
@@ -647,6 +703,20 @@ static struct platform_device dma2_device = {
.num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
};

+static struct platform_device rtdma0_device = {
+ .name = "shdma-r8a7740",
+ .id = 4,
+ .resource = r8a7740_rtdma0_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_rtdma0_resources),
+};
+
+static struct platform_device rtdma1_device = {
+ .name = "shdma-r8a7740",
+ .id = 5,
+ .resource = r8a7740_rtdma1_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_rtdma1_resources),
+};
+
/* USB-DMAC */
static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
{
@@ -781,6 +851,8 @@ static struct platform_device *r8a7740_late_devices[] __initdata = {
&dma0_device,
&dma1_device,
&dma2_device,
+ &rtdma0_device,
+ &rtdma1_device,
&usb_dma_device,
&pmu_device,
};
--
1.7.2.5

2013-07-23 10:50:58

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 03/15] DMA: shdma: add r8a73a4 DMAC data to the device ID table

This configuration data will be re-used, when DMAC DT support is added to
r8a73a4.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

v4: make struct sh_dmae_pdata r8a73a4_dma_pdata "const"

drivers/dma/sh/Kconfig | 4 ++
drivers/dma/sh/Makefile | 1 +
drivers/dma/sh/shdma-r8a73a4.c | 75 ++++++++++++++++++++++++++++++++++++++++
drivers/dma/sh/shdma.h | 7 ++++
drivers/dma/sh/shdmac.c | 1 +
5 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 drivers/dma/sh/shdma-r8a73a4.c

diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 0ac3e94..6921ba2 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -23,6 +23,10 @@ config SUDMAC
help
Enable support for the Renesas SUDMAC controllers.

+config SHDMA_R8A73A4
+ def_bool y
+ depends on ARCH_R8A73A4 && SH_DMAE != n
+
config SHDMA_R8A7740
def_bool y
depends on ARCH_R8A7740 && SH_DMAE != n
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index acdd3cb..8352bfb 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o
obj-$(CONFIG_SH_DMAE) += shdma.o
shdma-y := shdmac.o
+shdma-$(CONFIG_SHDMA_R8A73A4) += shdma-r8a73a4.o
shdma-$(CONFIG_SHDMA_R8A7740) += shdma-r8a7740.o
shdma-objs := $(shdma-y)
obj-$(CONFIG_SUDMAC) += sudmac.o
diff --git a/drivers/dma/sh/shdma-r8a73a4.c b/drivers/dma/sh/shdma-r8a73a4.c
new file mode 100644
index 0000000..9db9b4d
--- /dev/null
+++ b/drivers/dma/sh/shdma-r8a73a4.c
@@ -0,0 +1,75 @@
+#include <linux/sh_dma.h>
+
+#include <mach/dma-register.h>
+#include <mach/r8a73a4.h>
+
+static const struct sh_dmae_slave_config dma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_MMCIF0_TX,
+ .addr = 0xee200034,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd1,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF0_RX,
+ .addr = 0xee200034,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd2,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF1_TX,
+ .addr = 0xee220034,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xe1,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF1_RX,
+ .addr = 0xee220034,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xe2,
+ },
+};
+
+#define DMAE_CHANNEL(a, b) \
+ { \
+ .offset = (a) - 0x20, \
+ .dmars = (a) - 0x20 + 0x40, \
+ .chclr_bit = (b), \
+ .chclr_offset = 0x80 - 0x20, \
+ }
+
+static const struct sh_dmae_channel dma_channels[] = {
+ DMAE_CHANNEL(0x8000, 0),
+ DMAE_CHANNEL(0x8080, 1),
+ DMAE_CHANNEL(0x8100, 2),
+ DMAE_CHANNEL(0x8180, 3),
+ DMAE_CHANNEL(0x8200, 4),
+ DMAE_CHANNEL(0x8280, 5),
+ DMAE_CHANNEL(0x8300, 6),
+ DMAE_CHANNEL(0x8380, 7),
+ DMAE_CHANNEL(0x8400, 8),
+ DMAE_CHANNEL(0x8480, 9),
+ DMAE_CHANNEL(0x8500, 10),
+ DMAE_CHANNEL(0x8580, 11),
+ DMAE_CHANNEL(0x8600, 12),
+ DMAE_CHANNEL(0x8680, 13),
+ DMAE_CHANNEL(0x8700, 14),
+ DMAE_CHANNEL(0x8780, 15),
+ DMAE_CHANNEL(0x8800, 16),
+ DMAE_CHANNEL(0x8880, 17),
+ DMAE_CHANNEL(0x8900, 18),
+ DMAE_CHANNEL(0x8980, 19),
+};
+
+const struct sh_dmae_pdata r8a73a4_dma_pdata = {
+ .slave = dma_slaves,
+ .slave_num = ARRAY_SIZE(dma_slaves),
+ .channel = dma_channels,
+ .channel_num = ARRAY_SIZE(dma_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+ .chclr_bitwise = 1,
+};
diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
index b5fe545..82a83f8 100644
--- a/drivers/dma/sh/shdma.h
+++ b/drivers/dma/sh/shdma.h
@@ -61,6 +61,13 @@ struct sh_dmae_desc {
#define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\
struct sh_dmae_device, shdma_dev.dma_dev)

+#ifdef CONFIG_SHDMA_R8A73A4
+extern const struct sh_dmae_pdata r8a73a4_dma_pdata;
+#define r8a73a4_shdma_devid &r8a73a4_dma_pdata
+#else
+#define r8a73a4_shdma_devid NULL
+#endif
+
#ifdef CONFIG_SHDMA_R8A7740
extern const struct sh_dmae_pdata r8a7740_dma_pdata;
#define r8a7740_shdma_devid &r8a7740_dma_pdata
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index fe54cda..6546bf9 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -907,6 +907,7 @@ MODULE_DEVICE_TABLE(of, sh_dmae_of_match);

const struct platform_device_id sh_dmae_id_table[] = {
{.name = SH_DMAE_DRV_NAME,},
+ {.name = "shdma-r8a73a4", .driver_data = (kernel_ulong_t)r8a73a4_shdma_devid,},
{.name = "shdma-r8a7740", .driver_data = (kernel_ulong_t)r8a7740_shdma_devid,},
{}
};
--
1.7.2.5

2013-07-23 10:50:56

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 14/15] ARM: shmobile: sh73a0: switch DMAC controllers to using device ID data

This patch removes DMAC platform data on sh73a0 and switches to using
device ID data.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
arch/arm/mach-shmobile/clock-sh73a0.c | 2 +-
arch/arm/mach-shmobile/setup-sh73a0.c | 182 +--------------------------------
2 files changed, 2 insertions(+), 182 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 1942eae..3a00b49 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -646,7 +646,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
- CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
+ CLKDEV_DEV_ID("shdma-sh73a0.0", &mstp_clks[MSTP218]), /* SY-DMAC */
CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 516c239..2e9f3cc 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -396,183 +396,6 @@ static struct platform_device i2c4_device = {
.num_resources = ARRAY_SIZE(i2c4_resources),
};

-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 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 = TS_LOW_SHIFT,
- .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
- .ts_high_shift = TS_HI_SHIFT,
- .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
- .ts_shift = dma_ts_shift,
- .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
- .dmaor_init = DMAOR_DME,
-};
-
static struct resource sh73a0_dmae_resources[] = {
DEFINE_RES_MEM(0xfe000020, 0x89e0),
{
@@ -590,13 +413,10 @@ static struct resource sh73a0_dmae_resources[] = {
};

static struct platform_device dma0_device = {
- .name = "sh-dma-engine",
+ .name = "shdma-sh73a0",
.id = 0,
.resource = sh73a0_dmae_resources,
.num_resources = ARRAY_SIZE(sh73a0_dmae_resources),
- .dev = {
- .platform_data = &sh73a0_dmae_platform_data,
- },
};

/* MPDMAC */
--
1.7.2.5

2013-07-23 10:50:54

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 11/15] ARM: shmobile: r8a7740: switch DMAC controllers to using device ID data

This patch removes DMAC platform data on r8a7740 and switches to using
device ID data.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
arch/arm/mach-shmobile/clock-r8a7740.c | 6 +-
arch/arm/mach-shmobile/setup-r8a7740.c | 106 +-------------------------------
2 files changed, 6 insertions(+), 106 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index f4265e5..f32a22d 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -575,9 +575,9 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
CLKDEV_DEV_ID("e6cb0000.sci", &mstp_clks[MSTP207]),
CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
- CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
- CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
- CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
+ CLKDEV_DEV_ID("shdma-r8a7740.2", &mstp_clks[MSTP216]),
+ CLKDEV_DEV_ID("shdma-r8a7740.1", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("shdma-r8a7740.0", &mstp_clks[MSTP218]),
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
CLKDEV_DEV_ID("e6cd0000.sci", &mstp_clks[MSTP222]),
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 84c5bb6..01dcb3b 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -542,97 +542,6 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
};

/* DMA */
-static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
- {
- .slave_id = SHDMA_SLAVE_SDHI0_TX,
- .addr = 0xe6850030,
- .chcr = CHCR_TX(XMIT_SZ_16BIT),
- .mid_rid = 0xc1,
- }, {
- .slave_id = SHDMA_SLAVE_SDHI0_RX,
- .addr = 0xe6850030,
- .chcr = CHCR_RX(XMIT_SZ_16BIT),
- .mid_rid = 0xc2,
- }, {
- .slave_id = SHDMA_SLAVE_SDHI1_TX,
- .addr = 0xe6860030,
- .chcr = CHCR_TX(XMIT_SZ_16BIT),
- .mid_rid = 0xc9,
- }, {
- .slave_id = SHDMA_SLAVE_SDHI1_RX,
- .addr = 0xe6860030,
- .chcr = CHCR_RX(XMIT_SZ_16BIT),
- .mid_rid = 0xca,
- }, {
- .slave_id = SHDMA_SLAVE_SDHI2_TX,
- .addr = 0xe6870030,
- .chcr = CHCR_TX(XMIT_SZ_16BIT),
- .mid_rid = 0xcd,
- }, {
- .slave_id = SHDMA_SLAVE_SDHI2_RX,
- .addr = 0xe6870030,
- .chcr = CHCR_RX(XMIT_SZ_16BIT),
- .mid_rid = 0xce,
- }, {
- .slave_id = SHDMA_SLAVE_FSIA_TX,
- .addr = 0xfe1f0024,
- .chcr = CHCR_TX(XMIT_SZ_32BIT),
- .mid_rid = 0xb1,
- }, {
- .slave_id = SHDMA_SLAVE_FSIA_RX,
- .addr = 0xfe1f0020,
- .chcr = CHCR_RX(XMIT_SZ_32BIT),
- .mid_rid = 0xb2,
- }, {
- .slave_id = SHDMA_SLAVE_FSIB_TX,
- .addr = 0xfe1f0064,
- .chcr = CHCR_TX(XMIT_SZ_32BIT),
- .mid_rid = 0xb5,
- }, {
- .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 DMA_CHANNEL(a, b, c) \
-{ \
- .offset = a, \
- .dmars = b, \
- .dmars_bit = c, \
- .chclr_offset = (0x220 - 0x20) + a \
-}
-
-static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
- DMA_CHANNEL(0x00, 0, 0),
- DMA_CHANNEL(0x10, 0, 8),
- DMA_CHANNEL(0x20, 4, 0),
- DMA_CHANNEL(0x30, 4, 8),
- DMA_CHANNEL(0x50, 8, 0),
- DMA_CHANNEL(0x60, 8, 8),
-};
-
-static struct sh_dmae_pdata dma_platform_data = {
- .slave = r8a7740_dmae_slaves,
- .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
- .channel = r8a7740_dmae_channels,
- .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
- .ts_low_shift = TS_LOW_SHIFT,
- .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
- .ts_high_shift = TS_HI_SHIFT,
- .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
- .ts_shift = dma_ts_shift,
- .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
- .dmaor_init = DMAOR_DME,
- .chclr_present = 1,
-};
-
/* Resource order important! */
static struct resource r8a7740_dmae0_resources[] = {
{
@@ -718,33 +627,24 @@ static struct resource r8a7740_dmae2_resources[] = {
};

static struct platform_device dma0_device = {
- .name = "sh-dma-engine",
+ .name = "shdma-r8a7740",
.id = 0,
.resource = r8a7740_dmae0_resources,
.num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
- .dev = {
- .platform_data = &dma_platform_data,
- },
};

static struct platform_device dma1_device = {
- .name = "sh-dma-engine",
+ .name = "shdma-r8a7740",
.id = 1,
.resource = r8a7740_dmae1_resources,
.num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
- .dev = {
- .platform_data = &dma_platform_data,
- },
};

static struct platform_device dma2_device = {
- .name = "sh-dma-engine",
+ .name = "shdma-r8a7740",
.id = 2,
.resource = r8a7740_dmae2_resources,
.num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
- .dev = {
- .platform_data = &dma_platform_data,
- },
};

/* USB-DMAC */
--
1.7.2.5

2013-07-23 10:50:51

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 08/15] DMA: shdma: move two macros to a header

Move two generic pointer-conversion macros to a header for common shdma use.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
drivers/dma/sh/shdma-base.c | 3 ---
drivers/dma/sh/shdma-of.c | 2 --
include/linux/shdma-base.h | 3 +++
3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index c5ea256..5b92e72 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -36,9 +36,6 @@ enum shdma_desc_status {

#define NR_DESCS_PER_CHANNEL 32

-#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
-#define to_shdma_dev(d) container_of(d, struct shdma_dev, dma_dev)
-
/*
* For slave DMA we assume, that there is a finite number of DMA slaves in the
* system, and that each such slave can only use a finite number of channels.
diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c
index 2acf7b6..80d07b5 100644
--- a/drivers/dma/sh/shdma-of.c
+++ b/drivers/dma/sh/shdma-of.c
@@ -17,8 +17,6 @@
#include <linux/platform_device.h>
#include <linux/shdma-base.h>

-#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
-
static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
index 31cf89f..45191d7 100644
--- a/include/linux/shdma-base.h
+++ b/include/linux/shdma-base.h
@@ -114,6 +114,9 @@ struct shdma_dev {
#define shdma_for_each_chan(c, d, i) for (i = 0, c = (d)->schan[0]; \
i < (d)->dma_dev.chancnt; c = (d)->schan[++i])

+#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
+#define to_shdma_dev(d) container_of(d, struct shdma_dev, dma_dev)
+
int shdma_request_irq(struct shdma_chan *, int,
unsigned long, const char *);
bool shdma_reset(struct shdma_dev *sdev);
--
1.7.2.5

2013-07-23 10:50:48

by Guennadi Liakhovetski

[permalink] [raw]
Subject: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

This configuration data will be re-used, when DMAC DT support is added to
r8a7740, DMAC platform data in setup-r8a7740.c will be removed.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"

drivers/dma/sh/Kconfig | 4 ++
drivers/dma/sh/Makefile | 1 +
drivers/dma/sh/shdma-r8a7740.c | 95 ++++++++++++++++++++++++++++++++++++++++
drivers/dma/sh/shdma.h | 7 +++
drivers/dma/sh/shdmac.c | 1 +
5 files changed, 108 insertions(+), 0 deletions(-)
create mode 100644 drivers/dma/sh/shdma-r8a7740.c

diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 5c1dee2..0ac3e94 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -22,3 +22,7 @@ config SUDMAC
depends on SH_DMAE_BASE
help
Enable support for the Renesas SUDMAC controllers.
+
+config SHDMA_R8A7740
+ def_bool y
+ depends on ARCH_R8A7740 && SH_DMAE != n
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index 893ee09..acdd3cb 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o
obj-$(CONFIG_SH_DMAE) += shdma.o
shdma-y := shdmac.o
+shdma-$(CONFIG_SHDMA_R8A7740) += shdma-r8a7740.o
shdma-objs := $(shdma-y)
obj-$(CONFIG_SUDMAC) += sudmac.o
diff --git a/drivers/dma/sh/shdma-r8a7740.c b/drivers/dma/sh/shdma-r8a7740.c
new file mode 100644
index 0000000..b7ae8ef
--- /dev/null
+++ b/drivers/dma/sh/shdma-r8a7740.c
@@ -0,0 +1,95 @@
+#include <linux/sh_dma.h>
+
+#include <mach/dma-register.h>
+#include <mach/r8a7740.h>
+
+static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_TX,
+ .addr = 0xfe1f0024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb1,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_RX,
+ .addr = 0xfe1f0020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb2,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIB_TX,
+ .addr = 0xfe1f0064,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb5,
+ }, {
+ .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 DMA_CHANNEL(a, b, c) \
+{ \
+ .offset = a, \
+ .dmars = b, \
+ .dmars_bit = c, \
+ .chclr_offset = (0x220 - 0x20) + a \
+}
+
+static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
+ DMA_CHANNEL(0x00, 0, 0),
+ DMA_CHANNEL(0x10, 0, 8),
+ DMA_CHANNEL(0x20, 4, 0),
+ DMA_CHANNEL(0x30, 4, 8),
+ DMA_CHANNEL(0x50, 8, 0),
+ DMA_CHANNEL(0x60, 8, 8),
+};
+
+const struct sh_dmae_pdata r8a7740_dma_pdata = {
+ .slave = r8a7740_dmae_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
+ .channel = r8a7740_dmae_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+};
diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
index 06aae6e..b5fe545 100644
--- a/drivers/dma/sh/shdma.h
+++ b/drivers/dma/sh/shdma.h
@@ -61,4 +61,11 @@ struct sh_dmae_desc {
#define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\
struct sh_dmae_device, shdma_dev.dma_dev)

+#ifdef CONFIG_SHDMA_R8A7740
+extern const struct sh_dmae_pdata r8a7740_dma_pdata;
+#define r8a7740_shdma_devid &r8a7740_dma_pdata
+#else
+#define r8a7740_shdma_devid NULL
+#endif
+
#endif /* __DMA_SHDMA_H */
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index 751a4e3..fe54cda 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -907,6 +907,7 @@ MODULE_DEVICE_TABLE(of, sh_dmae_of_match);

const struct platform_device_id sh_dmae_id_table[] = {
{.name = SH_DMAE_DRV_NAME,},
+ {.name = "shdma-r8a7740", .driver_data = (kernel_ulong_t)r8a7740_shdma_devid,},
{}
};
MODULE_DEVICE_TABLE(platform, sh_dmae_id_table);
--
1.7.2.5

2013-07-23 11:32:35

by Guennadi Liakhovetski

[permalink] [raw]
Subject: Re: [PATCH/RFC v4 09/15] DMA: shdma: support referencing specific DMACs within a multiplexer in DT

This is the only patch in the series, non-trivially touching
Documentation/devicetree/bindings, let's cc it to devicetree mailing
lists.

Thanks
Guennadi

On Tue, 23 Jul 2013, Guennadi Liakhovetski wrote:

> Currently shdma DT nodes have to be placed under a multiplexer node. DMA
> slave DT nodes then use that multiplexer's phandle in their "dmas"
> properties. However, sometimes it can be necessary to let DMA slaves only
> use a specific DMAC instance. In this case it would be logical to just use
> the respective phandle in that slave's "dmas" property. For this to work
> the referenced DMAC has to register a struct of_dma instance, which isn't
> presently done. Instead the driver currently only registers one struct
> of_dma for the multiplexer. This patch adds support for such
> configurations. To enable this option a "#dma-cells" property also must be
> added to the respective DMAC DT node.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
> ---
>
> As mentioned in the cover letter patch, this is an RFC. We are certain,
> that we want to be able to reference specific DMACs within multiplexers.
> However, with the current implementation this cannot work, because single
> DMAC DT nodes don't have of_dma objects associated with them, currently
> there is only one such object per multiplexer. The proposal is to
> implement such direct referencing by adding a "#dma-cells" property to
> respective DT nodes, in which case an of_dma object will be allocated for
> them too.
>
> Documentation/devicetree/bindings/dma/shdma.txt | 16 ++++++
> drivers/dma/sh/shdma.h | 7 +++
> drivers/dma/sh/shdmac.c | 66 +++++++++++++++++++++++
> 3 files changed, 89 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt
> index 6b015d6..aeed9b8 100644
> --- a/Documentation/devicetree/bindings/dma/shdma.txt
> +++ b/Documentation/devicetree/bindings/dma/shdma.txt
> @@ -27,6 +27,22 @@ Required properties:
> "renesas,shdma-r8a7740" for the DMACs (not RTDMAC) on r8a7740
> "renesas,shdma-sh73a0" for the DMACs on sh73a0
>
> +Optional properties:
> +- #dma-cells: this property is only needed in one specific case: if DMA slaves
> + have to be able to request channels specifically from this DMAC,
> + not from anyone from the multiplexer. In such a case the board
> + .dts file can contain code, similar to this:
> +
> +&dma1 {
> + #dma-cells = <1>;
> +};
> +
> +&mmc0 {
> + dmas = <&dma1 0xd1
> + &dma1 0xd2>;
> + dma-names = "tx", "rx";
> +};
> +
> Example:
> dmac: dma-mux0 {
> compatible = "renesas,shdma-mux";
> diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
> index 8394424..991316f 100644
> --- a/drivers/dma/sh/shdma.h
> +++ b/drivers/dma/sh/shdma.h
> @@ -23,6 +23,7 @@
> #define SH_DMAE_TCR_MAX 0x00FFFFFF /* 16MB */
>
> struct device;
> +struct device_node;
>
> struct sh_dmae_chan {
> struct shdma_chan shdma_chan;
> @@ -33,6 +34,11 @@ struct sh_dmae_chan {
> int pm_error;
> };
>
> +struct sh_dmae_filter_info {
> + u32 hw_req;
> + struct device_node *of_node;
> +};
> +
> struct sh_dmae_device {
> struct shdma_dev shdma_dev;
> struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS];
> @@ -42,6 +48,7 @@ struct sh_dmae_device {
> void __iomem *dmars;
> unsigned int chcr_offset;
> u32 chcr_ie_bit;
> + struct sh_dmae_filter_info filter_info;
> };
>
> struct sh_dmae_regs {
> diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
> index 9ee3c28..fcaed8d 100644
> --- a/drivers/dma/sh/shdmac.c
> +++ b/drivers/dma/sh/shdmac.c
> @@ -22,6 +22,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_device.h>
> +#include <linux/of_dma.h>
> #include <linux/slab.h>
> #include <linux/interrupt.h>
> #include <linux/dmaengine.h>
> @@ -665,6 +666,63 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
> .get_partial = sh_dmae_get_partial,
> };
>
> +static bool sh_dmae_chan_filter(struct dma_chan *chan, void *arg)
> +{
> + struct sh_dmae_filter_info *info = arg;
> + struct shdma_chan *schan = to_shdma_chan(chan);
> + int match = info->hw_req;
> +
> + if (match < 0)
> + /* No slave requested - arbitrary channel */
> + return true;
> +
> + dev_dbg(schan->dev, "%s(): trying %s for 0x%x\n", __func__,
> + info->of_node->full_name, match);
> +
> + if (schan->dev->of_node != info->of_node)
> + return false;
> +
> + return !sh_dmae_set_slave(schan, match, true);
> +}
> +
> +static struct dma_chan *sh_dmae_of_xlate(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct sh_dmae_filter_info *info = ofdma->of_dma_data;
> + u32 id = dma_spec->args[0];
> + dma_cap_mask_t mask;
> + struct dma_chan *chan;
> +
> + if (dma_spec->args_count != 1)
> + return NULL;
> +
> + dma_cap_zero(mask);
> + /* Only slave DMA channels can be allocated via DT */
> + dma_cap_set(DMA_SLAVE, mask);
> +
> + info->hw_req = id;
> + info->of_node = dma_spec->np;
> +
> + chan = dma_request_channel(mask, sh_dmae_chan_filter, info);
> + if (chan)
> + to_shdma_chan(chan)->hw_req = id;
> +
> + return chan;
> +}
> +
> +static int sh_dmae_of_add(struct device *dev, struct sh_dmae_device *shdev)
> +{
> + u32 cells;
> + int ret = of_property_read_u32(dev->of_node, "#dma-cells", &cells);
> +
> + dev_dbg(dev, "%s(): %u (%d)\n", __func__, cells, ret);
> + if (ret < 0 || !cells)
> + return 0;
> +
> + return of_dma_controller_register(dev->of_node,
> + sh_dmae_of_xlate, &shdev->filter_info);
> +}
> +
> static const struct of_device_id sh_dmae_of_match[] = {
> {.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,},
> {.compatible = "renesas,shdma-r8a7740", .data = r8a7740_shdma_devid,},
> @@ -845,6 +903,10 @@ static int sh_dmae_probe(struct platform_device *pdev)
> } while (irq_cnt < pdata->channel_num && chanirq_res);
> }
>
> + err = sh_dmae_of_add(&pdev->dev, shdev);
> + if (err < 0)
> + goto of_add_err;
> +
> /* Create DMA Channel */
> for (i = 0; i < irq_cnt; i++) {
> err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
> @@ -869,6 +931,8 @@ edmadevreg:
> pm_runtime_get(&pdev->dev);
>
> chan_probe_err:
> + of_dma_controller_free(pdev->dev.of_node);
> +of_add_err:
> sh_dmae_chan_remove(shdev);
>
> #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
> @@ -895,6 +959,8 @@ static int sh_dmae_remove(struct platform_device *pdev)
> struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
> struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev;
>
> + of_dma_controller_free(pdev->dev.of_node);
> +
> dma_async_device_unregister(dma_dev);
>
> spin_lock_irq(&sh_dmae_lock);
> --
> 1.7.2.5
>

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

2013-07-23 19:54:13

by Magnus Damm

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

Hi Guennadi,

Thanks for your efforts on this.

On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski
<[email protected]> wrote:
> This configuration data will be re-used, when DMAC DT support is added to
> r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
> ---
>
> v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
>

[snip]

> --- /dev/null
> +++ b/drivers/dma/sh/shdma-r8a7740.c
> @@ -0,0 +1,95 @@
> +#include <linux/sh_dma.h>
> +
> +#include <mach/dma-register.h>
> +#include <mach/r8a7740.h>

Including stuff from <mach/..> isn't really compatible with
MULTIPLATFORM, so please don't write new code like this. Actually we
don't want any code under drivers/ to include stuff from the mach
directory.

I suggest that you arrange your code in a way so the C version of DMAC
support has tables with slave ids as usual under
arch/arm/mach-shmobile/, but the DT bits that operate independently of
C stay in drivers/... Over time we will get rid of the C version, and
until that happens the DT and C version can coexist in parallel.

Cheers,

/ magnus

2013-07-23 21:20:00

by Guennadi Liakhovetski

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

On Wed, 24 Jul 2013, Magnus Damm wrote:

> Hi Guennadi,
>
> Thanks for your efforts on this.
>
> On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski
> <[email protected]> wrote:
> > This configuration data will be re-used, when DMAC DT support is added to
> > r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
> >
> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
> > ---
> >
> > v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
> >
>
> [snip]
>
> > --- /dev/null
> > +++ b/drivers/dma/sh/shdma-r8a7740.c
> > @@ -0,0 +1,95 @@
> > +#include <linux/sh_dma.h>
> > +
> > +#include <mach/dma-register.h>
> > +#include <mach/r8a7740.h>
>
> Including stuff from <mach/..> isn't really compatible with
> MULTIPLATFORM,

Hmm, right. I modeled this arch-specific driver code after Laurent's
pinctrl driver revamp, which also includes <mach/*.h> headers. So, we'll
have to think how to fix both.

> so please don't write new code like this. Actually we
> don't want any code under drivers/ to include stuff from the mach
> directory.

Sure, understood.

> I suggest that you arrange your code in a way so the C version of DMAC
> support has tables with slave ids as usual under
> arch/arm/mach-shmobile/, but the DT bits that operate independently of
> C stay in drivers/... Over time we will get rid of the C version, and
> until that happens the DT and C version can coexist in parallel.

That's already how it is. Data, that I took to drivers/dma/sh/ is needed
for both DT and C. DMA stuff, needed only for C are only DMAC devices and
resources. I think, I might be able to carry those DMA specific headers
and defines over from mach/ to drivers/dma/sh. Maybe it would be easier to
do this in several steps:

1. add my drivers/dma/sh/shdma-<arch>.c files *with* mach/ headers
2. switch arches over to those files
(the above two steps are already done in my patch series)
3. move headers to drivers/dma/sh

Ok, alternatively, I might be able to do (1) above without using mach/
headers at all by directly copying them to drivers/dma/sh/ and then
removing the original mach/headers in step (2)? I'll look in more detail
at the code tomorrow.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

2013-07-23 21:30:59

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

Hi Guennadi,

On Tuesday 23 July 2013 23:19:29 Guennadi Liakhovetski wrote:
> On Wed, 24 Jul 2013, Magnus Damm wrote:
> > On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski wrote:
> > > This configuration data will be re-used, when DMAC DT support is added
> > > to
> > > r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
> > >
> > > Signed-off-by: Guennadi Liakhovetski <[email protected]>
> > > ---
> > >
> > > v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
> >
> > [snip]
> >
> > > --- /dev/null
> > > +++ b/drivers/dma/sh/shdma-r8a7740.c
> > > @@ -0,0 +1,95 @@
> > > +#include <linux/sh_dma.h>
> > > +
> > > +#include <mach/dma-register.h>
> > > +#include <mach/r8a7740.h>
> >
> > Including stuff from <mach/..> isn't really compatible with
> > MULTIPLATFORM,
>
> Hmm, right. I modeled this arch-specific driver code after Laurent's
> pinctrl driver revamp, which also includes <mach/*.h> headers. So, we'll
> have to think how to fix both.

Just for the record, I've already fixed some of those issues in my tree, and
I'll work on the remaining ones (three instances of <mach/irqs.h> for the
irq_pin() macro).

> > so please don't write new code like this. Actually we
> > don't want any code under drivers/ to include stuff from the mach
> > directory.
>
> Sure, understood.
>
> > I suggest that you arrange your code in a way so the C version of DMAC
> > support has tables with slave ids as usual under
> > arch/arm/mach-shmobile/, but the DT bits that operate independently of
> > C stay in drivers/... Over time we will get rid of the C version, and
> > until that happens the DT and C version can coexist in parallel.
>
> That's already how it is. Data, that I took to drivers/dma/sh/ is needed
> for both DT and C. DMA stuff, needed only for C are only DMAC devices and
> resources. I think, I might be able to carry those DMA specific headers
> and defines over from mach/ to drivers/dma/sh. Maybe it would be easier to
> do this in several steps:
>
> 1. add my drivers/dma/sh/shdma-<arch>.c files *with* mach/ headers
> 2. switch arches over to those files
> (the above two steps are already done in my patch series)
> 3. move headers to drivers/dma/sh
>
> Ok, alternatively, I might be able to do (1) above without using mach/
> headers at all by directly copying them to drivers/dma/sh/ and then
> removing the original mach/headers in step (2)? I'll look in more detail
> at the code tomorrow.

--
Regards,

Laurent Pinchart

2013-07-24 06:22:48

by Magnus Damm

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

Hi Guennadi,

On Wed, Jul 24, 2013 at 6:19 AM, Guennadi Liakhovetski
<[email protected]> wrote:
> On Wed, 24 Jul 2013, Magnus Damm wrote:
>
>> Hi Guennadi,
>>
>> Thanks for your efforts on this.
>>
>> On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski
>> <[email protected]> wrote:
>> > This configuration data will be re-used, when DMAC DT support is added to
>> > r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
>> >
>> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
>> > ---
>> >
>> > v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
>> >
>>
>> [snip]
>>
>> > --- /dev/null
>> > +++ b/drivers/dma/sh/shdma-r8a7740.c
>> > @@ -0,0 +1,95 @@
>> > +#include <linux/sh_dma.h>
>> > +
>> > +#include <mach/dma-register.h>
>> > +#include <mach/r8a7740.h>
>>
>> Including stuff from <mach/..> isn't really compatible with
>> MULTIPLATFORM,
>
> Hmm, right. I modeled this arch-specific driver code after Laurent's
> pinctrl driver revamp, which also includes <mach/*.h> headers. So, we'll
> have to think how to fix both.

I mentioned this to Laurent when he started converting to PINCTRL, and
I believe the only remaining bits are the static GPIO-to-IRQ tables.

>> so please don't write new code like this. Actually we
>> don't want any code under drivers/ to include stuff from the mach
>> directory.
>
> Sure, understood.

Good.

>> I suggest that you arrange your code in a way so the C version of DMAC
>> support has tables with slave ids as usual under
>> arch/arm/mach-shmobile/, but the DT bits that operate independently of
>> C stay in drivers/... Over time we will get rid of the C version, and
>> until that happens the DT and C version can coexist in parallel.
>
> That's already how it is. Data, that I took to drivers/dma/sh/ is needed
> for both DT and C. DMA stuff, needed only for C are only DMAC devices and
> resources. I think, I might be able to carry those DMA specific headers
> and defines over from mach/ to drivers/dma/sh. Maybe it would be easier to
> do this in several steps:
>
> 1. add my drivers/dma/sh/shdma-<arch>.c files *with* mach/ headers
> 2. switch arches over to those files
> (the above two steps are already done in my patch series)
> 3. move headers to drivers/dma/sh
>
> Ok, alternatively, I might be able to do (1) above without using mach/
> headers at all by directly copying them to drivers/dma/sh/ and then
> removing the original mach/headers in step (2)? I'll look in more detail
> at the code tomorrow.

Thanks. My apologies for reviewing your code late in the cycle, but
I've now looked through this series and the following questions popped
up:

1) How will it look like in DT when a DMA Engine slave device will use DMA?

2) Isn't it possible to leave the SHDMA_SLAVE_xx bits to only be used
by legacy C SoC and board code in arch/arm/mach-shmobile? I don't
understand why you have to move them over to drivers/... I just assume
these SHDMA_SLAVE bits won't be used by 1) above.

3) How difficult would it be to describe the information in "struct
sh_dmae_slave_config" using DT?

4) It seems that some patches in this series are unrelated. Can you
submit 4/15 and 9/15 from v4 independently somehow?

5) Reducing and extending (reducing is optional of course)

At this point you cover r8a7740, r8a73a0 and r8a73a4. I'm not sure why
your picked those 3 SoCs, but perhaps it would be a good idea to
select a single SoC to begin with but extend the support to also
provide DT code that makes use of DMA Engine in slave devices like for
instance MMCIF (this would cover question 1) above). When we have
agreed on the big picture then additional SoCs can easily be added
later.

6) Remove untested bits

And while doing this conversion, perhaps this is a good opportunity to
only move over DMA Engine slaves that can be tested? Having tons of
unused DMA configuration seems overly heavy to me. If it's not tested
then it's broken.

Cheers,

/ magnus

2013-07-24 08:33:22

by Guennadi Liakhovetski

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

On Wed, 24 Jul 2013, Magnus Damm wrote:

> Hi Guennadi,
>
> On Wed, Jul 24, 2013 at 6:19 AM, Guennadi Liakhovetski
> <[email protected]> wrote:
> > On Wed, 24 Jul 2013, Magnus Damm wrote:
> >
> >> Hi Guennadi,
> >>
> >> Thanks for your efforts on this.
> >>
> >> On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski
> >> <[email protected]> wrote:
> >> > This configuration data will be re-used, when DMAC DT support is added to
> >> > r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
> >> >
> >> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
> >> > ---
> >> >
> >> > v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
> >> >
> >>
> >> [snip]
> >>
> >> > --- /dev/null
> >> > +++ b/drivers/dma/sh/shdma-r8a7740.c
> >> > @@ -0,0 +1,95 @@
> >> > +#include <linux/sh_dma.h>
> >> > +
> >> > +#include <mach/dma-register.h>
> >> > +#include <mach/r8a7740.h>
> >>
> >> Including stuff from <mach/..> isn't really compatible with
> >> MULTIPLATFORM,
> >
> > Hmm, right. I modeled this arch-specific driver code after Laurent's
> > pinctrl driver revamp, which also includes <mach/*.h> headers. So, we'll
> > have to think how to fix both.
>
> I mentioned this to Laurent when he started converting to PINCTRL, and
> I believe the only remaining bits are the static GPIO-to-IRQ tables.
>
> >> so please don't write new code like this. Actually we
> >> don't want any code under drivers/ to include stuff from the mach
> >> directory.
> >
> > Sure, understood.
>
> Good.
>
> >> I suggest that you arrange your code in a way so the C version of DMAC
> >> support has tables with slave ids as usual under
> >> arch/arm/mach-shmobile/, but the DT bits that operate independently of
> >> C stay in drivers/... Over time we will get rid of the C version, and
> >> until that happens the DT and C version can coexist in parallel.
> >
> > That's already how it is. Data, that I took to drivers/dma/sh/ is needed
> > for both DT and C. DMA stuff, needed only for C are only DMAC devices and
> > resources. I think, I might be able to carry those DMA specific headers
> > and defines over from mach/ to drivers/dma/sh. Maybe it would be easier to
> > do this in several steps:
> >
> > 1. add my drivers/dma/sh/shdma-<arch>.c files *with* mach/ headers
> > 2. switch arches over to those files
> > (the above two steps are already done in my patch series)
> > 3. move headers to drivers/dma/sh
> >
> > Ok, alternatively, I might be able to do (1) above without using mach/
> > headers at all by directly copying them to drivers/dma/sh/ and then
> > removing the original mach/headers in step (2)? I'll look in more detail
> > at the code tomorrow.
>
> Thanks. My apologies for reviewing your code late in the cycle, but
> I've now looked through this series and the following questions popped
> up:
>
> 1) How will it look like in DT when a DMA Engine slave device will use DMA?

You have already seen them by now, since you replied to that thread too,
but just for reference, e.g. for an MMCIF controller here
http://thread.gmane.org/gmane.linux.ports.sh.devel/25445/focus=25442

+ dmas = <&dmac 0xd1
+ &dmac 0xd2>;
+ dma-names = "tx", "rx";

> 2) Isn't it possible to leave the SHDMA_SLAVE_xx bits to only be used
> by legacy C SoC and board code in arch/arm/mach-shmobile? I don't
> understand why you have to move them over to drivers/... I just assume
> these SHDMA_SLAVE bits won't be used by 1) above.

That's right, those macros aren't used by (1) above, i.e. they aren't used
in DT. But they are used pretty intensively internally by the driver. The
C code might be "legacy," but as far as I understand, SuperH will never go
to DT, so, as long as it has to be supported, we need to support that
mode. Same for ARM - IIUC, board-*.c (not -reference) files are also still
quite intensively developed and supported. So, it doesn't look like the C
version will go any time soon, right?

Based on that I tried to keep the difference between the C and the DT
versions as small as possible. And that includes keeping slave IDs at
least internally without changes.

Of course, we can think about changing the driver more extensively and
leaving those IDs only for the C case, but in fact they don't seem so
horrifying to me. We have 2 options to keep them while eliminating the use
of the <mach/<soc>.h> header:
(a) redefine them in the driver
(b) define a single list of slave IDs for all SoCs, AFAICS they don't have
to be contiguous

> 3) How difficult would it be to describe the information in "struct
> sh_dmae_slave_config" using DT?

Just as difficult as anything else in DT, I presume. Technically it's not
very difficult, but we'll have to go through all the rounds to define
proper bindings and once defined, they'll have to be kept, as you know.
And if in the future we need to change that information we'll have a
problem. E.g., we could define that array as an array of tuples like

slaves = <chcr0 midrid0>,
<chcr1 midrid1>,
...;

but that would mean we'll never be able to add a third element to them.
Whereas if kept in C as now, the full flexibility is preserved. So, I
would really prefer to only push into DT things, for which standard
bindings are defined, or those, which we absolutely need there.
Information, that is SoC specific and not standard I'd rather keep in C.

> 4) It seems that some patches in this series are unrelated. Can you
> submit 4/15 and 9/15 from v4 independently somehow?

4/15 is required to avoid a compiler warning. 9/15 can be submitted
separately, but it depends on this patch-series, so, it would be easier to
keep them all together.

> 5) Reducing and extending (reducing is optional of course)
>
> At this point you cover r8a7740, r8a73a0 and r8a73a4. I'm not sure why
> your picked those 3 SoCs,

That's simple: because I can test them.

> but perhaps it would be a good idea to
> select a single SoC to begin with but extend the support to also
> provide DT code that makes use of DMA Engine in slave devices like for
> instance MMCIF (this would cover question 1) above).

I did, as you know by now.

> When we have
> agreed on the big picture then additional SoCs can easily be added
> later.
>
> 6) Remove untested bits
>
> And while doing this conversion, perhaps this is a good opportunity to
> only move over DMA Engine slaves that can be tested? Having tons of
> unused DMA configuration seems overly heavy to me. If it's not tested
> then it's broken.

Tested in general or tested by me? I am sure other developers, that added
support for various interfaces like audio would be better able to test
them than me. And since I'm actually migrating platforms to this in-driver
code, dropping any slaves would actually be a regression. If really
wanted, that would have to go via the standard deprecation process, right?
E.g., I can well imagine that noone is actually using DMA on SCIF* serial
interfaces on sh73a0, but removing them should probably be done as a
separate patch-set.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

2013-07-24 09:54:53

by Magnus Damm

[permalink] [raw]
Subject: Re: [PATCH v4 02/15] DMA: shdma: add r8a7740 DMAC data to the device ID table

Hi Guennadi,

On Wed, Jul 24, 2013 at 5:33 PM, Guennadi Liakhovetski
<[email protected]> wrote:
> On Wed, 24 Jul 2013, Magnus Damm wrote:
>
>> Hi Guennadi,
>>
>> On Wed, Jul 24, 2013 at 6:19 AM, Guennadi Liakhovetski
>> <[email protected]> wrote:
>> > On Wed, 24 Jul 2013, Magnus Damm wrote:
>> >
>> >> Hi Guennadi,
>> >>
>> >> Thanks for your efforts on this.
>> >>
>> >> On Tue, Jul 23, 2013 at 7:49 PM, Guennadi Liakhovetski
>> >> <[email protected]> wrote:
>> >> > This configuration data will be re-used, when DMAC DT support is added to
>> >> > r8a7740, DMAC platform data in setup-r8a7740.c will be removed.
>> >> >
>> >> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
>> >> > ---
>> >> >
>> >> > v4: make struct sh_dmae_pdata r8a7740_dma_pdata "const"
>> >> >
>> >>
>> >> [snip]
>> >>
>> >> > --- /dev/null
>> >> > +++ b/drivers/dma/sh/shdma-r8a7740.c
>> >> > @@ -0,0 +1,95 @@
>> >> > +#include <linux/sh_dma.h>
>> >> > +
>> >> > +#include <mach/dma-register.h>
>> >> > +#include <mach/r8a7740.h>
>> >>
>> >> Including stuff from <mach/..> isn't really compatible with
>> >> MULTIPLATFORM,
>> >
>> > Hmm, right. I modeled this arch-specific driver code after Laurent's
>> > pinctrl driver revamp, which also includes <mach/*.h> headers. So, we'll
>> > have to think how to fix both.
>>
>> I mentioned this to Laurent when he started converting to PINCTRL, and
>> I believe the only remaining bits are the static GPIO-to-IRQ tables.
>>
>> >> so please don't write new code like this. Actually we
>> >> don't want any code under drivers/ to include stuff from the mach
>> >> directory.
>> >
>> > Sure, understood.
>>
>> Good.
>>
>> >> I suggest that you arrange your code in a way so the C version of DMAC
>> >> support has tables with slave ids as usual under
>> >> arch/arm/mach-shmobile/, but the DT bits that operate independently of
>> >> C stay in drivers/... Over time we will get rid of the C version, and
>> >> until that happens the DT and C version can coexist in parallel.
>> >
>> > That's already how it is. Data, that I took to drivers/dma/sh/ is needed
>> > for both DT and C. DMA stuff, needed only for C are only DMAC devices and
>> > resources. I think, I might be able to carry those DMA specific headers
>> > and defines over from mach/ to drivers/dma/sh. Maybe it would be easier to
>> > do this in several steps:
>> >
>> > 1. add my drivers/dma/sh/shdma-<arch>.c files *with* mach/ headers
>> > 2. switch arches over to those files
>> > (the above two steps are already done in my patch series)
>> > 3. move headers to drivers/dma/sh
>> >
>> > Ok, alternatively, I might be able to do (1) above without using mach/
>> > headers at all by directly copying them to drivers/dma/sh/ and then
>> > removing the original mach/headers in step (2)? I'll look in more detail
>> > at the code tomorrow.
>>
>> Thanks. My apologies for reviewing your code late in the cycle, but
>> I've now looked through this series and the following questions popped
>> up:
>>
>> 1) How will it look like in DT when a DMA Engine slave device will use DMA?
>
> You have already seen them by now, since you replied to that thread too,
> but just for reference, e.g. for an MMCIF controller here
> http://thread.gmane.org/gmane.linux.ports.sh.devel/25445/focus=25442
>
> + dmas = <&dmac 0xd1
> + &dmac 0xd2>;
> + dma-names = "tx", "rx";

Yes, thanks for the pointer.

>> 2) Isn't it possible to leave the SHDMA_SLAVE_xx bits to only be used
>> by legacy C SoC and board code in arch/arm/mach-shmobile? I don't
>> understand why you have to move them over to drivers/... I just assume
>> these SHDMA_SLAVE bits won't be used by 1) above.
>
> That's right, those macros aren't used by (1) above, i.e. they aren't used
> in DT. But they are used pretty intensively internally by the driver. The
> C code might be "legacy," but as far as I understand, SuperH will never go
> to DT, so, as long as it has to be supported, we need to support that
> mode. Same for ARM - IIUC, board-*.c (not -reference) files are also still
> quite intensively developed and supported. So, it doesn't look like the C
> version will go any time soon, right?

In general the driver will have to keep supporting platform device
bindings for board and SoC code written in C, yes.

But for newer SoCs I imagine we will only write DT support. And the
idea is to move over the ARM mach-shmobile board and SoC code to DT.
So only SH will be left in the end unless it is migrated. So I agree
we should support SH of course, but there is no point in shuffling
around all the headers just to optimize for the legacy case.

> Based on that I tried to keep the difference between the C and the DT
> versions as small as possible. And that includes keeping slave IDs at
> least internally without changes.

I understand. Thanks for explaining.

> Of course, we can think about changing the driver more extensively and
> leaving those IDs only for the C case, but in fact they don't seem so
> horrifying to me. We have 2 options to keep them while eliminating the use
> of the <mach/<soc>.h> header:
> (a) redefine them in the driver
> (b) define a single list of slave IDs for all SoCs, AFAICS they don't have
> to be contiguous

Seems like a lot of churn but I can't see the benefit. Can you explain it to me?

Say that we only use DT for future devices. Then why do we want to
expose bits that no one will use in a header file? The legacy case is
already working. Reworking that code for this purpose seems backwards
to me. The legacy case is already working. Fix the DT case. =)

In the case of "struct sh_dmae_slave_config", above you mention that
the enum is used internally, but can't you simply use the index like
this?

Current style:

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,
},

New proposed style in case enum is used:

static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
[SHDMA_SLAVE_SCIF0_TX] = {
.addr = 0xe6c40020,
.chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x21,
},

New proposed style for DT when enum is omitted:

static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
{
.addr = 0xe6c40020,
.chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x21,
},

In the driver, when parsing "struct sh_dmae_slave_config", what's
stopping you from simply using the index? Wouldn't the above allow you
to drop the enums in the DT case?

>> 3) How difficult would it be to describe the information in "struct
>> sh_dmae_slave_config" using DT?
>
> Just as difficult as anything else in DT, I presume. Technically it's not
> very difficult, but we'll have to go through all the rounds to define
> proper bindings and once defined, they'll have to be kept, as you know.

They have to be kept for that particular "compatible" string. But a
new SoC with a new compatible string can use a new format, no?

> And if in the future we need to change that information we'll have a
> problem. E.g., we could define that array as an array of tuples like
>
> slaves = <chcr0 midrid0>,
> <chcr1 midrid1>,
> ...;

That looks quite close to my C proposal above, no? =)

> but that would mean we'll never be able to add a third element to them.

I don't think that's correct. You can add a third element in case of a
new compatible string, no?

> Whereas if kept in C as now, the full flexibility is preserved. So, I
> would really prefer to only push into DT things, for which standard
> bindings are defined, or those, which we absolutely need there.
> Information, that is SoC specific and not standard I'd rather keep in C.

Ok. I think it makes sense to use C in the case we support both DT and C.

>> 4) It seems that some patches in this series are unrelated. Can you
>> submit 4/15 and 9/15 from v4 independently somehow?
>
> 4/15 is required to avoid a compiler warning. 9/15 can be submitted
> separately, but it depends on this patch-series, so, it would be easier to
> keep them all together.

Oops, I was supposed to write 4/15 and 8/15, not 9/15. I suppose you
still want to include them in your series.

>> 5) Reducing and extending (reducing is optional of course)
>>
>> At this point you cover r8a7740, r8a73a0 and r8a73a4. I'm not sure why
>> your picked those 3 SoCs,
>
> That's simple: because I can test them.

Ok, I see. I think some of those have a USBHS-DMAC. I saw that one was
omitted. If the USB drivers bits would support DT then can you support
USBHS-DMAC with these patches?

>> but perhaps it would be a good idea to
>> select a single SoC to begin with but extend the support to also
>> provide DT code that makes use of DMA Engine in slave devices like for
>> instance MMCIF (this would cover question 1) above).
>
> I did, as you know by now.

Yes, in separate series. In next patch series version, would it be
possible to keep these things together?

>> When we have
>> agreed on the big picture then additional SoCs can easily be added
>> later.
>>
>> 6) Remove untested bits
>>
>> And while doing this conversion, perhaps this is a good opportunity to
>> only move over DMA Engine slaves that can be tested? Having tons of
>> unused DMA configuration seems overly heavy to me. If it's not tested
>> then it's broken.
>
> Tested in general or tested by me? I am sure other developers, that added
> support for various interfaces like audio would be better able to test
> them than me. And since I'm actually migrating platforms to this in-driver
> code, dropping any slaves would actually be a regression.

It's not a regression if no one is using it. Having tons of untested
code doesn't make any sense. I'm fine with you keeping your current
code as-is, but when you add DT support then please try to make it
more streamlined and only add bits that you can actually test
yourself.

> If really
> wanted, that would have to go via the standard deprecation process, right?
> E.g., I can well imagine that noone is actually using DMA on SCIF* serial
> interfaces on sh73a0, but removing them should probably be done as a
> separate patch-set.

So you are thinking that you will move over the old C legacy bits into
drivers/. I'm not so keen on that since it will result in a lot of
churn.

I am thinking that you can keep the legacy C bits as-is (perhaps
rework slightly) at the same location, but for the DT reference
support you can add a subset of the code to drivers/. At this time I
want you to only add code that will be used. Then over time we will
get rid of the legacy C bits either by moving to DT or phasing out
software support.

What do you think?

Thanks,

/ magnus