linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] mmc: renesas_sdhi: support manual calibration
@ 2020-06-05 10:12 Wolfram Sang
  2020-06-05 10:12 ` [PATCH 1/2] mmc: tmio: add generic hook to fixup after a completed request Wolfram Sang
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Wolfram Sang @ 2020-06-05 10:12 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-renesas-soc, Yoshihiro Shimoda, Wolfram Sang

Some R-Car Gen3 SoCs need corrections after they tuned to HS400. This
series implements that. Please have a look at the patch descriptions for
details. The origins were patches in the BSP from Takeshi Saito.

Changes since RFC v3:

* moved detection in probe() a bit to the front before calling into the
  TMIO driver ensuring all fields are properly initialized
* tested on Gen2 (R-Car H2), too; no regressions

There is a branch for testing here (with the debug patch on top):

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/topic/sdhi-manual-calib

Note: handling 'hs400_calib_table' in patch 2 uses some multidimensional
array vs pointers judo. I think it is correct C this way but I am
especially grateful for further review there.


Current test results:
---------------------

An unaffected SDHI instance (no eMMC (R-Car H2) or no table (H3 ES2.0)):

No calib table, so flag gets disabled during the reset in the beginning
of the initialization. The same reset routine will be called when tuning
fails.

     kworker/0:0-3     [000] ....     2.799451: renesas_sdhi_reset_hs400_mode: ee100000.sd: calib table 00000000
     kworker/0:0-3     [000] ....     2.799459: renesas_sdhi_hw_reset: ee100000.sd: reset! flag disabled

An SDHI instance with a HS400 capable eMMC connected (R-Car M3-N):

When preparing HS400 tuning, a calib table is found. So, (potential) old
HS400 tuning gets reset and the manual adjustment gets disabled, the
runtime flag (signalling new manual adjustment will be needed) is set:

     kworker/1:2-139   [001] ....     4.028232: renesas_sdhi_reset_hs400_mode: ee140000.sd: calib table ffff800010c76ee8
     kworker/1:2-139   [001] ....     4.028237: renesas_sdhi_reset_hs400_mode: ee140000.sd: adjustment disabled
     kworker/1:2-139   [001] ....     4.028239: renesas_sdhi_prepare_hs400_tuning: ee140000.sd: flag enabled

Lots of tuning CMDs:

     kworker/0:1-21    [000] ....     4.028370: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028576: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028668: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028754: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028832: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028909: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.028989: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029065: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029149: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029228: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029302: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029378: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029453: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029532: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029612: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029694: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
     kworker/0:1-21    [000] ....     4.029775: renesas_sdhi_fixup_request: ee140000.sd: opcode 6, flag 1

First CMD13 after tuning discovered, enable adjustment, clear runtime
flag, show replacement value:

     kworker/0:1-21    [000] ....     4.030294: renesas_sdhi_fixup_request: ee140000.sd: opcode 13, flag 1
     kworker/0:1-21    [000] ....     4.030299: renesas_sdhi_fixup_request: ee140000.sd: adjustment enabled, flag disabled
     kworker/0:1-21    [000] ....     4.030300: renesas_sdhi_fixup_request: code 0 replacement 1

And then checksumming a large file works without performance
regressions. Retunes happen once occasionally and follow the above
pattern exactly (with different replacement values, though).

So, again a lot of text but I want interested parties to verify results.

Looking forward to comments, although I won't complain if this is the
final version ;)

Thanks and kind regards,

   Wolfram


Wolfram Sang (2):
  mmc: tmio: add generic hook to fixup after a completed request
  mmc: renesas_sdhi: support manual calibration

 drivers/mmc/host/renesas_sdhi.h      |   5 +
 drivers/mmc/host/renesas_sdhi_core.c | 152 ++++++++++++++++++++++++++-
 drivers/mmc/host/tmio_mmc.h          |   1 +
 drivers/mmc/host/tmio_mmc_core.c     |   3 +
 4 files changed, 159 insertions(+), 2 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] mmc: tmio: add generic hook to fixup after a completed request
  2020-06-05 10:12 [PATCH 0/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
@ 2020-06-05 10:12 ` Wolfram Sang
  2020-06-05 10:12 ` [PATCH 2/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
  2020-06-16 11:32 ` [PATCH 0/2] " Ulf Hansson
  2 siblings, 0 replies; 7+ messages in thread
From: Wolfram Sang @ 2020-06-05 10:12 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-renesas-soc, Yoshihiro Shimoda, Wolfram Sang

