Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1434165 > unrolled thread

fix some host driver defect

Started byChaotian Jing <chaotian.jing@mediatek.com>
First post2016-06-30 04:10 +0200
Last post2016-07-06 18:30 +0200
Articles 6 — 2 participants

Back to article view | Back to linux.kernel


Contents

  fix some host driver defect Chaotian Jing <chaotian.jing@mediatek.com> - 2016-06-30 04:10 +0200
    [PATCH 3/4] mmc: mediatek: fix CMD21/CMD19 timeout issue Chaotian Jing <chaotian.jing@mediatek.com> - 2016-06-30 04:10 +0200
    [PATCH 2/4] mmc: mediatek: fix CRC error when calling mmc_select_hs400() Chaotian Jing <chaotian.jing@mediatek.com> - 2016-06-30 04:10 +0200
    [PATCH 4/4] mmc: mediatek: perfer to use rise edge latching Chaotian Jing <chaotian.jing@mediatek.com> - 2016-06-30 04:10 +0200
    [PATCH 1/4] mmc: mediatek: do not tune data for HS400 mode Chaotian Jing <chaotian.jing@mediatek.com> - 2016-06-30 04:10 +0200
    Re: fix some host driver defect Ulf Hansson <ulf.hansson@linaro.org> - 2016-07-06 18:30 +0200

#1434165 — fix some host driver defect

FromChaotian Jing <chaotian.jing@mediatek.com>
Date2016-06-30 04:10 +0200
Subjectfix some host driver defect
Message-ID<rPzAt-3BV-13@gated-at.bofh.it>
Chaotian Jing (4):
  mmc: mediatek: do not tune data for HS400 mode
  mmc: mediatek: fix CRC error when calling mmc_select_hs400()
  mmc: mediatek: fix CMD21/CMD19 timeout issue
  mmc: mediatek: perfer to use rise edge latching

 drivers/mmc/host/mtk-sd.c | 70 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 56 insertions(+), 14 deletions(-)

-- 
1.8.1.1.dirty

[toc] | [next] | [standalone]


#1434166 — [PATCH 3/4] mmc: mediatek: fix CMD21/CMD19 timeout issue

FromChaotian Jing <chaotian.jing@mediatek.com>
Date2016-06-30 04:10 +0200
Subject[PATCH 3/4] mmc: mediatek: fix CMD21/CMD19 timeout issue
Message-ID<rPzAt-3BV-19@gated-at.bofh.it>
In reply to#1434165
we did not deal with the read data of CMD21/CMD19 if there is
response CRC error of CMD21/CMD19, in this case, eMMC/SD may
still in send-data state. therefore, all of next commands cannot
get response as device is not in transfer state.

for resolving this issue, still need deal with the data receive
to make device back to transfer state.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4b175a6..91277b9 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -801,7 +801,13 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	}
 
 	if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
-		msdc_reset_hw(host);
+		if (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
+		    cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200)
+			/*
+			 * should not clear fifo/interrupt as the tune data
+			 * may have alreay come.
+			 */
+			msdc_reset_hw(host);
 		if (events & MSDC_INT_RSPCRCERR) {
 			cmd->error = -EILSEQ;
 			host->error |= REQ_CMD_EIO;
@@ -885,7 +891,11 @@ static void msdc_start_command(struct msdc_host *host,
 static void msdc_cmd_next(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd)
 {
-	if (cmd->error || (mrq->sbc && mrq->sbc->error))
+	if ((cmd->error &&
+	    !(cmd->error == -EILSEQ &&
+	      (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+	       cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200))) ||
+	    (mrq->sbc && mrq->sbc->error))
 		msdc_request_done(host, mrq);
 	else if (cmd == mrq->sbc)
 		msdc_start_command(host, mrq, mrq->cmd);
-- 
1.8.1.1.dirty

[toc] | [prev] | [next] | [standalone]


#1434167 — [PATCH 2/4] mmc: mediatek: fix CRC error when calling mmc_select_hs400()

FromChaotian Jing <chaotian.jing@mediatek.com>
Date2016-06-30 04:10 +0200
Subject[PATCH 2/4] mmc: mediatek: fix CRC error when calling mmc_select_hs400()
Message-ID<rPzAt-3BV-21@gated-at.bofh.it>
In reply to#1434165
the tune result of hs200 mode at 200Mhz is not suitable for 50Mhz,
mmc_select_hs400() will set clock frequency to 50Mhz, use defalut
tune setting for 50Mhz to avoid CRC error.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4d7ce65..4b175a6 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -287,6 +287,11 @@ struct msdc_save_para {
 	u32 emmc50_cfg0;
 };
 
+struct msdc_tune_para {
+	u32 iocon;
+	u32 pad_tune;
+};
+
 struct msdc_delay_phase {
 	u8 maxlen;
 	u8 start;
@@ -328,6 +333,8 @@ struct msdc_host {
 	u32 hs400_ds_delay;
 	bool hs400_mode;	/* current eMMC will run at hs400 mode */
 	struct msdc_save_para save_para; /* used when gate HCLK */
+	struct msdc_tune_para def_tune_para; /* default tune setting */
+	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
 };
 
 static void sdr_set_bits(void __iomem *reg, u32 bs)
@@ -583,6 +590,18 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
 	sdr_set_bits(host->base + MSDC_INTEN, flags);
 
+	/*
+	 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
+	 * tune result of hs200/200Mhz is not suitable for 50Mhz
+	 */
+	if (host->sclk <= 52000000) {
+		writel(host->def_tune_para.iocon, host->base + MSDC_IOCON);
+		writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
+	} else {
+		writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON);
+		writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
+	}
+
 	dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1159,6 +1178,8 @@ static void msdc_init_hw(struct msdc_host *host)
 	/* Configure to default data timeout */
 	sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
 
+	host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
+	host->def_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	dev_dbg(host->dev, "init hardware done!");
 }
 
@@ -1409,6 +1430,8 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 			dev_err(host->dev, "Tune data fail!\n");
 	}
 
+	host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
+	host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	return ret;
 }
 
