All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support
@ 2016-07-06 20:23 Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular Simon Horman
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

Hi,

this short series adds support for R-Car Gen-3 Internal DMAC to the SDHI
driver.

The approach taken is as follows:

1. Refactor the TMIO DMA code so that it is provided by a set of callbacks
   rather than compiled-in function calls; Refactor the DMA SDHI to use
   this.
2. Rename tmio_mmc_dma.c as renesas_sdhi_sysc_dmac.c which better reflects
   what it is is, particularly after step 2.
3. Add max_segs restriction
4. Add Gen3 DMA code as a separate set of callbacks

Changes since v2:
* Correct discrepancies with BSP v3.2.2 in intermal DMAC implementation.
* Correctly set mmc->max_blk_count in accordance with max_segs.
  This appears to boost performance from ~4.7Mb/s to ~11Mb/s.
* Allow fallback to PIO
* Correct name of SYS DMAC

Changes since v1:
* Cleanup and more renaming as suggested by Wolfram Sang
* max_segs restriction

Testing:

As described on http://elinux.org/Tests:r-car-gen3-sdhi-dma

Previously performance of 4.7Mb/s was reported.
With this series performance of 11Mb/s has been achieved.
However, this is still lower than the 20Mb/s I originally expected.

Simon Horman (3):
  mmc: sh_mobile_sdhi, tmio: make dma more modular
  mmc: sh_mobile_sdhi: rename DMA source file as renesas_sdhi_sys_dmac.c
  arm64: defconfig: Enable SDHI SD/SDIO controller

Yoshihiro Shimoda (3):
  mmc: tmio: add max_segs and max_blk_count in tmio_mmc_data
  mmc: sh_mobile_sdhi: add some SoC specific data for R-Car Gen3
  mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC

 arch/arm64/configs/defconfig                       |   1 +
 drivers/mmc/host/Kconfig                           |  18 ++
 drivers/mmc/host/Makefile                          |   7 +-
 drivers/mmc/host/renesas_sdhi_internal_dmac.c      | 196 +++++++++++++++++++++
 .../{tmio_mmc_dma.c => renesas_sdhi_sys_dmac.c}    |  53 ++++--
 drivers/mmc/host/sh_mobile_sdhi.c                  |  41 +++++
 drivers/mmc/host/tmio_mmc.h                        |  39 +---
 drivers/mmc/host/tmio_mmc_pio.c                    |  53 +++++-
 include/linux/mfd/tmio.h                           |   2 +
 9 files changed, 357 insertions(+), 53 deletions(-)
 create mode 100644 drivers/mmc/host/renesas_sdhi_internal_dmac.c
 rename drivers/mmc/host/{tmio_mmc_dma.c => renesas_sdhi_sys_dmac.c} (83%)

-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  2016-07-06 20:43   ` Arnd Bergmann
  2016-07-06 20:23 ` [PATCH/RFC v3 2/6] mmc: sh_mobile_sdhi: rename DMA source file as renesas_sdhi_sys_dmac.c Simon Horman
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

Refactor DMA support to allow it to be provided by a set of call-backs
that are provided by a host driver. The motivation is to allow multiple
DMA implementations to be provided and instantiated at run-time.

Instantiate the existing DMA implementation from the sh_mobile_sdhi driver
which appears to match the current use-case. This has the side effect
of moving the DMA code from the tmio_core to the sh_mobile_sdhi driver.

A follow-up patch will change the source file for the SDHI DMA
implementation accordingly.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v3
* Allow fallback to PIO
* Remove __initdata annotation
* Use name SYS DMAC rather than SYSC DMAC

v2
* Fix compilation issue due to error in Makefile
* Use MMC_SDHI_SYSC_DMA rather than MMC_SDHI_DMA as new Kconfig symbole
  to better reflect revamped file rename in a follow-up patch.
---
 drivers/mmc/host/Kconfig          |  9 ++++++++
 drivers/mmc/host/Makefile         |  4 +++-
 drivers/mmc/host/sh_mobile_sdhi.c |  8 +++++++
 drivers/mmc/host/tmio_mmc.h       | 39 ++++++++------------------------
 drivers/mmc/host/tmio_mmc_dma.c   | 24 +++++++++++++++-----
 drivers/mmc/host/tmio_mmc_pio.c   | 47 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 95 insertions(+), 36 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 5274f503a39a..0d2ac04d98ed 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -554,10 +554,19 @@ config MMC_SDHI
 	depends on SUPERH || ARM || ARM64
 	depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
 	select MMC_TMIO_CORE
+	select MMC_SDHI_SYS_DMAC if (SUPERH || ARM)
 	help
 	  This provides support for the SDHI SD/SDIO controller found in
 	  SuperH and ARM SH-Mobile SoCs
 
+config MMC_SDHI_SYS_DMAC
+	tristate "DMA support use of SYS DMAC with SDHI SD/SDIO controller"
+	depends on SUPERH || ARM || COMPILE_TEST
+	depends on MMC_SDHI
+	help
+	  This provides DMA support for the SDHI SD/SDIO controller
+	  found in SuperH and Renesas ARM based SoCs.
+
 config MMC_CB710
 	tristate "ENE CB710 MMC/SD Interface support"
 	depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e2bdaaf43184..c72d442908a2 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -37,8 +37,10 @@ obj-$(CONFIG_MMC_SDRICOH_CS)	+= sdricoh_cs.o
 obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
 obj-$(CONFIG_MMC_TMIO_CORE)	+= tmio_mmc_core.o
 tmio_mmc_core-y			:= tmio_mmc_pio.o
-tmio_mmc_core-$(subst m,y,$(CONFIG_MMC_SDHI))	+= tmio_mmc_dma.o
 obj-$(CONFIG_MMC_SDHI)		+= sh_mobile_sdhi.o
+ifeq ($(subst m,y,$(CONFIG_MMC_SDHI_SYS_DMAC)),y)
+obj-$(CONFIG_MMC_SDHI)		+= tmio_mmc_dma.o
+endif
 obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index c3b651bf89cb..b2ab8c3d27af 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -106,6 +106,12 @@ struct sh_mobile_sdhi {
 	struct pinctrl_state *pins_default, *pins_uhs;
 };
 
