* [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support
@ 2018-06-18 12:57 Simon Horman
2018-06-18 12:57 ` [PATCH v5 1/3] mmc: core: more fine-grained hooks for HS400 tuning Simon Horman
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Simon Horman @ 2018-06-18 12:57 UTC (permalink / raw)
To: Wolfram Sang, Ulf Hansson
Cc: Magnus Damm, linux-mmc, linux-renesas-soc, Simon Horman
Hi,
this patch-set provides SDHI driver support for eMMC HS400.
Based on mmc-v4.18-rc1
Dependencies for applying these patches:
* none
Dependencies to test eMMC HS400:
* [PATCH] clk: renesas: rcar-gen3: Fix SD divider setting
* [PATCH v2] arm64: dts: salvator-common: Enable HS400 of SDHI2
To assist testing and review this patch and the above mentioned
dependencies, which are necessary and sufficient to enable HS400 on
R-Car {H3,M3-W,M3-N} / Salvator-{X,XS}.
https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/hs400-v5
Changes since v4:
* Refactor host tuning operations as suggested by Ulf
* Differeniate between 4 tap and 8 tap support for HS400
* Support HS400 with R-Car M3-N (r8a77965)
Changes since v3:
* As a follow-up to discussion with Ulf and Wolfram I have proposed
two new HS400 tuning host operations. These are provided, and explained,
in "mmc: core: more fine-grained hooks for HS400 tuning".
The following driver patches have been updated to use these new operations.
And "mmc: tmio: add eMMC HS400 mode support" proposes a minor cleanup
to make it a little cleaner to add the proposed new host operations to
the MMC core.
Changes since v2:
* Consolidate disable_scc and reset_hs400_mode into reset_hs400_tuning
callback
* Reuse renesas_sdhi_reset_hs400_mode() in renesas_sdhi_hw_reset()
* Factor out renesas_sdhi_reset_scc()
Masaharu Hayakawa (2):
mmc: tmio: add eMMC HS400 mode support
mmc: renesas_sdhi: add eMMC HS400 mode support
Simon Horman (1):
mmc: core: more fine-grained hooks for HS400 tuning
drivers/mmc/core/mmc.c | 10 ++
drivers/mmc/host/renesas_sdhi_core.c | 127 +++++++++++++++++++++-----
drivers/mmc/host/renesas_sdhi_internal_dmac.c | 20 +++-
drivers/mmc/host/renesas_sdhi_sys_dmac.c | 17 +++-
drivers/mmc/host/tmio_mmc.h | 6 ++
drivers/mmc/host/tmio_mmc_core.c | 47 +++++++++-
include/linux/mfd/tmio.h | 3 +
include/linux/mmc/host.h | 7 ++
8 files changed, 209 insertions(+), 28 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v5 1/3] mmc: core: more fine-grained hooks for HS400 tuning
2018-06-18 12:57 [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
@ 2018-06-18 12:57 ` Simon Horman
2018-06-18 12:57 ` [PATCH v5 2/3] mmc: tmio: add eMMC HS400 mode support Simon Horman
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2018-06-18 12:57 UTC (permalink / raw)
To: Wolfram Sang, Ulf Hansson
Cc: Magnus Damm, linux-mmc, linux-renesas-soc, Simon Horman
This adds two new HS400 tuning operations:
* hs400_downgrade
* hs400_complete
These supplement the existing HS400 operation:
* prepare_hs400_tuning
This is motivated by a requirement of Renesas SDHI for the following:
1. Disabling SCC before selecting to HS if selection of HS400 has occurred.
This can be done in an implementation of prepare_hs400_tuning_downgrade
2. Updating registers after switching to HS400
This can be done in an implementation of complete_hs400_tuning
If hs400_downgrade or hs400_complete are not implemented then they are not
called. Thus means there should be no affect for existing drivers as none
implemt these ops.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v5
* Reworked as per feedback from Ulf Hansson
- Call ops from mmc_hs400_to_hs200() and mmc_select_hs400()
rather than mmc_retune() and mmc_select_timing().
This moves card code further away from core code and
makes the patch somewhat tider.
- Use shorter names for new ops.
v4
* New patch
---
drivers/mmc/core/mmc.c | 10 ++++++++++
include/linux/mmc/host.h | 7 +++++++
2 files changed, 17 insertions(+)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4466f5de54d4..63a52379e8ab 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1169,6 +1169,10 @@ static int mmc_select_hs400(struct mmc_card *card)
/* Set host controller to HS timing */
mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ /* Prepare host to downgrade to HS timing */
+ if (host->ops->hs400_downgrade)
+ host->ops->hs400_downgrade(host);
+
/* Reduce frequency to HS frequency */
max_dtr = card->ext_csd.hs_max_dtr;
mmc_set_clock(host, max_dtr);
@@ -1209,6 +1213,9 @@ static int mmc_select_hs400(struct mmc_card *card)
if (err)
goto out_err;
+ if (host->ops->hs400_complete)
+ host->ops->hs400_complete(host);
+
return 0;
out_err:
@@ -1256,6 +1263,9 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_HS);
+ if (host->ops->hs400_downgrade)
+ host->ops->hs400_downgrade(host);
+
err = mmc_switch_status(card);
if (err)
goto out_err;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 64300a48dcce..a39e2925c84c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -146,6 +146,13 @@ struct mmc_host_ops {
/* Prepare HS400 target operating frequency depending host driver */
int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
+
+ /* Prepare for switching from HS400 to HS200 */
+ void (*hs400_downgrade)(struct mmc_host *host);
+
+ /* Complete selection of HS400 */
+ void (*hs400_complete)(struct mmc_host *host);
+
/* Prepare enhanced strobe depending host driver */
void (*hs400_enhanced_strobe)(struct mmc_host *host,
struct mmc_ios *ios);
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v5 2/3] mmc: tmio: add eMMC HS400 mode support
2018-06-18 12:57 [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
2018-06-18 12:57 ` [PATCH v5 1/3] mmc: core: more fine-grained hooks for HS400 tuning Simon Horman
@ 2018-06-18 12:57 ` Simon Horman
2018-06-18 12:57 ` [PATCH v5 3/3] mmc: renesas_sdhi: " Simon Horman
2018-07-02 13:17 ` [PATCH v5 0/3] " Ulf Hansson
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2018-06-18 12:57 UTC (permalink / raw)
To: Wolfram Sang, Ulf Hansson
Cc: Magnus Damm, linux-mmc, linux-renesas-soc, Masaharu Hayakawa,
Simon Horman
From: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
This patch adds processing for selecting HS400 mode.
Signed-off-by: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v5 [Simon Horman]
* Make new local functions static
* Use new names of new HS400 host ops
* Allow differentiation between 4tap and 8tap support
v4 [Simon Horman]
* Make use of proposed new HS400 host ops
v3 [Simon Horman]
* Consolidate disable_scc and reset_hs400_mode into reset_hs400_tuning
callback
v2 [Simon Horman]
* Updated to new version of BSP patch from BSP v3.6.0
* Dropped 4 and 8 tap differentiation as all SoCs currently supported
by the driver in upstream use 4 taps for HS400.
* Minor cleanup
v1 [Simon Horman]
* Combined patches by Ai Kyuse and Masaharu Hayakawa.
* Rebase
* Minor clean-up
v0 [Masaharu Hayakawa]
---
drivers/mmc/host/tmio_mmc.h | 6 +++++
drivers/mmc/host/tmio_mmc_core.c | 47 ++++++++++++++++++++++++++++++++++++++--
include/linux/mfd/tmio.h | 3 +++
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index e7d651352dc9..5d141f79e175 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -46,6 +46,7 @@
#define CTL_DMA_ENABLE 0xd8
#define CTL_RESET_SD 0xe0
#define CTL_VERSION 0xe2
+#define CTL_SDIF_MODE 0xe6
#define CTL_SDIO_REGS 0x100
#define CTL_CLK_AND_WAIT_CTL 0x138
#define CTL_RESET_SDIO 0x1e0
@@ -191,6 +192,11 @@ struct tmio_mmc_host {
/* Tuning values: 1 for success, 0 for failure */
DECLARE_BITMAP(taps, BITS_PER_BYTE * sizeof(long));
unsigned int tap_num;
+ unsigned long tap_set;
+
+ void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
+ void (*hs400_downgrade)(struct tmio_mmc_host *host);
+ void (*hs400_complete)(struct tmio_mmc_host *host);
const struct tmio_mmc_dma_ops *dma_ops;
};
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 308029930304..416f9e078fda 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -199,6 +199,14 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
tmio_mmc_clk_stop(host);
return;
}
+ /*
+ * Both HS400 and HS200/SD104 set 200MHz, but some devices need to
+ * set 400MHz to distinguish the CPG settings in HS400.
+ */
+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 &&
+ host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 &&
+ new_clock == 200000000)
+ new_clock = 400000000;
if (host->clk_update)
clock = host->clk_update(host, new_clock) / 512;
@@ -209,8 +217,13 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
clock <<= 1;
/* 1/1 clock is option */
- if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1))
- clk |= 0xff;
+ if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
+ ((clk >> 22) & 0x1)) {
+ if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400))
+ clk |= 0xff;
+ else
+ clk &= ~0xff;
+ }
if (host->set_clk_div)
host->set_clk_div(host->pdev, (clk >> 22) & 1);
@@ -1087,6 +1100,33 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
return blk_size;
}
+static int tmio_mmc_prepare_hs400_tuning(struct mmc_host *mmc,
+ struct mmc_ios *ios)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (host->prepare_hs400_tuning)
+ host->prepare_hs400_tuning(host);
+
+ return 0;
+}
+
+static void tmio_mmc_hs400_downgrade(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (host->hs400_downgrade)
+ host->hs400_downgrade(host);
+}
+
+static void tmio_mmc_hs400_complete(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (host->hs400_complete)
+ host->hs400_complete(host);
+}
+
static const struct mmc_host_ops tmio_mmc_ops = {
.request = tmio_mmc_request,
.set_ios = tmio_mmc_set_ios,
@@ -1096,6 +1136,9 @@ static const struct mmc_host_ops tmio_mmc_ops = {
.multi_io_quirk = tmio_multi_io_quirk,
.hw_reset = tmio_mmc_hw_reset,
.execute_tuning = tmio_mmc_execute_tuning,
+ .prepare_hs400_tuning = tmio_mmc_prepare_hs400_tuning,
+ .hs400_downgrade = tmio_mmc_hs400_downgrade,
+ .hs400_complete = tmio_mmc_hs400_complete,
};
static int tmio_mmc_init_ocr(struct tmio_mmc_host *host)
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 91f92215ca74..77866214ab51 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -90,6 +90,9 @@
/* Some controllers have a CBSY bit */
#define TMIO_MMC_HAVE_CBSY BIT(11)
+/* Some controllers that support HS400 use use 4 taps while others use 8. */
+#define TMIO_MMC_HAVE_4TAP_HS400 BIT(13)
+
int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base);
int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base);
void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state);
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v5 3/3] mmc: renesas_sdhi: add eMMC HS400 mode support
2018-06-18 12:57 [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
2018-06-18 12:57 ` [PATCH v5 1/3] mmc: core: more fine-grained hooks for HS400 tuning Simon Horman
2018-06-18 12:57 ` [PATCH v5 2/3] mmc: tmio: add eMMC HS400 mode support Simon Horman
@ 2018-06-18 12:57 ` Simon Horman
2018-07-02 13:17 ` [PATCH v5 0/3] " Ulf Hansson
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2018-06-18 12:57 UTC (permalink / raw)
To: Wolfram Sang, Ulf Hansson
Cc: Magnus Damm, linux-mmc, linux-renesas-soc, Masaharu Hayakawa,
Simon Horman
From: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
This patch adds processing for selecting HS400 mode.
Signed-off-by: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v5 [Simon Horman]
* Use new names of new HS400 host ops
* Differentiate between 4tap and 8tap support
v4 [Simon Horman]
* Make use of proposed new HS400 host ops
v3 [Simon Horman]
* Consolidate disable_scc and reset_hs400_mode into reset_hs400_tuning
callback
* Reuse renesas_sdhi_reset_hs400_mode() in renesas_sdhi_hw_reset()
* Factor out renesas_sdhi_reset_scc()
v2 [Simon Horman]
* Updated to new version from BSP v3.6.0
* Dropped 4 and 8 tap differentiation as all SoCs currently supported
by the driver in upstream use 4 taps for HS400.
v1 [Simon Horman]
* Combined patched by Ai Kyuse and Masaharu Hayakawa
* Rebase
v0 [Masaharu Hayakawa]
---
drivers/mmc/host/renesas_sdhi_core.c | 127 +++++++++++++++++++++-----
drivers/mmc/host/renesas_sdhi_internal_dmac.c | 20 +++-
drivers/mmc/host/renesas_sdhi_sys_dmac.c | 17 +++-
3 files changed, 138 insertions(+), 26 deletions(-)
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 45c015da2e75..384ae6cfa289 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -212,6 +212,7 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
#define SH_MOBILE_SDHI_SCC_CKSEL 0x006
#define SH_MOBILE_SDHI_SCC_RVSCNTL 0x008
#define SH_MOBILE_SDHI_SCC_RVSREQ 0x00A
+#define SH_MOBILE_SDHI_SCC_TMPPORT2 0x00E
/* Definitions for values the SH_MOBILE_SDHI_SCC_DTCNTL register */
#define SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN BIT(0)
@@ -224,6 +225,9 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
#define SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN BIT(0)
/* Definitions for values the SH_MOBILE_SDHI_SCC_RVSREQ register */
#define SH_MOBILE_SDHI_SCC_RVSREQ_RVSERR BIT(2)
+/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT2 register */
+#define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL BIT(4)
+#define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN BIT(31)
static inline u32 sd_scc_read32(struct tmio_mmc_host *host,
struct renesas_sdhi *priv, int addr)
@@ -244,33 +248,30 @@ static unsigned int renesas_sdhi_init_tuning(struct tmio_mmc_host *host)
priv = host_to_priv(host);
- /* set sampling clock selection range */
- sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
- 0x8 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT);
-
/* Initialize SCC */
sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, 0x0);
- sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
- SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN |
- sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL));
-
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ /* set sampling clock selection range */
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
+ SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN |
+ 0x8 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT);
+
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL,
SH_MOBILE_SDHI_SCC_CKSEL_DTSEL |
sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL));
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
~SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN &
sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF, priv->scc_tappos);
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
/* Read TAPNUM */
return (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL) >>
SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) &
@@ -286,13 +287,95 @@ static void renesas_sdhi_prepare_tuning(struct tmio_mmc_host *host,
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, tap);
}
+static void renesas_sdhi_hs400_complete(struct tmio_mmc_host *host)
+{
+ struct renesas_sdhi *priv = host_to_priv(host);
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
+ /* Set HS400 mode */
+ sd_ctrl_write16(host, CTL_SDIF_MODE, 0x0001 |
+ sd_ctrl_read16(host, CTL_SDIF_MODE));
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
+ (SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
+ SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) |
+ sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
+
+ /* Set the sampling clock selection range of HS400 mode */
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
+ SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN |
+ 0x4 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT);
+
+
+ if (host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400)
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET,
+ host->tap_set / 2);
+
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL,
+ SH_MOBILE_SDHI_SCC_CKSEL_DTSEL |
+ sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL));
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+}
+
+static void renesas_sdhi_reset_scc(struct tmio_mmc_host *host,
+ struct renesas_sdhi *priv)
+{
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL,
+ ~SH_MOBILE_SDHI_SCC_CKSEL_DTSEL &
+ sd_scc_read32(host, priv,
+ SH_MOBILE_SDHI_SCC_CKSEL));
+}
+
+static void renesas_sdhi_disable_scc(struct tmio_mmc_host *host)
+{
+ struct renesas_sdhi *priv = host_to_priv(host);
+
+ renesas_sdhi_reset_scc(host, priv);
+
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
+ ~SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN &
+ sd_scc_read32(host, priv,
+ SH_MOBILE_SDHI_SCC_DTCNTL));
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+}
+
+static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
+ struct renesas_sdhi *priv)
+{
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
+ /* Reset HS400 mode */
+ sd_ctrl_write16(host, CTL_SDIF_MODE, ~0x0001 &
+ sd_ctrl_read16(host, CTL_SDIF_MODE));
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
+ ~(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
+ SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
+ sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+}
+
+static void renesas_sdhi_prepare_hs400_tuning(struct tmio_mmc_host *host)
+{
+ renesas_sdhi_reset_hs400_mode(host, host_to_priv(host));
+}
+
#define SH_MOBILE_SDHI_MAX_TAP 3
static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
{
struct renesas_sdhi *priv = host_to_priv(host);
unsigned long tap_cnt; /* counter of tuning success */
- unsigned long tap_set; /* tap position */
unsigned long tap_start;/* start position of tuning success */
unsigned long tap_end; /* end position of tuning success */
unsigned long ntap; /* temporary counter of tuning success */
@@ -330,12 +413,12 @@ static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
}
if (tap_cnt >= SH_MOBILE_SDHI_MAX_TAP)
- tap_set = (tap_start + tap_end) / 2 % host->tap_num;
+ host->tap_set = (tap_start + tap_end) / 2 % host->tap_num;
else
return -EIO;
/* Set SCC */
- sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, tap_set);
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, host->tap_set);
/* Enable auto re-tuning */
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
@@ -368,13 +451,8 @@ static void renesas_sdhi_hw_reset(struct tmio_mmc_host *host)
priv = host_to_priv(host);
- /* Reset SCC */
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-
- sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL,
- ~SH_MOBILE_SDHI_SCC_CKSEL_DTSEL &
- sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL));
+ renesas_sdhi_reset_scc(host, priv);
+ renesas_sdhi_reset_hs400_mode(host, priv);
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -592,7 +670,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
/* Enable tuning iff we have an SCC and a supported mode */
if (of_data && of_data->scc_offset &&
(host->mmc->caps & MMC_CAP_UHS_SDR104 ||
- host->mmc->caps2 & MMC_CAP2_HS200_1_8V_SDR)) {
+ host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
+ MMC_CAP2_HS400_1_8V))) {
const struct renesas_sdhi_scc *taps = of_data->taps;
bool hit = false;
@@ -616,6 +695,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
host->select_tuning = renesas_sdhi_select_tuning;
host->check_scc_error = renesas_sdhi_check_scc_error;
host->hw_reset = renesas_sdhi_hw_reset;
+ host->prepare_hs400_tuning =
+ renesas_sdhi_prepare_hs400_tuning;
+ host->hs400_downgrade = renesas_sdhi_disable_scc;
+ host->hs400_complete = renesas_sdhi_hs400_complete;
}
i = 0;
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index f7f9773d161f..a8ae34c6d446 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -82,6 +82,22 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
},
};
+static const struct renesas_sdhi_of_data of_rcar_r8a7795_compatible = {
+ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
+ TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 |
+ TMIO_MMC_HAVE_4TAP_HS400,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_CMD23,
+ .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT,
+ .bus_shift = 2,
+ .scc_offset = 0x1000,
+ .taps = rcar_gen3_scc_taps,
+ .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
+ /* DMAC can handle 0xffffffff blk count but only 1 segment */
+ .max_blk_count = 0xffffffff,
+ .max_segs = 1,
+};
+
static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
@@ -98,8 +114,8 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
};
static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
- { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
- { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_r8a7795_compatible, },
+ { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_r8a7795_compatible, },
{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
{},
};
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index 4bb46c489d71..890f192dedbd 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -78,6 +78,19 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
},
};
+static const struct renesas_sdhi_of_data of_rcar_r8a7795_compatible = {
+ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
+ TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 |
+ TMIO_MMC_HAVE_4TAP_HS400,
+ .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_CMD23,
+ .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT,
+ .bus_shift = 2,
+ .scc_offset = 0x1000,
+ .taps = rcar_gen3_scc_taps,
+ .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
+};
+
static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
@@ -104,8 +117,8 @@ static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = {
{ .compatible = "renesas,sdhi-r8a7792", .data = &of_rcar_gen2_compatible, },
{ .compatible = "renesas,sdhi-r8a7793", .data = &of_rcar_gen2_compatible, },
{ .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, },
- { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
- { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_r8a7795_compatible, },
+ { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_r8a7795_compatible, },
{ .compatible = "renesas,rcar-gen1-sdhi", .data = &of_rcar_gen1_compatible, },
{ .compatible = "renesas,rcar-gen2-sdhi", .data = &of_rcar_gen2_compatible, },
{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
--
2.11.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support
2018-06-18 12:57 [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
` (2 preceding siblings ...)
2018-06-18 12:57 ` [PATCH v5 3/3] mmc: renesas_sdhi: " Simon Horman
@ 2018-07-02 13:17 ` Ulf Hansson
3 siblings, 0 replies; 5+ messages in thread
From: Ulf Hansson @ 2018-07-02 13:17 UTC (permalink / raw)
To: Simon Horman; +Cc: Wolfram Sang, Magnus Damm, linux-mmc, Linux-Renesas
On 18 June 2018 at 14:57, Simon Horman <horms+renesas@verge.net.au> wrote:
> Hi,
>
> this patch-set provides SDHI driver support for eMMC HS400.
>
> Based on mmc-v4.18-rc1
>
> Dependencies for applying these patches:
> * none
>
> Dependencies to test eMMC HS400:
> * [PATCH] clk: renesas: rcar-gen3: Fix SD divider setting
> * [PATCH v2] arm64: dts: salvator-common: Enable HS400 of SDHI2
>
> To assist testing and review this patch and the above mentioned
> dependencies, which are necessary and sufficient to enable HS400 on
> R-Car {H3,M3-W,M3-N} / Salvator-{X,XS}.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/hs400-v5
>
> Changes since v4:
> * Refactor host tuning operations as suggested by Ulf
> * Differeniate between 4 tap and 8 tap support for HS400
> * Support HS400 with R-Car M3-N (r8a77965)
>
> Changes since v3:
> * As a follow-up to discussion with Ulf and Wolfram I have proposed
> two new HS400 tuning host operations. These are provided, and explained,
> in "mmc: core: more fine-grained hooks for HS400 tuning".
>
> The following driver patches have been updated to use these new operations.
>
> And "mmc: tmio: add eMMC HS400 mode support" proposes a minor cleanup
> to make it a little cleaner to add the proposed new host operations to
> the MMC core.
>
> Changes since v2:
> * Consolidate disable_scc and reset_hs400_mode into reset_hs400_tuning
> callback
> * Reuse renesas_sdhi_reset_hs400_mode() in renesas_sdhi_hw_reset()
> * Factor out renesas_sdhi_reset_scc()
>
> Masaharu Hayakawa (2):
> mmc: tmio: add eMMC HS400 mode support
> mmc: renesas_sdhi: add eMMC HS400 mode support
>
> Simon Horman (1):
> mmc: core: more fine-grained hooks for HS400 tuning
>
> drivers/mmc/core/mmc.c | 10 ++
> drivers/mmc/host/renesas_sdhi_core.c | 127 +++++++++++++++++++++-----
> drivers/mmc/host/renesas_sdhi_internal_dmac.c | 20 +++-
> drivers/mmc/host/renesas_sdhi_sys_dmac.c | 17 +++-
> drivers/mmc/host/tmio_mmc.h | 6 ++
> drivers/mmc/host/tmio_mmc_core.c | 47 +++++++++-
> include/linux/mfd/tmio.h | 3 +
> include/linux/mmc/host.h | 7 ++
> 8 files changed, 209 insertions(+), 28 deletions(-)
>
> --
> 2.11.0
>
Thanks, applied for next!
Kind regards
Uffe
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-07-02 13:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-18 12:57 [PATCH v5 0/3] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
2018-06-18 12:57 ` [PATCH v5 1/3] mmc: core: more fine-grained hooks for HS400 tuning Simon Horman
2018-06-18 12:57 ` [PATCH v5 2/3] mmc: tmio: add eMMC HS400 mode support Simon Horman
2018-06-18 12:57 ` [PATCH v5 3/3] mmc: renesas_sdhi: " Simon Horman
2018-07-02 13:17 ` [PATCH v5 0/3] " Ulf Hansson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.