From 6e5cc9ee3e9cdbbd5e5bc429d57f86c52da8a0b2 Mon Sep 17 00:00:00 2001 From: Ram Prakash Gupta Date: Wed, 7 Oct 2020 13:18:42 +0530 Subject: [PATCH 1/2] mmc: sdhci-msm: Restore cmdq vendor cfg register During cqe initialization, upon enabling cqe enable bit, command queue engine gets reset. During hw reset this is leading to SMMU fault as during reset tdl base register contents are getting lost. Restore cmdq vendor cfg register data post hw reset to disable cqe reset post cqe initialization. Change-Id: I8ffa2c2fa6754b697c4d441004efa4dc366bbf5f Signed-off-by: Ram Prakash Gupta --- drivers/mmc/host/sdhci-msm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 97d30e6f0759..0f1b91162a50 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -307,6 +307,10 @@ struct sdhci_msm_dll_hsr { u32 ddr_config; }; +struct cqe_regs_restore { + u32 cqe_vendor_cfg1; +}; + struct sdhci_msm_regs_restore { bool is_supported; bool is_valid; @@ -442,6 +446,7 @@ struct sdhci_msm_host { bool use_7nm_dll; struct sdhci_msm_dll_hsr *dll_hsr; struct sdhci_msm_regs_restore regs_restore; + struct cqe_regs_restore cqe_regs; u32 *sup_ice_clk_table; unsigned char sup_ice_clk_cnt; u32 ice_clk_max; @@ -2452,6 +2457,7 @@ static void sdhci_msm_registers_save(struct sdhci_host *host) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); const struct sdhci_msm_offset *msm_offset = msm_host->offset; + struct cqhci_host *cq_host = host->mmc->cqe_private; if (!msm_host->regs_restore.is_supported && !msm_host->reg_store) @@ -2500,6 +2506,9 @@ static void sdhci_msm_registers_save(struct sdhci_host *host) msm_offset->core_dll_config_3); msm_host->regs_restore.dll_usr_ctl = readl_relaxed(host->ioaddr + msm_offset->core_dll_usr_ctl); + if (cq_host) + msm_host->cqe_regs.cqe_vendor_cfg1 = + cqhci_readl(cq_host, CQHCI_VENDOR_CFG1); msm_host->regs_restore.is_valid = true; @@ -2516,6 +2525,7 @@ static void sdhci_msm_registers_restore(struct sdhci_host *host) const struct sdhci_msm_offset *msm_offset = msm_host->offset; u32 irq_status; struct mmc_ios ios = host->mmc->ios; + struct cqhci_host *cq_host = host->mmc->cqe_private; if ((!msm_host->regs_restore.is_supported || !msm_host->regs_restore.is_valid) && @@ -2569,6 +2579,10 @@ static void sdhci_msm_registers_restore(struct sdhci_host *host) writel_relaxed(msm_host->regs_restore.vendor_pwrctl_mask, host->ioaddr + msm_offset->core_pwrctl_mask); + if (cq_host) + cqhci_writel(cq_host, msm_host->cqe_regs.cqe_vendor_cfg1, + CQHCI_VENDOR_CFG1); + if (((ios.timing == MMC_TIMING_MMC_HS400) || (ios.timing == MMC_TIMING_MMC_HS200) || (ios.timing == MMC_TIMING_UHS_SDR104)) From 2589a250bde0feb7ba6d1533990d1a29721d02ee Mon Sep 17 00:00:00 2001 From: Ram Prakash Gupta Date: Wed, 22 Jan 2020 19:00:40 +0530 Subject: [PATCH 2/2] mmc: core: Set reset done after hw reset Set hw reset flag as done after sdcc hw reset else hw reset as part of recovery happens only once. md->reset_done flag is set inside mmc_blk_reset function with flag MMC_BLK_CQE_RECOVERY. And this flag is cleared only inside function mmc_blk_reset_success. But since mmc_blk_reset and mmc_blk_reset_success are used with if else condition, code flow can execute only one of the function, hence if mmc_blk_reset is executed and not cleared within mmc_blk_reset_success, next mmc_blk_reset call returns without resetting the hw. Change-Id: I14915ae26240769b45cec8d2793e5f8604062eef Signed-off-by: Ram Prakash Gupta --- drivers/mmc/core/block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 20e3632af5ce..d66d005d08fc 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1483,8 +1483,7 @@ void mmc_blk_cqe_recovery(struct mmc_queue *mq) err = mmc_cqe_recovery(host); if (err) mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY); - else - mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); + mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); pr_debug("%s: CQE recovery done\n", mmc_hostname(host)); }