+#if IS_ENABLED(CONFIG_MMC_SDHI_SYS_DMAC)
+void tmio_mmc_init_dma(void);
+#else
+static void tmio_mmc_init_dma(void) { }
+#endif
+
 static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
 {
 	u32 val;
@@ -363,6 +369,8 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 		host->bus_shift = of_data->bus_shift;
 	}
 
+	tmio_mmc_init_dma();
+
 	host->dma		= dma_priv;
 	host->write16_hook	= sh_mobile_sdhi_write16_hook;
 	host->clk_enable	= sh_mobile_sdhi_clk_enable;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 7f63ec05bdf4..cbe0212fbbf4 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -187,37 +187,16 @@ static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
 	local_irq_restore(*flags);
 }
 
-#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
-void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
-void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
-void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
-void tmio_mmc_release_dma(struct tmio_mmc_host *host);
-void tmio_mmc_abort_dma(struct tmio_mmc_host *host);
-#else
-static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
-			       struct mmc_data *data)
-{
-}
-
-static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
-{
-}
-
-static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
-				 struct tmio_mmc_data *pdata)
-{
-	host->chan_tx = NULL;
-	host->chan_rx = NULL;
-}
-
-static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
-{
-}
+struct tmio_mmc_dma_ops {
+	void (*start)(struct tmio_mmc_host *host, struct mmc_data *data);
+	void (*enable)(struct tmio_mmc_host *host, bool enable);
+	void (*request)(struct tmio_mmc_host *host,
+			struct tmio_mmc_data *pdata);
+	void (*release)(struct tmio_mmc_host *host);
+	void (*abort)(struct tmio_mmc_host *host);
+};
 
-static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
-{
-}
-#endif
+void tmio_set_dma_ops(const struct tmio_mmc_dma_ops *ops);
 
 #ifdef CONFIG_PM
 int tmio_mmc_host_runtime_suspend(struct device *dev);
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
index fa8a936a3d9b..a866842f607c 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -22,7 +22,7 @@
 
 #define TMIO_MMC_MIN_DMA_LEN 8
 
-void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
 {
 	if (!host->chan_tx || !host->chan_rx)
 		return;
@@ -31,7 +31,7 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
 		host->dma->enable(host, enable);
 }
 
-void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+static void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
 {
 	tmio_mmc_enable_dma(host, false);
 
@@ -187,7 +187,7 @@ pio:
 	}
 }
 
-void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+static void tmio_mmc_start_dma(struct tmio_mmc_host *host,
 			       struct mmc_data *data)
 {
 	if (data->flags & MMC_DATA_READ) {
@@ -244,7 +244,8 @@ out:
 	spin_unlock_irq(&host->lock);
 }
 
-void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata)
+static void tmio_mmc_request_dma(struct tmio_mmc_host *host,
+				 struct tmio_mmc_data *pdata)
 {
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
 	if (!host->dma || (!host->pdev->dev.of_node &&
@@ -324,7 +325,7 @@ ecfgtx:
 	host->chan_tx = NULL;
 }
 
-void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
 {
 	if (host->chan_tx) {
 		struct dma_chan *chan = host->chan_tx;
@@ -341,3 +342,16 @@ void tmio_mmc_release_dma(struct tmio_mmc_host *host)
 		host->bounce_buf = NULL;
 	}
 }
+
+static struct tmio_mmc_dma_ops tmio_mmc_dma_ops = {
+	.start = tmio_mmc_start_dma,
+	.enable = tmio_mmc_enable_dma,
+	.request = tmio_mmc_request_dma,
+	.release = tmio_mmc_release_dma,
+	.abort = tmio_mmc_abort_dma,
+};
+
+void tmio_mmc_init_dma(void)
+{
+	tmio_set_dma_ops(&tmio_mmc_dma_ops);
+}
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 92467efc4e2c..c0020c331595 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -52,17 +52,63 @@
 
 #include "tmio_mmc.h"
 
+static struct tmio_mmc_dma_ops tmio_dma_ops;
+
+void tmio_set_dma_ops(const struct tmio_mmc_dma_ops *ops)
+{
+	tmio_dma_ops = *ops;
+}
+EXPORT_SYMBOL(tmio_set_dma_ops);
+
+static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+				      struct mmc_data *data)
+{
+	if (tmio_dma_ops.start)
+		tmio_dma_ops.start(host, data);
+}
+
+static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+{
+	if (tmio_dma_ops.enable)
+		tmio_dma_ops.enable(host, enable);
+}
+
+static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
+					struct tmio_mmc_data *pdata)
+{
+	if (tmio_dma_ops.request) {
+		tmio_dma_ops.request(host, pdata);
+	} else {
+		host->chan_tx = NULL;
+		host->chan_rx = NULL;
+	}
+}
+
+static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+{
+	if (tmio_dma_ops.release)
+		tmio_dma_ops.release(host);
+}
+
+static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+{
+	if (tmio_dma_ops.abort)
+		tmio_dma_ops.abort(host);
+}
+
 void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
 	host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
 	sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
 }
+EXPORT_SYMBOL(tmio_mmc_enable_mmc_irqs);
 
 void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
 	host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
 	sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
 }
+EXPORT_SYMBOL(tmio_mmc_disable_mmc_irqs);
 
 static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
@@ -519,6 +565,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
 
 	schedule_work(&host->done);
 }
+EXPORT_SYMBOL(tmio_mmc_do_data_irq);
 
 static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
 {
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 2/6] mmc: sh_mobile_sdhi: rename DMA source file as renesas_sdhi_sys_dmac.c
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 3/6] mmc: tmio: add max_segs and max_blk_count in tmio_mmc_data Simon Horman
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

Rename the source file for DMA for SDHI as a follow-up to attaching
DMA code to the SDHI driver rather than the tmio_core driver and
prepartation for allowing more than one DMA provider.

The name Renesas is chosen as the the SDHI driver is applicable to a wider
range of SoCs than SH-Mobile, Renesas seems to be a more appropriate name.
However, the SDHI driver source itself, is left as sh_mobile_sdhi to
avoid unnecessary churn.

