From: Haibo Chen <haibo.chen@nxp.com>
Date: Wed, 24 Jun 2020 16:03:50 +0800
Subject: mmc: sdhci-esdhc-imx: dump internal IC debug status during error
Git-commit: 3722c74c721b5612ffa45027984bd8161d1aae06
Patch-mainline: v5.9-rc1
References: jsc#SLE-16106
USDHC of i.MX has internal IC debug register, which record the IC
logical status. So dump these logical status in error condition,
this can help analyzing issue.
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/1592985830-13038-1-git-send-email-haibo.chen@nxp.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 39 ++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1d7f84b23a22..a76b4513fbec 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -38,6 +38,16 @@
#define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 << 1)
#define ESDHC_VENDOR_SPEC_VSELECT (1 << 1)
#define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8)
+#define ESDHC_DEBUG_SEL_AND_STATUS_REG 0xc2
+#define ESDHC_DEBUG_SEL_REG 0xc3
+#define ESDHC_DEBUG_SEL_MASK 0xf
+#define ESDHC_DEBUG_SEL_CMD_STATE 1
+#define ESDHC_DEBUG_SEL_DATA_STATE 2
+#define ESDHC_DEBUG_SEL_TRANS_STATE 3
+#define ESDHC_DEBUG_SEL_DMA_STATE 4
+#define ESDHC_DEBUG_SEL_ADMA_STATE 5
+#define ESDHC_DEBUG_SEL_FIFO_STATE 6
+#define ESDHC_DEBUG_SEL_ASYNC_FIFO_STATE 7
#define ESDHC_WTMK_LVL 0x44
#define ESDHC_WTMK_DEFAULT_VAL 0x10401040
#define ESDHC_WTMK_LVL_RD_WML_MASK 0x000000FF
@@ -348,6 +358,34 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
}
+#define DRIVER_NAME "sdhci-esdhc-imx"
+#define ESDHC_IMX_DUMP(f, x...) \
+ pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
+static void esdhc_dump_debug_regs(struct sdhci_host *host)
+{
+ int i;
+ char *debug_status[7] = {
+ "cmd debug status",
+ "data debug status",
+ "trans debug status",
+ "dma debug status",
+ "adma debug status",
+ "fifo debug status",
+ "async fifo debug status"
+ };
+
+ ESDHC_IMX_DUMP("========= ESDHC IMX DEBUG STATUS DUMP =========\n");
+ for (i = 0; i < 7; i++) {
+ esdhc_clrset_le(host, ESDHC_DEBUG_SEL_MASK,
+ ESDHC_DEBUG_SEL_CMD_STATE + i, ESDHC_DEBUG_SEL_REG);
+ ESDHC_IMX_DUMP("%s: 0x%04x\n", debug_status[i],
+ readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG));
+ }
+
+ esdhc_clrset_le(host, ESDHC_DEBUG_SEL_MASK, 0, ESDHC_DEBUG_SEL_REG);
+
+}
+
static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
{
u32 present_state;
@@ -1237,6 +1275,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.set_uhs_signaling = esdhc_set_uhs_signaling,
.reset = esdhc_reset,
.irq = esdhc_cqhci_irq,
+ .dump_vendor_regs = esdhc_dump_debug_regs,
};
static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {