forked from Minki/linux
MMC host:
- 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 -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmEfq70XHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCmnpw/5AcGohl2QCQsPaFootvgXGqlG cBPw9Ag5sK8GCD+hdEJ9Yj+LPCiLESJsk6+4SeMFFwWfBgDv9z6j8dSfZtAYp06/ lRyT2eI4zIOXWVxTkr7KUdacjF9EySbrTug6m7VN4yNb1dxL6Xsl/frTqk8FmqW7 T7HI67fJM795reqw0PEiWeSL+2191aOLFUp17spYsCdMrsc77cgrrH1AaWyVFFr6 P7C/ZvHHsF3MI3yNPfz4QLwHnGffCCLxTQdeJ+EmMsKGIoQTga1aAl4t3nwb+ZIR b8zRIReGdXXq5bw6BwDzKaTMyyvLN0B85EtfwyVsDsw76evp8QEC6ZMIKvQCB260 jj4fqCpfgkCBLnD2LnkL2vZZ3MQAJ1v3RRlWwChm/FBYVmsVrKjK71ZlMiEt2H9m KZJnQ8t+OoooFjAEb6u+1q8inPtsLjFY9433FWYg1pfiD9STHQ28FTUD7JtYPhvy alxQCqykQChWpMHfhiUzWM2LJSxt/ts5yrvdlrRuIb6uwBrT2841e/2SG+0YCraN Hg3tOs2z/O4EdDYMXH3blJFSi4emzGeDnuLyRFOxI/akvnpucEdpnFvmaSsG5rk5 x6FLljAFiKUM755I14dLsLq1rzqs/E956Fl1g3BNmEsBfZFed6PKLBNRG6shIbAY N6L/4D7VaAeZvek2/Og= =Y+uG -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a27c75e554
@ -2018,8 +2018,8 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
|
||||
continue;
|
||||
}
|
||||
|
||||
dw_mci_stop_dma(host);
|
||||
send_stop_abort(host, data);
|
||||
dw_mci_stop_dma(host);
|
||||
state = STATE_SENDING_STOP;
|
||||
break;
|
||||
}
|
||||
@ -2043,10 +2043,10 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
|
||||
*/
|
||||
if (test_and_clear_bit(EVENT_DATA_ERROR,
|
||||
&host->pending_events)) {
|
||||
dw_mci_stop_dma(host);
|
||||
if (!(host->data_status & (SDMMC_INT_DRTO |
|
||||
SDMMC_INT_EBE)))
|
||||
send_stop_abort(host, data);
|
||||
dw_mci_stop_dma(host);
|
||||
state = STATE_DATA_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -2079,10 +2079,10 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t)
|
||||
*/
|
||||
if (test_and_clear_bit(EVENT_DATA_ERROR,
|
||||
&host->pending_events)) {
|
||||
dw_mci_stop_dma(host);
|
||||
if (!(host->data_status & (SDMMC_INT_DRTO |
|
||||
SDMMC_INT_EBE)))
|
||||
send_stop_abort(host, data);
|
||||
dw_mci_stop_dma(host);
|
||||
state = STATE_DATA_ERROR;
|
||||
break;
|
||||
}
|
||||
|
@ -479,8 +479,9 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
|
||||
u32 status;
|
||||
int ret = 0;
|
||||
|
||||
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 &&
|
||||
host->pwr_reg & MCI_STM32_VSWITCHEN) {
|
||||
mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH);
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
@ -492,9 +493,11 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
|
||||
|
||||
writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC,
|
||||
host->base + MMCICLEAR);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
mmci_write_pwrreg(host, host->pwr_reg &
|
||||
~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH));
|
||||
}
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
|
||||
return pltfm_host->clock;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is a known bug on BCM2711's SDHCI core integration where the
|
||||
* controller will hang when the difference between the core clock and the bus
|
||||
* clock is too great. Specifically this can be reproduced under the following
|
||||
* conditions:
|
||||
*
|
||||
* - No SD card plugged in, polling thread is running, probing cards at
|
||||
* 100 kHz.
|
||||
* - BCM2711's core clock configured at 500MHz or more
|
||||
*
|
||||
* So we set 200kHz as the minimum clock frequency available for that SoC.
|
||||
*/
|
||||
static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
|
||||
{
|
||||
return 200000;
|
||||
}
|
||||
|
||||
static const struct sdhci_ops sdhci_iproc_ops = {
|
||||
.set_clock = sdhci_set_clock,
|
||||
.get_max_clock = sdhci_iproc_get_max_clock,
|
||||
@ -271,13 +288,15 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
|
||||
.set_clock = sdhci_set_clock,
|
||||
.set_power = sdhci_set_power_and_bus_voltage,
|
||||
.get_max_clock = sdhci_iproc_get_max_clock,
|
||||
.get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
|
||||
.set_bus_width = sdhci_set_bus_width,
|
||||
.reset = sdhci_reset,
|
||||
.set_uhs_signaling = sdhci_set_uhs_signaling,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
|
||||
.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
|
||||
.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
|
||||
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
|
||||
.ops = &sdhci_iproc_bcm2711_ops,
|
||||
};
|
||||
|
||||
|
@ -2089,6 +2089,23 @@ static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
|
||||
sdhci_cqe_disable(mmc, recovery);
|
||||
}
|
||||
|
||||
static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
|
||||
{
|
||||
u32 count, start = 15;
|
||||
|
||||
__sdhci_set_timeout(host, cmd);
|
||||
count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL);
|
||||
/*
|
||||
* Update software timeout value if its value is less than hardware data
|
||||
* timeout value. Qcom SoC hardware data timeout value was calculated
|
||||
* using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock.
|
||||
*/
|
||||
if (cmd && cmd->data && host->clock > 400000 &&
|
||||
host->clock <= 50000000 &&
|
||||
((1 << (count + start)) > (10 * host->clock)))
|
||||
host->data_timeout = 22LL * NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
|
||||
.enable = sdhci_msm_cqe_enable,
|
||||
.disable = sdhci_msm_cqe_disable,
|
||||
@ -2438,6 +2455,7 @@ static const struct sdhci_ops sdhci_msm_ops = {
|
||||
.irq = sdhci_msm_cqe_irq,
|
||||
.dump_vendor_regs = sdhci_msm_dump_vendor_regs,
|
||||
.set_power = sdhci_set_power_noreg,
|
||||
.set_timeout = sdhci_msm_set_timeout,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data sdhci_msm_pdata = {
|
||||
|
Loading…
Reference in New Issue
Block a user