The name sys_dmac was chosen to reflect the type of DMA used.

Internal symbols have also been renamed to reflect the filename change.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v3
* Update names to SYS DMAC instead of SYSC DMAC
* Allow fallback to PIO
* Allow selection of SYS DMAC via Kconfig

v2
* Use renesas_sdhi_sysc_dmac rather than renesas_sdhi_dmac as file name
* Rename symbols to reflect filename change
* Drop bogus use of __initdata
---
 drivers/mmc/host/Kconfig                           |  8 +++
 drivers/mmc/host/Makefile                          |  2 +-
 .../{tmio_mmc_dma.c => renesas_sdhi_sys_dmac.c}    | 57 +++++++++++-----------
 drivers/mmc/host/sh_mobile_sdhi.c                  |  6 +--
 4 files changed, 41 insertions(+), 32 deletions(-)
 rename drivers/mmc/host/{tmio_mmc_dma.c => renesas_sdhi_sys_dmac.c} (83%)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0d2ac04d98ed..fd3c4b2a0576 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -567,6 +567,14 @@ config MMC_SDHI_SYS_DMAC
 	  This provides DMA support for the SDHI SD/SDIO controller
 	  found in SuperH and Renesas ARM based SoCs.
 
+config MMC_SDHI_INTERNAL_DMA
+	tristate "DMA support for Internal DMAC with SDHI SD/SDIO controller"
+	depends on ARM64
+	depends on MMC_SDHI
+	help
+	  This provides DMA support for the SDHI SD/SDIO controller
+	  found in Renesas arm64 based SoCs.
+
 config MMC_CB710
 	tristate "ENE CB710 MMC/SD Interface support"
 	depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c72d442908a2..5a67643d5e3d 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_MMC_TMIO_CORE)	+= tmio_mmc_core.o
 tmio_mmc_core-y			:= tmio_mmc_pio.o
 obj-$(CONFIG_MMC_SDHI)		+= sh_mobile_sdhi.o
 ifeq ($(subst m,y,$(CONFIG_MMC_SDHI_SYS_DMAC)),y)
-obj-$(CONFIG_MMC_SDHI)		+= tmio_mmc_dma.o
+obj-$(CONFIG_MMC_SDHI)		+= renesas_sdhi_sys_dmac.o
 endif
 obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
similarity index 83%
rename from drivers/mmc/host/tmio_mmc_dma.c
rename to drivers/mmc/host/renesas_sdhi_sys_dmac.c
index a866842f607c..0e2f29b7d31c 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/mmc/tmio_mmc_dma.c
+ * linux/drivers/mmc/renesas_sdhi_sys_dmac_dma.c
  *
  * Copyright (C) 2010-2011 Guennadi Liakhovetski
  *
@@ -22,7 +22,8 @@
 
 #define TMIO_MMC_MIN_DMA_LEN 8
 
-static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+static void sdhi_sys_dmac_enable_dma(struct tmio_mmc_host *host,
+				      bool enable)
 {
 	if (!host->chan_tx || !host->chan_rx)
 		return;
@@ -31,19 +32,19 @@ static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
 		host->dma->enable(host, enable);
 }
 
-static void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+static void sdhi_sys_dmac_abort_dma(struct tmio_mmc_host *host)
 {
-	tmio_mmc_enable_dma(host, false);
+	sdhi_sys_dmac_enable_dma(host, false);
 
 	if (host->chan_rx)
 		dmaengine_terminate_all(host->chan_rx);
 	if (host->chan_tx)
 		dmaengine_terminate_all(host->chan_tx);
 
-	tmio_mmc_enable_dma(host, true);
+	sdhi_sys_dmac_enable_dma(host, true);
 }
 
-static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
+static void sdhi_sys_dmac_start_dma_rx(struct tmio_mmc_host *host)
 {
 	struct scatterlist *sg = host->sg_ptr, *sg_tmp;
 	struct dma_async_tx_descriptor *desc = NULL;
@@ -97,7 +98,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
 pio:
 	if (!desc) {
 		/* DMA failed, fall back to PIO */
-		tmio_mmc_enable_dma(host, false);
+		sdhi_sys_dmac_enable_dma(host, false);
 		if (ret >= 0)
 			ret = -EIO;
 		host->chan_rx = NULL;
@@ -113,7 +114,7 @@ pio:
 	}
 }
 
-static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
+static void sdhi_sys_dmac_start_dma_tx(struct tmio_mmc_host *host)
 {
 	struct scatterlist *sg = host->sg_ptr, *sg_tmp;
 	struct dma_async_tx_descriptor *desc = NULL;
@@ -171,7 +172,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
 pio:
 	if (!desc) {
 		/* DMA failed, fall back to PIO */
-		tmio_mmc_enable_dma(host, false);
+		sdhi_sys_dmac_enable_dma(host, false);
 		if (ret >= 0)
 			ret = -EIO;
 		host->chan_tx = NULL;
@@ -187,19 +188,19 @@ pio:
 	}
 }
 
-static void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+static void sdhi_sys_dmac_start_dma(struct tmio_mmc_host *host,
 			       struct mmc_data *data)
 {
 	if (data->flags & MMC_DATA_READ) {
 		if (host->chan_rx)
-			tmio_mmc_start_dma_rx(host);
+			sdhi_sys_dmac_start_dma_rx(host);
 	} else {
 		if (host->chan_tx)
-			tmio_mmc_start_dma_tx(host);
+			sdhi_sys_dmac_start_dma_tx(host);
 	}
 }
 
-static void tmio_mmc_issue_tasklet_fn(unsigned long priv)
+static void sdhi_sys_dmac_issue_tasklet_fn(unsigned long priv)
 {
 	struct tmio_mmc_host *host = (struct tmio_mmc_host *)priv;
 	struct dma_chan *chan = NULL;
@@ -221,7 +222,7 @@ static void tmio_mmc_issue_tasklet_fn(unsigned long priv)
 		dma_async_issue_pending(chan);
 }
 
