128 lines
4.8 KiB
Diff
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
|
|
|