Sadly, due to HW bugs, we need a callback to work around issues just
before completing the request.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/tmio_mmc.h      | 1 +
 drivers/mmc/host/tmio_mmc_core.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index b4cf10109162..766a6116a9d1 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -177,6 +177,7 @@ struct tmio_mmc_host {
 	void (*reset)(struct tmio_mmc_host *host);
 	void (*hw_reset)(struct tmio_mmc_host *host);
 	bool (*check_retune)(struct tmio_mmc_host *host);
+	void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
 
 	/*
 	 * Mandatory callback for tuning to occur which is optional for SDR50
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index d7fde57c78c1..1672c849f78a 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -827,6 +827,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
 		return;
 	}
 
+	if (host->fixup_request)
+		host->fixup_request(host, mrq);
+
 	mmc_request_done(host->mmc, mrq);
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] mmc: renesas_sdhi: support manual calibration
  2020-06-05 10:12 [PATCH 0/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
  2020-06-05 10:12 ` [PATCH 1/2] mmc: tmio: add generic hook to fixup after a completed request Wolfram Sang
@ 2020-06-05 10:12 ` Wolfram Sang
  2020-08-31  6:22   ` Yoshihiro Shimoda
  2020-06-16 11:32 ` [PATCH 0/2] " Ulf Hansson
  2 siblings, 1 reply; 7+ messages in thread
From: Wolfram Sang @ 2020-06-05 10:12 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Wolfram Sang, Takeshi Saito

Some R-Car Gen3 SoCs need some manual correction of timing parameters
after the automatic tuning has finished but before next CMD13 is
completed. This patch implements that by this state machine:

- introducing a per-SoC correction table if needed
- iff such a table exists, the 'fixup_request' callback is populated
  during probe
- iff such a table exists, a runtime flag ('needs_adjust_hs400')
  is set when HS400 tuning gets prepared
- if tuning HS400 fails, the runtime flag is cleared again
- the callback will check the runtime flag and enable the corrected
  manual mode if the flag is set and CMD13 is encountered
- at the end of the enablement the runtime flag is cleared
- iff the configuration flag is set, the manual mode will be disabled
  when HS400 gets downgraded

There also some helper functions added to access the TMPPORT registers.
The actual correction table is SoC and instance(!) specific and is
added to the quirks struct.

Signed-off-by: Takeshi Saito <takeshi.saito.xv@renesas.com>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi.h      |   5 +
 drivers/mmc/host/renesas_sdhi_core.c | 152 ++++++++++++++++++++++++++-
 2 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 58a8c9133ba4..be80c5edff68 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -33,10 +33,13 @@ struct renesas_sdhi_of_data {
 	unsigned short max_segs;
 };
 
+#define SDHI_CALIB_TABLE_MAX 32
+
 struct renesas_sdhi_quirks {
 	bool hs400_disabled;
 	bool hs400_4taps;
 	u32 hs400_bad_taps;
+	const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
 };
 
 struct tmio_mmc_dma {
@@ -58,6 +61,8 @@ struct renesas_sdhi {
 	void __iomem *scc_ctl;
 	u32 scc_tappos;
 	u32 scc_tappos_hs400;
+	const u8 *adjust_hs400_calib_table;
+	bool needs_adjust_hs400;
 	bool doing_tune;
 	bool keep_scc_freq;
 
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 589a59fb70eb..d90c0defa14e 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/mfd/tmio.h>
 #include <linux/sh_dma.h>
@@ -47,6 +48,8 @@
 #define SDHI_VER_GEN3_SD	0xcc10
 #define SDHI_VER_GEN3_SDMMC	0xcd10
 
+#define SDHI_GEN3_MMC0_ADDR	0xee140000
+
 static void renesas_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
 {
 	u32 val;
@@ -251,6 +254,11 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
 #define SH_MOBILE_SDHI_SCC_RVSREQ	0x00A
 #define SH_MOBILE_SDHI_SCC_SMPCMP       0x00C
 #define SH_MOBILE_SDHI_SCC_TMPPORT2	0x00E
+#define SH_MOBILE_SDHI_SCC_TMPPORT3	0x014
+#define SH_MOBILE_SDHI_SCC_TMPPORT4	0x016
+#define SH_MOBILE_SDHI_SCC_TMPPORT5	0x018
+#define SH_MOBILE_SDHI_SCC_TMPPORT6	0x01A
+#define SH_MOBILE_SDHI_SCC_TMPPORT7	0x01C
 
 #define SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN		BIT(0)
 #define SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT	16
@@ -271,6 +279,40 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
 #define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL	BIT(4)
 #define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN	BIT(31)
 
+/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT4 register */
+#define SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START	BIT(0)
+
+/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT5 register */
+#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R	BIT(8)
+#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W	(0 << 8)
+#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK	0x3F
+
+/* Definitions for values the SH_MOBILE_SDHI_SCC register */
+#define SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE	0xa5000000
+#define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK	0x1f
+#define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE		BIT(7)
+
+static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 3,  3,  3,  3,  3,  3,  3,  4,  4,  5,  6,  7,  8,  9, 10, 15,
+	 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
+	{ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  7,  8, 11,
+	 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
+};
+
+static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 1,  2,  6,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
+	 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
+	{ 2,  3,  4,  4,  5,  6,  7,  9, 10, 11, 12, 13, 14, 15, 16, 17,
+	 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
+};
+
+static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+	{ 0,  0,  0,  1,  2,  3,  3,  4,  4,  4,  5,  5,  6,  8,  9, 10,
+	 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
+};
+
 static inline u32 sd_scc_read32(struct tmio_mmc_host *host,
 				struct renesas_sdhi *priv, int addr)
 {
@@ -418,6 +460,74 @@ static void renesas_sdhi_disable_scc(struct mmc_host *mmc)
 		priv->keep_scc_freq = true;
 }
 
+static u32 sd_scc_tmpport_read32(struct tmio_mmc_host *host,
+				 struct renesas_sdhi *priv, u32 addr)
+{
+	/* read mode */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT5,
+		       SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R |
+		       (SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr));
+
+	/* access start and stop */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4,
+		       SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START);
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, 0);
+
+	return sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT7);
+}
+
+static void sd_scc_tmpport_write32(struct tmio_mmc_host *host,
+				   struct renesas_sdhi *priv, u32 addr, u32 val)
+{
+	/* write mode */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT5,
+		       SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W |
+		       (SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr));
+
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT6, val);
+
+	/* access start and stop */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4,
+		       SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START);
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, 0);
+}
+
+static void renesas_sdhi_adjust_hs400_mode_enable(struct tmio_mmc_host *host)
+{
+	struct renesas_sdhi *priv = host_to_priv(host);
+	u32 calib_code;
+
+	/* disable write protect */
+	sd_scc_tmpport_write32(host, priv, 0x00,
+			       SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE);
+	/* read calibration code and adjust */
+	calib_code = sd_scc_tmpport_read32(host, priv, 0x26);
+	calib_code &= SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK;
+
+	sd_scc_tmpport_write32(host, priv, 0x22,
+			       SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE |
+			       priv->adjust_hs400_calib_table[calib_code]);
+
+	/* set offset value to TMPPORT3, hardcoded to OFFSET0 (= 0x3) for now */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT3, 0x3);
+
+	/* adjustment done, clear flag */
+	priv->needs_adjust_hs400 = false;
+}
+
+static void renesas_sdhi_adjust_hs400_mode_disable(struct tmio_mmc_host *host)
+{
+	struct renesas_sdhi *priv = host_to_priv(host);
+
+	/* disable write protect */
+	sd_scc_tmpport_write32(host, priv, 0x00,
+			       SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE);
+	/* disable manual calibration */
+	sd_scc_tmpport_write32(host, priv, 0x22, 0);
+	/* clear offset value of TMPPORT3 */
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT3, 0);
+}
+
 static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
 					  struct renesas_sdhi *priv)
 {
@@ -435,6 +545,9 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
 			 SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
 			sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
 
+	if (priv->adjust_hs400_calib_table)
+		renesas_sdhi_adjust_hs400_mode_disable(host);
+
 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
 			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
 }
