summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRitesh Harjani <riteshh@codeaurora.org>2015-07-15 13:32:07 +0530
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:27:01 -0700
commit982df7cff45688d1a2415122bbfa310f3ded4412 (patch)
tree37343e621d09cb319980065851caacaceb5fa052
parent2be603cfa5f22f91a9ee4dcc41e47a33b9a9f26f (diff)
mmc: sdhci-msm: Configure CMDEN_HS400_INPUT_MASK_CNT for cmdq
When sending CMD during data in HS400 Enhanced Strobe mode, the command that is being sent is also sampled internally on CMDIN line by the RCLK that is toggling due to the data traffic. To mask this <false> CMDIN a new mask is introduced throughout the CMD transmission time. This mask is controlled by HC_VENDOR_SPECIFIC_FUNC3.CMDEN_HS400_INPUT_MASK_CNT register. The default reset value of this register is 2. Before running CMDQ transfers in HS400 Enhanced Strobe mode, SW should write 3 to HC_VENDOR_SPECIFIC_FUNC3.CMDEN_HS400_INPUT_MASK_CNT register. Change-Id: If0467855e23cb93e57a4581b375885136902835d Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
-rw-r--r--drivers/mmc/host/sdhci-msm.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 326e1512ec1c..ffc2d5b11326 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -157,6 +157,7 @@
#define CORE_VENDOR_SPEC3 0x1B0
#define CORE_PWRSAVE_DLL (1 << 3)
+#define CORE_CMDEN_HS400_INPUT_MASK_CNT (1 << 13)
#define CORE_DLL_CONFIG_2 0x1B4
#define CORE_DDR_CAL_EN (1 << 0)
@@ -2795,6 +2796,35 @@ void sdhci_msm_reset(struct sdhci_host *host, u8 mask)
sdhci_reset(host, mask);
}
+/*
+ * sdhci_msm_enhanced_strobe_mask :-
+ * Before running CMDQ transfers in HS400 Enhanced Strobe mode,
+ * SW should write 3 to
+ * HC_VENDOR_SPECIFIC_FUNC3.CMDEN_HS400_INPUT_MASK_CNT register.
+ * The default reset value of this register is 2.
+ */
+static void sdhci_msm_enhanced_strobe_mask(struct sdhci_host *host, bool set)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+
+ if (!msm_host->enhanced_strobe) {
+ pr_debug("%s: host does not support hs400 enhanced strobe\n",
+ mmc_hostname(host->mmc));
+ return;
+ }
+
+ if (set) {
+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC3)
+ | CORE_CMDEN_HS400_INPUT_MASK_CNT),
+ host->ioaddr + CORE_VENDOR_SPEC3);
+ } else {
+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC3)
+ & ~CORE_CMDEN_HS400_INPUT_MASK_CNT),
+ host->ioaddr + CORE_VENDOR_SPEC3);
+ }
+}
+
static void sdhci_msm_clear_set_dumpregs(struct sdhci_host *host, bool set)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -2829,6 +2859,7 @@ static struct sdhci_ops sdhci_msm_ops = {
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_msm_reset,
.clear_set_dumpregs = sdhci_msm_clear_set_dumpregs,
+ .enhanced_strobe_mask = sdhci_msm_enhanced_strobe_mask,
};
static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,