Skip to content

Commit a27c75e

Browse files
committed
Merge tag 'mmc-v5.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC host fixes from Ulf Hansson: - dw_mmc: Fix hang on data CRC error - mmci: Fix voltage switch procedure for the stm32 variant - sdhci-iproc: Fix some clock issues for BCM2711 - sdhci-msm: Fixup software timeout value * tag 'mmc-v5.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci-iproc: Set SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711 mmc: sdhci-iproc: Cap min clock frequency on BCM2711 mmc: sdhci-msm: Update the software timeout value for sdhc mmc: mmci: stm32: Check when the voltage switch procedure should be done mmc: dw_mmc: Fix hang on data CRC error
2 parents 43a6473 + 419dd62 commit a27c75e

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

drivers/mmc/host/dw_mmc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,8 +2018,8 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
20182018
continue;
20192019
}
20202020

2021-
dw_mci_stop_dma(host);
20222021
send_stop_abort(host, data);
2022+
dw_mci_stop_dma(host);
20232023
state = STATE_SENDING_STOP;
20242024
break;
20252025
}
@@ -2043,10 +2043,10 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
20432043
*/
20442044
if (test_and_clear_bit(EVENT_DATA_ERROR,
20452045
&host->pending_events)) {
2046-
dw_mci_stop_dma(host);
20472046
if (!(host->data_status & (SDMMC_INT_DRTO |
20482047
SDMMC_INT_EBE)))
20492048
send_stop_abort(host, data);
2049+
dw_mci_stop_dma(host);
20502050
state = STATE_DATA_ERROR;
20512051
break;
20522052
}
@@ -2079,10 +2079,10 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
20792079
*/
20802080
if (test_and_clear_bit(EVENT_DATA_ERROR,
20812081
&host->pending_events)) {
2082-
dw_mci_stop_dma(host);
20832082
if (!(host->data_status & (SDMMC_INT_DRTO |
20842083
SDMMC_INT_EBE)))
20852084
send_stop_abort(host, data);
2085+
dw_mci_stop_dma(host);
20862086
state = STATE_DATA_ERROR;
20872087
break;
20882088
}

drivers/mmc/host/mmci_stm32_sdmmc.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,9 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
479479
u32 status;
480480
int ret = 0;
481481

482-
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
483-
spin_lock_irqsave(&host->lock, flags);
482+
spin_lock_irqsave(&host->lock, flags);
483+
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 &&
484+
host->pwr_reg & MCI_STM32_VSWITCHEN) {
484485
mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH);
485486
spin_unlock_irqrestore(&host->lock, flags);
486487

@@ -492,9 +493,11 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
492493

493494
writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC,
494495
host->base + MMCICLEAR);
496+
spin_lock_irqsave(&host->lock, flags);
495497
mmci_write_pwrreg(host, host->pwr_reg &
496498
~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH));
497499
}
500+
spin_unlock_irqrestore(&host->lock, flags);
498501

499502
return ret;
500503
}

drivers/mmc/host/sdhci-iproc.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
173173
return pltfm_host->clock;
174174
}
175175

176+
/*
177+
* There is a known bug on BCM2711's SDHCI core integration where the
178+
* controller will hang when the difference between the core clock and the bus
179+
* clock is too great. Specifically this can be reproduced under the following
180+
* conditions:
181+
*
182+
* - No SD card plugged in, polling thread is running, probing cards at
183+
* 100 kHz.
184+
* - BCM2711's core clock configured at 500MHz or more
185+
*
186+
* So we set 200kHz as the minimum clock frequency available for that SoC.
187+
*/
188+
static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
189+
{
190+
return 200000;
191+
}
192+
176193
static const struct sdhci_ops sdhci_iproc_ops = {
177194
.set_clock = sdhci_set_clock,
178195
.get_max_clock = sdhci_iproc_get_max_clock,
@@ -271,13 +288,15 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
271288
.set_clock = sdhci_set_clock,
272289
.set_power = sdhci_set_power_and_bus_voltage,
273290
.get_max_clock = sdhci_iproc_get_max_clock,
291+
.get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
274292
.set_bus_width = sdhci_set_bus_width,
275293
.reset = sdhci_reset,
276294
.set_uhs_signaling = sdhci_set_uhs_signaling,
277295
};
278296

279297
static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
280-
.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
298+
.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
299+
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
281300
.ops = &sdhci_iproc_bcm2711_ops,
282301
};
283302

drivers/mmc/host/sdhci-msm.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,23 @@ static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
20892089
sdhci_cqe_disable(mmc, recovery);
20902090
}
20912091

2092+
static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
2093+
{
2094+
u32 count, start = 15;
2095+
2096+
__sdhci_set_timeout(host, cmd);
2097+
count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL);
2098+
/*
2099+
* Update software timeout value if its value is less than hardware data
2100+
* timeout value. Qcom SoC hardware data timeout value was calculated
2101+
* using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock.
2102+
*/
2103+
if (cmd && cmd->data && host->clock > 400000 &&
2104+
host->clock <= 50000000 &&
2105+
((1 << (count + start)) > (10 * host->clock)))
2106+
host->data_timeout = 22LL * NSEC_PER_SEC;
2107+
}
2108+
20922109
static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
20932110
.enable = sdhci_msm_cqe_enable,
20942111
.disable = sdhci_msm_cqe_disable,
@@ -2438,6 +2455,7 @@ static const struct sdhci_ops sdhci_msm_ops = {
24382455
.irq = sdhci_msm_cqe_irq,
24392456
.dump_vendor_regs = sdhci_msm_dump_vendor_regs,
24402457
.set_power = sdhci_set_power_noreg,
2458+
.set_timeout = sdhci_msm_set_timeout,
24412459
};
24422460

24432461
static const struct sdhci_pltfm_data sdhci_msm_pdata = {

0 commit comments

Comments
 (0)