@@ -448,6 +561,9 @@ static int renesas_sdhi_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_io
 	priv->keep_scc_freq = true;
 	renesas_sdhi_reset_hs400_mode(host, priv);
 
+	if (priv->adjust_hs400_calib_table)
+		priv->needs_adjust_hs400 = true;
+
 	return 0;
 }
 
@@ -658,6 +774,7 @@ static void renesas_sdhi_hw_reset(struct tmio_mmc_host *host)
 
 	renesas_sdhi_reset_scc(host, priv);
 	renesas_sdhi_reset_hs400_mode(host, priv);
+	priv->needs_adjust_hs400 = false;
 
 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
 			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -730,6 +847,13 @@ static int renesas_sdhi_multi_io_quirk(struct mmc_card *card,
 	return blk_size;
 }
 
+static void renesas_sdhi_fixup_request(struct tmio_mmc_host *host, struct mmc_request *mrq)
+{
+	struct renesas_sdhi *priv = host_to_priv(host);
+
+	if (priv->needs_adjust_hs400 && mrq->cmd->opcode == MMC_SEND_STATUS)
+		renesas_sdhi_adjust_hs400_mode_enable(host);
+}
 static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
 {
 	/* Iff regs are 8 byte apart, sdbuf is 64 bit. Otherwise always 32. */
@@ -761,6 +885,21 @@ static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
 	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
 };
 
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
+	.hs400_4taps = true,
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+	.hs400_calib_table = r8a7796_es13_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+	.hs400_calib_table = r8a77965_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
+	.hs400_calib_table = r8a77990_calib_table,
+};
+
 /*
  * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
  * So, we want to treat them equally and only have a match for ES1.2 to enforce
@@ -772,10 +911,11 @@ static const struct soc_device_attribute sdhi_quirks_match[]  = {
 	{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
 	{ .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
 	{ .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
-	{ .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_4tap },
+	{ .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
 	{ .soc_id = "r8a7796", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps1357 },
-	{ .soc_id = "r8a77965", .data = &sdhi_quirks_bad_taps2367 },
+	{ .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 },
 	{ .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
+	{ .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 },
 	{ /* Sentinel. */ },
 };
 
