From c0a2074ac575fff2848c8ef804bdc8590466c36c Mon Sep 17 00:00:00 2001 From: Wenbin Mei Date: Wed, 18 Nov 2020 14:34:05 +0800 Subject: [PATCH 1/6] mmc: mediatek: Fix system suspend/resume support for CQHCI Before we got these errors on MT8192 platform: [ 59.153891] Restarting tasks ... [ 59.154540] done. [ 59.159175] PM: suspend exit [ 59.218724] mtk-msdc 11f60000.mmc: phase: [map:fffffffe] [maxlen:31] [final:16] [ 119.776083] mmc0: cqhci: timeout for tag 9 [ 119.780196] mmc0: cqhci: ============ CQHCI REGISTER DUMP =========== [ 119.786709] mmc0: cqhci: Caps: 0x100020b6 | Version: 0x00000510 [ 119.793225] mmc0: cqhci: Config: 0x00000101 | Control: 0x00000000 [ 119.799706] mmc0: cqhci: Int stat: 0x00000000 | Int enab: 0x00000000 [ 119.806177] mmc0: cqhci: Int sig: 0x00000000 | Int Coal: 0x00000000 [ 119.812670] mmc0: cqhci: TDL base: 0x00000000 | TDL up32: 0x00000000 [ 119.819149] mmc0: cqhci: Doorbell: 0x003ffc00 | TCN: 0x00000200 [ 119.825656] mmc0: cqhci: Dev queue: 0x00000000 | Dev Pend: 0x00000000 [ 119.832155] mmc0: cqhci: Task clr: 0x00000000 | SSC1: 0x00001000 [ 119.838627] mmc0: cqhci: SSC2: 0x00000000 | DCMD rsp: 0x00000000 [ 119.845174] mmc0: cqhci: RED mask: 0xfdf9a080 | TERRI: 0x0000891c [ 119.851654] mmc0: cqhci: Resp idx: 0x00000000 | Resp arg: 0x00000000 [ 119.865773] mmc0: cqhci: : =========================================== [ 119.872358] mmc0: running CQE recovery From these logs, we found TDL base was back to the default value. After suspend, the mmc host is powered off by HW, and bring CQE register to the default value, so we add system suspend/resume interface, then bring CQE to deactivated state before suspend, it will be enabled by CQE first request after resume. Signed-off-by: Wenbin Mei Link: https://lore.kernel.org/r/20201118063405.24906-1-wenbin.mei@mediatek.com Fixes: 88bd652b3c74 ("mmc: mediatek: command queue support") Cc: stable@vger.kernel.org [Ulf: Renamed functions] Signed-off-by: Ulf Hansson --- drivers/mmc/host/mtk-sd.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index a704745e5882..b40ec966288e 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -2681,11 +2681,29 @@ static int msdc_runtime_resume(struct device *dev) msdc_restore_reg(host); return 0; } + +static int msdc_suspend(struct device *dev) +{ + struct mmc_host *mmc = dev_get_drvdata(dev); + int ret; + + if (mmc->caps2 & MMC_CAP2_CQE) { + ret = cqhci_suspend(mmc); + if (ret) + return ret; + } + + return pm_runtime_force_suspend(dev); +} + +static int msdc_resume(struct device *dev) +{ + return pm_runtime_force_resume(dev); +} #endif static const struct dev_pm_ops msdc_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume) SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL) }; From 903a72eca4abf241293dcc1385896fd428e15fe9 Mon Sep 17 00:00:00 2001 From: yong mao Date: Thu, 19 Nov 2020 11:02:37 +0800 Subject: [PATCH 2/6] mmc: mediatek: Extend recheck_sdio_irq fix to more variants The SDIO recheck fix is required for more of the supported variants. Let's add it to those that needs it. Reported-by: Fabien Parent Reported-by: Mattijs Korpershoek Signed-off-by: Yong Mao Link: https://lore.kernel.org/r/20201119030237.9414-1-yong.mao@mediatek.com Fixes: 9e2582e57407 ("mmc: mediatek: fix SDIO irq issue") Cc: stable@vger.kernel.org [Ulf: Clarified commitmsg ] Signed-off-by: Ulf Hansson --- drivers/mmc/host/mtk-sd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index b40ec966288e..7eb99255ae3d 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -446,7 +446,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt8135_compat = { .clk_div_bits = 8, - .recheck_sdio_irq = false, + .recheck_sdio_irq = true, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE, .async_fifo = false, @@ -485,7 +485,7 @@ static const struct mtk_mmc_compatible mt8183_compat = { static const struct mtk_mmc_compatible mt2701_compat = { .clk_div_bits = 12, - .recheck_sdio_irq = false, + .recheck_sdio_irq = true, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -511,7 +511,7 @@ static const struct mtk_mmc_compatible mt2712_compat = { static const struct mtk_mmc_compatible mt7622_compat = { .clk_div_bits = 12, - .recheck_sdio_irq = false, + .recheck_sdio_irq = true, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -524,7 +524,7 @@ static const struct mtk_mmc_compatible mt7622_compat = { static const struct mtk_mmc_compatible mt8516_compat = { .clk_div_bits = 12, - .recheck_sdio_irq = false, + .recheck_sdio_irq = true, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -535,7 +535,7 @@ static const struct mtk_mmc_compatible mt8516_compat = { static const struct mtk_mmc_compatible mt7620_compat = { .clk_div_bits = 8, - .recheck_sdio_irq = false, + .recheck_sdio_irq = true, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE, .async_fifo = false, @@ -548,6 +548,7 @@ static const struct mtk_mmc_compatible mt7620_compat = { static const struct mtk_mmc_compatible mt6779_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, From a42a7ec9bb99a17869c3b9f3d365aaf2bdb1a554 Mon Sep 17 00:00:00 2001 From: Muhammad Husaini Zulkifli Date: Wed, 18 Nov 2020 20:01:20 +0800 Subject: [PATCH 3/6] mmc: sdhci-of-arasan: Fix clock registration error for Keem Bay SOC The commit 16ada730a759 ("mmc: sdhci-of-arasan: Modify clock operations handling") introduced support for platform specific clock operations. Around the same point in time the commit 36c6aadaae86 ("mmc: sdhci-of-arasan: Add support for Intel Keem Bay") was also merged. Unfortunate it was not really tested on top of the previously mentioned commit, which causes clock registration failures for Keem Bay SOC devices. Let's fix this, by properly declaring the clock operation for Keem Bay SOC devices. Fixes: 36c6aadaae86 ("mmc: sdhci-of-arasan: Add support for Intel Keem Bay") Signed-off-by: Muhammad Husaini Zulkifli Reviewed-by: Adrian Hunter Link: https://lore.kernel.org/r/20201118120120.24908-2-muhammad.husaini.zulkifli@intel.com Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index d25a4b50c2f3..3b8d456e857d 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -1186,16 +1186,19 @@ static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { static struct sdhci_arasan_of_data intel_keembay_emmc_data = { .soc_ctl_map = &intel_keembay_soc_ctl_map, .pdata = &sdhci_keembay_emmc_pdata, + .clk_ops = &arasan_clk_ops, }; static struct sdhci_arasan_of_data intel_keembay_sd_data = { .soc_ctl_map = &intel_keembay_soc_ctl_map, .pdata = &sdhci_keembay_sd_pdata, + .clk_ops = &arasan_clk_ops, }; static struct sdhci_arasan_of_data intel_keembay_sdio_data = { .soc_ctl_map = &intel_keembay_soc_ctl_map, .pdata = &sdhci_keembay_sdio_pdata, + .clk_ops = &arasan_clk_ops, }; static const struct of_device_id sdhci_arasan_of_match[] = { From 32a9e0c445fa5abfd8730461c3ae0be1860bc6b2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 25 Nov 2020 21:49:53 +0100 Subject: [PATCH 4/6] mmc: tmio: improve bringing HW to a sane state with MMC_POWER_OFF Further testing of error cases revealed that downgrade is not enough, so we need to reset the SCC which is done by calling the custom reset function. This reset function can distinguish between the various SDHI variants, so protecting the call with MIN_RCAR2 is enough here. Fixes: 24ce2d7b8bea ("mmc: tmio: bring tuning HW to a sane state with MMC_POWER_OFF") Reported-by: Yoshihiro Shimoda Signed-off-by: Wolfram Sang Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20201125204953.3344-1-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/tmio_mmc_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index cb4149fd12e0..ac4e7874a3f1 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -927,9 +927,9 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) switch (ios->power_mode) { case MMC_POWER_OFF: tmio_mmc_power_off(host); - /* Downgrade ensures a sane state for tuning HW (e.g. SCC) */ - if (host->mmc->ops->hs400_downgrade) - host->mmc->ops->hs400_downgrade(host->mmc); + /* For R-Car Gen2+, we need to reset SDHI specific SCC */ + if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) + host->reset(host); host->set_clock(host, 0); break; case MMC_POWER_UP: From 6246d7c9d15aaff0bc3863f67900c6a6e6be921b Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 2 Dec 2020 21:23:20 +0100 Subject: [PATCH 5/6] mmc: block: Fixup condition for CMD13 polling for RPMB requests The CMD13 polling is needed for commands with R1B responses. In commit a0d4c7eb71dd ("mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response"), the intent was to introduce this for requests targeted to the RPMB partition. However, the condition to trigger the polling loop became wrong, leading to unnecessary polling. Let's fix the condition to avoid this. Fixes: a0d4c7eb71dd ("mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response") Cc: stable@vger.kernel.org Reported-by: Zhan Liu Signed-off-by: Zhan Liu Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20201202202320.22165-1-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 8d3df0be0355..42e27a298218 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -580,7 +580,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B)) { + if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { /* * Ensure RPMB/R1B command has completed by polling CMD13 * "Send Status". From c0d638a03bc5dfdb08fb95d0a79ecada25f40da8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 3 Dec 2020 23:29:16 +0100 Subject: [PATCH 6/6] mmc: mediatek: mark PM functions as __maybe_unused The #ifdef check for the suspend/resume functions is wrong: drivers/mmc/host/mtk-sd.c:2765:12: error: unused function 'msdc_suspend' [-Werror,-Wunused-function] static int msdc_suspend(struct device *dev) drivers/mmc/host/mtk-sd.c:2779:12: error: unused function 'msdc_resume' [-Werror,-Wunused-function] static int msdc_resume(struct device *dev) Remove the #ifdef and mark all four as __maybe_unused to aovid the problem. Fixes: c0a2074ac575 ("mmc: mediatek: Fix system suspend/resume support for CQHCI") Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20201203222922.1067522-1-arnd@kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/mtk-sd.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 7eb99255ae3d..004fbfc23672 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -2604,7 +2604,6 @@ static int msdc_drv_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static void msdc_save_reg(struct msdc_host *host) { u32 tune_reg = host->dev_comp->pad_tune_reg; @@ -2663,7 +2662,7 @@ static void msdc_restore_reg(struct msdc_host *host) __msdc_enable_sdio_irq(host, 1); } -static int msdc_runtime_suspend(struct device *dev) +static int __maybe_unused msdc_runtime_suspend(struct device *dev) { struct mmc_host *mmc = dev_get_drvdata(dev); struct msdc_host *host = mmc_priv(mmc); @@ -2673,7 +2672,7 @@ static int msdc_runtime_suspend(struct device *dev) return 0; } -static int msdc_runtime_resume(struct device *dev) +static int __maybe_unused msdc_runtime_resume(struct device *dev) { struct mmc_host *mmc = dev_get_drvdata(dev); struct msdc_host *host = mmc_priv(mmc); @@ -2683,7 +2682,7 @@ static int msdc_runtime_resume(struct device *dev) return 0; } -static int msdc_suspend(struct device *dev) +static int __maybe_unused msdc_suspend(struct device *dev) { struct mmc_host *mmc = dev_get_drvdata(dev); int ret; @@ -2697,11 +2696,10 @@ static int msdc_suspend(struct device *dev) return pm_runtime_force_suspend(dev); } -static int msdc_resume(struct device *dev) +static int __maybe_unused msdc_resume(struct device *dev) { return pm_runtime_force_resume(dev); } -#endif static const struct dev_pm_ops msdc_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)