* [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements
@ 2022-11-08 12:56 Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 1/3] mmc: tmio: avoid glitches when resetting Biju Das
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Biju Das @ 2022-11-08 12:56 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Chris Paterson, Biju Das
This patch series aims to add rounding error fixes for selecting
533MHz SDHI source clk and avoid glitches when resetting.
Biju Das (2):
mmc: renesas_sdhi: Fix rounding errors
clk: renesas: rzg2l: Support sd clk mux round operation
Wolfram Sang (1):
mmc: tmio: avoid glitches when resetting
drivers/clk/renesas/rzg2l-cpg.c | 2 +-
drivers/mmc/host/renesas_sdhi_core.c | 48 ++++++++++++++++++----------
drivers/mmc/host/tmio_mmc.c | 2 +-
drivers/mmc/host/tmio_mmc.h | 6 +++-
drivers/mmc/host/tmio_mmc_core.c | 28 ++++++++++++----
5 files changed, 61 insertions(+), 25 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5.10.y-cip 1/3] mmc: tmio: avoid glitches when resetting
2022-11-08 12:56 [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Biju Das
@ 2022-11-08 12:56 ` Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 2/3] mmc: renesas_sdhi: Fix rounding errors Biju Das
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Biju Das @ 2022-11-08 12:56 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Chris Paterson, Biju Das
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
commit 2e586f8a5b0ed4a525014a692923ac96f6647816 upstream.
If we reset because of an error, we need to preserve values for the
clock frequency. Otherwise, glitches may be seen on the bus.
To achieve that, we introduce a 'preserve' parameter to the reset
function and the IP core specific reset callbacks to handle everything
accordingly.
Reported-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/20220625131722.1397-1-wsa@kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/mmc/host/renesas_sdhi_core.c | 27 ++++++++++++++-------------
drivers/mmc/host/tmio_mmc.c | 2 +-
drivers/mmc/host/tmio_mmc.h | 6 +++++-
drivers/mmc/host/tmio_mmc_core.c | 28 ++++++++++++++++++++++------
4 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index ca74fe8bfd9c..120bb5860645 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -51,9 +51,6 @@
#define HOST_MODE_GEN3_32BIT (HOST_MODE_GEN3_WMODE | HOST_MODE_GEN3_BUSWIDTH)
#define HOST_MODE_GEN3_64BIT 0
-#define CTL_SDIF_MODE 0xe6
-#define SDIF_MODE_HS400 BIT(0)
-
#define SDHI_VER_GEN2_SDR50 0x490c
#define SDHI_VER_RZ_A1 0x820b
/* very old datasheets said 0x490c for SDR104, too. They are wrong! */
@@ -571,21 +568,25 @@ static void renesas_sdhi_scc_reset(struct tmio_mmc_host *host, struct renesas_sd
}
/* only populated for TMIO_MMC_MIN_RCAR2 */
-static void renesas_sdhi_reset(struct tmio_mmc_host *host)
+static void renesas_sdhi_reset(struct tmio_mmc_host *host, bool preserve)
{
struct renesas_sdhi *priv = host_to_priv(host);
int ret;
u16 val;
- if (priv->rstc) {
- reset_control_reset(priv->rstc);
- /* Unknown why but without polling reset status, it will hang */
- read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
- false, priv->rstc);
- priv->needs_adjust_hs400 = false;
- renesas_sdhi_set_clock(host, host->clk_cache);
- } else if (priv->scc_ctl) {
- renesas_sdhi_scc_reset(host, priv);
+ if (!preserve) {
+ if (priv->rstc) {
+ reset_control_reset(priv->rstc);
+ /* Unknown why but without polling reset status, it will hang */
+ read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
+ false, priv->rstc);
+ /* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */
+ sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
+ priv->needs_adjust_hs400 = false;
+ renesas_sdhi_set_clock(host, host->clk_cache);
+ } else if (priv->scc_ctl) {
+ renesas_sdhi_scc_reset(host, priv);
+ }
}
if (sd_ctrl_read16(host, CTL_VERSION) >= SDHI_VER_GEN3_SD) {
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index d2d3b8df1bbe..49732054237f 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -75,7 +75,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
tmio_mmc_clk_start(host);
}
-static void tmio_mmc_reset(struct tmio_mmc_host *host)
+static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
{
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
usleep_range(10000, 11000);
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index f936aad945ce..da63193dd45b 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -42,6 +42,7 @@
#define CTL_DMA_ENABLE 0xd8
#define CTL_RESET_SD 0xe0
#define CTL_VERSION 0xe2
+#define CTL_SDIF_MODE 0xe6 /* only known on R-Car 2+ */
/* Definitions for values the CTL_STOP_INTERNAL_ACTION register can take */
#define TMIO_STOP_STP BIT(0)
@@ -98,6 +99,9 @@
/* Definitions for values the CTL_DMA_ENABLE register can take */
#define DMA_ENABLE_DMASDRW BIT(1)
+/* Definitions for values the CTL_SDIF_MODE register can take */
+#define SDIF_MODE_HS400 BIT(0) /* only known on R-Car 2+ */
+
/* Define some IRQ masks */
/* This is the mask used at reset by the chip */
#define TMIO_MASK_ALL 0x837f031d
@@ -181,7 +185,7 @@ struct tmio_mmc_host {
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
int (*write16_hook)(struct tmio_mmc_host *host, int addr);
- void (*reset)(struct tmio_mmc_host *host);
+ void (*reset)(struct tmio_mmc_host *host, bool preserve);
bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq);
void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 79f237d754bd..aaa7f15f2169 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -179,8 +179,17 @@ static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
}
-static void tmio_mmc_reset(struct tmio_mmc_host *host)
+static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
{
+ u16 card_opt, clk_ctrl, sdif_mode;
+
+ if (preserve) {
+ card_opt = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT);
+ clk_ctrl = sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL);
+ if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
+ sdif_mode = sd_ctrl_read16(host, CTL_SDIF_MODE);
+ }
+
/* FIXME - should we set stop clock reg here */
sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
usleep_range(10000, 11000);
@@ -190,7 +199,7 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
tmio_mmc_abort_dma(host);
if (host->reset)
- host->reset(host);
+ host->reset(host, preserve);
sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all);
host->sdcard_irq_mask = host->sdcard_irq_mask_all;
@@ -206,6 +215,13 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
}
+ if (preserve) {
+ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, card_opt);
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk_ctrl);
+ if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
+ sd_ctrl_write16(host, CTL_SDIF_MODE, sdif_mode);
+ }
+
if (host->mmc->card)
mmc_retune_needed(host->mmc);
}
@@ -248,7 +264,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
spin_unlock_irqrestore(&host->lock, flags);
- tmio_mmc_reset(host);
+ tmio_mmc_reset(host, true);
/* Ready for new calls */
host->mrq = NULL;
@@ -959,7 +975,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
tmio_mmc_power_off(host);
/* For R-Car Gen2+, we need to reset SDHI specific SCC */
if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
- tmio_mmc_reset(host);
+ tmio_mmc_reset(host, false);
host->set_clock(host, 0);
break;
@@ -1196,7 +1212,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
_host->sdcard_irq_mask_all = TMIO_MASK_ALL;
_host->set_clock(_host, 0);
- tmio_mmc_reset(_host);
+ tmio_mmc_reset(_host, false);
spin_lock_init(&_host->lock);
mutex_init(&_host->ios_lock);
@@ -1292,7 +1308,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
struct tmio_mmc_host *host = dev_get_drvdata(dev);
tmio_mmc_clk_enable(host);
- tmio_mmc_reset(host);
+ tmio_mmc_reset(host, false);
if (host->clk_cache)
host->set_clock(host, host->clk_cache);
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5.10.y-cip 2/3] mmc: renesas_sdhi: Fix rounding errors
2022-11-08 12:56 [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 1/3] mmc: tmio: avoid glitches when resetting Biju Das
@ 2022-11-08 12:56 ` Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 3/3] clk: renesas: rzg2l: Support sd clk mux round operation Biju Das
2022-11-08 18:47 ` [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Pavel Machek
3 siblings, 0 replies; 6+ messages in thread
From: Biju Das @ 2022-11-08 12:56 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Chris Paterson, Biju Das
commit f0c00454bf78975925eccc9737faaa4d4951edbf upstream.
Due to clk rounding errors on RZ/G2L platforms, it selects a clock source
with a lower clock rate compared to a higher one.
For eg: The rounding error (533333333 Hz / 4 * 4 = 533333332 Hz < 5333333
33 Hz) selects a clk source of 400 MHz instead of 533.333333 MHz.
This patch fixes this issue by adding a margin of (1/1024) higher to
the clock rate.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Fixes: bb6d3fa98a41 ("clk: renesas: rcar-gen3: Switch to new SD clock handling")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220928110755.849275-1-biju.das.jz@bp.renesas.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
[biju: fixed the conflicts manually]
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/mmc/host/renesas_sdhi_core.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 120bb5860645..589e19ff52c6 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -128,6 +128,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
{
struct renesas_sdhi *priv = host_to_priv(host);
unsigned int freq, diff, best_freq = 0, diff_min = ~0;
+ unsigned int new_upper_limit;
int i;
/*
@@ -143,14 +144,21 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
* greater than, new_clock. As we can divide by 1 << i for
* any i in [0, 9] we want the input clock to be as close as
* possible, but no greater than, new_clock << i.
+ *
+ * Add an upper limit of 1/1024 rate higher to the clock rate to fix
+ * clk rate jumping to lower rate due to rounding error (eg: RZ/G2L has
+ * 3 clk sources 533.333333 MHz, 400 MHz and 266.666666 MHz. The request
+ * for 533.333333 MHz will selects a slower 400 MHz due to rounding
+ * error (533333333 Hz / 4 * 4 = 533333332 Hz < 533333333 Hz)).
*/
for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
freq = clk_round_rate(priv->clk, new_clock << i);
- if (freq > (new_clock << i)) {
+ new_upper_limit = (new_clock << i) + ((new_clock << i) >> 10);
+ if (freq > new_upper_limit) {
/* Too fast; look for a slightly slower option */
freq = clk_round_rate(priv->clk,
(new_clock << i) / 4 * 3);
- if (freq > (new_clock << i))
+ if (freq > new_upper_limit)
continue;
}
@@ -169,6 +177,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
unsigned int new_clock)
{
+ unsigned int clk_margin;
u32 clk = 0, clock;
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
@@ -182,7 +191,13 @@ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
host->mmc->actual_clock = renesas_sdhi_clk_update(host, new_clock);
clock = host->mmc->actual_clock / 512;
- for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
+ /*
+ * Add a margin of 1/1024 rate higher to the clock rate in order
+ * to avoid clk variable setting a value of 0 due to the margin
+ * provided for actual_clock in renesas_sdhi_clk_update().
+ */
+ clk_margin = new_clock >> 10;
+ for (clk = 0x80000080; new_clock + clk_margin >= (clock << 1); clk >>= 1)
clock <<= 1;
/* 1/1 clock is option */
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5.10.y-cip 3/3] clk: renesas: rzg2l: Support sd clk mux round operation
2022-11-08 12:56 [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 1/3] mmc: tmio: avoid glitches when resetting Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 2/3] mmc: renesas_sdhi: Fix rounding errors Biju Das
@ 2022-11-08 12:56 ` Biju Das
2022-11-08 18:47 ` [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Pavel Machek
3 siblings, 0 replies; 6+ messages in thread
From: Biju Das @ 2022-11-08 12:56 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Chris Paterson, Biju Das
commit 1625fbc1f73f1fa8f77c38ea554cc0b2327b156b upstream.
Currently, determine_rate() is not doing any round operation
and due to this it always selects a lower clock source compared
to the closest higher one.
Support sd clk mux round operation by passing
CLK_MUX_ROUND_CLOSEST flag to clk_mux_determine_rate_flags().
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20220919084110.3065156-1-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/renesas/rzg2l-cpg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 4d056057f28e..42c6405d6025 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -161,7 +161,7 @@ rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core,
static int rzg2l_cpg_sd_clk_mux_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
- return clk_mux_determine_rate_flags(hw, req, 0);
+ return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST);
}
static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements
2022-11-08 12:56 [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Biju Das
` (2 preceding siblings ...)
2022-11-08 12:56 ` [PATCH 5.10.y-cip 3/3] clk: renesas: rzg2l: Support sd clk mux round operation Biju Das
@ 2022-11-08 18:47 ` Pavel Machek
2022-11-09 19:38 ` Pavel Machek
3 siblings, 1 reply; 6+ messages in thread
From: Pavel Machek @ 2022-11-08 18:47 UTC (permalink / raw)
To: Biju Das; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek, Chris Paterson,
Biju Das
[-- Attachment #1: Type: text/plain, Size: 554 bytes --]
Hi!
> This patch series aims to add rounding error fixes for selecting
> 533MHz SDHI source clk and avoid glitches when resetting.
Series looks okay to me, and it looks like it will pass testing, too.
If there are no other comments, I can apply it. (But I guess I'll wait
for 5.10-cip kernel to be released, first, in order not to interfere
with the release).
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements
2022-11-08 18:47 ` [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Pavel Machek
@ 2022-11-09 19:38 ` Pavel Machek
0 siblings, 0 replies; 6+ messages in thread
From: Pavel Machek @ 2022-11-09 19:38 UTC (permalink / raw)
To: Pavel Machek
Cc: Biju Das, cip-dev, Nobuhiro Iwamatsu, Chris Paterson, Biju Das
[-- Attachment #1: Type: text/plain, Size: 591 bytes --]
Hi!
> > This patch series aims to add rounding error fixes for selecting
> > 533MHz SDHI source clk and avoid glitches when resetting.
>
> Series looks okay to me, and it looks like it will pass testing, too.
>
> If there are no other comments, I can apply it. (But I guess I'll wait
> for 5.10-cip kernel to be released, first, in order not to interfere
> with the release).
Thank you, applied.
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-11-09 19:38 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-08 12:56 [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 1/3] mmc: tmio: avoid glitches when resetting Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 2/3] mmc: renesas_sdhi: Fix rounding errors Biju Das
2022-11-08 12:56 ` [PATCH 5.10.y-cip 3/3] clk: renesas: rzg2l: Support sd clk mux round operation Biju Das
2022-11-08 18:47 ` [PATCH 5.10.y-cip 0/3] SDHI Fixes/enhancements Pavel Machek
2022-11-09 19:38 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox