arm/dt: msm8974: add support for SD/eMMC bus speed modes
SDC1 supports following bus speed modes:
- HS200 at 1.8V
- DDR at 1.8V
SDC2 supports following bus speed modes:
- SDR12, SDR25, SDR50, SDR104, DDR50
Change-Id: Id24b1211d1110ffb4873fff42af50f63a3ef04c0
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index ffe096f..a4af6c9 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -4718,9 +4718,9 @@
int i, ret;
struct mmc_platform_data *pdata;
struct device_node *np = dev->of_node;
- u32 bus_width = 0;
+ u32 bus_width = 0, current_limit = 0;
u32 *clk_table, *sup_voltages;
- int clk_table_len, sup_volt_len;
+ int clk_table_len, sup_volt_len, len;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
@@ -4818,6 +4818,50 @@
&pdata->vreg_data->vdd_io_data, "vdd-io"))
goto err;
+ len = of_property_count_strings(np, "qcom,sdcc-bus-speed-mode");
+
+ for (i = 0; i < len; i++) {
+ const char *name = NULL;
+
+ of_property_read_string_index(np,
+ "qcom,sdcc-bus-speed-mode", i, &name);
+ if (!name)
+ continue;
+
+ if (!strncmp(name, "SDR12", sizeof("SDR12")))
+ pdata->uhs_caps |= MMC_CAP_UHS_SDR12;
+ else if (!strncmp(name, "SDR25", sizeof("SDR25")))
+ pdata->uhs_caps |= MMC_CAP_UHS_SDR25;
+ else if (!strncmp(name, "SDR50", sizeof("SDR50")))
+ pdata->uhs_caps |= MMC_CAP_UHS_SDR50;
+ else if (!strncmp(name, "DDR50", sizeof("DDR50")))
+ pdata->uhs_caps |= MMC_CAP_UHS_DDR50;
+ else if (!strncmp(name, "SDR104", sizeof("SDR104")))
+ pdata->uhs_caps |= MMC_CAP_UHS_SDR104;
+ else if (!strncmp(name, "HS200_1p8v", sizeof("HS200_1p8v")))
+ pdata->uhs_caps2 |= MMC_CAP2_HS200_1_8V_SDR;
+ else if (!strncmp(name, "HS200_1p2v", sizeof("HS200_1p2v")))
+ pdata->uhs_caps2 |= MMC_CAP2_HS200_1_2V_SDR;
+ else if (!strncmp(name, "DDR_1p8v", sizeof("DDR_1p8v")))
+ pdata->uhs_caps |= MMC_CAP_1_8V_DDR
+ | MMC_CAP_UHS_DDR50;
+ else if (!strncmp(name, "DDR_1p2v", sizeof("DDR_1p2v")))
+ pdata->uhs_caps |= MMC_CAP_1_2V_DDR
+ | MMC_CAP_UHS_DDR50;
+ }
+
+ of_property_read_u32(np, "qcom,sdcc-current-limit", ¤t_limit);
+ if (current_limit == 800)
+ pdata->uhs_caps |= MMC_CAP_MAX_CURRENT_800;
+ else if (current_limit == 600)
+ pdata->uhs_caps |= MMC_CAP_MAX_CURRENT_600;
+ else if (current_limit == 400)
+ pdata->uhs_caps |= MMC_CAP_MAX_CURRENT_400;
+ else if (current_limit == 200)
+ pdata->uhs_caps |= MMC_CAP_MAX_CURRENT_200;
+
+ if (of_get_property(np, "qcom,sdcc-xpc", NULL))
+ pdata->xpc_cap = true;
if (of_get_property(np, "qcom,sdcc-nonremovable", NULL))
pdata->nonremovable = true;
if (of_get_property(np, "qcom,sdcc-disable_cmd23", NULL))
@@ -5125,6 +5169,7 @@
mmc->caps |= MMC_CAP_CMD23;
mmc->caps |= plat->uhs_caps;
+ mmc->caps2 |= plat->uhs_caps2;
/*
* XPC controls the maximum current in the default speed mode of SDXC
* card. XPC=0 means 100mA (max.) but speed class is not supported.
@@ -5139,12 +5184,6 @@
mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
mmc->caps2 |= MMC_CAP2_SANITIZE;
- if (pdev->dev.of_node) {
- if (of_get_property((&pdev->dev)->of_node,
- "qcom,sdcc-hs200", NULL))
- mmc->caps2 |= MMC_CAP2_HS200_1_8V_SDR;
- }
-
if (plat->nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
mmc->caps |= MMC_CAP_SDIO_IRQ;