All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ludovic Barre <ludovic.Barre@st.com>
To: Ulf Hansson <ulf.hansson@linaro.org>, Rob Herring <robh+dt@kernel.org>
Cc: <srinivas.kandagatla@linaro.org>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@st.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-mmc@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	Ludovic Barre <ludovic.barre@st.com>
Subject: [PATCH V3 2/2] mmc: mmci: send stop command to clear the dpsm
Date: Thu, 6 Dec 2018 16:13:32 +0100	[thread overview]
Message-ID: <1544109212-12621-3-git-send-email-ludovic.Barre@st.com> (raw)
In-Reply-To: <1544109212-12621-1-git-send-email-ludovic.Barre@st.com>

From: Ludovic Barre <ludovic.barre@st.com>

The current approach with sending a CMD12 (STOP_TRANSMISSION) to
complete a data transfer request, either because of using the open
ended transmission type or because of receiving an error during a data
transfer, isn't sufficient for the STM32 sdmmc variant.

More precisely, for STM32 sdmmc the DPSM ("Data Path State Machine")
needs to be cleared by sending a CMD12, also for the so called ADTC
commands. For this reason, let the driver send a CMD12 to complete
ADTC commands, in case it's set (depend of cmdreg_stop variant property).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
 drivers/mmc/host/mmci.c | 37 +++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index e352f5a..4e5643d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -58,6 +58,8 @@ void sdmmc_variant_init(struct mmci_host *host);
 #else
 static inline void sdmmc_variant_init(struct mmci_host *host) {}
 #endif
+static void
+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c);
 
 static unsigned int fmax = 515633;
 
@@ -572,9 +574,37 @@ void mmci_dma_error(struct mmci_host *host)
 		host->ops->dma_error(host);
 }
 
