All of lore.kernel.org
 help / color / mirror / Atom feed
From: Doug Brown <doug@schmorgal.com>
To: Ulf Hansson <ulf.hansson@linaro.org>,
	Adrian Hunter <adrian.hunter@intel.com>
Cc: Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	linux-mmc@vger.kernel.org, devicetree@vger.kernel.org,
	Doug Brown <doug@schmorgal.com>
Subject: [PATCH 6/8] mmc: sdhci-pxav2: add SDIO card IRQ workaround for PXA168 V1 controller
Date: Sun, 27 Nov 2022 18:44:05 -0800	[thread overview]
Message-ID: <20221128024407.224393-7-doug@schmorgal.com> (raw)
In-Reply-To: <20221128024407.224393-1-doug@schmorgal.com>

The PXA168 has a documented silicon bug that causes SDIO card IRQs to be
missed. Implement the first half of the suggested workaround, which
involves resetting the data port logic and issuing a dummy CMD0 to
restart the clock.

Signed-off-by: Doug Brown <doug@schmorgal.com>
---
 drivers/mmc/host/sdhci-pxav2.c | 36 ++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 4996d72c6d23..0b9b2e4b2153 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -20,6 +20,8 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/mmc.h>
 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
@@ -43,6 +45,7 @@
 
 struct sdhci_pxav2_host {
 	struct clk *clk_core;
+	void (*orig_post_req)(struct mmc_host *mmc, struct mmc_request *mrq, int err);
 };
 
 static void pxav2_reset(struct sdhci_host *host, u8 mask)
@@ -96,6 +99,37 @@ static inline u16 pxav1_readw(struct sdhci_host *host, int reg)
 	return readw(host->ioaddr + reg);
 }
 
+static void pxav1_post_req(struct mmc_host *mmc, struct mmc_request *mrq, int err)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pxav2_host *pxav2_host;
+	struct mmc_command dummy_cmd = {};
+	u16 tmp;
+
+	/* If this is an SDIO command, perform errata workaround for silicon bug. */
+	if (!err && mrq->cmd && !mrq->cmd->error &&
+	    (mrq->cmd->opcode == SD_IO_RW_DIRECT ||
+	    mrq->cmd->opcode == SD_IO_RW_EXTENDED)) {
+		/* Reset data port */
+		tmp = readw(host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+		tmp |= 0x400;
+		writew(tmp, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+
+		/* Clock is now stopped, so restart it by sending a dummy CMD0. */
+		pxav2_host = sdhci_pltfm_priv(sdhci_priv(host));
+
+		dummy_cmd.opcode = MMC_GO_IDLE_STATE;
+		dummy_cmd.arg = 0;
+		dummy_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
+
+		mmc_wait_for_cmd(host->mmc, &dummy_cmd, 0);
+	}
+
+	/* Pass onto SDHCI host driver now */
+	if (pxav2_host->orig_post_req)
+		pxav2_host->orig_post_req(mmc, mrq, err);
+}
+
 static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
@@ -252,6 +286,8 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
 	if (match && of_device_is_compatible(dev->of_node, "mrvl,pxav1-mmc")) {
 		host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ | SDHCI_QUIRK_32BIT_DMA_SIZE;
 		host->ops = &pxav1_sdhci_ops;
+		pxav2_host->orig_post_req = host->mmc_host_ops.post_req;
+		host->mmc_host_ops.post_req = pxav1_post_req;
 	} else {
 		host->ops = &pxav2_sdhci_ops;
 	}
-- 
2.34.1


  parent reply	other threads:[~2022-11-28  2:45 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-28  2:43 [PATCH 0/8] mmc: sdhci-pxav2: Add support for PXA168 Doug Brown
2022-11-28  2:44 ` [PATCH 1/8] mmc: sdhci-pxav2: add initial support for PXA168 V1 controller Doug Brown
2022-11-28  2:44 ` [PATCH 2/8] mmc: sdhci-pxav2: enable CONFIG_MMC_SDHCI_IO_ACCESSORS Doug Brown
2022-11-28  2:44 ` [PATCH 3/8] mmc: sdhci-pxav2: add register workaround for PXA168 silicon bug Doug Brown
2022-11-29  6:31   ` Adrian Hunter
2022-11-28  2:44 ` [PATCH 4/8] mmc: sdhci-pxav2: change clock name to match DT bindings Doug Brown
2022-11-28  2:44 ` [PATCH 5/8] mmc: sdhci-pxav2: add optional core clock Doug Brown
2022-11-28  2:44 ` Doug Brown [this message]
2022-11-29  7:29   ` [PATCH 6/8] mmc: sdhci-pxav2: add SDIO card IRQ workaround for PXA168 V1 controller Adrian Hunter
2022-12-01  5:27     ` Doug Brown
2022-11-28  2:44 ` [PATCH 7/8] mmc: sdhci-pxav2: add optional pinctrl for SDIO IRQ workaround Doug Brown
2022-11-28  2:44 ` [PATCH 8/8] dt-bindings: mmc: sdhci-pxa: add pxav1 Doug Brown
2022-11-28  8:58   ` Krzysztof Kozlowski
2022-11-29  3:44     ` Doug Brown
2022-11-28 12:20   ` Rob Herring

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=20221128024407.224393-7-doug@schmorgal.com \
    --to=doug@schmorgal.com \
    --cc=adrian.hunter@intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=robh+dt@kernel.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.