@@ -934,6 +1074,14 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 	if (ver == SDHI_VER_GEN2_SDR50)
 		mmc_data->flags &= ~TMIO_MMC_HAVE_CBSY;
 
+	if (ver == SDHI_VER_GEN3_SDMMC && quirks && quirks->hs400_calib_table) {
+		host->fixup_request = renesas_sdhi_fixup_request;
+		priv->adjust_hs400_calib_table = *(
+			res->start == SDHI_GEN3_MMC0_ADDR ?
+			quirks->hs400_calib_table :
+			quirks->hs400_calib_table + 1);
+	}
+
 	ret = tmio_mmc_host_probe(host);
 	if (ret < 0)
 		goto edisclk;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] mmc: renesas_sdhi: support manual calibration
  2020-06-05 10:12 [PATCH 0/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
  2020-06-05 10:12 ` [PATCH 1/2] mmc: tmio: add generic hook to fixup after a completed request Wolfram Sang
  2020-06-05 10:12 ` [PATCH 2/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
@ 2020-06-16 11:32 ` Ulf Hansson
  2020-06-18  5:39   ` Wolfram Sang
  2 siblings, 1 reply; 7+ messages in thread
From: Ulf Hansson @ 2020-06-16 11:32 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linux-mmc, Linux-Renesas, Yoshihiro Shimoda

On Fri, 5 Jun 2020 at 12:12, Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> Some R-Car Gen3 SoCs need corrections after they tuned to HS400. This
> series implements that. Please have a look at the patch descriptions for
> details. The origins were patches in the BSP from Takeshi Saito.
>
> Changes since RFC v3:
>
> * moved detection in probe() a bit to the front before calling into the
>   TMIO driver ensuring all fields are properly initialized
> * tested on Gen2 (R-Car H2), too; no regressions
>
> There is a branch for testing here (with the debug patch on top):
>
> git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/topic/sdhi-manual-calib
>
> Note: handling 'hs400_calib_table' in patch 2 uses some multidimensional
> array vs pointers judo. I think it is correct C this way but I am
> especially grateful for further review there.

Wolfram,

I tried applying this, but got some conflict. I guess you have based
this on some of the other series that's in the pipe. Maybe you can
give me some advice about the order or how to apply things?


Kind regards
Uffe



>
>
> Current test results:
> ---------------------
>
> An unaffected SDHI instance (no eMMC (R-Car H2) or no table (H3 ES2.0)):
>
> No calib table, so flag gets disabled during the reset in the beginning
> of the initialization. The same reset routine will be called when tuning
> fails.
>
>      kworker/0:0-3     [000] ....     2.799451: renesas_sdhi_reset_hs400_mode: ee100000.sd: calib table 00000000
>      kworker/0:0-3     [000] ....     2.799459: renesas_sdhi_hw_reset: ee100000.sd: reset! flag disabled
>
> An SDHI instance with a HS400 capable eMMC connected (R-Car M3-N):
>
> When preparing HS400 tuning, a calib table is found. So, (potential) old
> HS400 tuning gets reset and the manual adjustment gets disabled, the
> runtime flag (signalling new manual adjustment will be needed) is set:
>
>      kworker/1:2-139   [001] ....     4.028232: renesas_sdhi_reset_hs400_mode: ee140000.sd: calib table ffff800010c76ee8
>      kworker/1:2-139   [001] ....     4.028237: renesas_sdhi_reset_hs400_mode: ee140000.sd: adjustment disabled
>      kworker/1:2-139   [001] ....     4.028239: renesas_sdhi_prepare_hs400_tuning: ee140000.sd: flag enabled
>
> Lots of tuning CMDs:
>
>      kworker/0:1-21    [000] ....     4.028370: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028576: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028668: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028754: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028832: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028909: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.028989: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029065: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029149: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029228: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029302: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029378: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029453: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029532: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029612: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029694: renesas_sdhi_fixup_request: ee140000.sd: opcode 21, flag 1
>      kworker/0:1-21    [000] ....     4.029775: renesas_sdhi_fixup_request: ee140000.sd: opcode 6, flag 1
>
> First CMD13 after tuning discovered, enable adjustment, clear runtime
> flag, show replacement value:
>
>      kworker/0:1-21    [000] ....     4.030294: renesas_sdhi_fixup_request: ee140000.sd: opcode 13, flag 1
>      kworker/0:1-21    [000] ....     4.030299: renesas_sdhi_fixup_request: ee140000.sd: adjustment enabled, flag disabled
>      kworker/0:1-21    [000] ....     4.030300: renesas_sdhi_fixup_request: code 0 replacement 1
>
> And then checksumming a large file works without performance
> regressions. Retunes happen once occasionally and follow the above
> pattern exactly (with different replacement values, though).
>
> So, again a lot of text but I want interested parties to verify results.
>
> Looking forward to comments, although I won't complain if this is the
> final version ;)
>
> Thanks and kind regards,
>
>    Wolfram
>
>
> Wolfram Sang (2):
>   mmc: tmio: add generic hook to fixup after a completed request
>   mmc: renesas_sdhi: support manual calibration
>
>  drivers/mmc/host/renesas_sdhi.h      |   5 +
>  drivers/mmc/host/renesas_sdhi_core.c | 152 ++++++++++++++++++++++++++-
>  drivers/mmc/host/tmio_mmc.h          |   1 +
>  drivers/mmc/host/tmio_mmc_core.c     |   3 +
>  4 files changed, 159 insertions(+), 2 deletions(-)
>
> --
> 2.20.1
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] mmc: renesas_sdhi: support manual calibration
  2020-06-16 11:32 ` [PATCH 0/2] " Ulf Hansson
@ 2020-06-18  5:39   ` Wolfram Sang
  0 siblings, 0 replies; 7+ messages in thread