+static int mmci_stop_command(struct mmci_host *host, struct mmc_request *mrq)
+{
+	u32 dpsm;
+
+	/*
+	 * If an error happens on command or data transmission
+	 * the DPSM stay enabled. The CPSM required a stop command
+	 * to reinitialize the DPSM.
+	 */
+	dpsm = readl_relaxed(host->base + MMCISTATUS);
+	dpsm &= MCI_STM32_DPSMACTIVE;
+
+	if (dpsm && ((mrq->cmd && mrq->cmd->error) ||
+		     (mrq->data && mrq->data->error))) {
+		mmci_start_command(host, &host->stop_abort, 0);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
+	/*
+	 * For variant with cmdstop bit, a stop command could be needed
+	 * to finish the request.
+	 */
+	if (host->variant->cmdreg_stop && mmci_stop_command(host, mrq))
+		return;
+
 	writel(0, host->base + MMCICOMMAND);
 
 	BUG_ON(host->data);
@@ -1956,6 +1986,13 @@ static int mmci_probe(struct amba_device *dev,
 		mmc->max_busy_timeout = 0;
 	}
 
+	/* prepare the stop command, used to abort and reinitialized the DPSM */
+	if (variant->cmdreg_stop) {
+		host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
+		host->stop_abort.arg = 0;
+		host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
+	}
+
 	mmc->ops = &mmci_ops;
 
 	/* We support these PM capabilities. */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 2422909..35372cd 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -161,6 +161,7 @@
 #define MCI_ST_CEATAEND		(1 << 23)
 #define MCI_ST_CARDBUSY		(1 << 24)
 /* Extended status bits for the STM32 variants */
+#define MCI_STM32_DPSMACTIVE	BIT(12)
 #define MCI_STM32_BUSYD0	BIT(20)
 
 #define MMCICLEAR		0x038
@@ -377,6 +378,7 @@ struct mmci_host {
 	void __iomem		*base;
 	struct mmc_request	*mrq;
 	struct mmc_command	*cmd;
+	struct mmc_command	stop_abort;
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
-- 
2.7.4


WARNING: multiple messages have this Message-ID (diff)
From: Ludovic Barre <ludovic.Barre@st.com>
To: Ulf Hansson <ulf.hansson@linaro.org>, Rob Herring <robh+dt@kernel.org>
Cc: srinivas.kandagatla@linaro.org,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@st.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-mmc@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	Ludovic Barre <ludovic.barre@st.com>
Subject: [PATCH V3 2/2] mmc: mmci: send stop command to clear the dpsm
Date: Thu, 6 Dec 2018 16:13:32 +0100	[thread overview]
Message-ID: <1544109212-12621-3-git-send-email-ludovic.Barre@st.com> (raw)
In-Reply-To: <1544109212-12621-1-git-send-email-ludovic.Barre@st.com>

From: Ludovic Barre <ludovic.barre@st.com>

The current approach with sending a CMD12 (STOP_TRANSMISSION) to
complete a data transfer request, either because of using the open
ended transmission type or because of receiving an error during a data
transfer, isn't sufficient for the STM32 sdmmc variant.

More precisely, for STM32 sdmmc the DPSM ("Data Path State Machine")
needs to be cleared by sending a CMD12, also for the so called ADTC
commands. For this reason, let the driver send a CMD12 to complete
ADTC commands, in case it's set (depend of cmdreg_stop variant property).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
 drivers/mmc/host/mmci.c | 37 +++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index e352f5a..4e5643d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -58,6 +58,8 @@ void sdmmc_variant_init(struct mmci_host *host);
 #else
 static inline void sdmmc_variant_init(struct mmci_host *host) {}
 #endif
+static void
+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c);
 
 static unsigned int fmax = 515633;
 
@@ -572,9 +574,37 @@ void mmci_dma_error(struct mmci_host *host)
 		host->ops->dma_error(host);
 }
 
+static int mmci_stop_command(struct mmci_host *host, struct mmc_request *mrq)
+{
+	u32 dpsm;
+
+	/*
+	 * If an error happens on command or data transmission
+	 * the DPSM stay enabled. The CPSM required a stop command
+	 * to reinitialize the DPSM.
+	 */
+	dpsm = readl_relaxed(host->base + MMCISTATUS);
+	dpsm &= MCI_STM32_DPSMACTIVE;
+
+	if (dpsm && ((mrq->cmd && mrq->cmd->error) ||
+		     (mrq->data && mrq->data->error))) {
+		mmci_start_command(host, &host->stop_abort, 0);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
+	/*
+	 * For variant with cmdstop bit, a stop command could be needed
+	 * to finish the request.
+	 */
+	if (host->variant->cmdreg_stop && mmci_stop_command(host, mrq))
+		return;
+
 	writel(0, host->base + MMCICOMMAND);
 
 	BUG_ON(host->data);
@@ -1956,6 +1986,13 @@ static int mmci_probe(struct amba_device *dev,
 		mmc->max_busy_timeout = 0;
 	}
 
+	/* prepare the stop command, used to abort and reinitialized the DPSM */
+	if (variant->cmdreg_stop) {
+		host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
+		host->stop_abort.arg = 0;
+		host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
+	}
+
 	mmc->ops = &mmci_ops;
 
 	/* We support these PM capabilities. */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 2422909..35372cd 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -161,6 +161,7 @@
 #define MCI_ST_CEATAEND		(1 << 23)
 #define MCI_ST_CARDBUSY		(1 << 24)
 /* Extended status bits for the STM32 variants */
+#define MCI_STM32_DPSMACTIVE	BIT(12)
 #define MCI_STM32_BUSYD0	BIT(20)
 
 #define MMCICLEAR		0x038
@@ -377,6 +378,7 @@ struct mmci_host {
 	void __iomem		*base;
 	struct mmc_request	*mrq;
 	struct mmc_command	*cmd;
+	struct mmc_command	stop_abort;
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: Ludovic Barre <ludovic.Barre@st.com>
To: Ulf Hansson <ulf.hansson@linaro.org>, Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org,
	Alexandre Torgue <alexandre.torgue@st.com>,
	linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
	srinivas.kandagatla@linaro.org,
	Ludovic Barre <ludovic.barre@st.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH V3 2/2] mmc: mmci: send stop command to clear the dpsm
Date: Thu, 6 Dec 2018 16:13:32 +0100	[thread overview]
Message-ID: <1544109212-12621-3-git-send-email-ludovic.Barre@st.com> (raw)
In-Reply-To: <1544109212-12621-1-git-send-email-ludovic.Barre@st.com>

From: Ludovic Barre <ludovic.barre@st.com>

The current approach with sending a CMD12 (STOP_TRANSMISSION) to
complete a data transfer request, either because of using the open
ended transmission type or because of receiving an error during a data
transfer, isn't sufficient for the STM32 sdmmc variant.

More precisely, for STM32 sdmmc the DPSM ("Data Path State Machine")
needs to be cleared by sending a CMD12, also for the so called ADTC
commands. For this reason, let the driver send a CMD12 to complete
ADTC commands, in case it's set (depend of cmdreg_stop variant property).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
---
 drivers/mmc/host/mmci.c | 37 +++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index e352f5a..4e5643d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -58,6 +58,8 @@ void sdmmc_variant_init(struct mmci_host *host);
 #else
 static inline void sdmmc_variant_init(struct mmci_host *host) {}
 #endif
+static void
+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c);
 
 static unsigned int fmax = 515633;
 
@@ -572,9 +574,37 @@ void mmci_dma_error(struct mmci_host *host)
 		host->ops->dma_error(host);
 }
 
+static int mmci_stop_command(struct mmci_host *host, struct mmc_request *mrq)
+{
+	u32 dpsm;
+
+	/*
+	 * If an error happens on command or data transmission
+	 * the DPSM stay enabled. The CPSM required a stop command
+	 * to reinitialize the DPSM.
+	 */
+	dpsm = readl_relaxed(host->base + MMCISTATUS);
+	dpsm &= MCI_STM32_DPSMACTIVE;
+
+	if (dpsm && ((mrq->cmd && mrq->cmd->error) ||
+		     (mrq->data && mrq->data->error))) {
+		mmci_start_command(host, &host->stop_abort, 0);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
+	/*
+	 * For variant with cmdstop bit, a stop command could be needed
+	 * to finish the request.
+	 */
+	if (host->variant->cmdreg_stop && mmci_stop_command(host, mrq))
+		return;
+
 	writel(0, host->base + MMCICOMMAND);
 
 	BUG_ON(host->data);
@@ -1956,6 +1986,13 @@ static int mmci_probe(struct amba_device *dev,
 		mmc->max_busy_timeout = 0;
 	}
 
+	/* prepare the stop command, used to abort and reinitialized the DPSM */
+	if (variant->cmdreg_stop) {
+		host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
+		host->stop_abort.arg = 0;
+		host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
+	}
+
 	mmc->ops = &mmci_ops;
 
 	/* We support these PM capabilities. */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 2422909..35372cd 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -161,6 +161,7 @@
 #define MCI_ST_CEATAEND		(1 << 23)
 #define MCI_ST_CARDBUSY		(1 << 24)
 /* Extended status bits for the STM32 variants */
+#define MCI_STM32_DPSMACTIVE	BIT(12)
 #define MCI_STM32_BUSYD0	BIT(20)
 
 #define MMCICLEAR		0x038
@@ -377,6 +378,7 @@ struct mmci_host {
 	void __iomem		*base;
 	struct mmc_request	*mrq;
 	struct mmc_command	*cmd;
+	struct mmc_command	stop_abort;
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2018-12-06 15:14 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-06 15:13 [PATCH V3 0/2] mmc: mmci: add stop command Ludovic Barre
2018-12-06 15:13 ` Ludovic Barre
2018-12-06 15:13 ` Ludovic Barre
2018-12-06 15:13 ` [PATCH V3 1/2] mmc: mmci: add variant property to set command stop bit Ludovic Barre
2018-12-06 15:13   ` Ludovic Barre
2018-12-06 15:13   ` Ludovic Barre
2018-12-11  9:47   ` Ulf Hansson
2018-12-11  9:47     ` Ulf Hansson
2018-12-11  9:53     ` Ludovic BARRE
2018-12-11  9:53       ` Ludovic BARRE
2018-12-11  9:53       ` Ludovic BARRE
2019-01-03 10:35       ` Ludovic BARRE
2019-01-03 10:35         ` Ludovic BARRE
2019-01-03 10:35         ` Ludovic BARRE
2019-01-24 15:03         ` [Linux-stm32] " Ludovic BARRE
2019-01-24 15:03           ` Ludovic BARRE
2019-01-24 15:03           ` Ludovic BARRE
2019-01-24 15:12           ` Ulf Hansson
2019-01-24 15:12             ` Ulf Hansson
2018-12-06 15:13 ` Ludovic Barre [this message]
2018-12-06 15:13   ` [PATCH V3 2/2] mmc: mmci: send stop command to clear the dpsm Ludovic Barre
2018-12-06 15:13   ` Ludovic Barre
2019-01-29 14:31   ` Ulf Hansson
2019-01-29 14:31     ` Ulf Hansson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1544109212-12621-3-git-send-email-ludovic.Barre@st.com \
    --to=ludovic.barre@st.com \
    --cc=alexandre.torgue@st.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.