-static void tmio_mmc_tasklet_fn(unsigned long arg)
+static void sdhi_sys_dmac_tasklet_fn(unsigned long arg)
 {
 	struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
 
@@ -244,8 +245,8 @@ out:
 	spin_unlock_irq(&host->lock);
 }
 
-static void tmio_mmc_request_dma(struct tmio_mmc_host *host,
-				 struct tmio_mmc_data *pdata)
+static void sdhi_sys_dmac_request_dma(struct tmio_mmc_host *host,
+				       struct tmio_mmc_data *pdata)
 {
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
 	if (!host->dma || (!host->pdev->dev.of_node &&
@@ -307,11 +308,11 @@ static void tmio_mmc_request_dma(struct tmio_mmc_host *host,
 		if (!host->bounce_buf)
 			goto ebouncebuf;
 
-		tasklet_init(&host->dma_complete, tmio_mmc_tasklet_fn, (unsigned long)host);
-		tasklet_init(&host->dma_issue, tmio_mmc_issue_tasklet_fn, (unsigned long)host);
+		tasklet_init(&host->dma_complete, sdhi_sys_dmac_tasklet_fn, (unsigned long)host);
+		tasklet_init(&host->dma_issue, sdhi_sys_dmac_issue_tasklet_fn, (unsigned long)host);
 	}
 
-	tmio_mmc_enable_dma(host, true);
+	sdhi_sys_dmac_enable_dma(host, true);
 
 	return;
 
@@ -325,7 +326,7 @@ ecfgtx:
 	host->chan_tx = NULL;
 }
 
-static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+static void sdhi_sys_dmac_release_dma(struct tmio_mmc_host *host)
 {
 	if (host->chan_tx) {
 		struct dma_chan *chan = host->chan_tx;
@@ -343,15 +344,15 @@ static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
 	}
 }
 
-static struct tmio_mmc_dma_ops tmio_mmc_dma_ops = {
-	.start = tmio_mmc_start_dma,
-	.enable = tmio_mmc_enable_dma,
-	.request = tmio_mmc_request_dma,
-	.release = tmio_mmc_release_dma,
-	.abort = tmio_mmc_abort_dma,
+static struct tmio_mmc_dma_ops sdhi_sys_dmac_dma_ops = {
+	.start = sdhi_sys_dmac_start_dma,
+	.enable = sdhi_sys_dmac_enable_dma,
+	.request = sdhi_sys_dmac_request_dma,
+	.release = sdhi_sys_dmac_release_dma,
+	.abort = sdhi_sys_dmac_abort_dma,
 };
 
-void tmio_mmc_init_dma(void)
+void sdhi_sys_dmac_init_dma(void)
 {
-	tmio_set_dma_ops(&tmio_mmc_dma_ops);
+	tmio_set_dma_ops(&sdhi_sys_dmac_dma_ops);
 }
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index b2ab8c3d27af..394e018e6f39 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -107,9 +107,9 @@ struct sh_mobile_sdhi {
 };
 
 #if IS_ENABLED(CONFIG_MMC_SDHI_SYS_DMAC)
-void tmio_mmc_init_dma(void);
+void sdhi_sys_dmac_init_dma(void);
 #else
-static void tmio_mmc_init_dma(void) { }
+static void sdhi_sys_dmac_init_dma(void) { }
 #endif
 
 static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
@@ -369,7 +369,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 		host->bus_shift = of_data->bus_shift;
 	}
 
-	tmio_mmc_init_dma();
+	sdhi_sys_dmac_init_dma();
 
 	host->dma		= dma_priv;
 	host->write16_hook	= sh_mobile_sdhi_write16_hook;
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 3/6] mmc: tmio: add max_segs and max_blk_count in tmio_mmc_data
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 2/6] mmc: sh_mobile_sdhi: rename DMA source file as renesas_sdhi_sys_dmac.c Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 4/6] mmc: sh_mobile_sdhi: add some SoC specific data for R-Car Gen3 Simon Horman
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

To change each value from related driver (e.g. sh_mobile_sdhi driver),
this patch adds these member in the struct tmio_mmc_data.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Ai Kyuse <ai.kyuse.uw@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v3
* Add missing hunk to set mmc->max_blk_count

v2
* First post
---
 drivers/mmc/host/tmio_mmc_pio.c | 6 +++---
 include/linux/mfd/tmio.h        | 2 ++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index c0020c331595..30d136c72005 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -1124,10 +1124,10 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
 
 	mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities;
 	mmc->caps2 |= pdata->capabilities2;
-	mmc->max_segs = 32;
+	mmc->max_segs = pdata->max_segs ? pdata->max_segs : 32;
 	mmc->max_blk_size = 512;
