mmc: enable DDR50 for CLV v2.0 host controller
authorChuanxiao Dong <chuanxiao.dong@intel.com>
Thu, 8 Mar 2012 03:43:45 +0000 (11:43 +0800)
committerbuildbot <buildbot@intel.com>
Mon, 19 Mar 2012 15:01:27 +0000 (08:01 -0700)
BZ: 27376

Clovertrail+ platform has a v2.0 host controller which can support
DDR50 mode. Since silicon still have bugs on this feature, driver
also has to add a bit workaround.

Change-Id: I1c399d0a014b61ffeca4bc30bcac4c5aa178984d
Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
Reviewed-on: http://android.intel.com:8080/38965
Reviewed-by: Tang, Richard <richard.tang@intel.com>
Tested-by: Sun, Jianhua <jianhua.sun@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/mmc/core/debugfs.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
include/linux/mmc/sdhci.h

index 81fc6ac..b60305d 100644 (file)
@@ -114,6 +114,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
        case MMC_TIMING_SD_HS:
                str = "sd high-speed";
                break;
+       case MMC_TIMING_UHS_DDR50:
+               str = "UHS DDR50";
+               break;
        default:
                str = "invalid";
                break;
index ee179e2..5e99c5f 100644 (file)
@@ -343,11 +343,18 @@ static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
                gpio = mfd_emmc0_rst_gpio;
                name = "eMMC0_reset";
                sdhci_alloc_panic_host(slot->host);
+               slot->host->quirks2 |= SDHCI_QUIRK2_V2_0_SUPPORT_DDR50;
+               slot->host->mmc->caps |= MMC_CAP_1_8V_DDR;
                break;
-       case PCI_DEVICE_ID_INTEL_MFD_EMMC1:
        case PCI_DEVICE_ID_INTEL_CLV_EMMC1:
                gpio = mfd_emmc1_rst_gpio;
                name = "eMMC1_reset";
+               slot->host->quirks2 |= SDHCI_QUIRK2_V2_0_SUPPORT_DDR50;
+               slot->host->mmc->caps |= MMC_CAP_1_8V_DDR;
+               break;
+       case PCI_DEVICE_ID_INTEL_MFD_EMMC1:
+               gpio = mfd_emmc1_rst_gpio;
+               name = "eMMC1_reset";
                break;
        }
 
index 4f81d99..6969322 100644 (file)
@@ -1590,7 +1590,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
        else
                ctrl &= ~SDHCI_CTRL_HISPD;
 
-       if (host->version >= SDHCI_SPEC_300) {
+       if ((host->version >= SDHCI_SPEC_300) ||
+                       (host->quirks2 & SDHCI_QUIRK2_V2_0_SUPPORT_DDR50)) {
                u16 clk, ctrl_2;
                unsigned int clock;
 
@@ -3662,7 +3663,8 @@ int sdhci_add_host(struct sdhci_host *host)
        else if (caps[1] & SDHCI_SUPPORT_SDR50)
                mmc->caps |= MMC_CAP_UHS_SDR50;
 
-       if (caps[1] & SDHCI_SUPPORT_DDR50)
+       if ((caps[1] & SDHCI_SUPPORT_DDR50) ||
+                       (host->quirks2 & SDHCI_QUIRK2_V2_0_SUPPORT_DDR50))
                mmc->caps |= MMC_CAP_UHS_DDR50;
 
        /* Does the host needs tuning for SDR50? */
index 7b21c2b..5ae63cd 100644 (file)
@@ -93,6 +93,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_OWN_CARD_DETECTION                        (1<<0)
 /* Host controller cannot keep power control value after power off */
 #define SDHCI_QUIRK_CANNOT_KEEP_POWERCTL               (1<<1)
+/* V2.0 host controller support DDR50 */
+#define SDHCI_QUIRK2_V2_0_SUPPORT_DDR50                        (1<<2)
 
 
        int irq;                /* Device IRQ */