Loading drivers/mmc/host/sdhci-msm.c +59 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,11 @@ enum sdc_mpm_pin_state { #define CORE_HC_SELECT_IN_HS400 (6 << 19) #define CORE_HC_SELECT_IN_MASK (7 << 19) #define CORE_VENDOR_SPEC_FUNC2 0x110 #define HC_SW_RST_WAIT_IDLE_DIS (1 << 20) #define HC_SW_RST_REQ (1 << 21) #define CORE_ONE_MID_EN (1 << 25) #define CORE_VENDOR_SPEC_CAPABILITIES0 0x11C #define CORE_8_BIT_SUPPORT (1 << 18) #define CORE_3_3V_SUPPORT (1 << 24) Loading Loading @@ -3018,6 +3023,48 @@ void sdhci_msm_dump_vendor_regs(struct sdhci_host *host) CORE_TESTBUS_CONFIG); } void sdhci_msm_reset_workaround(struct sdhci_host *host, u32 enable) { u32 vendor_func2; unsigned long timeout; vendor_func2 = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); if (enable) { writel_relaxed(vendor_func2 | HC_SW_RST_REQ, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); timeout = 10000; while (readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2) & HC_SW_RST_REQ) { if (timeout == 0) { pr_info("%s: Applying wait idle disable workaround\n", mmc_hostname(host->mmc)); /* * Apply the reset workaround to not wait for * pending data transfers on AXI before * resetting the controller. This could be * risky if the transfers were stuck on the * AXI bus. */ vendor_func2 = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); writel_relaxed(vendor_func2 | HC_SW_RST_WAIT_IDLE_DIS, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); host->reset_wa_t = ktime_get(); return; } timeout--; udelay(10); } pr_info("%s: waiting for SW_RST_REQ is successful\n", mmc_hostname(host->mmc)); } else { writel_relaxed(vendor_func2 & ~HC_SW_RST_WAIT_IDLE_DIS, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); } } static struct sdhci_ops sdhci_msm_ops = { .set_uhs_signaling = sdhci_msm_set_uhs_signaling, .check_power_status = sdhci_msm_check_power_status, Loading @@ -3031,6 +3078,7 @@ static struct sdhci_ops sdhci_msm_ops = { .dump_vendor_regs = sdhci_msm_dump_vendor_regs, .config_auto_tuning_cmd = sdhci_msm_config_auto_tuning_cmd, .enable_controller_clock = sdhci_msm_enable_controller_clock, .reset_workaround = sdhci_msm_reset_workaround, }; static int sdhci_msm_cfg_mpm_pin_wakeup(struct sdhci_host *host, unsigned mode) Loading Loading @@ -3071,6 +3119,7 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host, u32 version, caps = 0; u16 minor; u8 major; u32 val; version = readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION); major = (version & CORE_VERSION_MAJOR_MASK) >> Loading Loading @@ -3101,6 +3150,16 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host, CORE_VENDOR_SPEC_CAPABILITIES0); } /* * Enable one MID mode for SDCC5 (major 1) on 8916/8939 (minor 0x2e) and * on 8992 (minor 0x3e) as a workaround to reset for data stuck issue. */ if (major == 1 && (minor == 0x2e || minor == 0x3e)) { host->quirks2 |= SDHCI_QUIRK2_USE_RESET_WORKAROUND; val = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); writel_relaxed((val | CORE_ONE_MID_EN), host->ioaddr + CORE_VENDOR_SPEC_FUNC2); } /* * SDCC 5 controller with major version 1, minor version 0x34 and later * with HS 400 mode support will use CM DLL instead of CDC LP 533 DLL. Loading Loading
drivers/mmc/host/sdhci-msm.c +59 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,11 @@ enum sdc_mpm_pin_state { #define CORE_HC_SELECT_IN_HS400 (6 << 19) #define CORE_HC_SELECT_IN_MASK (7 << 19) #define CORE_VENDOR_SPEC_FUNC2 0x110 #define HC_SW_RST_WAIT_IDLE_DIS (1 << 20) #define HC_SW_RST_REQ (1 << 21) #define CORE_ONE_MID_EN (1 << 25) #define CORE_VENDOR_SPEC_CAPABILITIES0 0x11C #define CORE_8_BIT_SUPPORT (1 << 18) #define CORE_3_3V_SUPPORT (1 << 24) Loading Loading @@ -3018,6 +3023,48 @@ void sdhci_msm_dump_vendor_regs(struct sdhci_host *host) CORE_TESTBUS_CONFIG); } void sdhci_msm_reset_workaround(struct sdhci_host *host, u32 enable) { u32 vendor_func2; unsigned long timeout; vendor_func2 = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); if (enable) { writel_relaxed(vendor_func2 | HC_SW_RST_REQ, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); timeout = 10000; while (readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2) & HC_SW_RST_REQ) { if (timeout == 0) { pr_info("%s: Applying wait idle disable workaround\n", mmc_hostname(host->mmc)); /* * Apply the reset workaround to not wait for * pending data transfers on AXI before * resetting the controller. This could be * risky if the transfers were stuck on the * AXI bus. */ vendor_func2 = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); writel_relaxed(vendor_func2 | HC_SW_RST_WAIT_IDLE_DIS, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); host->reset_wa_t = ktime_get(); return; } timeout--; udelay(10); } pr_info("%s: waiting for SW_RST_REQ is successful\n", mmc_hostname(host->mmc)); } else { writel_relaxed(vendor_func2 & ~HC_SW_RST_WAIT_IDLE_DIS, host->ioaddr + CORE_VENDOR_SPEC_FUNC2); } } static struct sdhci_ops sdhci_msm_ops = { .set_uhs_signaling = sdhci_msm_set_uhs_signaling, .check_power_status = sdhci_msm_check_power_status, Loading @@ -3031,6 +3078,7 @@ static struct sdhci_ops sdhci_msm_ops = { .dump_vendor_regs = sdhci_msm_dump_vendor_regs, .config_auto_tuning_cmd = sdhci_msm_config_auto_tuning_cmd, .enable_controller_clock = sdhci_msm_enable_controller_clock, .reset_workaround = sdhci_msm_reset_workaround, }; static int sdhci_msm_cfg_mpm_pin_wakeup(struct sdhci_host *host, unsigned mode) Loading Loading @@ -3071,6 +3119,7 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host, u32 version, caps = 0; u16 minor; u8 major; u32 val; version = readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION); major = (version & CORE_VERSION_MAJOR_MASK) >> Loading Loading @@ -3101,6 +3150,16 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host, CORE_VENDOR_SPEC_CAPABILITIES0); } /* * Enable one MID mode for SDCC5 (major 1) on 8916/8939 (minor 0x2e) and * on 8992 (minor 0x3e) as a workaround to reset for data stuck issue. */ if (major == 1 && (minor == 0x2e || minor == 0x3e)) { host->quirks2 |= SDHCI_QUIRK2_USE_RESET_WORKAROUND; val = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2); writel_relaxed((val | CORE_ONE_MID_EN), host->ioaddr + CORE_VENDOR_SPEC_FUNC2); } /* * SDCC 5 controller with major version 1, minor version 0x34 and later * with HS 400 mode support will use CM DLL instead of CDC LP 533 DLL. Loading