diff options
-rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 25 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.h | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pxav3.c | 15 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 74 | ||||
-rw-r--r-- | include/linux/mmc/sdhci.h | 1 |
6 files changed, 86 insertions, 34 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index e3e56d35f0ee..970314e0aac8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | |||
247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, | 247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, |
248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, | 248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, |
249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, | 249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, |
250 | { "INT344D" , NULL, &sdhci_acpi_slot_int_sdio }, | ||
250 | { "PNP0D40" }, | 251 | { "PNP0D40" }, |
251 | { }, | 252 | { }, |
252 | }; | 253 | }; |
@@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { | |||
257 | { "INT33BB" }, | 258 | { "INT33BB" }, |
258 | { "INT33C6" }, | 259 | { "INT33C6" }, |
259 | { "INT3436" }, | 260 | { "INT3436" }, |
261 | { "INT344D" }, | ||
260 | { "PNP0D40" }, | 262 | { "PNP0D40" }, |
261 | { }, | 263 | { }, |
262 | }; | 264 | }; |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 03427755b902..4f38554ce679 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = { | |||
993 | .subdevice = PCI_ANY_ID, | 993 | .subdevice = PCI_ANY_ID, |
994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, | 994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, |
995 | }, | 995 | }, |
996 | |||
997 | { | ||
998 | .vendor = PCI_VENDOR_ID_INTEL, | ||
999 | .device = PCI_DEVICE_ID_INTEL_SPT_EMMC, | ||
1000 | .subvendor = PCI_ANY_ID, | ||
1001 | .subdevice = PCI_ANY_ID, | ||
1002 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, | ||
1003 | }, | ||
1004 | |||
1005 | { | ||
1006 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1007 | .device = PCI_DEVICE_ID_INTEL_SPT_SDIO, | ||
1008 | .subvendor = PCI_ANY_ID, | ||
1009 | .subdevice = PCI_ANY_ID, | ||
1010 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, | ||
1011 | }, | ||
1012 | |||
1013 | { | ||
1014 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1015 | .device = PCI_DEVICE_ID_INTEL_SPT_SD, | ||
1016 | .subvendor = PCI_ANY_ID, | ||
1017 | .subdevice = PCI_ANY_ID, | ||
1018 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, | ||
1019 | }, | ||
1020 | |||
996 | { | 1021 | { |
997 | .vendor = PCI_VENDOR_ID_O2, | 1022 | .vendor = PCI_VENDOR_ID_O2, |
998 | .device = PCI_DEVICE_ID_O2_8120, | 1023 | .device = PCI_DEVICE_ID_O2_8120, |
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d57c3d169914..1ec684d06d54 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 | 21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 |
22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 | 22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 |
23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 | 23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 |
24 | #define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b | ||
25 | #define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c | ||
26 | #define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d | ||
24 | 27 | ||
25 | /* | 28 | /* |
26 | * PCI registers | 29 | * PCI registers |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 45238871192d..ca3424e7ef71 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
300 | if (IS_ERR(host)) | 300 | if (IS_ERR(host)) |
301 | return PTR_ERR(host); | 301 | return PTR_ERR(host); |
302 | 302 | ||
303 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
304 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
305 | if (ret < 0) | ||
306 | goto err_mbus_win; | ||
307 | } | ||
308 | |||
309 | |||
310 | pltfm_host = sdhci_priv(host); | 303 | pltfm_host = sdhci_priv(host); |
311 | pltfm_host->priv = pxa; | 304 | pltfm_host->priv = pxa; |
312 | 305 | ||
@@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
325 | if (!IS_ERR(pxa->clk_core)) | 318 | if (!IS_ERR(pxa->clk_core)) |
326 | clk_prepare_enable(pxa->clk_core); | 319 | clk_prepare_enable(pxa->clk_core); |
327 | 320 | ||
321 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
322 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
323 | if (ret < 0) | ||
324 | goto err_mbus_win; | ||
325 | } | ||
326 | |||
328 | /* enable 1/8V DDR capable */ | 327 | /* enable 1/8V DDR capable */ |
329 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | 328 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
330 | 329 | ||
@@ -396,11 +395,11 @@ err_add_host: | |||
396 | pm_runtime_disable(&pdev->dev); | 395 | pm_runtime_disable(&pdev->dev); |
397 | err_of_parse: | 396 | err_of_parse: |
398 | err_cd_req: | 397 | err_cd_req: |
398 | err_mbus_win: | ||
399 | clk_disable_unprepare(pxa->clk_io); | 399 | clk_disable_unprepare(pxa->clk_io); |
400 | if (!IS_ERR(pxa->clk_core)) | 400 | if (!IS_ERR(pxa->clk_core)) |
401 | clk_disable_unprepare(pxa->clk_core); | 401 | clk_disable_unprepare(pxa->clk_core); |
402 | err_clk_get: | 402 | err_clk_get: |
403 | err_mbus_win: | ||
404 | sdhci_pltfm_free(pdev); | 403 | sdhci_pltfm_free(pdev); |
405 | return ret; | 404 | return ret; |
406 | } | 405 | } |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..1453cd127921 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host) | |||
259 | 259 | ||
260 | del_timer_sync(&host->tuning_timer); | 260 | del_timer_sync(&host->tuning_timer); |
261 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 261 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
262 | host->mmc->max_blk_count = | ||
263 | (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; | ||
264 | } | 262 | } |
265 | sdhci_enable_card_detection(host); | 263 | sdhci_enable_card_detection(host); |
266 | } | 264 | } |
@@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1353 | 1351 | ||
1354 | sdhci_runtime_pm_get(host); | 1352 | sdhci_runtime_pm_get(host); |
1355 | 1353 | ||
1354 | present = mmc_gpio_get_cd(host->mmc); | ||
1355 | |||
1356 | spin_lock_irqsave(&host->lock, flags); | 1356 | spin_lock_irqsave(&host->lock, flags); |
1357 | 1357 | ||
1358 | WARN_ON(host->mrq != NULL); | 1358 | WARN_ON(host->mrq != NULL); |
@@ -1381,7 +1381,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1381 | * zero: cd-gpio is used, and card is removed | 1381 | * zero: cd-gpio is used, and card is removed |
1382 | * one: cd-gpio is used, and card is present | 1382 | * one: cd-gpio is used, and card is present |
1383 | */ | 1383 | */ |
1384 | present = mmc_gpio_get_cd(host->mmc); | ||
1385 | if (present < 0) { | 1384 | if (present < 0) { |
1386 | /* If polling, assume that the card is always present. */ | 1385 | /* If polling, assume that the card is always present. */ |
1387 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | 1386 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) |
@@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc) | |||
1880 | return !(present_state & SDHCI_DATA_LVL_MASK); | 1879 | return !(present_state & SDHCI_DATA_LVL_MASK); |
1881 | } | 1880 | } |
1882 | 1881 | ||
1882 | static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) | ||
1883 | { | ||
1884 | struct sdhci_host *host = mmc_priv(mmc); | ||
1885 | unsigned long flags; | ||
1886 | |||
1887 | spin_lock_irqsave(&host->lock, flags); | ||
1888 | host->flags |= SDHCI_HS400_TUNING; | ||
1889 | spin_unlock_irqrestore(&host->lock, flags); | ||
1890 | |||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1883 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | 1894 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
1884 | { | 1895 | { |
1885 | struct sdhci_host *host = mmc_priv(mmc); | 1896 | struct sdhci_host *host = mmc_priv(mmc); |
@@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1887 | int tuning_loop_counter = MAX_TUNING_LOOP; | 1898 | int tuning_loop_counter = MAX_TUNING_LOOP; |
1888 | int err = 0; | 1899 | int err = 0; |
1889 | unsigned long flags; | 1900 | unsigned long flags; |
1901 | unsigned int tuning_count = 0; | ||
1902 | bool hs400_tuning; | ||
1890 | 1903 | ||
1891 | sdhci_runtime_pm_get(host); | 1904 | sdhci_runtime_pm_get(host); |
1892 | spin_lock_irqsave(&host->lock, flags); | 1905 | spin_lock_irqsave(&host->lock, flags); |
1893 | 1906 | ||
1907 | hs400_tuning = host->flags & SDHCI_HS400_TUNING; | ||
1908 | host->flags &= ~SDHCI_HS400_TUNING; | ||
1909 | |||
1910 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) | ||
1911 | tuning_count = host->tuning_count; | ||
1912 | |||
1894 | /* | 1913 | /* |
1895 | * The Host Controller needs tuning only in case of SDR104 mode | 1914 | * The Host Controller needs tuning only in case of SDR104 mode |
1896 | * and for SDR50 mode when Use Tuning for SDR50 is set in the | 1915 | * and for SDR50 mode when Use Tuning for SDR50 is set in the |
@@ -1899,8 +1918,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1899 | * tuning function has to be executed. | 1918 | * tuning function has to be executed. |
1900 | */ | 1919 | */ |
1901 | switch (host->timing) { | 1920 | switch (host->timing) { |
1921 | /* HS400 tuning is done in HS200 mode */ | ||
1902 | case MMC_TIMING_MMC_HS400: | 1922 | case MMC_TIMING_MMC_HS400: |
1923 | err = -EINVAL; | ||
1924 | goto out_unlock; | ||
1925 | |||
1903 | case MMC_TIMING_MMC_HS200: | 1926 | case MMC_TIMING_MMC_HS200: |
1927 | /* | ||
1928 | * Periodic re-tuning for HS400 is not expected to be needed, so | ||
1929 | * disable it here. | ||
1930 | */ | ||
1931 | if (hs400_tuning) | ||
1932 | tuning_count = 0; | ||
1933 | break; | ||
1934 | |||
1904 | case MMC_TIMING_UHS_SDR104: | 1935 | case MMC_TIMING_UHS_SDR104: |
1905 | break; | 1936 | break; |
1906 | 1937 | ||
@@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1911 | /* FALLTHROUGH */ | 1942 | /* FALLTHROUGH */ |
1912 | 1943 | ||
1913 | default: | 1944 | default: |
1914 | spin_unlock_irqrestore(&host->lock, flags); | 1945 | goto out_unlock; |
1915 | sdhci_runtime_pm_put(host); | ||
1916 | return 0; | ||
1917 | } | 1946 | } |
1918 | 1947 | ||
1919 | if (host->ops->platform_execute_tuning) { | 1948 | if (host->ops->platform_execute_tuning) { |
@@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2037 | } | 2066 | } |
2038 | 2067 | ||
2039 | out: | 2068 | out: |
2040 | /* | 2069 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
2041 | * If this is the very first time we are here, we start the retuning | 2070 | |
2042 | * timer. Since only during the first time, SDHCI_NEEDS_RETUNING | 2071 | if (tuning_count) { |
2043 | * flag won't be set, we check this condition before actually starting | ||
2044 | * the timer. | ||
2045 | */ | ||
2046 | if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && | ||
2047 | (host->tuning_mode == SDHCI_TUNING_MODE_1)) { | ||
2048 | host->flags |= SDHCI_USING_RETUNING_TIMER; | 2072 | host->flags |= SDHCI_USING_RETUNING_TIMER; |
2049 | mod_timer(&host->tuning_timer, jiffies + | 2073 | mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ); |
2050 | host->tuning_count * HZ); | ||
2051 | /* Tuning mode 1 limits the maximum data length to 4MB */ | ||
2052 | mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; | ||
2053 | } else if (host->flags & SDHCI_USING_RETUNING_TIMER) { | ||
2054 | host->flags &= ~SDHCI_NEEDS_RETUNING; | ||
2055 | /* Reload the new initial value for timer */ | ||
2056 | mod_timer(&host->tuning_timer, jiffies + | ||
2057 | host->tuning_count * HZ); | ||
2058 | } | 2074 | } |
2059 | 2075 | ||
2060 | /* | 2076 | /* |
@@ -2070,6 +2086,7 @@ out: | |||
2070 | 2086 | ||
2071 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | 2087 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); |
2072 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 2088 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
2089 | out_unlock: | ||
2073 | spin_unlock_irqrestore(&host->lock, flags); | 2090 | spin_unlock_irqrestore(&host->lock, flags); |
2074 | sdhci_runtime_pm_put(host); | 2091 | sdhci_runtime_pm_put(host); |
2075 | 2092 | ||
@@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
2110 | { | 2127 | { |
2111 | struct sdhci_host *host = mmc_priv(mmc); | 2128 | struct sdhci_host *host = mmc_priv(mmc); |
2112 | unsigned long flags; | 2129 | unsigned long flags; |
2130 | int present; | ||
2113 | 2131 | ||
2114 | /* First check if client has provided their own card event */ | 2132 | /* First check if client has provided their own card event */ |
2115 | if (host->ops->card_event) | 2133 | if (host->ops->card_event) |
2116 | host->ops->card_event(host); | 2134 | host->ops->card_event(host); |
2117 | 2135 | ||
2136 | present = sdhci_do_get_cd(host); | ||
2137 | |||
2118 | spin_lock_irqsave(&host->lock, flags); | 2138 | spin_lock_irqsave(&host->lock, flags); |
2119 | 2139 | ||
2120 | /* Check host->mrq first in case we are runtime suspended */ | 2140 | /* Check host->mrq first in case we are runtime suspended */ |
2121 | if (host->mrq && !sdhci_do_get_cd(host)) { | 2141 | if (host->mrq && !present) { |
2122 | pr_err("%s: Card removed during transfer!\n", | 2142 | pr_err("%s: Card removed during transfer!\n", |
2123 | mmc_hostname(host->mmc)); | 2143 | mmc_hostname(host->mmc)); |
2124 | pr_err("%s: Resetting controller.\n", | 2144 | pr_err("%s: Resetting controller.\n", |
@@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = { | |||
2142 | .hw_reset = sdhci_hw_reset, | 2162 | .hw_reset = sdhci_hw_reset, |
2143 | .enable_sdio_irq = sdhci_enable_sdio_irq, | 2163 | .enable_sdio_irq = sdhci_enable_sdio_irq, |
2144 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, | 2164 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, |
2165 | .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, | ||
2145 | .execute_tuning = sdhci_execute_tuning, | 2166 | .execute_tuning = sdhci_execute_tuning, |
2146 | .card_event = sdhci_card_event, | 2167 | .card_event = sdhci_card_event, |
2147 | .card_busy = sdhci_card_busy, | 2168 | .card_busy = sdhci_card_busy, |
@@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3260 | mmc->max_segs = SDHCI_MAX_SEGS; | 3281 | mmc->max_segs = SDHCI_MAX_SEGS; |
3261 | 3282 | ||
3262 | /* | 3283 | /* |
3263 | * Maximum number of sectors in one transfer. Limited by DMA boundary | 3284 | * Maximum number of sectors in one transfer. Limited by SDMA boundary |
3264 | * size (512KiB). | 3285 | * size (512KiB). Note some tuning modes impose a 4MiB limit, but this |
3286 | * is less anyway. | ||
3265 | */ | 3287 | */ |
3266 | mmc->max_req_size = 524288; | 3288 | mmc->max_req_size = 524288; |
3267 | 3289 | ||
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 375af80bde7d..f767a0de611f 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
@@ -137,6 +137,7 @@ struct sdhci_host { | |||
137 | #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ | 137 | #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ |
138 | #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ | 138 | #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ |
139 | #define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ | 139 | #define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ |
140 | #define SDHCI_HS400_TUNING (1<<13) /* Tuning for HS400 */ | ||
140 | 141 | ||
141 | unsigned int version; /* SDHCI spec. version */ | 142 | unsigned int version; /* SDHCI spec. version */ |
142 | 143 | ||