-	mmc->max_blk_count = (PAGE_SIZE / mmc->max_blk_size) *
-		mmc->max_segs;
+	mmc->max_blk_count = pdata->max_blk_count ? :
+		(PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
 	mmc->max_seg_size = mmc->max_req_size;
 
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 7a26286db895..3b95dc7eb314 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -125,6 +125,8 @@ struct tmio_mmc_data {
 	unsigned int			cd_gpio;
 	int				alignment_shift;
 	dma_addr_t			dma_rx_offset;
+	unsigned int			max_blk_count;
+	unsigned short			max_segs;
 	void (*set_pwr)(struct platform_device *host, int state);
 	void (*set_clk_div)(struct platform_device *host, int state);
 };
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 4/6] mmc: sh_mobile_sdhi: add some SoC specific data for R-Car Gen3
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
                   ` (2 preceding siblings ...)
  2016-07-06 20:23 ` [PATCH/RFC v3 3/6] mmc: tmio: add max_segs and max_blk_count in tmio_mmc_data Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC Simon Horman
  2016-07-06 20:23 ` [PATCH/RFC v3 6/6] arm64: defconfig: Enable SDHI SD/SDIO controller Simon Horman
  5 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

To avoid complicate code in own dma code for gen3, this patch
adds set max_segs to 1. Then, the tmio driver will get requests
as sg_len = 1 only.

In the performance point of view, the CONFIG_MMC_BLOCK_BOUNCE should
be set. Otherwise, mmc block layer will set 4-kbyte each as a request.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Ai Kyuse <ai.kyuse.uw@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* First post
---
 drivers/mmc/host/sh_mobile_sdhi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 394e018e6f39..83ca6cb78484 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -54,6 +54,8 @@ struct sh_mobile_sdhi_of_data {
 	enum dma_slave_buswidth dma_buswidth;
 	dma_addr_t dma_rx_offset;
 	unsigned bus_shift;
+	unsigned int max_blk_count;
+	unsigned short max_segs;
 };
 
 static const struct sh_mobile_sdhi_of_data of_default_cfg = {
@@ -79,6 +81,9 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen3_compatible = {
 			  TMIO_MMC_CLK_ACTUAL | TMIO_MMC_MIN_RCAR2,
 	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
 	.bus_shift	= 2,
+	/* Gen3 SDHI DMAC can handle 0xffffffff blk count, but seg = 1 */
+	.max_blk_count  = 0xffffffff,
+	.max_segs = 1,
 };
 
 static const struct of_device_id sh_mobile_sdhi_of_match[] = {
@@ -365,6 +370,8 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 		mmc_data->capabilities |= of_data->capabilities;
 		mmc_data->capabilities2 |= of_data->capabilities2;
 		mmc_data->dma_rx_offset = of_data->dma_rx_offset;
+		mmc_data->max_blk_count = of_data->max_blk_count;
+		mmc_data->max_segs = of_data->max_segs;
 		dma_priv->dma_buswidth = of_data->dma_buswidth;
 		host->bus_shift = of_data->bus_shift;
 	}
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
                   ` (3 preceding siblings ...)
  2016-07-06 20:23 ` [PATCH/RFC v3 4/6] mmc: sh_mobile_sdhi: add some SoC specific data for R-Car Gen3 Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  2016-07-06 21:21   ` Arnd Bergmann
  2016-07-06 20:23 ` [PATCH/RFC v3 6/6] arm64: defconfig: Enable SDHI SD/SDIO controller Simon Horman
  5 siblings, 1 reply; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

R-Car Gen3 has a dedicated DMA controller for SDHI module. Since
the DMAC is in a part of SDHI module and is not suitable as dmaengine,
this patch adds a different code as tmio_mmc_dma_gen3.c.

Clearing of DM_CM_INFO1 after DMA thanks to Dirk Behme

Cc: Dirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Ai Kyuse <ai.kyuse.uw@renesas.com>
---
v3 [Simon Horman]
* Add missing sdhi_internal_dmac_enable_dma() calls to
  sdhi_internal_dmac_start_dma() and sdhi_internal_dmac_complete_tasklet_fn()
* Clear DM_CM_INFO1 after DMA
* Allow fallback to PIO

v2 [Simon Horman]
* Correct build error in Mekefile
* Correct inverted logic in sh_mobile_sdhi_init_dma()
* Use renesas_sdhi_internal_dmac.c as new file name to better reflect
  the contents.

v1 [Simon Horman]
* Use newly introduced tmio_set_dma_ops() to allow driver
  to be compiled along side non-Gen3 SDHI DMA driver
  - - Use renesas_sdhi_dma_gen3.c rather than tmio_mmc_dma_gen3.c
      as source file name as driver is now attached to renesas_sdhi
      rather than tmio_core driver.
* Remove debugging code

v0 [Yoshihiro Shimoda]
---
 drivers/mmc/host/Kconfig                      |   1 +
 drivers/mmc/host/Makefile                     |   3 +
 drivers/mmc/host/renesas_sdhi_internal_dmac.c | 196 ++++++++++++++++++++++++++
 drivers/mmc/host/sh_mobile_sdhi.c             |  28 +++-
 4 files changed, 227 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/host/renesas_sdhi_internal_dmac.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index fd3c4b2a0576..0d56a4928abf 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -555,6 +555,7 @@ config MMC_SDHI
 	depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
 	select MMC_TMIO_CORE
 	select MMC_SDHI_SYS_DMAC if (SUPERH || ARM)
+	select MMC_SDHI_INTERNAL_DMA if ARM64
 	help
 	  This provides support for the SDHI SD/SDIO controller found in
 	  SuperH and ARM SH-Mobile SoCs
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 5a67643d5e3d..451bbeee0d2a 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -41,6 +41,9 @@ obj-$(CONFIG_MMC_SDHI)		+= sh_mobile_sdhi.o
 ifeq ($(subst m,y,$(CONFIG_MMC_SDHI_SYS_DMAC)),y)
 obj-$(CONFIG_MMC_SDHI)		+= renesas_sdhi_sys_dmac.o
 endif
+ifeq ($(subst m,y,$(CONFIG_MMC_SDHI_INTERNAL_DMA)),y)
+obj-$(CONFIG_MMC_SDHI)		+= renesas_sdhi_internal_dmac.o
+endif
 obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
new file mode 100644
index 000000000000..2868d8d439fd
--- /dev/null
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -0,0 +1,196 @@
+/*
+ * linux/drivers/mmc/renesas_sdhi_internal_dmac.c
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * R-Car Gen3 DMA function for TMIO MMC implementations
+ */
+
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/pagemap.h>
+#include <linux/scatterlist.h>
+
+#include "tmio_mmc.h"
+
+#define DM_CM_DTRAN_MODE	0x820
+#define DM_CM_DTRAN_CTRL	0x828
+#define DM_CM_RST		0x830
+#define DM_CM_INFO1		0x840
+#define DM_CM_INFO1_MASK	0x848
+#define DM_CM_INFO2		0x850
+#define DM_CM_INFO2_MASK	0x858
+#define DM_DTRAN_ADDR		0x880
+
+/* DM_CM_DTRAN_MODE */
+#define DTRAN_MODE_CH_NUM_CH0	0	/* "downstream" = for write commands */
+#define DTRAN_MODE_CH_NUM_CH1	BIT(16)	/* "uptream" = for read commands */
+#define DTRAN_MODE_BUS_WID_TH	(BIT(5) | BIT(4))
+#define DTRAN_MODE_ADDR_MODE	BIT(0)	/* 1 = Increment address */
+
+/* DM_CM_DTRAN_CTRL */
+#define DTRAN_CTRL_DM_START	BIT(0)
+
+/* DM_CM_RST */
+#define RST_DTRANRST1		BIT(9)
+#define RST_DTRANRST0		BIT(8)
+#define RST_RESERVED_BITS	GENMASK_ULL(32, 0)
+
+/* DM_CM_INFO1 and DM_CM_INFO1_MASK */
+#define INFO1_CLEAR		0
+#define INFO1_DTRANEND1		BIT(17)
+#define INFO1_DTRANEND0		BIT(16)
+
+/* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+#define INFO2_DTRANERR1		BIT(17)
+#define INFO2_DTRANERR0		BIT(16)
+
+/*
+ * Specification of this driver:
+ * - host->chan_{rx,tx} will be used as a flag of enabling/disabling the dma
+ * - Since this SDHI DMAC register set has actual 32-bit and "bus_shift" is 2,
+ *   this driver cannot use original sd_ctrl_{write,read}32 functions.
+ */
+
+static void tmio_dm_write(struct tmio_mmc_host *host, int addr, u64 val)
+{
+	writeq(val, host->ctl + addr);
+}
+
+static void sdhi_internal_dmac_enable_dma(struct tmio_mmc_host *host,
+					  bool enable)
+{
+	if (!host->chan_tx || !host->chan_rx)
+		return;
+
+	if (!enable)
+		tmio_dm_write(host, DM_CM_INFO1, INFO1_CLEAR);
+
+	if (host->dma->enable)
+		host->dma->enable(host, enable);
+}
+
+static void sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host)
+{
+	u64 val = RST_DTRANRST1 | RST_DTRANRST0;
+
+	sdhi_internal_dmac_enable_dma(host, false);
+
+	tmio_dm_write(host, DM_CM_RST, RST_RESERVED_BITS & ~val);
+	tmio_dm_write(host, DM_CM_RST, RST_RESERVED_BITS | val);
+
+	sdhi_internal_dmac_enable_dma(host, true);
+}
+
+static void sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
+			       struct mmc_data *data)
+{
+	struct scatterlist *sg = host->sg_ptr;
+	u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE;
+	enum dma_data_direction dir;
+	int ret;
+	u32 irq_mask;
+
+	/* This DMAC cannot handle if sg_len is not 1 */
+	WARN_ON(host->sg_len > 1);
+
+	/* This DMAC cannot handle if buffer is not 8-bytes alignment */
+	if (!IS_ALIGNED(sg->offset, 8)) {
+		host->force_pio = true;
+		sdhi_internal_dmac_enable_dma(host, false);
+		return;
+	}
+
+	if (data->flags & MMC_DATA_READ) {
+		dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
+		dir = DMA_FROM_DEVICE;
+		irq_mask = TMIO_STAT_RXRDY;
+	} else {
+		dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
+		dir = DMA_TO_DEVICE;
+		irq_mask = TMIO_STAT_TXRQ;
+	}
+
+	ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir);
+	if (ret < 0) {
+		dev_err(&host->pdev->dev, "%s: dma_map_sg failed\n", __func__);
+		return;
+	}
+
+	sdhi_internal_dmac_enable_dma(host, true);
+
+	/* disable PIO irqs to avoid "PIO IRQ in DMA mode!" */
+	tmio_mmc_disable_mmc_irqs(host, irq_mask);
+
+	/* set dma parameters */
+	tmio_dm_write(host, DM_CM_DTRAN_MODE, dtran_mode);
+	tmio_dm_write(host, DM_DTRAN_ADDR, sg->dma_address);
+}
+
+static void sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg)
+{
+	struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
+
+	tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
+
+	/* start the DMAC */
+	tmio_dm_write(host, DM_CM_DTRAN_CTRL, DTRAN_CTRL_DM_START);
+}
+
+static void sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
+{
+	struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
+	enum dma_data_direction dir;
+
+	if (!host->data)
+		return;
+
+	if (host->data->flags & MMC_DATA_READ)
+		dir = DMA_FROM_DEVICE;
+	else
+		dir = DMA_TO_DEVICE;
+
+	sdhi_internal_dmac_enable_dma(host, false);
+	dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir);
+	tmio_mmc_do_data_irq(host);
+}
+
+static void sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
+					   struct tmio_mmc_data *pdata)
+{
+	/* Each value is set to non-zero to assume "enabling" each DMA */
+	host->chan_rx = host->chan_tx = (void *)0xdeadbeaf;
+
+	tasklet_init(&host->dma_complete,
+		     sdhi_internal_dmac_complete_tasklet_fn,
+		     (unsigned long)host);
+	tasklet_init(&host->dma_issue, sdhi_internal_dmac_issue_tasklet_fn,
+		     (unsigned long)host);
+}
+
+static void sdhi_internal_dmac_release_dma(struct tmio_mmc_host *host)
+{
+	/* Each value is set to zero to assume "disabling" each DMA */
+	host->chan_rx = host->chan_tx = NULL;
+}
+
+static struct tmio_mmc_dma_ops sdhi_internal_dmac_dma_ops = {
+	.start = sdhi_internal_dmac_start_dma,
+	.enable = sdhi_internal_dmac_enable_dma,
+	.request = sdhi_internal_dmac_request_dma,
+	.release = sdhi_internal_dmac_release_dma,
+	.abort = sdhi_internal_dmac_abort_dma,
+};
+
+void sdhi_internal_dmac_init_dma(void)
+{
+	tmio_set_dma_ops(&sdhi_internal_dmac_dma_ops);
+}
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 83ca6cb78484..e76b0afb854f 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -47,6 +47,11 @@
 
 #define host_to_priv(host) container_of((host)->pdata, struct sh_mobile_sdhi, mmc_data)
 
+enum tmio_mmc_dmac_type {
+	TMIO_MMC_SYSC_DMAC	= 0,
+	TMIO_MMC_INTERNAL_DMAC,
+};
+
 struct sh_mobile_sdhi_of_data {
 	unsigned long tmio_flags;
 	unsigned long capabilities;
@@ -56,6 +61,7 @@ struct sh_mobile_sdhi_of_data {
 	unsigned bus_shift;
 	unsigned int max_blk_count;
 	unsigned short max_segs;
+	enum tmio_mmc_dmac_type dmac_type;
 };
 
 static const struct sh_mobile_sdhi_of_data of_default_cfg = {
@@ -84,6 +90,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen3_compatible = {
 	/* Gen3 SDHI DMAC can handle 0xffffffff blk count, but seg = 1 */
 	.max_blk_count  = 0xffffffff,
 	.max_segs = 1,
+	.dmac_type	= TMIO_MMC_INTERNAL_DMAC,
 };
 
 static const struct of_device_id sh_mobile_sdhi_of_match[] = {
@@ -117,6 +124,23 @@ void sdhi_sys_dmac_init_dma(void);
 static void sdhi_sys_dmac_init_dma(void) { }
 #endif
 
+#if IS_ENABLED(CONFIG_MMC_SDHI_INTERNAL_DMA)
+void sdhi_internal_dmac_init_dma(void);
+#else
+static void sdhi_internal_dmac_init_dma(void) { }
+#endif
+
+static void sh_mobile_sdhi_init_dma(enum tmio_mmc_dmac_type dmac_type)
+{
+	switch (dmac_type) {
+	case TMIO_MMC_INTERNAL_DMAC:
+		return sdhi_internal_dmac_init_dma();
+
+	case TMIO_MMC_SYSC_DMAC:
+		return sdhi_sys_dmac_init_dma();
+	}
+}
+
 static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
 {
 	u32 val;
@@ -323,6 +347,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *of_id =
 		of_match_device(sh_mobile_sdhi_of_match, &pdev->dev);
+	enum tmio_mmc_dmac_type dmac_type = TMIO_MMC_SYSC_DMAC;
 	struct sh_mobile_sdhi *priv;
 	struct tmio_mmc_data *mmc_data;
 	struct tmio_mmc_data *mmd = pdev->dev.platform_data;
@@ -374,9 +399,10 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 		mmc_data->max_segs = of_data->max_segs;
 		dma_priv->dma_buswidth = of_data->dma_buswidth;
 		host->bus_shift = of_data->bus_shift;
+		dmac_type = of_data->dmac_type;
 	}
 
-	sdhi_sys_dmac_init_dma();
+	sh_mobile_sdhi_init_dma(dmac_type);
 
 	host->dma		= dma_priv;
 	host->write16_hook	= sh_mobile_sdhi_write16_hook;
-- 
2.7.0.rc3.207.g0ac5344


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH/RFC v3 6/6] arm64: defconfig: Enable SDHI SD/SDIO controller
  2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
                   ` (4 preceding siblings ...)
  2016-07-06 20:23 ` [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC Simon Horman
@ 2016-07-06 20:23 ` Simon Horman
  5 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-06 20:23 UTC (permalink / raw)
  To: Wolfram Sang, Ulf Hansson; +Cc: Magnus Damm, linux-mmc, linux-renesas-soc