From: Wolfram Sang @ 2020-06-18  5:39 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: linux-mmc, Linux-Renesas, Yoshihiro Shimoda

[-- Attachment #1: Type: text/plain, Size: 405 bytes --]

	
> I tried applying this, but got some conflict. I guess you have based
> this on some of the other series that's in the pipe. Maybe you can
> give me some advice about the order or how to apply things?

Sorry, this depends on the stalled SCC patchset and I need to send a
second version of that (hopefully next week). Should have mentioned it
here, mea culpa! So, this needs to wait a little.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 2/2] mmc: renesas_sdhi: support manual calibration
  2020-06-05 10:12 ` [PATCH 2/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
@ 2020-08-31  6:22   ` Yoshihiro Shimoda
  2020-08-31 11:41     ` Wolfram Sang
  0 siblings, 1 reply; 7+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-31  6:22 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc; +Cc: linux-renesas-soc, Takeshi Saito

Hi Wolfram-san,

Thank you for the patch!
 (And, I'm sorry for the delayed response.)

> From: Wolfram Sang, Sent: Friday, June 5, 2020 7:12 PM
> 
> Some R-Car Gen3 SoCs need some manual correction of timing parameters
> after the automatic tuning has finished but before next CMD13 is
> completed. This patch implements that by this state machine:
> 
> - introducing a per-SoC correction table if needed
> - iff such a table exists, the 'fixup_request' callback is populated
>   during probe
> - iff such a table exists, a runtime flag ('needs_adjust_hs400')
>   is set when HS400 tuning gets prepared

We should set the needs_adjust_hs400 when HS400EN=1 is set.
In other words, we should set it in renesas_sdhi_hs400_complete(),
not renesas_sdhi_prepare_hs400_tuning().
	
> - if tuning HS400 fails, the runtime flag is cleared again
> - the callback will check the runtime flag and enable the corrected
>   manual mode if the flag is set and CMD13 is encountered
> - at the end of the enablement the runtime flag is cleared
> - iff the configuration flag is set, the manual mode will be disabled
>   when HS400 gets downgraded
> 
> There also some helper functions added to access the TMPPORT registers.
> The actual correction table is SoC and instance(!) specific and is
> added to the quirks struct.
> 
> Signed-off-by: Takeshi Saito <takeshi.saito.xv@renesas.com>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
<snip>
> +static void renesas_sdhi_adjust_hs400_mode_enable(struct tmio_mmc_host *host)
> +{
> +	struct renesas_sdhi *priv = host_to_priv(host);
> +	u32 calib_code;
> +
> +	/* disable write protect */
> +	sd_scc_tmpport_write32(host, priv, 0x00,
> +			       SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE);
> +	/* read calibration code and adjust */
> +	calib_code = sd_scc_tmpport_read32(host, priv, 0x26);

When we read the calib_code at room temperature, the value will be around 0x10.
However, we will get 0x00 here. So, we need to fix it.

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] mmc: renesas_sdhi: support manual calibration
  2020-08-31  6:22   ` Yoshihiro Shimoda
