kernel/0049-fix-optimize-SDHCI-driver.patch

128 lines
4.8 KiB
Diff

From e62120e3b77a52a4647585b3f27e56cac7b6b0da Mon Sep 17 00:00:00 2001
From: liangshuang <liangshuang@eswincomputing.com>
Date: Fri, 7 Jun 2024 11:10:10 +0800
Subject: [PATCH 049/219] fix:optimize SDHCI driver.
Changelogs:
1.Fix the issue of failed tuning of the Sandisk SD card.
2.Fix the issue of unexpected interrupts generated by EMMC/SDIO during the probe process.
---
drivers/mmc/host/sdhci-of-eswin-sdio.c | 36 +++++++++++++++++++++-----
drivers/mmc/host/sdhci-of-eswin.c | 8 ++++--
2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-eswin-sdio.c b/drivers/mmc/host/sdhci-of-eswin-sdio.c
index 83cbdb61c936..badbee00b39e 100644
--- a/drivers/mmc/host/sdhci-of-eswin-sdio.c
+++ b/drivers/mmc/host/sdhci-of-eswin-sdio.c
@@ -42,7 +42,7 @@
#define ESWIN_SDHCI_SD1_INT_STATUS 0x708
#define ESWIN_SDHCI_SD1_PWR_CTRL 0x70c
-#define DELAY_RANGE_THRESHOLD 40
+#define DELAY_RANGE_THRESHOLD 20
struct eswin_sdio_private {
int phase_code;
@@ -150,7 +150,22 @@ static void eswin_sdhci_sdio_reset(struct sdhci_host *host, u8 mask)
struct eswin_sdhci_data *eswin_sdhci_sdio =
sdhci_pltfm_priv(pltfm_host);
- sdhci_reset(host, mask);
+ sdhci_writel(host, 0, SDHCI_INT_ENABLE);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+
+ if (mask & SDHCI_RESET_ALL) {
+ sdhci_reset(host, SDHCI_RESET_ALL);
+ }
+ if (mask & SDHCI_RESET_DATA) {
+ sdhci_reset(host, SDHCI_RESET_DATA);
+ }
+
+ if (mask & SDHCI_RESET_CMD) {
+ sdhci_reset(host, SDHCI_RESET_CMD);
+ }
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
if (eswin_sdhci_sdio->quirks & SDHCI_ESWIN_QUIRK_FORCE_CDTEST) {
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
@@ -181,10 +196,9 @@ static int eswin_sdhci_sdio_delay_tuning(struct sdhci_host *host, u32 opcode)
eswin_sdhci_sdio_config_phy_delay(host, i);
eswin_sdhci_enable_card_clk(host);
ret = mmc_send_tuning(host->mmc, opcode, &cmd_error);
+ host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
if (ret) {
- pr_debug("%s: bad delay:0x%x\n", mmc_hostname(host->mmc), i);
- sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
- udelay(200);
+ pr_debug("%s: bad delay:0x%x!\n", mmc_hostname(host->mmc), i);
if (delay_min != -1 && delay_max != -1) {
if (delay_max - delay_min > delay_range) {
delay_range = delay_max - delay_min;
@@ -227,6 +241,14 @@ static int eswin_sdhci_sdio_delay_tuning(struct sdhci_host *host, u32 opcode)
eswin_sdhci_sdio_config_phy_delay(host, delay);
eswin_sdhci_enable_card_clk(host);
+ ret = mmc_send_tuning(host->mmc, opcode, &cmd_error);
+ host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+ if (ret) {
+ pr_err("%s: delay code(0x%x) not work, tuning failed!\n",
+ mmc_hostname(host->mmc), delay);
+ return ret;
+ }
+
return 0;
}
@@ -245,9 +267,9 @@ static int eswin_sdhci_sdio_phase_code_tuning(struct sdhci_host *host,
eswin_sdhci_enable_card_clk(host);
ret = mmc_send_tuning(host->mmc, opcode, &cmd_error);
+ host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
if (ret) {
- sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
- udelay(200);
+ pr_debug("%s: bad phase_code:0x%x\n", mmc_hostname(host->mmc), phase_code);
if (code_min != -1 && code_max != -1)
break;
} else {
diff --git a/drivers/mmc/host/sdhci-of-eswin.c b/drivers/mmc/host/sdhci-of-eswin.c
index 41aa80f8dbe3..a0347ac5c739 100644
--- a/drivers/mmc/host/sdhci-of-eswin.c
+++ b/drivers/mmc/host/sdhci-of-eswin.c
@@ -181,7 +181,11 @@ static void eswin_sdhci_reset(struct sdhci_host *host, u8 mask)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct eswin_sdhci_data *eswin_sdhci = sdhci_pltfm_priv(pltfm_host);
+ sdhci_writel(host, 0, SDHCI_INT_ENABLE);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
sdhci_reset(host, mask);
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
if (eswin_sdhci->quirks & SDHCI_ESWIN_QUIRK_FORCE_CDTEST) {
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
@@ -243,7 +247,7 @@ static int eswin_sdhci_delay_tuning(struct sdhci_host *host, u32 opcode)
eswin_sdhci_enable_card_clk(host);
ret = mmc_send_tuning(host->mmc, opcode, &cmd_error);
if (ret) {
- sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+ host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
udelay(200);
if (delay_min != -1 && delay_max != -1)
break;
@@ -291,7 +295,7 @@ static int eswin_sdhci_phase_code_tuning(struct sdhci_host *host, u32 opcode)
ret = mmc_send_tuning(host->mmc, opcode, &cmd_error);
if (ret) {
- sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+ host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
udelay(200);
if (code_min != -1 && code_max != -1)
break;
--
2.47.0