This is present on R-Car Gen3 SoCs and is already present
in the DT of the r8a7795/salvator-x (H3).

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v3
* New patch
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd2d74d0491e..78e02f3675f4 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -250,6 +250,7 @@ CONFIG_MMC_SDHCI_OF_ESDHC=y
 CONFIG_MMC_SDHCI_TEGRA=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_SPI=y
+CONFIG_MMC_SDHI=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_K3=y
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular
  2016-07-06 20:23 ` [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular Simon Horman
@ 2016-07-06 20:43   ` Arnd Bergmann
  0 siblings, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2016-07-06 20:43 UTC (permalink / raw)
  To: Simon Horman
  Cc: Wolfram Sang, Ulf Hansson, Magnus Damm, linux-mmc, linux-renesas-soc

On Wednesday, July 6, 2016 10:23:25 PM CEST Simon Horman wrote:
> 
> +static struct tmio_mmc_dma_ops tmio_dma_ops;
> +
> +void tmio_set_dma_ops(const struct tmio_mmc_dma_ops *ops)
> +{
> +       tmio_dma_ops = *ops;
> +}
> +EXPORT_SYMBOL(tmio_set_dma_ops);
> +
> 

Having a global instance of this pointer seems wrong, why not
store the pointer per device in struct tmio_mmc_host?

