Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Wolfram Sang and committed by
Ulf Hansson
2e586f8a aabf199c

+42 -23
+14 -15
drivers/mmc/host/renesas_sdhi_core.c
··· 49 49 #define HOST_MODE_GEN3_32BIT (HOST_MODE_GEN3_WMODE | HOST_MODE_GEN3_BUSWIDTH) 50 50 #define HOST_MODE_GEN3_64BIT 0 51 51 52 - #define CTL_SDIF_MODE 0xe6 53 - #define SDIF_MODE_HS400 BIT(0) 54 - 55 52 #define SDHI_VER_GEN2_SDR50 0x490c 56 53 #define SDHI_VER_RZ_A1 0x820b 57 54 /* very old datasheets said 0x490c for SDR104, too. They are wrong! */ ··· 559 562 } 560 563 561 564 /* only populated for TMIO_MMC_MIN_RCAR2 */ 562 - static void renesas_sdhi_reset(struct tmio_mmc_host *host) 565 + static void renesas_sdhi_reset(struct tmio_mmc_host *host, bool preserve) 563 566 { 564 567 struct renesas_sdhi *priv = host_to_priv(host); 565 568 int ret; 566 569 u16 val; 567 570 568 - if (priv->rstc) { 569 - reset_control_reset(priv->rstc); 570 - /* Unknown why but without polling reset status, it will hang */ 571 - read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100, 572 - false, priv->rstc); 573 - /* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */ 574 - sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 575 - priv->needs_adjust_hs400 = false; 576 - renesas_sdhi_set_clock(host, host->clk_cache); 577 - } else if (priv->scc_ctl) { 578 - renesas_sdhi_scc_reset(host, priv); 571 + if (!preserve) { 572 + if (priv->rstc) { 573 + reset_control_reset(priv->rstc); 574 + /* Unknown why but without polling reset status, it will hang */ 575 + read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100, 576 + false, priv->rstc); 577 + /* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */ 578 + sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 579 + priv->needs_adjust_hs400 = false; 580 + renesas_sdhi_set_clock(host, host->clk_cache); 581 + } else if (priv->scc_ctl) { 582 + renesas_sdhi_scc_reset(host, priv); 583 + } 579 584 } 580 585 581 586 if (sd_ctrl_read16(host, CTL_VERSION) >= SDHI_VER_GEN3_SD) {
+1 -1
drivers/mmc/host/tmio_mmc.c
··· 75 75 tmio_mmc_clk_start(host); 76 76 } 77 77 78 - static void tmio_mmc_reset(struct tmio_mmc_host *host) 78 + static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve) 79 79 { 80 80 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); 81 81 usleep_range(10000, 11000);
+5 -1
drivers/mmc/host/tmio_mmc.h
··· 42 42 #define CTL_DMA_ENABLE 0xd8 43 43 #define CTL_RESET_SD 0xe0 44 44 #define CTL_VERSION 0xe2 45 + #define CTL_SDIF_MODE 0xe6 /* only known on R-Car 2+ */ 45 46 46 47 /* Definitions for values the CTL_STOP_INTERNAL_ACTION register can take */ 47 48 #define TMIO_STOP_STP BIT(0) ··· 98 97 99 98 /* Definitions for values the CTL_DMA_ENABLE register can take */ 100 99 #define DMA_ENABLE_DMASDRW BIT(1) 100 + 101 + /* Definitions for values the CTL_SDIF_MODE register can take */ 102 + #define SDIF_MODE_HS400 BIT(0) /* only known on R-Car 2+ */ 101 103 102 104 /* Define some IRQ masks */ 103 105 /* This is the mask used at reset by the chip */ ··· 185 181 int (*multi_io_quirk)(struct mmc_card *card, 186 182 unsigned int direction, int blk_size); 187 183 int (*write16_hook)(struct tmio_mmc_host *host, int addr); 188 - void (*reset)(struct tmio_mmc_host *host); 184 + void (*reset)(struct tmio_mmc_host *host, bool preserve); 189 185 bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq); 190 186 void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq); 191 187 unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
+22 -6
drivers/mmc/host/tmio_mmc_core.c
··· 179 179 sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg); 180 180 } 181 181 182 - static void tmio_mmc_reset(struct tmio_mmc_host *host) 182 + static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve) 183 183 { 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 + 184 193 /* FIXME - should we set stop clock reg here */ 185 194 sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); 186 195 usleep_range(10000, 11000); ··· 199 190 tmio_mmc_abort_dma(host); 200 191 201 192 if (host->reset) 202 - host->reset(host); 193 + host->reset(host, preserve); 203 194 204 195 sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all); 205 196 host->sdcard_irq_mask = host->sdcard_irq_mask_all; ··· 213 204 if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) { 214 205 sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); 215 206 sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); 207 + } 208 + 209 + if (preserve) { 210 + sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, card_opt); 211 + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk_ctrl); 212 + if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) 213 + sd_ctrl_write16(host, CTL_SDIF_MODE, sdif_mode); 216 214 } 217 215 218 216 if (host->mmc->card) ··· 264 248 265 249 spin_unlock_irqrestore(&host->lock, flags); 266 250 267 - tmio_mmc_reset(host); 251 + tmio_mmc_reset(host, true); 268 252 269 253 /* Ready for new calls */ 270 254 host->mrq = NULL; ··· 977 961 tmio_mmc_power_off(host); 978 962 /* For R-Car Gen2+, we need to reset SDHI specific SCC */ 979 963 if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) 980 - tmio_mmc_reset(host); 964 + tmio_mmc_reset(host, false); 981 965 982 966 host->set_clock(host, 0); 983 967 break; ··· 1205 1189 _host->sdcard_irq_mask_all = TMIO_MASK_ALL; 1206 1190 1207 1191 _host->set_clock(_host, 0); 1208 - tmio_mmc_reset(_host); 1192 + tmio_mmc_reset(_host, false); 1209 1193 1210 1194 spin_lock_init(&_host->lock); 1211 1195 mutex_init(&_host->ios_lock); ··· 1301 1285 struct tmio_mmc_host *host = dev_get_drvdata(dev); 1302 1286 1303 1287 tmio_mmc_clk_enable(host); 1304 - tmio_mmc_reset(host); 1288 + tmio_mmc_reset(host, false); 1305 1289 1306 1290 if (host->clk_cache) 1307 1291 host->set_clock(host, host->clk_cache);