@ 2020-08-31 11:41     ` Wolfram Sang
  0 siblings, 0 replies; 7+ messages in thread
From: Wolfram Sang @ 2020-08-31 11:41 UTC (permalink / raw)
  To: Yoshihiro Shimoda; +Cc: linux-mmc, linux-renesas-soc, Takeshi Saito

[-- Attachment #1: Type: text/plain, Size: 2161 bytes --]

Hi Shimoda-san,

> We should set the needs_adjust_hs400 when HS400EN=1 is set.
> In other words, we should set it in renesas_sdhi_hs400_complete(),
> not renesas_sdhi_prepare_hs400_tuning().

Oh, thanks for pointing this out! I simply put it into the same function
as the BSP, but due to massive refactoring in the upstream driver we
really need to put it where tuning is completed. I used the following
patch on top of this patch:

diff --git b/drivers/mmc/host/renesas_sdhi_core.c a/drivers/mmc/host/renesas_sdhi_core.c
index 2834b30c3ba6..b54dd8a7ecaa 100644
--- b/drivers/mmc/host/renesas_sdhi_core.c
+++ a/drivers/mmc/host/renesas_sdhi_core.c
@@ -419,6 +419,9 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)
 
 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
 			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
+	if (priv->adjust_hs400_calib_table)
+		priv->needs_adjust_hs400 = true;
 }
 
 static void renesas_sdhi_reset_scc(struct tmio_mmc_host *host,
@@ -544,12 +547,8 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
 static int renesas_sdhi_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
-	struct renesas_sdhi *priv = host_to_priv(host);
 
-	if (priv->adjust_hs400_calib_table)
-		priv->needs_adjust_hs400 = true;
-
-	renesas_sdhi_reset_hs400_mode(host, priv);
+	renesas_sdhi_reset_hs400_mode(host, host_to_priv(host));
 	return 0;
 }

and got these debug reports from my M3-N:

     kworker/0:1-21    [000] ....     4.171435: renesas_sdhi_fixup_request: code 17 replacement 18

which was different without the fix:

     kworker/0:1-21    [000] ....     4.171435: renesas_sdhi_fixup_request: code 31 replacement 31

> When we read the calib_code at room temperature, the value will be around 0x10.
> However, we will get 0x00 here. So, we need to fix it.

So, my new debug output looks good.

I will fold the fixup patch into the next version of this series. I
still need to get the stalled-SCC issue tackled first. But I am now
working on it.

Thanks again,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-08-31 11:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-05 10:12 [PATCH 0/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
2020-06-05 10:12 ` [PATCH 1/2] mmc: tmio: add generic hook to fixup after a completed request Wolfram Sang
2020-06-05 10:12 ` [PATCH 2/2] mmc: renesas_sdhi: support manual calibration Wolfram Sang
2020-08-31  6:22   ` Yoshihiro Shimoda
2020-08-31 11:41     ` Wolfram Sang
2020-06-16 11:32 ` [PATCH 0/2] " Ulf Hansson
2020-06-18  5:39   ` Wolfram Sang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).