Hi Ulf, On Thu, May 11, 2023 at 12:43 PM Ulf Hansson <ulf.hansson@xxxxxxxxxx> wrote: [...] > > Indeed, removing mmc_set_clock() from mmc_select_hs200() also makes my > > eMMC appear again on top of Linux 6.4-rc1. > > See the attached diff in case it's not fully clear which > > mmc_set_clock() call I removed. > > Thanks for the update! Removing that call restores mmc_select_hs200() > to the previous behaviour - so thanks for confirming that this is > working. > > However, to find the proper solution, I think we need to understand > why we are hanging in the meson-mx-sdhc driver first. Here's a couple > of follow up questions from me: > > 1) Before calling mmc_set_clock() what is the actual clock rate that > has been set by the meson driver? > > 2) Does the call to mmc_set_clock() return or hang? Can we verify that > the clock gets set correctly? I used the attached diff to answer these two questions. See the following log extract (full log is attached): meson-mx-sdhc c1108e00.mmc: Trying to set MMC clock to 400000Hz meson-mx-sdhc c1108e00.mmc: Actual MMC clock to 399812Hz mmc1: mmc_select_hs200 switching to clock from card->ext_csd.hs_max_dtr... meson-mx-sdhc c1108e00.mmc: Trying to set MMC clock to 52000000Hz meson-mx-sdhc c1108e00.mmc: Actual MMC clock to 51000000Hz mmc1: mmc_select_hs200 mmc_set_clock returned > 3) If 2) seems to work above, we need to figure out why > mmc_switch_status() is hanging. If there is a problem with the eMMC > card responding in-correctly, the host driver should return with an > error code, right? You're right: it's indeed hanging in mmc_switch_status() I don't get any interrupts (timeout, CRC error, ...) for it. Do you have any suggestions what to check next? Best regards, Martin
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 89cd48fcec79..ef2986ff4528 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1500,7 +1500,11 @@ static int mmc_select_hs200(struct mmc_card *card) old_timing = host->ios.timing; old_clock = host->ios.clock; mmc_set_timing(host, MMC_TIMING_MMC_HS200); + pr_err("%s: %s switching to clock from card->ext_csd.hs_max_dtr...\n", mmc_hostname(card->host), + __func__); mmc_set_clock(card->host, card->ext_csd.hs_max_dtr); + pr_err("%s: %s mmc_set_clock returned\n", mmc_hostname(card->host), + __func__); /* * For HS200, CRC errors are not a reliable way to know the @@ -1508,6 +1512,8 @@ static int mmc_select_hs200(struct mmc_card *card) * tuning will fail and the result ends up the same. */ err = mmc_switch_status(card, false); + pr_err("%s: %s status after mmc_set_clock: %d\n", mmc_hostname(card->host), + __func__, err); /* * mmc_select_timing() assumes timing has not changed if diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c index 8799f47edf23..104f0027594f 100644 --- a/drivers/mmc/host/meson-mx-sdhc-mmc.c +++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c @@ -272,6 +272,8 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) meson_mx_sdhc_disable_clks(mmc); + dev_err(mmc_dev(mmc), "Trying to set MMC clock to %uHz\n", ios->clock); + if (ios->clock) { ret = clk_set_rate(host->sd_clk, ios->clock); if (ret) { @@ -317,6 +319,8 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) mmc->actual_clock = 0; } + dev_err(mmc_dev(mmc), "Actual MMC clock to %uHz\n", mmc->actual_clock); + return 0; } @@ -562,6 +566,9 @@ static irqreturn_t meson_mx_sdhc_irq(int irq, void *data) if (!(ictl & ista)) return IRQ_NONE; + dev_err(mmc_dev(host->mmc), "CMD%d ISTA: 0x%08x, ICTL: 0x%08x\n", + cmd->opcode, ista, ictl); + if (ista & MESON_SDHC_ISTA_RXFIFO_FULL || ista & MESON_SDHC_ISTA_TXFIFO_EMPTY) cmd->error = -EIO;