It's unlikely to ever clash between two devices in the same system,
but we generally try not to rely on that.

	Arnd

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC
  2016-07-06 20:23 ` [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC Simon Horman
@ 2016-07-06 21:21   ` Arnd Bergmann
  2016-07-07  6:57     ` Simon Horman
  0 siblings, 1 reply; 10+ messages in thread
From: Arnd Bergmann @ 2016-07-06 21:21 UTC (permalink / raw)
  To: Simon Horman
  Cc: Wolfram Sang, Ulf Hansson, Magnus Damm, linux-mmc, linux-renesas-soc

On Wednesday, July 6, 2016 10:23:29 PM CEST Simon Horman wrote:
> @@ -117,6 +124,23 @@ void sdhi_sys_dmac_init_dma(void);
>  static void sdhi_sys_dmac_init_dma(void) { }
>  #endif
>  
> +#if IS_ENABLED(CONFIG_MMC_SDHI_INTERNAL_DMA)
> +void sdhi_internal_dmac_init_dma(void);
> +#else
> +static void sdhi_internal_dmac_init_dma(void) { }
> +#endif
> +
> +static void sh_mobile_sdhi_init_dma(enum tmio_mmc_dmac_type dmac_type)
> +{
> +       switch (dmac_type) {
> +       case TMIO_MMC_INTERNAL_DMAC:
> +               return sdhi_internal_dmac_init_dma();
> +
> +       case TMIO_MMC_SYSC_DMAC:
> +               return sdhi_sys_dmac_init_dma();
> +       }
> +}
> +
>  static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
>  {
>         u32 val;
> 

I've commented on this part for v2 already but got no reply. This
time I took a little more care to understand the structure of the
driver and how it gets modified.

The way I see it, we have the MMC_TMIO_CORE driver that consists of
tmio_mmc_pio.c and tmio_mmc_dma.c, which are tightly connected though the
second one is optional, and two front-ends named tmio_mmc.c and
sh_mobile_sdhi.c.

The first front-end never uses DMA, while the second one may or may
not use DMA but is always built with the DMA support linked into the
core driver.

I think abstracting the two DMA modes through a structure of
function pointers as you do is the right strategy, but to build on
top of that, we can change the link order:

- rename tmio_mmc_pio.c to tmio_mmc_core.c and make that the actual
  driver core (without DMA)
- tmio_mmc_dma.c becomes the main driver module for sh_mobile_sdhi
  and gets the sh_mobile_sdhi_driver structure, sh_mobile_sdhi_of_match
  table and module_platform_driver() statement
- the existing sh_mobile_sdhi.c is a library module that exports
  sh_mobile_sdhi_probe() and sh_mobile_sdhi_remove(), which now
  gain a 'struct tmio_mmc_dma_ops *' and a 'struct sh_mobile_sdhi_of_data *'
  argument and get called by the new probe function in what used to
  be tmio_mmc_dma.c.
- The new renesas_sdhi_internal_dmac.c becomes a third top-level
  module that also calls sh_mobile_sdhi_probe() but passes its
  own struct tmio_mmc_dma_ops and registers a different
  platform_driver that only matches the of_rcar_gen3_compatible.

	Arnd

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC
  2016-07-06 21:21   ` Arnd Bergmann
