Skip to content

Commit 2e586f8

Browse files
Wolfram SangUlf Hansson
authored andcommitted
mmc: tmio: avoid glitches when resetting
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>
1 parent aabf199 commit 2e586f8

4 files changed

Lines changed: 42 additions & 23 deletions

File tree

drivers/mmc/host/renesas_sdhi_core.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949
#define HOST_MODE_GEN3_32BIT (HOST_MODE_GEN3_WMODE | HOST_MODE_GEN3_BUSWIDTH)
5050
#define HOST_MODE_GEN3_64BIT 0
5151

52-
#define CTL_SDIF_MODE 0xe6
53-
#define SDIF_MODE_HS400 BIT(0)
54-
5552
#define SDHI_VER_GEN2_SDR50 0x490c
5653
#define SDHI_VER_RZ_A1 0x820b
5754
/* very old datasheets said 0x490c for SDR104, too. They are wrong! */
@@ -562,23 +559,25 @@ static void renesas_sdhi_scc_reset(struct tmio_mmc_host *host, struct renesas_sd
562559
}
563560

564561
/* only populated for TMIO_MMC_MIN_RCAR2 */
565-
static void renesas_sdhi_reset(struct tmio_mmc_host *host)
562+
static void renesas_sdhi_reset(struct tmio_mmc_host *host, bool preserve)
566563
{
567564
struct renesas_sdhi *priv = host_to_priv(host);
568565
int ret;
569566
u16 val;
570567

571-
if (priv->rstc) {
572-
reset_control_reset(priv->rstc);
573-
/* Unknown why but without polling reset status, it will hang */
574-
read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
575-
false, priv->rstc);
576-
/* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */
577-
sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
578-
priv->needs_adjust_hs400 = false;
579-
renesas_sdhi_set_clock(host, host->clk_cache);
580-
} else if (priv->scc_ctl) {
581-
renesas_sdhi_scc_reset(host, priv);
568+
if (!preserve) {
569+
if (priv->rstc) {
570+
reset_control_reset(priv->rstc);
571+
/* Unknown why but without polling reset status, it will hang */
572+
read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
573+
false, priv->rstc);
574+
/* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */
575+
sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
576+
priv->needs_adjust_hs400 = false;
577+
renesas_sdhi_set_clock(host, host->clk_cache);
578+
} else if (priv->scc_ctl) {
579+
renesas_sdhi_scc_reset(host, priv);
580+
}
582581
}
583582

584583
if (sd_ctrl_read16(host, CTL_VERSION) >= SDHI_VER_GEN3_SD) {

drivers/mmc/host/tmio_mmc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
7575
tmio_mmc_clk_start(host);
7676
}
7777

78-
static void tmio_mmc_reset(struct tmio_mmc_host *host)
78+
static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
7979
{
8080
sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
8181
usleep_range(10000, 11000);

drivers/mmc/host/tmio_mmc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#define CTL_DMA_ENABLE 0xd8
4343
#define CTL_RESET_SD 0xe0
4444
#define CTL_VERSION 0xe2
45+
#define CTL_SDIF_MODE 0xe6 /* only known on R-Car 2+ */
4546

4647
/* Definitions for values the CTL_STOP_INTERNAL_ACTION register can take */
4748
#define TMIO_STOP_STP BIT(0)
@@ -98,6 +99,9 @@
9899
/* Definitions for values the CTL_DMA_ENABLE register can take */
99100
#define DMA_ENABLE_DMASDRW BIT(1)
100101

102+
/* Definitions for values the CTL_SDIF_MODE register can take */
103+
#define SDIF_MODE_HS400 BIT(0) /* only known on R-Car 2+ */
104+
101105
/* Define some IRQ masks */
102106
/* This is the mask used at reset by the chip */
103107
#define TMIO_MASK_ALL 0x837f031d
@@ -181,7 +185,7 @@ struct tmio_mmc_host {
181185
int (*multi_io_quirk)(struct mmc_card *card,
182186
unsigned int direction, int blk_size);
183187
int (*write16_hook)(struct tmio_mmc_host *host, int addr);
184-
void (*reset)(struct tmio_mmc_host *host);
188+
void (*reset)(struct tmio_mmc_host *host, bool preserve);
185189
bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq);
186190
void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
187191
unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);

drivers/mmc/host/tmio_mmc_core.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,17 @@ static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
179179
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
180180
}
181181

182-
static void tmio_mmc_reset(struct tmio_mmc_host *host)
182+
static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
183183
{
184+
u16 card_opt, clk_ctrl, sdif_mode;
185+
186+
if (preserve) {
187+
card_opt = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT);
188+
clk_ctrl = sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL);
189+
if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
190+
sdif_mode = sd_ctrl_read16(host, CTL_SDIF_MODE);
191+
}
192+
184193
/* FIXME - should we set stop clock reg here */
185194
sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
186195
usleep_range(10000, 11000);
@@ -190,7 +199,7 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
190199
tmio_mmc_abort_dma(host);
191200

192201
if (host->reset)
193-
host->reset(host);
202+
host->reset(host, preserve);
194203

195204
sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all);
196205
host->sdcard_irq_mask = host->sdcard_irq_mask_all;
@@ -206,6 +215,13 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
206215
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
207216
}
208217

218+
if (preserve) {
219+
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, card_opt);
220+
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk_ctrl);
221+
if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
222+
sd_ctrl_write16(host, CTL_SDIF_MODE, sdif_mode);
223+
}
224+
209225
if (host->mmc->card)
210226
mmc_retune_needed(host->mmc);
211227
}
@@ -248,7 +264,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
248264

249265
spin_unlock_irqrestore(&host->lock, flags);
250266

251-
tmio_mmc_reset(host);
267+
tmio_mmc_reset(host, true);
252268

253269
/* Ready for new calls */
254270
host->mrq = NULL;
@@ -961,7 +977,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
961977
tmio_mmc_power_off(host);
962978
/* For R-Car Gen2+, we need to reset SDHI specific SCC */
963979
if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
964-
tmio_mmc_reset(host);
980+
tmio_mmc_reset(host, false);
965981

966982
host->set_clock(host, 0);
967983
break;
@@ -1189,7 +1205,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
11891205
_host->sdcard_irq_mask_all = TMIO_MASK_ALL;
11901206

11911207
_host->set_clock(_host, 0);
1192-
tmio_mmc_reset(_host);
1208+
tmio_mmc_reset(_host, false);
11931209

11941210
spin_lock_init(&_host->lock);
11951211
mutex_init(&_host->ios_lock);
@@ -1285,7 +1301,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
12851301
struct tmio_mmc_host *host = dev_get_drvdata(dev);
12861302

12871303
tmio_mmc_clk_enable(host);
1288-
tmio_mmc_reset(host);
1304+
tmio_mmc_reset(host, false);
12891305

12901306
if (host->clk_cache)
12911307
host->set_clock(host, host->clk_cache);

0 commit comments

Comments
 (0)