-- 
1.8.1.1.dirty

[toc] | [prev] | [next] | [standalone]


#1434168 — [PATCH 4/4] mmc: mediatek: perfer to use rise edge latching

FromChaotian Jing <chaotian.jing@mediatek.com>
Date2016-06-30 04:10 +0200
Subject[PATCH 4/4] mmc: mediatek: perfer to use rise edge latching
Message-ID<rPzAu-3BV-25@gated-at.bofh.it>
In reply to#1434165
in our host design, rise edge latching is more stable than fall edge
latching. so that if rise edge has enough margin, no need scan fall edge.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 91277b9..84e9afc 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1328,7 +1328,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	u32 rise_delay = 0, fall_delay = 0;
-	struct msdc_delay_phase final_rise_delay, final_fall_delay;
+	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
 	u8 final_delay, final_maxlen;
 	int cmd_err;
 	int i;
@@ -1341,6 +1341,11 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 		if (!cmd_err)
 			rise_delay |= (1 << i);
 	}
+	final_rise_delay = get_best_delay(host, rise_delay);
+	/* if rising edge has enough margin, then do not scan falling edge */
+	if (final_rise_delay.maxlen >= 10 ||
+	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+		goto skip_fall;
 
 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
 	for (i = 0; i < PAD_DELAY_MAX; i++) {
@@ -1350,10 +1355,9 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 		if (!cmd_err)
 			fall_delay |= (1 << i);
 	}
-
-	final_rise_delay = get_best_delay(host, rise_delay);
 	final_fall_delay = get_best_delay(host, fall_delay);
 
+skip_fall:
 	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
 	if (final_maxlen == final_rise_delay.maxlen) {
 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
@@ -1374,7 +1378,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	u32 rise_delay = 0, fall_delay = 0;
-	struct msdc_delay_phase final_rise_delay, final_fall_delay;
+	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
 	u8 final_delay, final_maxlen;
 	int i, ret;
 
@@ -1387,6 +1391,11 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 		if (!ret)
 			rise_delay |= (1 << i);
 	}
+	final_rise_delay = get_best_delay(host, rise_delay);
+	/* if rising edge has enough margin, then do not scan falling edge */
+	if (final_rise_delay.maxlen >= 10 ||
+	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+		goto skip_fall;
 
 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
@@ -1397,14 +1406,10 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 		if (!ret)
 			fall_delay |= (1 << i);
 	}
-
-	final_rise_delay = get_best_delay(host, rise_delay);
 	final_fall_delay = get_best_delay(host, fall_delay);
 
+skip_fall:
 	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
-	/* Rising edge is more stable, prefer to use it */
-	if (final_rise_delay.maxlen >= 10)
-		final_maxlen = final_rise_delay.maxlen;
 	if (final_maxlen == final_rise_delay.maxlen) {
 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
-- 
1.8.1.1.dirty

[toc] | [prev] | [next] | [standalone]


#1434170 — [PATCH 1/4] mmc: mediatek: do not tune data for HS400 mode

FromChaotian Jing <chaotian.jing@mediatek.com>
Date2016-06-30 04:10 +0200
Subject[PATCH 1/4] mmc: mediatek: do not tune data for HS400 mode
Message-ID<rPzAu-3BV-31@gated-at.bofh.it>
In reply to#1434165
for hs400 mode, should only tune DS delay, should not
tune PAD_TUNE for data path.
if eMMC will run at hs400 mode, do not tune data while
call ops->execute_tuning().

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 5642f71..4d7ce65 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -326,6 +326,7 @@ struct msdc_host {
 	unsigned char timing;
 	bool vqmmc_enabled;
 	u32 hs400_ds_delay;
+	bool hs400_mode;	/* current eMMC will run at hs400 mode */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
 
@@ -1402,9 +1403,11 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 		dev_err(host->dev, "Tune response fail!\n");
 		return ret;
 	}
-	ret = msdc_tune_data(mmc, opcode);
-	if (ret == -EIO)
-		dev_err(host->dev, "Tune data fail!\n");
+	if (host->hs400_mode == false) {
+		ret = msdc_tune_data(mmc, opcode);
+		if (ret == -EIO)
+			dev_err(host->dev, "Tune data fail!\n");
+	}
 
 	return ret;
 }
@@ -1412,6 +1415,7 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct msdc_host *host = mmc_priv(mmc);
+	host->hs400_mode = true;
 
 	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
 	return 0;
-- 
1.8.1.1.dirty

[toc] | [prev] | [next] | [standalone]


#1437829

FromUlf Hansson <ulf.hansson@linaro.org>
Date2016-07-06 18:30 +0200
Message-ID<rRXS1-32X-13@gated-at.bofh.it>
In reply to#1434165
On 30 June 2016 at 04:00, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
>
> Chaotian Jing (4):
>   mmc: mediatek: do not tune data for HS400 mode
>   mmc: mediatek: fix CRC error when calling mmc_select_hs400()
>   mmc: mediatek: fix CMD21/CMD19 timeout issue
>   mmc: mediatek: perfer to use rise edge latching
>
>  drivers/mmc/host/mtk-sd.c | 70 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 56 insertions(+), 14 deletions(-)
>
> --
> 1.8.1.1.dirty
>

Thanks, applied for next!

Kind regards
Uffe

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web