@ 2016-07-07  6:57     ` Simon Horman
  0 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2016-07-07  6:57 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Wolfram Sang, Ulf Hansson, Magnus Damm, linux-mmc, linux-renesas-soc

On Wed, Jul 06, 2016 at 11:21:40PM +0200, Arnd Bergmann wrote:
> On Wednesday, July 6, 2016 10:23:29 PM CEST Simon Horman wrote:
> > @@ -117,6 +124,23 @@ void sdhi_sys_dmac_init_dma(void);
> >  static void sdhi_sys_dmac_init_dma(void) { }
> >  #endif
> >  
> > +#if IS_ENABLED(CONFIG_MMC_SDHI_INTERNAL_DMA)
> > +void sdhi_internal_dmac_init_dma(void);
> > +#else
> > +static void sdhi_internal_dmac_init_dma(void) { }
> > +#endif
> > +
> > +static void sh_mobile_sdhi_init_dma(enum tmio_mmc_dmac_type dmac_type)
> > +{
> > +       switch (dmac_type) {
> > +       case TMIO_MMC_INTERNAL_DMAC:
> > +               return sdhi_internal_dmac_init_dma();
> > +
> > +       case TMIO_MMC_SYSC_DMAC:
> > +               return sdhi_sys_dmac_init_dma();
> > +       }
> > +}
> > +
> >  static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
> >  {
> >         u32 val;
> > 
> 
> I've commented on this part for v2 already but got no reply. This
> time I took a little more care to understand the structure of the
> driver and how it gets modified.

Hi Arnd,

somehow I completely missed that feedback, sorry about that.

In general I think there is ample scope to restructure the TMIO/SDHI
drivers as they have grown in various directions over time. I'll look
over your proposal in more detail and see how it fits with my understanding
of TMIO/SDHI.

Wolfram, could you also take a look over this?

> 
> The way I see it, we have the MMC_TMIO_CORE driver that consists of
> tmio_mmc_pio.c and tmio_mmc_dma.c, which are tightly connected though the
> second one is optional, and two front-ends named tmio_mmc.c and
> sh_mobile_sdhi.c.
> 
> The first front-end never uses DMA, while the second one may or may
> not use DMA but is always built with the DMA support linked into the
> core driver.
> 
> I think abstracting the two DMA modes through a structure of
> function pointers as you do is the right strategy, but to build on
> top of that, we can change the link order:
> 
> - rename tmio_mmc_pio.c to tmio_mmc_core.c and make that the actual
>   driver core (without DMA)
> - tmio_mmc_dma.c becomes the main driver module for sh_mobile_sdhi
>   and gets the sh_mobile_sdhi_driver structure, sh_mobile_sdhi_of_match
>   table and module_platform_driver() statement
> - the existing sh_mobile_sdhi.c is a library module that exports
>   sh_mobile_sdhi_probe() and sh_mobile_sdhi_remove(), which now
>   gain a 'struct tmio_mmc_dma_ops *' and a 'struct sh_mobile_sdhi_of_data *'
>   argument and get called by the new probe function in what used to
>   be tmio_mmc_dma.c.
> - The new renesas_sdhi_internal_dmac.c becomes a third top-level
>   module that also calls sh_mobile_sdhi_probe() but passes its
>   own struct tmio_mmc_dma_ops and registers a different
>   platform_driver that only matches the of_rcar_gen3_compatible.
> 
> 	Arnd
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-07-07  6:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-06 20:23 [PATCH/RFC v3 0/6] mmc: renesas_sdhi: add R-Car Gen-3 DMA support Simon Horman
2016-07-06 20:23 ` [PATCH/RFC v3 1/6] mmc: sh_mobile_sdhi, tmio: make dma more modular Simon Horman
2016-07-06 20:43   ` Arnd Bergmann
2016-07-06 20:23 ` [PATCH/RFC v3 2/6] mmc: sh_mobile_sdhi: rename DMA source file as renesas_sdhi_sys_dmac.c Simon Horman
2016-07-06 20:23 ` [PATCH/RFC v3 3/6] mmc: tmio: add max_segs and max_blk_count in tmio_mmc_data Simon Horman
2016-07-06 20:23 ` [PATCH/RFC v3 4/6] mmc: sh_mobile_sdhi: add some SoC specific data for R-Car Gen3 Simon Horman
2016-07-06 20:23 ` [PATCH/RFC v3 5/6] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC Simon Horman
2016-07-06 21:21   ` Arnd Bergmann
2016-07-07  6:57     ` Simon Horman
2016-07-06 20:23 ` [PATCH/RFC v3 6/6] arm64: defconfig: Enable SDHI SD/SDIO controller Simon Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.