Loading drivers/mmc/host/sdhci-msm.c +53 −7 Original line number Diff line number Diff line Loading @@ -2387,6 +2387,9 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev, pdata->largeaddressbus = of_property_read_bool(np, "qcom,large-address-bus"); msm_host->vbias_skip_wa = of_property_read_bool(np, "qcom,vbias-skip-wa"); sdhci_msm_pm_qos_parse(dev, pdata); if (of_get_property(np, "qcom,core_3_0v_support", NULL)) Loading Loading @@ -3130,6 +3133,45 @@ static int sdhci_msm_clear_pwrctl_status(struct sdhci_host *host, u8 value) return ret; } static void sdhci_msm_vbias_bypass_wa(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = pltfm_host->priv; const struct sdhci_msm_offset *msm_host_offset = msm_host->offset; struct mmc_host *mmc = host->mmc; u32 config; int card_detect = 0; if (mmc->ops->get_cd) card_detect = mmc->ops->get_cd(mmc); config = readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); /* * Following cases are covered. * 1. Card Probe * 2. Card suspend * 3. Card Resume * 4. Card remove */ if ((mmc->card == NULL) && card_detect && (mmc->ios.power_mode == MMC_POWER_UP)) config &= ~CORE_IO_PAD_PWR_SWITCH; else if (mmc->card && card_detect && (mmc->ios.power_mode == MMC_POWER_OFF)) config |= CORE_IO_PAD_PWR_SWITCH; else if (mmc->card && card_detect && (mmc->ios.power_mode == MMC_POWER_UP)) config &= ~CORE_IO_PAD_PWR_SWITCH; else if (mmc->card == NULL && !card_detect && (mmc->ios.power_mode == MMC_POWER_OFF)) config |= CORE_IO_PAD_PWR_SWITCH; writel_relaxed(config, host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); } static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) { struct sdhci_host *host = (struct sdhci_host *)data; Loading Loading @@ -3218,17 +3260,21 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) mb(); if ((io_level & REQ_IO_HIGH) && (msm_host->caps_0 & CORE_3_0V_SUPPORT) && !msm_host->core_3_0v_support) !msm_host->core_3_0v_support) { if (msm_host->vbias_skip_wa) sdhci_msm_vbias_bypass_wa(host); else writel_relaxed((readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC) & ~CORE_IO_PAD_PWR_SWITCH), host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); else if ((io_level & REQ_IO_LOW) || (msm_host->caps_0 & CORE_1_8V_SUPPORT)) } else if ((io_level & REQ_IO_LOW) || (msm_host->caps_0 & CORE_1_8V_SUPPORT)) { writel_relaxed((readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC) | CORE_IO_PAD_PWR_SWITCH), host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); } /* * SDHC has core_mem and hc_mem device memory and these memory * addresses do not fall within 1KB region. Hence, any update to Loading drivers/mmc/host/sdhci-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ struct sdhci_msm_host { u32 ice_clk_rate; bool debug_mode_enabled; bool reg_store; bool vbias_skip_wa; struct reset_control *core_reset; u32 minor; }; Loading Loading
drivers/mmc/host/sdhci-msm.c +53 −7 Original line number Diff line number Diff line Loading @@ -2387,6 +2387,9 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev, pdata->largeaddressbus = of_property_read_bool(np, "qcom,large-address-bus"); msm_host->vbias_skip_wa = of_property_read_bool(np, "qcom,vbias-skip-wa"); sdhci_msm_pm_qos_parse(dev, pdata); if (of_get_property(np, "qcom,core_3_0v_support", NULL)) Loading Loading @@ -3130,6 +3133,45 @@ static int sdhci_msm_clear_pwrctl_status(struct sdhci_host *host, u8 value) return ret; } static void sdhci_msm_vbias_bypass_wa(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = pltfm_host->priv; const struct sdhci_msm_offset *msm_host_offset = msm_host->offset; struct mmc_host *mmc = host->mmc; u32 config; int card_detect = 0; if (mmc->ops->get_cd) card_detect = mmc->ops->get_cd(mmc); config = readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); /* * Following cases are covered. * 1. Card Probe * 2. Card suspend * 3. Card Resume * 4. Card remove */ if ((mmc->card == NULL) && card_detect && (mmc->ios.power_mode == MMC_POWER_UP)) config &= ~CORE_IO_PAD_PWR_SWITCH; else if (mmc->card && card_detect && (mmc->ios.power_mode == MMC_POWER_OFF)) config |= CORE_IO_PAD_PWR_SWITCH; else if (mmc->card && card_detect && (mmc->ios.power_mode == MMC_POWER_UP)) config &= ~CORE_IO_PAD_PWR_SWITCH; else if (mmc->card == NULL && !card_detect && (mmc->ios.power_mode == MMC_POWER_OFF)) config |= CORE_IO_PAD_PWR_SWITCH; writel_relaxed(config, host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); } static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) { struct sdhci_host *host = (struct sdhci_host *)data; Loading Loading @@ -3218,17 +3260,21 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) mb(); if ((io_level & REQ_IO_HIGH) && (msm_host->caps_0 & CORE_3_0V_SUPPORT) && !msm_host->core_3_0v_support) !msm_host->core_3_0v_support) { if (msm_host->vbias_skip_wa) sdhci_msm_vbias_bypass_wa(host); else writel_relaxed((readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC) & ~CORE_IO_PAD_PWR_SWITCH), host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); else if ((io_level & REQ_IO_LOW) || (msm_host->caps_0 & CORE_1_8V_SUPPORT)) } else if ((io_level & REQ_IO_LOW) || (msm_host->caps_0 & CORE_1_8V_SUPPORT)) { writel_relaxed((readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC) | CORE_IO_PAD_PWR_SWITCH), host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC); } /* * SDHC has core_mem and hc_mem device memory and these memory * addresses do not fall within 1KB region. Hence, any update to Loading
drivers/mmc/host/sdhci-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ struct sdhci_msm_host { u32 ice_clk_rate; bool debug_mode_enabled; bool reg_store; bool vbias_skip_wa; struct reset_control *core_reset; u32 minor; }; Loading