Skip to content

Commit

Permalink
Merge tag 'mmc-v5.18-rc4' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/ulfh/mmc

Pull mmc fixes from Ulf Hansson:
 "MMC core:

   - Fix initialization for eMMC's HS200/HS400 mode

  MMC host:

   - sdhci-msm: Reset GCC_SDCC_BCR register to prevent timeout issues

   - sunxi-mmc: Fix DMA descriptors allocated above 32 bits"

* tag 'mmc-v5.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-msm: Reset GCC_SDCC_BCR register for SDHC
  mmc: sunxi-mmc: Fix DMA descriptors allocated above 32 bits
  mmc: core: Set HS clock speed before sending HS CMD13
  • Loading branch information
Linus Torvalds committed May 6, 2022
2 parents 5fa576d + 3e5a8e8 commit 6426792
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 6 deletions.
23 changes: 19 additions & 4 deletions drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1384,13 +1384,17 @@ static int mmc_select_hs400es(struct mmc_card *card)
goto out_err;
}

/*
* Bump to HS timing and frequency. Some cards don't handle
* SEND_STATUS reliably at the initial frequency.
*/
mmc_set_timing(host, MMC_TIMING_MMC_HS);
mmc_set_bus_speed(card);

err = mmc_switch_status(card, true);
if (err)
goto out_err;

mmc_set_clock(host, card->ext_csd.hs_max_dtr);

/* Switch card to DDR with strobe bit */
val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
Expand Down Expand Up @@ -1448,7 +1452,7 @@ static int mmc_select_hs400es(struct mmc_card *card)
static int mmc_select_hs200(struct mmc_card *card)
{
struct mmc_host *host = card->host;
unsigned int old_timing, old_signal_voltage;
unsigned int old_timing, old_signal_voltage, old_clock;
int err = -EINVAL;
u8 val;

Expand Down Expand Up @@ -1479,8 +1483,17 @@ static int mmc_select_hs200(struct mmc_card *card)
false, true, MMC_CMD_RETRIES);
if (err)
goto err;

/*
* Bump to HS timing and frequency. Some cards don't handle
* SEND_STATUS reliably at the initial frequency.
* NB: We can't move to full (HS200) speeds until after we've
* successfully switched over.
*/
old_timing = host->ios.timing;
old_clock = host->ios.clock;
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
mmc_set_clock(card->host, card->ext_csd.hs_max_dtr);

/*
* For HS200, CRC errors are not a reliable way to know the
Expand All @@ -1493,8 +1506,10 @@ static int mmc_select_hs200(struct mmc_card *card)
* mmc_select_timing() assumes timing has not changed if
* it is a switch error.
*/
if (err == -EBADMSG)
if (err == -EBADMSG) {
mmc_set_clock(host, old_clock);
mmc_set_timing(host, old_timing);
}
}
err:
if (err) {
Expand Down
42 changes: 42 additions & 0 deletions drivers/mmc/host/sdhci-msm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h>
#include <linux/interconnect.h>
#include <linux/pinctrl/consumer.h>
#include <linux/reset.h>

#include "sdhci-pltfm.h"
#include "cqhci.h"
Expand Down Expand Up @@ -2482,6 +2483,43 @@ static inline void sdhci_msm_get_of_property(struct platform_device *pdev,
of_property_read_u32(node, "qcom,dll-config", &msm_host->dll_config);
}

static int sdhci_msm_gcc_reset(struct device *dev, struct sdhci_host *host)
{
struct reset_control *reset;
int ret = 0;

reset = reset_control_get_optional_exclusive(dev, NULL);
if (IS_ERR(reset))
return dev_err_probe(dev, PTR_ERR(reset),
"unable to acquire core_reset\n");

if (!reset)
return ret;

ret = reset_control_assert(reset);
if (ret) {
reset_control_put(reset);
return dev_err_probe(dev, ret, "core_reset assert failed\n");
}

/*
* The hardware requirement for delay between assert/deassert
* is at least 3-4 sleep clock (32.7KHz) cycles, which comes to
* ~125us (4/32768). To be on the safe side add 200us delay.
*/
usleep_range(200, 210);

ret = reset_control_deassert(reset);
if (ret) {
reset_control_put(reset);
return dev_err_probe(dev, ret, "core_reset deassert failed\n");
}

usleep_range(200, 210);
reset_control_put(reset);

return ret;
}

static int sdhci_msm_probe(struct platform_device *pdev)
{
Expand Down Expand Up @@ -2529,6 +2567,10 @@ static int sdhci_msm_probe(struct platform_device *pdev)

msm_host->saved_tuning_phase = INVALID_TUNING_PHASE;

ret = sdhci_msm_gcc_reset(&pdev->dev, host);
if (ret)
goto pltfm_free;

/* Setup SDCC bus voter clock. */
msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus");
if (!IS_ERR(msm_host->bus_clk)) {
Expand Down
5 changes: 3 additions & 2 deletions drivers/mmc/host/sunxi-mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,9 @@ static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host,
pdes[i].buf_addr_ptr1 =
cpu_to_le32(sg_dma_address(&data->sg[i]) >>
host->cfg->idma_des_shift);
pdes[i].buf_addr_ptr2 = cpu_to_le32((u32)next_desc >>
host->cfg->idma_des_shift);
pdes[i].buf_addr_ptr2 =
cpu_to_le32(next_desc >>
host->cfg->idma_des_shift);
}

pdes[0].config |= cpu_to_le32(SDXC_IDMAC_DES0_FD);
Expand Down

0 comments on commit 6426792

Please sign in to comment.