diff options
46 files changed, 1170 insertions, 666 deletions
diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index 99c5cf8507e8..edb8cadb9541 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | |||
| @@ -17,6 +17,7 @@ Required properties: | |||
| 17 | "fsl,t4240-esdhc" | 17 | "fsl,t4240-esdhc" |
| 18 | Possible compatibles for ARM: | 18 | Possible compatibles for ARM: |
| 19 | "fsl,ls1012a-esdhc" | 19 | "fsl,ls1012a-esdhc" |
| 20 | "fsl,ls1028a-esdhc" | ||
| 20 | "fsl,ls1088a-esdhc" | 21 | "fsl,ls1088a-esdhc" |
| 21 | "fsl,ls1043a-esdhc" | 22 | "fsl,ls1043a-esdhc" |
| 22 | "fsl,ls1046a-esdhc" | 23 | "fsl,ls1046a-esdhc" |
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 540c65ed9cba..f707b8bee304 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | |||
| @@ -17,6 +17,7 @@ Required properties: | |||
| 17 | "fsl,imx6sx-usdhc" | 17 | "fsl,imx6sx-usdhc" |
| 18 | "fsl,imx6ull-usdhc" | 18 | "fsl,imx6ull-usdhc" |
| 19 | "fsl,imx7d-usdhc" | 19 | "fsl,imx7d-usdhc" |
| 20 | "fsl,imx7ulp-usdhc" | ||
| 20 | "fsl,imx8qxp-usdhc" | 21 | "fsl,imx8qxp-usdhc" |
| 21 | 22 | ||
| 22 | Optional properties: | 23 | Optional properties: |
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index cdbcfd3a4ff2..c269dbe384fe 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
| @@ -64,6 +64,8 @@ Optional properties: | |||
| 64 | whether pwrseq-simple is used. Default to 10ms if no available. | 64 | whether pwrseq-simple is used. Default to 10ms if no available. |
| 65 | - supports-cqe : The presence of this property indicates that the corresponding | 65 | - supports-cqe : The presence of this property indicates that the corresponding |
| 66 | MMC host controller supports HW command queue feature. | 66 | MMC host controller supports HW command queue feature. |
| 67 | - disable-cqe-dcmd: This property indicates that the MMC controller's command | ||
| 68 | queue engine (CQE) does not support direct commands (DCMDs). | ||
| 67 | 69 | ||
| 68 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line | 70 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line |
| 69 | polarity properties, we have to fix the meaning of the "normal" and "inverted" | 71 | polarity properties, we have to fix the meaning of the "normal" and "inverted" |
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt index f5bcda3980cc..8a532f4453f2 100644 --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt | |||
| @@ -11,10 +11,12 @@ Required properties: | |||
| 11 | "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135 | 11 | "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135 |
| 12 | "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173 | 12 | "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173 |
| 13 | "mediatek,mt8183-mmc": for mmc host ip compatible with mt8183 | 13 | "mediatek,mt8183-mmc": for mmc host ip compatible with mt8183 |
| 14 | "mediatek,mt8516-mmc": for mmc host ip compatible with mt8516 | ||
| 14 | "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701 | 15 | "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701 |
| 15 | "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712 | 16 | "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712 |
| 16 | "mediatek,mt7622-mmc": for MT7622 SoC | 17 | "mediatek,mt7622-mmc": for MT7622 SoC |
| 17 | "mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC | 18 | "mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC |
| 19 | "mediatek,mt7620-mmc", for MT7621 SoC (and others) | ||
| 18 | 20 | ||
| 19 | - reg: physical base address of the controller and length | 21 | - reg: physical base address of the controller and length |
| 20 | - interrupts: Should contain MSDC interrupt number | 22 | - interrupts: Should contain MSDC interrupt number |
diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt index 2cecdc71d94c..2cf3affa1be7 100644 --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt | |||
| @@ -14,6 +14,7 @@ Required properties: | |||
| 14 | - "nvidia,tegra124-sdhci": for Tegra124 and Tegra132 | 14 | - "nvidia,tegra124-sdhci": for Tegra124 and Tegra132 |
| 15 | - "nvidia,tegra210-sdhci": for Tegra210 | 15 | - "nvidia,tegra210-sdhci": for Tegra210 |
| 16 | - "nvidia,tegra186-sdhci": for Tegra186 | 16 | - "nvidia,tegra186-sdhci": for Tegra186 |
| 17 | - "nvidia,tegra194-sdhci": for Tegra194 | ||
| 17 | - clocks : Must contain one entry, for the module clock. | 18 | - clocks : Must contain one entry, for the module clock. |
| 18 | See ../clocks/clock-bindings.txt for details. | 19 | See ../clocks/clock-bindings.txt for details. |
| 19 | - resets : Must contain an entry for each entry in reset-names. | 20 | - resets : Must contain an entry for each entry in reset-names. |
diff --git a/MAINTAINERS b/MAINTAINERS index 0a52061eacae..bf13e161b138 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -9785,6 +9785,12 @@ F: drivers/media/platform/mtk-vpu/ | |||
| 9785 | F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 9785 | F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt |
| 9786 | F: Documentation/devicetree/bindings/media/mediatek-vpu.txt | 9786 | F: Documentation/devicetree/bindings/media/mediatek-vpu.txt |
| 9787 | 9787 | ||
| 9788 | MEDIATEK MMC/SD/SDIO DRIVER | ||
| 9789 | M: Chaotian Jing <chaotian.jing@mediatek.com> | ||
| 9790 | S: Maintained | ||
| 9791 | F: drivers/mmc/host/mtk-sd.c | ||
| 9792 | F: Documentation/devicetree/bindings/mmc/mtk-sd.txt | ||
| 9793 | |||
| 9788 | MEDIATEK MT76 WIRELESS LAN DRIVER | 9794 | MEDIATEK MT76 WIRELESS LAN DRIVER |
| 9789 | M: Felix Fietkau <nbd@nbd.name> | 9795 | M: Felix Fietkau <nbd@nbd.name> |
| 9790 | M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | 9796 | M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> |
| @@ -14484,16 +14490,15 @@ T: git git://linuxtv.org/media_tree.git | |||
| 14484 | S: Maintained | 14490 | S: Maintained |
| 14485 | F: drivers/media/i2c/imx355.c | 14491 | F: drivers/media/i2c/imx355.c |
| 14486 | 14492 | ||
| 14487 | SONY MEMORYSTICK CARD SUPPORT | 14493 | SONY MEMORYSTICK SUBSYSTEM |
| 14488 | M: Alex Dubov <oakad@yahoo.com> | ||
| 14489 | W: http://tifmxx.berlios.de/ | ||
| 14490 | S: Maintained | ||
| 14491 | F: drivers/memstick/host/tifm_ms.c | ||
| 14492 | |||
| 14493 | SONY MEMORYSTICK STANDARD SUPPORT | ||
| 14494 | M: Maxim Levitsky <maximlevitsky@gmail.com> | 14494 | M: Maxim Levitsky <maximlevitsky@gmail.com> |
| 14495 | M: Alex Dubov <oakad@yahoo.com> | ||
| 14496 | M: Ulf Hansson <ulf.hansson@linaro.org> | ||
| 14497 | L: linux-mmc@vger.kernel.org | ||
| 14498 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git | ||
| 14495 | S: Maintained | 14499 | S: Maintained |
| 14496 | F: drivers/memstick/core/ms_block.* | 14500 | F: drivers/memstick/ |
| 14501 | F: include/linux/memstick.h | ||
| 14497 | 14502 | ||
| 14498 | SONY VAIO CONTROL DEVICE DRIVER | 14503 | SONY VAIO CONTROL DEVICE DRIVER |
| 14499 | M: Mattia Dongili <malattia@linux.it> | 14504 | M: Mattia Dongili <malattia@linux.it> |
| @@ -15518,9 +15523,11 @@ S: Maintained | |||
| 15518 | F: drivers/net/ethernet/ti/cpsw* | 15523 | F: drivers/net/ethernet/ti/cpsw* |
| 15519 | F: drivers/net/ethernet/ti/davinci* | 15524 | F: drivers/net/ethernet/ti/davinci* |
| 15520 | 15525 | ||
| 15521 | TI FLASH MEDIA INTERFACE DRIVER | 15526 | TI FLASH MEDIA MEMORYSTICK/MMC DRIVERS |
| 15522 | M: Alex Dubov <oakad@yahoo.com> | 15527 | M: Alex Dubov <oakad@yahoo.com> |
| 15523 | S: Maintained | 15528 | S: Maintained |
| 15529 | W: http://tifmxx.berlios.de/ | ||
| 15530 | F: drivers/memstick/host/tifm_ms.c | ||
| 15524 | F: drivers/misc/tifm* | 15531 | F: drivers/misc/tifm* |
| 15525 | F: drivers/mmc/host/tifm_sd.c | 15532 | F: drivers/mmc/host/tifm_sd.c |
| 15526 | F: include/linux/tifm.h | 15533 | F: include/linux/tifm.h |
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index b4f3d64e7da8..5733e8fe1aef 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c | |||
| @@ -370,7 +370,6 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) | |||
| 370 | static int jmb38x_ms_issue_cmd(struct memstick_host *msh) | 370 | static int jmb38x_ms_issue_cmd(struct memstick_host *msh) |
| 371 | { | 371 | { |
| 372 | struct jmb38x_ms_host *host = memstick_priv(msh); | 372 | struct jmb38x_ms_host *host = memstick_priv(msh); |
| 373 | unsigned char *data; | ||
| 374 | unsigned int data_len, cmd, t_val; | 373 | unsigned int data_len, cmd, t_val; |
| 375 | 374 | ||
| 376 | if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) { | 375 | if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) { |
| @@ -402,8 +401,6 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh) | |||
| 402 | cmd |= TPC_WAIT_INT; | 401 | cmd |= TPC_WAIT_INT; |
| 403 | } | 402 | } |
| 404 | 403 | ||
| 405 | data = host->req->data; | ||
| 406 | |||
| 407 | if (!no_dma) | 404 | if (!no_dma) |
| 408 | host->cmd_flags |= DMA_DATA; | 405 | host->cmd_flags |= DMA_DATA; |
| 409 | 406 | ||
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 1bbb2ead9556..6b13ac56eb27 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c | |||
| @@ -256,7 +256,6 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) | |||
| 256 | static int tifm_ms_issue_cmd(struct tifm_ms *host) | 256 | static int tifm_ms_issue_cmd(struct tifm_ms *host) |
| 257 | { | 257 | { |
| 258 | struct tifm_dev *sock = host->dev; | 258 | struct tifm_dev *sock = host->dev; |
| 259 | unsigned char *data; | ||
| 260 | unsigned int data_len, cmd, sys_param; | 259 | unsigned int data_len, cmd, sys_param; |
| 261 | 260 | ||
| 262 | host->cmd_flags = 0; | 261 | host->cmd_flags = 0; |
| @@ -265,8 +264,6 @@ static int tifm_ms_issue_cmd(struct tifm_ms *host) | |||
| 265 | host->io_word = 0; | 264 | host->io_word = 0; |
| 266 | host->cmd_flags = 0; | 265 | host->cmd_flags = 0; |
| 267 | 266 | ||
| 268 | data = host->req->data; | ||
| 269 | |||
| 270 | host->use_dma = !no_dma; | 267 | host->use_dma = !no_dma; |
| 271 | 268 | ||
| 272 | if (host->req->long_data) { | 269 | if (host->req->long_data) { |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 3a4402a79904..6a51f7a06ce7 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -363,11 +363,11 @@ int mmc_of_parse_voltage(struct device_node *np, u32 *mask) | |||
| 363 | int num_ranges, i; | 363 | int num_ranges, i; |
| 364 | 364 | ||
| 365 | voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); | 365 | voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); |
| 366 | num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; | ||
| 367 | if (!voltage_ranges) { | 366 | if (!voltage_ranges) { |
| 368 | pr_debug("%pOF: voltage-ranges unspecified\n", np); | 367 | pr_debug("%pOF: voltage-ranges unspecified\n", np); |
| 369 | return 0; | 368 | return 0; |
| 370 | } | 369 | } |
| 370 | num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; | ||
| 371 | if (!num_ranges) { | 371 | if (!num_ranges) { |
| 372 | pr_err("%pOF: voltage-ranges empty\n", np); | 372 | pr_err("%pOF: voltage-ranges empty\n", np); |
| 373 | return -EINVAL; | 373 | return -EINVAL; |
| @@ -429,8 +429,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
| 429 | 429 | ||
| 430 | if (mmc_gpio_alloc(host)) { | 430 | if (mmc_gpio_alloc(host)) { |
| 431 | put_device(&host->class_dev); | 431 | put_device(&host->class_dev); |
| 432 | ida_simple_remove(&mmc_host_ida, host->index); | ||
| 433 | kfree(host); | ||
| 434 | return NULL; | 432 | return NULL; |
| 435 | } | 433 | } |
| 436 | 434 | ||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index c5208fb312ae..a533cab8fccc 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
| @@ -184,11 +184,7 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 184 | if (err) | 184 | if (err) |
| 185 | break; | 185 | break; |
| 186 | 186 | ||
| 187 | /* if we're just probing, do a single pass */ | 187 | /* wait until reset completes */ |
| 188 | if (ocr == 0) | ||
| 189 | break; | ||
| 190 | |||
| 191 | /* otherwise wait until reset completes */ | ||
| 192 | if (mmc_host_is_spi(host)) { | 188 | if (mmc_host_is_spi(host)) { |
| 193 | if (!(cmd.resp[0] & R1_SPI_IDLE)) | 189 | if (!(cmd.resp[0] & R1_SPI_IDLE)) |
| 194 | break; | 190 | break; |
| @@ -200,6 +196,16 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 200 | err = -ETIMEDOUT; | 196 | err = -ETIMEDOUT; |
| 201 | 197 | ||
| 202 | mmc_delay(10); | 198 | mmc_delay(10); |
| 199 | |||
| 200 | /* | ||
| 201 | * According to eMMC specification v5.1 section 6.4.3, we | ||
| 202 | * should issue CMD1 repeatedly in the idle state until | ||
| 203 | * the eMMC is ready. Otherwise some eMMC devices seem to enter | ||
| 204 | * the inactive mode after mmc_init_card() issued CMD0 when | ||
| 205 | * the eMMC device is busy. | ||
| 206 | */ | ||
| 207 | if (!ocr && !mmc_host_is_spi(host)) | ||
| 208 | cmd.arg = cmd.resp[0] | BIT(30); | ||
| 203 | } | 209 | } |
| 204 | 210 | ||
| 205 | if (rocr && !mmc_host_is_spi(host)) | 211 | if (rocr && !mmc_host_is_spi(host)) |
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c index efb8a7965dd4..154f4204d58c 100644 --- a/drivers/mmc/core/pwrseq_emmc.c +++ b/drivers/mmc/core/pwrseq_emmc.c | |||
| @@ -30,19 +30,14 @@ struct mmc_pwrseq_emmc { | |||
| 30 | 30 | ||
| 31 | #define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq) | 31 | #define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq) |
| 32 | 32 | ||
| 33 | static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) | ||
| 34 | { | ||
| 35 | gpiod_set_value(pwrseq->reset_gpio, 1); | ||
| 36 | udelay(1); | ||
| 37 | gpiod_set_value(pwrseq->reset_gpio, 0); | ||
| 38 | udelay(200); | ||
| 39 | } | ||
| 40 | |||
| 41 | static void mmc_pwrseq_emmc_reset(struct mmc_host *host) | 33 | static void mmc_pwrseq_emmc_reset(struct mmc_host *host) |
| 42 | { | 34 | { |
| 43 | struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); | 35 | struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); |
| 44 | 36 | ||
| 45 | __mmc_pwrseq_emmc_reset(pwrseq); | 37 | gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); |
| 38 | udelay(1); | ||
| 39 | gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); | ||
| 40 | udelay(200); | ||
| 46 | } | 41 | } |
| 47 | 42 | ||
| 48 | static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, | 43 | static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, |
| @@ -50,8 +45,11 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, | |||
| 50 | { | 45 | { |
| 51 | struct mmc_pwrseq_emmc *pwrseq = container_of(this, | 46 | struct mmc_pwrseq_emmc *pwrseq = container_of(this, |
| 52 | struct mmc_pwrseq_emmc, reset_nb); | 47 | struct mmc_pwrseq_emmc, reset_nb); |
| 48 | gpiod_set_value(pwrseq->reset_gpio, 1); | ||
| 49 | udelay(1); | ||
| 50 | gpiod_set_value(pwrseq->reset_gpio, 0); | ||
| 51 | udelay(200); | ||
| 53 | 52 | ||
| 54 | __mmc_pwrseq_emmc_reset(pwrseq); | ||
| 55 | return NOTIFY_DONE; | 53 | return NOTIFY_DONE; |
| 56 | } | 54 | } |
| 57 | 55 | ||
| @@ -72,14 +70,18 @@ static int mmc_pwrseq_emmc_probe(struct platform_device *pdev) | |||
| 72 | if (IS_ERR(pwrseq->reset_gpio)) | 70 | if (IS_ERR(pwrseq->reset_gpio)) |
| 73 | return PTR_ERR(pwrseq->reset_gpio); | 71 | return PTR_ERR(pwrseq->reset_gpio); |
| 74 | 72 | ||
| 75 | /* | 73 | if (!gpiod_cansleep(pwrseq->reset_gpio)) { |
| 76 | * register reset handler to ensure emmc reset also from | 74 | /* |
| 77 | * emergency_reboot(), priority 255 is the highest priority | 75 | * register reset handler to ensure emmc reset also from |
| 78 | * so it will be executed before any system reboot handler. | 76 | * emergency_reboot(), priority 255 is the highest priority |
| 79 | */ | 77 | * so it will be executed before any system reboot handler. |
| 80 | pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; | 78 | */ |
| 81 | pwrseq->reset_nb.priority = 255; | 79 | pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; |
| 82 | register_restart_handler(&pwrseq->reset_nb); | 80 | pwrseq->reset_nb.priority = 255; |
| 81 | register_restart_handler(&pwrseq->reset_nb); | ||
| 82 | } else { | ||
| 83 | dev_notice(dev, "EMMC reset pin tied to a sleepy GPIO driver; reset on emergency-reboot disabled\n"); | ||
| 84 | } | ||
| 83 | 85 | ||
| 84 | pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; | 86 | pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; |
| 85 | pwrseq->pwrseq.dev = dev; | 87 | pwrseq->pwrseq.dev = dev; |
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 7c364a9c4eeb..b5b9c6142f08 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c | |||
| @@ -472,6 +472,7 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
| 472 | blk_mq_unquiesce_queue(q); | 472 | blk_mq_unquiesce_queue(q); |
| 473 | 473 | ||
| 474 | blk_cleanup_queue(q); | 474 | blk_cleanup_queue(q); |
| 475 | blk_mq_free_tag_set(&mq->tag_set); | ||
| 475 | 476 | ||
| 476 | /* | 477 | /* |
| 477 | * A request can be completed before the next request, potentially | 478 | * A request can be completed before the next request, potentially |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 265e1aeeb9d8..d3d32f9a2cb1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -221,6 +221,14 @@ static int mmc_decode_scr(struct mmc_card *card) | |||
| 221 | 221 | ||
| 222 | if (scr->sda_spec3) | 222 | if (scr->sda_spec3) |
| 223 | scr->cmds = UNSTUFF_BITS(resp, 32, 2); | 223 | scr->cmds = UNSTUFF_BITS(resp, 32, 2); |
| 224 | |||
| 225 | /* SD Spec says: any SD Card shall set at least bits 0 and 2 */ | ||
| 226 | if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) || | ||
| 227 | !(scr->bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
| 228 | pr_err("%s: invalid bus width\n", mmc_hostname(card->host)); | ||
| 229 | return -EINVAL; | ||
| 230 | } | ||
| 231 | |||
| 224 | return 0; | 232 | return 0; |
| 225 | } | 233 | } |
| 226 | 234 | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 28fcd8f580a1..0e86340536b6 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
| @@ -92,6 +92,7 @@ config MMC_SDHCI_PCI | |||
| 92 | tristate "SDHCI support on PCI bus" | 92 | tristate "SDHCI support on PCI bus" |
| 93 | depends on MMC_SDHCI && PCI | 93 | depends on MMC_SDHCI && PCI |
| 94 | select MMC_CQHCI | 94 | select MMC_CQHCI |
| 95 | select IOSF_MBI if X86 | ||
| 95 | help | 96 | help |
| 96 | This selects the PCI Secure Digital Host Controller Interface. | 97 | This selects the PCI Secure Digital Host Controller Interface. |
| 97 | Most controllers found today are PCI devices. | 98 | Most controllers found today are PCI devices. |
| @@ -437,7 +438,7 @@ config MMC_WBSD | |||
| 437 | depends on ISA_DMA_API | 438 | depends on ISA_DMA_API |
| 438 | help | 439 | help |
| 439 | This selects the Winbond(R) W83L51xD Secure digital and | 440 | This selects the Winbond(R) W83L51xD Secure digital and |
| 440 | Multimedia card Interface. | 441 | Multimedia card Interface. |
| 441 | If you have a machine with a integrated W83L518D or W83L519D | 442 | If you have a machine with a integrated W83L518D or W83L519D |
| 442 | SD/MMC card reader, say Y or M here. | 443 | SD/MMC card reader, say Y or M here. |
| 443 | 444 | ||
| @@ -515,7 +516,7 @@ config MMC_TIFM_SD | |||
| 515 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | 516 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support |
| 516 | (TIFM_7XX1)'. | 517 | (TIFM_7XX1)'. |
| 517 | 518 | ||
| 518 | To compile this driver as a module, choose M here: the | 519 | To compile this driver as a module, choose M here: the |
| 519 | module will be called tifm_sd. | 520 | module will be called tifm_sd. |
| 520 | 521 | ||
| 521 | config MMC_MVSDIO | 522 | config MMC_MVSDIO |
| @@ -531,12 +532,12 @@ config MMC_MVSDIO | |||
| 531 | module will be called mvsdio. | 532 | module will be called mvsdio. |
| 532 | 533 | ||
| 533 | config MMC_DAVINCI | 534 | config MMC_DAVINCI |
| 534 | tristate "TI DAVINCI Multimedia Card Interface support" | 535 | tristate "TI DAVINCI Multimedia Card Interface support" |
| 535 | depends on ARCH_DAVINCI | 536 | depends on ARCH_DAVINCI |
| 536 | help | 537 | help |
| 537 | This selects the TI DAVINCI Multimedia card Interface. | 538 | This selects the TI DAVINCI Multimedia card Interface. |
| 538 | If you have an DAVINCI board with a Multimedia Card slot, | 539 | If you have an DAVINCI board with a Multimedia Card slot, |
| 539 | say Y or M here. If unsure, say N. | 540 | say Y or M here. If unsure, say N. |
| 540 | 541 | ||
| 541 | config MMC_GOLDFISH | 542 | config MMC_GOLDFISH |
| 542 | tristate "goldfish qemu Multimedia Card Interface support" | 543 | tristate "goldfish qemu Multimedia Card Interface support" |
| @@ -565,18 +566,18 @@ config MMC_S3C | |||
| 565 | depends on S3C24XX_DMAC | 566 | depends on S3C24XX_DMAC |
| 566 | help | 567 | help |
| 567 | This selects a driver for the MCI interface found in | 568 | This selects a driver for the MCI interface found in |
| 568 | Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. | 569 | Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. |
| 569 | If you have a board based on one of those and a MMC/SD | 570 | If you have a board based on one of those and a MMC/SD |
| 570 | slot, say Y or M here. | 571 | slot, say Y or M here. |
| 571 | 572 | ||
| 572 | If unsure, say N. | 573 | If unsure, say N. |
| 573 | 574 | ||
| 574 | config MMC_S3C_HW_SDIO_IRQ | 575 | config MMC_S3C_HW_SDIO_IRQ |
| 575 | bool "Hardware support for SDIO IRQ" | 576 | bool "Hardware support for SDIO IRQ" |
| 576 | depends on MMC_S3C | 577 | depends on MMC_S3C |
| 577 | help | 578 | help |
| 578 | Enable the hardware support for SDIO interrupts instead of using | 579 | Enable the hardware support for SDIO interrupts instead of using |
| 579 | the generic polling code. | 580 | the generic polling code. |
| 580 | 581 | ||
| 581 | choice | 582 | choice |
| 582 | prompt "Samsung S3C SD/MMC transfer code" | 583 | prompt "Samsung S3C SD/MMC transfer code" |
| @@ -941,6 +942,7 @@ config MMC_BCM2835 | |||
| 941 | config MMC_MTK | 942 | config MMC_MTK |
| 942 | tristate "MediaTek SD/MMC Card Interface support" | 943 | tristate "MediaTek SD/MMC Card Interface support" |
| 943 | depends on HAS_DMA | 944 | depends on HAS_DMA |
| 945 | select REGULATOR | ||
| 944 | help | 946 | help |
| 945 | This selects the MediaTek(R) Secure digital and Multimedia card Interface. | 947 | This selects the MediaTek(R) Secure digital and Multimedia card Interface. |
| 946 | If you have a machine with a integrated SD/MMC card reader, say Y or M here. | 948 | If you have a machine with a integrated SD/MMC card reader, say Y or M here. |
| @@ -948,15 +950,16 @@ config MMC_MTK | |||
| 948 | If unsure, say N. | 950 | If unsure, say N. |
| 949 | 951 | ||
| 950 | config MMC_SDHCI_MICROCHIP_PIC32 | 952 | config MMC_SDHCI_MICROCHIP_PIC32 |
| 951 | tristate "Microchip PIC32MZDA SDHCI support" | 953 | tristate "Microchip PIC32MZDA SDHCI support" |
| 952 | depends on MMC_SDHCI && PIC32MZDA && MMC_SDHCI_PLTFM | 954 | depends on MMC_SDHCI && PIC32MZDA && MMC_SDHCI_PLTFM |
| 953 | help | 955 | help |
| 954 | This selects the Secure Digital Host Controller Interface (SDHCI) | 956 | This selects the Secure Digital Host Controller Interface (SDHCI) |
| 955 | for PIC32MZDA platform. | 957 | for PIC32MZDA platform. |
| 956 | 958 | ||
| 957 | If you have a controller with this interface, say Y or M here. | 959 | If you have a controller with this interface, say Y or M here. |
| 960 | |||
| 961 | If unsure, say N. | ||
| 958 | 962 | ||
| 959 | If unsure, say N. | ||
| 960 | config MMC_SDHCI_BRCMSTB | 963 | config MMC_SDHCI_BRCMSTB |
| 961 | tristate "Broadcom SDIO/SD/MMC support" | 964 | tristate "Broadcom SDIO/SD/MMC support" |
| 962 | depends on ARCH_BRCMSTB || BMIPS_GENERIC | 965 | depends on ARCH_BRCMSTB || BMIPS_GENERIC |
| @@ -993,6 +996,7 @@ config MMC_SDHCI_OMAP | |||
| 993 | config MMC_SDHCI_AM654 | 996 | config MMC_SDHCI_AM654 |
| 994 | tristate "Support for the SDHCI Controller in TI's AM654 SOCs" | 997 | tristate "Support for the SDHCI Controller in TI's AM654 SOCs" |
| 995 | depends on MMC_SDHCI_PLTFM && OF | 998 | depends on MMC_SDHCI_PLTFM && OF |
| 999 | select MMC_SDHCI_IO_ACCESSORS | ||
| 996 | help | 1000 | help |
| 997 | This selects the Secure Digital Host Controller Interface (SDHCI) | 1001 | This selects the Secure Digital Host Controller Interface (SDHCI) |
| 998 | support present in TI's AM654 SOCs. The controller supports | 1002 | support present in TI's AM654 SOCs. The controller supports |
diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c index 6e6b7ade4b60..e481535cba2b 100644 --- a/drivers/mmc/host/alcor.c +++ b/drivers/mmc/host/alcor.c | |||
| @@ -43,7 +43,6 @@ struct alcor_sdmmc_host { | |||
| 43 | struct device *dev; | 43 | struct device *dev; |
| 44 | struct alcor_pci_priv *alcor_pci; | 44 | struct alcor_pci_priv *alcor_pci; |
| 45 | 45 | ||
| 46 | struct mmc_host *mmc; | ||
| 47 | struct mmc_request *mrq; | 46 | struct mmc_request *mrq; |
| 48 | struct mmc_command *cmd; | 47 | struct mmc_command *cmd; |
| 49 | struct mmc_data *data; | 48 | struct mmc_data *data; |
| @@ -117,6 +116,9 @@ static void alcor_reset(struct alcor_sdmmc_host *host, u8 val) | |||
| 117 | dev_err(host->dev, "%s: timeout\n", __func__); | 116 | dev_err(host->dev, "%s: timeout\n", __func__); |
| 118 | } | 117 | } |
| 119 | 118 | ||
| 119 | /* | ||
| 120 | * Perform DMA I/O of a single page. | ||
| 121 | */ | ||
| 120 | static void alcor_data_set_dma(struct alcor_sdmmc_host *host) | 122 | static void alcor_data_set_dma(struct alcor_sdmmc_host *host) |
| 121 | { | 123 | { |
| 122 | struct alcor_pci_priv *priv = host->alcor_pci; | 124 | struct alcor_pci_priv *priv = host->alcor_pci; |
| @@ -153,12 +155,26 @@ static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host) | |||
| 153 | ctrl |= AU6601_DATA_WRITE; | 155 | ctrl |= AU6601_DATA_WRITE; |
| 154 | 156 | ||
| 155 | if (data->host_cookie == COOKIE_MAPPED) { | 157 | if (data->host_cookie == COOKIE_MAPPED) { |
| 158 | /* | ||
| 159 | * For DMA transfers, this function is called just once, | ||
| 160 | * at the start of the operation. The hardware can only | ||
| 161 | * perform DMA I/O on a single page at a time, so here | ||
| 162 | * we kick off the transfer with the first page, and expect | ||
| 163 | * subsequent pages to be transferred upon IRQ events | ||
| 164 | * indicating that the single-page DMA was completed. | ||
| 165 | */ | ||
| 156 | alcor_data_set_dma(host); | 166 | alcor_data_set_dma(host); |
| 157 | ctrl |= AU6601_DATA_DMA_MODE; | 167 | ctrl |= AU6601_DATA_DMA_MODE; |
| 158 | host->dma_on = 1; | 168 | host->dma_on = 1; |
| 159 | alcor_write32(priv, data->sg_count * 0x1000, | 169 | alcor_write32(priv, data->sg_count * 0x1000, |
| 160 | AU6601_REG_BLOCK_SIZE); | 170 | AU6601_REG_BLOCK_SIZE); |
| 161 | } else { | 171 | } else { |
| 172 | /* | ||
| 173 | * For PIO transfers, we break down each operation | ||
| 174 | * into several sector-sized transfers. When one sector has | ||
| 175 | * complete, the IRQ handler will call this function again | ||
| 176 | * to kick off the transfer of the next sector. | ||
| 177 | */ | ||
| 162 | alcor_write32(priv, data->blksz, AU6601_REG_BLOCK_SIZE); | 178 | alcor_write32(priv, data->blksz, AU6601_REG_BLOCK_SIZE); |
| 163 | } | 179 | } |
| 164 | 180 | ||
| @@ -276,7 +292,7 @@ static void alcor_send_cmd(struct alcor_sdmmc_host *host, | |||
| 276 | break; | 292 | break; |
| 277 | default: | 293 | default: |
| 278 | dev_err(host->dev, "%s: cmd->flag (0x%02x) is not valid\n", | 294 | dev_err(host->dev, "%s: cmd->flag (0x%02x) is not valid\n", |
| 279 | mmc_hostname(host->mmc), mmc_resp_type(cmd)); | 295 | mmc_hostname(mmc_from_priv(host)), mmc_resp_type(cmd)); |
| 280 | break; | 296 | break; |
| 281 | } | 297 | } |
| 282 | 298 | ||
| @@ -317,7 +333,7 @@ static void alcor_request_complete(struct alcor_sdmmc_host *host, | |||
| 317 | host->data = NULL; | 333 | host->data = NULL; |
| 318 | host->dma_on = 0; | 334 | host->dma_on = 0; |
| 319 | 335 | ||
| 320 | mmc_request_done(host->mmc, mrq); | 336 | mmc_request_done(mmc_from_priv(host), mrq); |
| 321 | } | 337 | } |
| 322 | 338 | ||
| 323 | static void alcor_finish_data(struct alcor_sdmmc_host *host) | 339 | static void alcor_finish_data(struct alcor_sdmmc_host *host) |
| @@ -547,7 +563,7 @@ static void alcor_cd_irq(struct alcor_sdmmc_host *host, u32 intmask) | |||
| 547 | alcor_request_complete(host, 1); | 563 | alcor_request_complete(host, 1); |
| 548 | } | 564 | } |
| 549 | 565 | ||
| 550 | mmc_detect_change(host->mmc, msecs_to_jiffies(1)); | 566 | mmc_detect_change(mmc_from_priv(host), msecs_to_jiffies(1)); |
| 551 | } | 567 | } |
| 552 | 568 | ||
| 553 | static irqreturn_t alcor_irq_thread(int irq, void *d) | 569 | static irqreturn_t alcor_irq_thread(int irq, void *d) |
| @@ -771,12 +787,17 @@ static void alcor_pre_req(struct mmc_host *mmc, | |||
| 771 | data->host_cookie = COOKIE_UNMAPPED; | 787 | data->host_cookie = COOKIE_UNMAPPED; |
| 772 | 788 | ||
| 773 | /* FIXME: looks like the DMA engine works only with CMD18 */ | 789 | /* FIXME: looks like the DMA engine works only with CMD18 */ |
| 774 | if (cmd->opcode != 18) | 790 | if (cmd->opcode != MMC_READ_MULTIPLE_BLOCK |
| 791 | && cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK) | ||
| 775 | return; | 792 | return; |
| 776 | /* | 793 | /* |
| 777 | * We don't do DMA on "complex" transfers, i.e. with | 794 | * We don't do DMA on "complex" transfers, i.e. with |
| 778 | * non-word-aligned buffers or lengths. Also, we don't bother | 795 | * non-word-aligned buffers or lengths. A future improvement |
| 779 | * with all the DMA setup overhead for short transfers. | 796 | * could be made to use temporary DMA bounce-buffers when these |
| 797 | * requirements are not met. | ||
| 798 | * | ||
| 799 | * Also, we don't bother with all the DMA setup overhead for | ||
| 800 | * short transfers. | ||
| 780 | */ | 801 | */ |
| 781 | if (data->blocks * data->blksz < AU6601_MAX_DMA_BLOCK_SIZE) | 802 | if (data->blocks * data->blksz < AU6601_MAX_DMA_BLOCK_SIZE) |
| 782 | return; | 803 | return; |
| @@ -787,6 +808,8 @@ static void alcor_pre_req(struct mmc_host *mmc, | |||
| 787 | for_each_sg(data->sg, sg, data->sg_len, i) { | 808 | for_each_sg(data->sg, sg, data->sg_len, i) { |
| 788 | if (sg->length != AU6601_MAX_DMA_BLOCK_SIZE) | 809 | if (sg->length != AU6601_MAX_DMA_BLOCK_SIZE) |
| 789 | return; | 810 | return; |
| 811 | if (sg->offset != 0) | ||
| 812 | return; | ||
| 790 | } | 813 | } |
| 791 | 814 | ||
| 792 | /* This data might be unmapped at this time */ | 815 | /* This data might be unmapped at this time */ |
| @@ -1024,7 +1047,7 @@ static void alcor_hw_uninit(struct alcor_sdmmc_host *host) | |||
| 1024 | 1047 | ||
| 1025 | static void alcor_init_mmc(struct alcor_sdmmc_host *host) | 1048 | static void alcor_init_mmc(struct alcor_sdmmc_host *host) |
| 1026 | { | 1049 | { |
| 1027 | struct mmc_host *mmc = host->mmc; | 1050 | struct mmc_host *mmc = mmc_from_priv(host); |
| 1028 | 1051 | ||
| 1029 | mmc->f_min = AU6601_MIN_CLOCK; | 1052 | mmc->f_min = AU6601_MIN_CLOCK; |
| 1030 | mmc->f_max = AU6601_MAX_CLOCK; | 1053 | mmc->f_max = AU6601_MAX_CLOCK; |
| @@ -1036,26 +1059,21 @@ static void alcor_init_mmc(struct alcor_sdmmc_host *host) | |||
| 1036 | mmc->ops = &alcor_sdc_ops; | 1059 | mmc->ops = &alcor_sdc_ops; |
| 1037 | 1060 | ||
| 1038 | /* The hardware does DMA data transfer of 4096 bytes to/from a single | 1061 | /* The hardware does DMA data transfer of 4096 bytes to/from a single |
| 1039 | * buffer address. Scatterlists are not supported, but upon DMA | 1062 | * buffer address. Scatterlists are not supported at the hardware |
| 1040 | * completion (signalled via IRQ), the original vendor driver does | 1063 | * level, however we can work with them at the driver level, |
| 1041 | * then immediately set up another DMA transfer of the next 4096 | 1064 | * provided that each segment is exactly 4096 bytes in size. |
| 1042 | * bytes. | 1065 | * Upon DMA completion of a single segment (signalled via IRQ), we |
| 1043 | * | 1066 | * immediately proceed to transfer the next segment from the |
| 1044 | * This means that we need to handle the I/O in 4096 byte chunks. | 1067 | * scatterlist. |
| 1045 | * Lacking a way to limit the sglist entries to 4096 bytes, we instead | ||
| 1046 | * impose that only one segment is provided, with maximum size 4096, | ||
| 1047 | * which also happens to be the minimum size. This means that the | ||
| 1048 | * single-entry sglist handled by this driver can be handed directly | ||
| 1049 | * to the hardware, nice and simple. | ||
| 1050 | * | 1068 | * |
| 1051 | * Unfortunately though, that means we only do 4096 bytes I/O per | 1069 | * The overall request is limited to 240 sectors, matching the |
| 1052 | * MMC command. A future improvement would be to make the driver | 1070 | * original vendor driver. |
| 1053 | * accept sg lists and entries of any size, and simply iterate | ||
| 1054 | * through them 4096 bytes at a time. | ||
| 1055 | */ | 1071 | */ |
| 1056 | mmc->max_segs = AU6601_MAX_DMA_SEGMENTS; | 1072 | mmc->max_segs = AU6601_MAX_DMA_SEGMENTS; |
| 1057 | mmc->max_seg_size = AU6601_MAX_DMA_BLOCK_SIZE; | 1073 | mmc->max_seg_size = AU6601_MAX_DMA_BLOCK_SIZE; |
| 1058 | mmc->max_req_size = mmc->max_seg_size; | 1074 | mmc->max_blk_count = 240; |
| 1075 | mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size; | ||
| 1076 | dma_set_max_seg_size(host->dev, mmc->max_seg_size); | ||
| 1059 | } | 1077 | } |
| 1060 | 1078 | ||
| 1061 | static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) | 1079 | static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) |
| @@ -1072,7 +1090,6 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
| 1072 | } | 1090 | } |
| 1073 | 1091 | ||
| 1074 | host = mmc_priv(mmc); | 1092 | host = mmc_priv(mmc); |
| 1075 | host->mmc = mmc; | ||
| 1076 | host->dev = &pdev->dev; | 1093 | host->dev = &pdev->dev; |
| 1077 | host->cur_power_mode = MMC_POWER_UNDEFINED; | 1094 | host->cur_power_mode = MMC_POWER_UNDEFINED; |
| 1078 | host->alcor_pci = priv; | 1095 | host->alcor_pci = priv; |
| @@ -1104,13 +1121,14 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
| 1104 | static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev) | 1121 | static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev) |
| 1105 | { | 1122 | { |
| 1106 | struct alcor_sdmmc_host *host = dev_get_drvdata(&pdev->dev); | 1123 | struct alcor_sdmmc_host *host = dev_get_drvdata(&pdev->dev); |
| 1124 | struct mmc_host *mmc = mmc_from_priv(host); | ||
| 1107 | 1125 | ||
| 1108 | if (cancel_delayed_work_sync(&host->timeout_work)) | 1126 | if (cancel_delayed_work_sync(&host->timeout_work)) |
| 1109 | alcor_request_complete(host, 0); | 1127 | alcor_request_complete(host, 0); |
| 1110 | 1128 | ||
| 1111 | alcor_hw_uninit(host); | 1129 | alcor_hw_uninit(host); |
| 1112 | mmc_remove_host(host->mmc); | 1130 | mmc_remove_host(mmc); |
| 1113 | mmc_free_host(host->mmc); | 1131 | mmc_free_host(mmc); |
| 1114 | 1132 | ||
| 1115 | return 0; | 1133 | return 0; |
| 1116 | } | 1134 | } |
diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index a8af682a9182..d59cb0a51964 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c | |||
| @@ -537,6 +537,8 @@ static void cqhci_prep_dcmd_desc(struct mmc_host *mmc, | |||
| 537 | CQHCI_ACT(0x5) | | 537 | CQHCI_ACT(0x5) | |
| 538 | CQHCI_CMD_INDEX(mrq->cmd->opcode) | | 538 | CQHCI_CMD_INDEX(mrq->cmd->opcode) | |
| 539 | CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type)); | 539 | CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type)); |
| 540 | if (cq_host->ops->update_dcmd_desc) | ||
| 541 | cq_host->ops->update_dcmd_desc(mmc, mrq, &data); | ||
| 540 | *task_desc |= data; | 542 | *task_desc |= data; |
| 541 | desc = (u8 *)task_desc; | 543 | desc = (u8 *)task_desc; |
| 542 | pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n", | 544 | pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n", |
diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h index 9e68286a07b4..1e8e01d81015 100644 --- a/drivers/mmc/host/cqhci.h +++ b/drivers/mmc/host/cqhci.h | |||
| @@ -88,6 +88,7 @@ | |||
| 88 | 88 | ||
| 89 | /* send status config 1 */ | 89 | /* send status config 1 */ |
| 90 | #define CQHCI_SSC1 0x40 | 90 | #define CQHCI_SSC1 0x40 |
| 91 | #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) | ||
| 91 | 92 | ||
| 92 | /* send status config 2 */ | 93 | /* send status config 2 */ |
| 93 | #define CQHCI_SSC2 0x44 | 94 | #define CQHCI_SSC2 0x44 |
| @@ -147,6 +148,7 @@ | |||
| 147 | 148 | ||
| 148 | struct cqhci_host_ops; | 149 | struct cqhci_host_ops; |
| 149 | struct mmc_host; | 150 | struct mmc_host; |
| 151 | struct mmc_request; | ||
| 150 | struct cqhci_slot; | 152 | struct cqhci_slot; |
| 151 | 153 | ||
| 152 | struct cqhci_host { | 154 | struct cqhci_host { |
| @@ -210,6 +212,8 @@ struct cqhci_host_ops { | |||
| 210 | u32 (*read_l)(struct cqhci_host *host, int reg); | 212 | u32 (*read_l)(struct cqhci_host *host, int reg); |
| 211 | void (*enable)(struct mmc_host *mmc); | 213 | void (*enable)(struct mmc_host *mmc); |
| 212 | void (*disable)(struct mmc_host *mmc, bool recovery); | 214 | void (*disable)(struct mmc_host *mmc, bool recovery); |
| 215 | void (*update_dcmd_desc)(struct mmc_host *mmc, struct mmc_request *mrq, | ||
| 216 | u64 *data); | ||
| 213 | }; | 217 | }; |
| 214 | 218 | ||
| 215 | static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg) | 219 | static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg) |
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 2eba507790e4..c5a8af4ca76b 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
| 26 | #include <linux/iopoll.h> | ||
| 26 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
| 27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 28 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
| @@ -48,6 +49,8 @@ | |||
| 48 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) | 49 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) |
| 49 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) | 50 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) |
| 50 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) | 51 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) |
| 52 | #define CLK_PHASE_0 0 | ||
| 53 | #define CLK_PHASE_180 2 | ||
| 51 | #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16) | 54 | #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16) |
| 52 | #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20) | 55 | #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20) |
| 53 | #define CLK_V2_ALWAYS_ON BIT(24) | 56 | #define CLK_V2_ALWAYS_ON BIT(24) |
| @@ -56,10 +59,6 @@ | |||
| 56 | #define CLK_V3_RX_DELAY_MASK GENMASK(27, 22) | 59 | #define CLK_V3_RX_DELAY_MASK GENMASK(27, 22) |
| 57 | #define CLK_V3_ALWAYS_ON BIT(28) | 60 | #define CLK_V3_ALWAYS_ON BIT(28) |
| 58 | 61 | ||
| 59 | #define CLK_DELAY_STEP_PS 200 | ||
| 60 | #define CLK_PHASE_STEP 30 | ||
| 61 | #define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) | ||
| 62 | |||
| 63 | #define CLK_TX_DELAY_MASK(h) (h->data->tx_delay_mask) | 62 | #define CLK_TX_DELAY_MASK(h) (h->data->tx_delay_mask) |
| 64 | #define CLK_RX_DELAY_MASK(h) (h->data->rx_delay_mask) | 63 | #define CLK_RX_DELAY_MASK(h) (h->data->rx_delay_mask) |
| 65 | #define CLK_ALWAYS_ON(h) (h->data->always_on) | 64 | #define CLK_ALWAYS_ON(h) (h->data->always_on) |
| @@ -164,10 +163,10 @@ struct meson_host { | |||
| 164 | 163 | ||
| 165 | void __iomem *regs; | 164 | void __iomem *regs; |
| 166 | struct clk *core_clk; | 165 | struct clk *core_clk; |
| 166 | struct clk *mux_clk; | ||
| 167 | struct clk *mmc_clk; | 167 | struct clk *mmc_clk; |
| 168 | struct clk *rx_clk; | ||
| 169 | struct clk *tx_clk; | ||
| 170 | unsigned long req_rate; | 168 | unsigned long req_rate; |
| 169 | bool ddr; | ||
| 171 | 170 | ||
| 172 | struct pinctrl *pinctrl; | 171 | struct pinctrl *pinctrl; |
| 173 | struct pinctrl_state *pins_default; | 172 | struct pinctrl_state *pins_default; |
| @@ -207,90 +206,6 @@ struct meson_host { | |||
| 207 | #define CMD_RESP_MASK GENMASK(31, 1) | 206 | #define CMD_RESP_MASK GENMASK(31, 1) |
| 208 | #define CMD_RESP_SRAM BIT(0) | 207 | #define CMD_RESP_SRAM BIT(0) |
| 209 | 208 | ||
| 210 | struct meson_mmc_phase { | ||
| 211 | struct clk_hw hw; | ||
| 212 | void __iomem *reg; | ||
| 213 | unsigned long phase_mask; | ||
| 214 | unsigned long delay_mask; | ||
| 215 | unsigned int delay_step_ps; | ||
| 216 | }; | ||
| 217 | |||
| 218 | #define to_meson_mmc_phase(_hw) container_of(_hw, struct meson_mmc_phase, hw) | ||
| 219 | |||
| 220 | static int meson_mmc_clk_get_phase(struct clk_hw *hw) | ||
| 221 | { | ||
| 222 | struct meson_mmc_phase *mmc = to_meson_mmc_phase(hw); | ||
| 223 | unsigned int phase_num = 1 << hweight_long(mmc->phase_mask); | ||
| 224 | unsigned long period_ps, p, d; | ||
| 225 | int degrees; | ||
| 226 | u32 val; | ||
| 227 | |||
| 228 | val = readl(mmc->reg); | ||
| 229 | p = (val & mmc->phase_mask) >> __ffs(mmc->phase_mask); | ||
| 230 | degrees = p * 360 / phase_num; | ||
| 231 | |||
| 232 | if (mmc->delay_mask) { | ||
| 233 | period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000, | ||
| 234 | clk_get_rate(hw->clk)); | ||
| 235 | d = (val & mmc->delay_mask) >> __ffs(mmc->delay_mask); | ||
| 236 | degrees += d * mmc->delay_step_ps * 360 / period_ps; | ||
| 237 | degrees %= 360; | ||
| 238 | } | ||
| 239 | |||
| 240 | return degrees; | ||
| 241 | } | ||
| 242 | |||
| 243 | static void meson_mmc_apply_phase_delay(struct meson_mmc_phase *mmc, | ||
| 244 | unsigned int phase, | ||
| 245 | unsigned int delay) | ||
| 246 | { | ||
| 247 | u32 val; | ||
| 248 | |||
| 249 | val = readl(mmc->reg); | ||
| 250 | val &= ~mmc->phase_mask; | ||
| 251 | val |= phase << __ffs(mmc->phase_mask); | ||
| 252 | |||
| 253 | if (mmc->delay_mask) { | ||
| 254 | val &= ~mmc->delay_mask; | ||
| 255 | val |= delay << __ffs(mmc->delay_mask); | ||
| 256 | } | ||
| 257 | |||
| 258 | writel(val, mmc->reg); | ||
| 259 | } | ||
| 260 | |||
| 261 | static int meson_mmc_clk_set_phase(struct clk_hw *hw, int degrees) | ||
| 262 | { | ||
| 263 | struct meson_mmc_phase *mmc = to_meson_mmc_phase(hw); | ||
| 264 | unsigned int phase_num = 1 << hweight_long(mmc->phase_mask); | ||
| 265 | unsigned long period_ps, d = 0, r; | ||
| 266 | uint64_t p; | ||
| 267 | |||
| 268 | p = degrees % 360; | ||
| 269 | |||
| 270 | if (!mmc->delay_mask) { | ||
| 271 | p = DIV_ROUND_CLOSEST_ULL(p, 360 / phase_num); | ||
| 272 | } else { | ||
| 273 | period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000, | ||
| 274 | clk_get_rate(hw->clk)); | ||
| 275 | |||
| 276 | /* First compute the phase index (p), the remainder (r) is the | ||
| 277 | * part we'll try to acheive using the delays (d). | ||
| 278 | */ | ||
| 279 | r = do_div(p, 360 / phase_num); | ||
| 280 | d = DIV_ROUND_CLOSEST(r * period_ps, | ||
| 281 | 360 * mmc->delay_step_ps); | ||
| 282 | d = min(d, mmc->delay_mask >> __ffs(mmc->delay_mask)); | ||
| 283 | } | ||
| 284 | |||
| 285 | meson_mmc_apply_phase_delay(mmc, p, d); | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | static const struct clk_ops meson_mmc_clk_phase_ops = { | ||
| 290 | .get_phase = meson_mmc_clk_get_phase, | ||
| 291 | .set_phase = meson_mmc_clk_set_phase, | ||
| 292 | }; | ||
| 293 | |||
| 294 | static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data) | 209 | static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data) |
| 295 | { | 210 | { |
| 296 | unsigned int timeout = data->timeout_ns / NSEC_PER_MSEC; | 211 | unsigned int timeout = data->timeout_ns / NSEC_PER_MSEC; |
| @@ -383,16 +298,6 @@ static void meson_mmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
| 383 | mmc_get_dma_dir(data)); | 298 | mmc_get_dma_dir(data)); |
| 384 | } | 299 | } |
| 385 | 300 | ||
| 386 | static bool meson_mmc_timing_is_ddr(struct mmc_ios *ios) | ||
| 387 | { | ||
| 388 | if (ios->timing == MMC_TIMING_MMC_DDR52 || | ||
| 389 | ios->timing == MMC_TIMING_UHS_DDR50 || | ||
| 390 | ios->timing == MMC_TIMING_MMC_HS400) | ||
| 391 | return true; | ||
| 392 | |||
| 393 | return false; | ||
| 394 | } | ||
| 395 | |||
| 396 | /* | 301 | /* |
| 397 | * Gating the clock on this controller is tricky. It seems the mmc clock | 302 | * Gating the clock on this controller is tricky. It seems the mmc clock |
| 398 | * is also used by the controller. It may crash during some operation if the | 303 | * is also used by the controller. It may crash during some operation if the |
| @@ -429,36 +334,41 @@ static void meson_mmc_clk_ungate(struct meson_host *host) | |||
| 429 | writel(cfg, host->regs + SD_EMMC_CFG); | 334 | writel(cfg, host->regs + SD_EMMC_CFG); |
| 430 | } | 335 | } |
| 431 | 336 | ||
| 432 | static int meson_mmc_clk_set(struct meson_host *host, struct mmc_ios *ios) | 337 | static int meson_mmc_clk_set(struct meson_host *host, unsigned long rate, |
| 338 | bool ddr) | ||
| 433 | { | 339 | { |
| 434 | struct mmc_host *mmc = host->mmc; | 340 | struct mmc_host *mmc = host->mmc; |
| 435 | unsigned long rate = ios->clock; | ||
| 436 | int ret; | 341 | int ret; |
| 437 | u32 cfg; | 342 | u32 cfg; |
| 438 | 343 | ||
| 439 | /* DDR modes require higher module clock */ | ||
| 440 | if (meson_mmc_timing_is_ddr(ios)) | ||
| 441 | rate <<= 1; | ||
| 442 | |||
| 443 | /* Same request - bail-out */ | 344 | /* Same request - bail-out */ |
| 444 | if (host->req_rate == rate) | 345 | if (host->ddr == ddr && host->req_rate == rate) |
| 445 | return 0; | 346 | return 0; |
| 446 | 347 | ||
| 447 | /* stop clock */ | 348 | /* stop clock */ |
| 448 | meson_mmc_clk_gate(host); | 349 | meson_mmc_clk_gate(host); |
| 449 | host->req_rate = 0; | 350 | host->req_rate = 0; |
| 351 | mmc->actual_clock = 0; | ||
| 450 | 352 | ||
| 451 | if (!rate) { | 353 | /* return with clock being stopped */ |
| 452 | mmc->actual_clock = 0; | 354 | if (!rate) |
| 453 | /* return with clock being stopped */ | ||
| 454 | return 0; | 355 | return 0; |
| 455 | } | ||
| 456 | 356 | ||
| 457 | /* Stop the clock during rate change to avoid glitches */ | 357 | /* Stop the clock during rate change to avoid glitches */ |
| 458 | cfg = readl(host->regs + SD_EMMC_CFG); | 358 | cfg = readl(host->regs + SD_EMMC_CFG); |
| 459 | cfg |= CFG_STOP_CLOCK; | 359 | cfg |= CFG_STOP_CLOCK; |
| 460 | writel(cfg, host->regs + SD_EMMC_CFG); | 360 | writel(cfg, host->regs + SD_EMMC_CFG); |
| 461 | 361 | ||
| 362 | if (ddr) { | ||
| 363 | /* DDR modes require higher module clock */ | ||
| 364 | rate <<= 1; | ||
| 365 | cfg |= CFG_DDR; | ||
| 366 | } else { | ||
| 367 | cfg &= ~CFG_DDR; | ||
| 368 | } | ||
| 369 | writel(cfg, host->regs + SD_EMMC_CFG); | ||
| 370 | host->ddr = ddr; | ||
| 371 | |||
| 462 | ret = clk_set_rate(host->mmc_clk, rate); | 372 | ret = clk_set_rate(host->mmc_clk, rate); |
| 463 | if (ret) { | 373 | if (ret) { |
| 464 | dev_err(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n", | 374 | dev_err(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n", |
| @@ -470,12 +380,14 @@ static int meson_mmc_clk_set(struct meson_host *host, struct mmc_ios *ios) | |||
| 470 | mmc->actual_clock = clk_get_rate(host->mmc_clk); | 380 | mmc->actual_clock = clk_get_rate(host->mmc_clk); |
| 471 | 381 | ||
| 472 | /* We should report the real output frequency of the controller */ | 382 | /* We should report the real output frequency of the controller */ |
| 473 | if (meson_mmc_timing_is_ddr(ios)) | 383 | if (ddr) { |
| 384 | host->req_rate >>= 1; | ||
| 474 | mmc->actual_clock >>= 1; | 385 | mmc->actual_clock >>= 1; |
| 386 | } | ||
| 475 | 387 | ||
| 476 | dev_dbg(host->dev, "clk rate: %u Hz\n", mmc->actual_clock); | 388 | dev_dbg(host->dev, "clk rate: %u Hz\n", mmc->actual_clock); |
| 477 | if (ios->clock != mmc->actual_clock) | 389 | if (rate != mmc->actual_clock) |
| 478 | dev_dbg(host->dev, "requested rate was %u\n", ios->clock); | 390 | dev_dbg(host->dev, "requested rate was %lu\n", rate); |
| 479 | 391 | ||
| 480 | /* (re)start clock */ | 392 | /* (re)start clock */ |
| 481 | meson_mmc_clk_ungate(host); | 393 | meson_mmc_clk_ungate(host); |
| @@ -493,8 +405,6 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 493 | struct clk_init_data init; | 405 | struct clk_init_data init; |
| 494 | struct clk_mux *mux; | 406 | struct clk_mux *mux; |
| 495 | struct clk_divider *div; | 407 | struct clk_divider *div; |
| 496 | struct meson_mmc_phase *core, *tx, *rx; | ||
| 497 | struct clk *clk; | ||
| 498 | char clk_name[32]; | 408 | char clk_name[32]; |
| 499 | int i, ret = 0; | 409 | int i, ret = 0; |
| 500 | const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; | 410 | const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; |
| @@ -502,9 +412,11 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 502 | u32 clk_reg; | 412 | u32 clk_reg; |
| 503 | 413 | ||
| 504 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ | 414 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ |
| 505 | clk_reg = 0; | 415 | clk_reg = CLK_ALWAYS_ON(host); |
| 506 | clk_reg |= CLK_ALWAYS_ON(host); | ||
| 507 | clk_reg |= CLK_DIV_MASK; | 416 | clk_reg |= CLK_DIV_MASK; |
| 417 | clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, CLK_PHASE_180); | ||
| 418 | clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, CLK_PHASE_0); | ||
| 419 | clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, CLK_PHASE_0); | ||
| 508 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); | 420 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); |
| 509 | 421 | ||
| 510 | /* get the mux parents */ | 422 | /* get the mux parents */ |
| @@ -540,9 +452,9 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 540 | mux->mask = CLK_SRC_MASK >> mux->shift; | 452 | mux->mask = CLK_SRC_MASK >> mux->shift; |
| 541 | mux->hw.init = &init; | 453 | mux->hw.init = &init; |
| 542 | 454 | ||
| 543 | clk = devm_clk_register(host->dev, &mux->hw); | 455 | host->mux_clk = devm_clk_register(host->dev, &mux->hw); |
| 544 | if (WARN_ON(IS_ERR(clk))) | 456 | if (WARN_ON(IS_ERR(host->mux_clk))) |
| 545 | return PTR_ERR(clk); | 457 | return PTR_ERR(host->mux_clk); |
| 546 | 458 | ||
| 547 | /* create the divider */ | 459 | /* create the divider */ |
| 548 | div = devm_kzalloc(host->dev, sizeof(*div), GFP_KERNEL); | 460 | div = devm_kzalloc(host->dev, sizeof(*div), GFP_KERNEL); |
| @@ -553,7 +465,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 553 | init.name = clk_name; | 465 | init.name = clk_name; |
| 554 | init.ops = &clk_divider_ops; | 466 | init.ops = &clk_divider_ops; |
| 555 | init.flags = CLK_SET_RATE_PARENT; | 467 | init.flags = CLK_SET_RATE_PARENT; |
| 556 | clk_parent[0] = __clk_get_name(clk); | 468 | clk_parent[0] = __clk_get_name(host->mux_clk); |
| 557 | init.parent_names = clk_parent; | 469 | init.parent_names = clk_parent; |
| 558 | init.num_parents = 1; | 470 | init.num_parents = 1; |
| 559 | 471 | ||
| @@ -563,190 +475,104 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 563 | div->hw.init = &init; | 475 | div->hw.init = &init; |
| 564 | div->flags = CLK_DIVIDER_ONE_BASED; | 476 | div->flags = CLK_DIVIDER_ONE_BASED; |
| 565 | 477 | ||
| 566 | clk = devm_clk_register(host->dev, &div->hw); | 478 | host->mmc_clk = devm_clk_register(host->dev, &div->hw); |
| 567 | if (WARN_ON(IS_ERR(clk))) | 479 | if (WARN_ON(IS_ERR(host->mmc_clk))) |
| 568 | return PTR_ERR(clk); | ||
| 569 | |||
| 570 | /* create the mmc core clock */ | ||
| 571 | core = devm_kzalloc(host->dev, sizeof(*core), GFP_KERNEL); | ||
| 572 | if (!core) | ||
| 573 | return -ENOMEM; | ||
| 574 | |||
| 575 | snprintf(clk_name, sizeof(clk_name), "%s#core", dev_name(host->dev)); | ||
| 576 | init.name = clk_name; | ||
| 577 | init.ops = &meson_mmc_clk_phase_ops; | ||
| 578 | init.flags = CLK_SET_RATE_PARENT; | ||
| 579 | clk_parent[0] = __clk_get_name(clk); | ||
| 580 | init.parent_names = clk_parent; | ||
| 581 | init.num_parents = 1; | ||
| 582 | |||
| 583 | core->reg = host->regs + SD_EMMC_CLOCK; | ||
| 584 | core->phase_mask = CLK_CORE_PHASE_MASK; | ||
| 585 | core->hw.init = &init; | ||
| 586 | |||
| 587 | host->mmc_clk = devm_clk_register(host->dev, &core->hw); | ||
| 588 | if (WARN_ON(PTR_ERR_OR_ZERO(host->mmc_clk))) | ||
| 589 | return PTR_ERR(host->mmc_clk); | 480 | return PTR_ERR(host->mmc_clk); |
| 590 | 481 | ||
| 591 | /* create the mmc tx clock */ | ||
| 592 | tx = devm_kzalloc(host->dev, sizeof(*tx), GFP_KERNEL); | ||
| 593 | if (!tx) | ||
| 594 | return -ENOMEM; | ||
| 595 | |||
| 596 | snprintf(clk_name, sizeof(clk_name), "%s#tx", dev_name(host->dev)); | ||
| 597 | init.name = clk_name; | ||
| 598 | init.ops = &meson_mmc_clk_phase_ops; | ||
| 599 | init.flags = 0; | ||
| 600 | clk_parent[0] = __clk_get_name(host->mmc_clk); | ||
| 601 | init.parent_names = clk_parent; | ||
| 602 | init.num_parents = 1; | ||
| 603 | |||
| 604 | tx->reg = host->regs + SD_EMMC_CLOCK; | ||
| 605 | tx->phase_mask = CLK_TX_PHASE_MASK; | ||
| 606 | tx->delay_mask = CLK_TX_DELAY_MASK(host); | ||
| 607 | tx->delay_step_ps = CLK_DELAY_STEP_PS; | ||
| 608 | tx->hw.init = &init; | ||
| 609 | |||
| 610 | host->tx_clk = devm_clk_register(host->dev, &tx->hw); | ||
| 611 | if (WARN_ON(PTR_ERR_OR_ZERO(host->tx_clk))) | ||
| 612 | return PTR_ERR(host->tx_clk); | ||
| 613 | |||
| 614 | /* create the mmc rx clock */ | ||
| 615 | rx = devm_kzalloc(host->dev, sizeof(*rx), GFP_KERNEL); | ||
| 616 | if (!rx) | ||
| 617 | return -ENOMEM; | ||
| 618 | |||
| 619 | snprintf(clk_name, sizeof(clk_name), "%s#rx", dev_name(host->dev)); | ||
| 620 | init.name = clk_name; | ||
| 621 | init.ops = &meson_mmc_clk_phase_ops; | ||
| 622 | init.flags = 0; | ||
| 623 | clk_parent[0] = __clk_get_name(host->mmc_clk); | ||
| 624 | init.parent_names = clk_parent; | ||
| 625 | init.num_parents = 1; | ||
| 626 | |||
| 627 | rx->reg = host->regs + SD_EMMC_CLOCK; | ||
| 628 | rx->phase_mask = CLK_RX_PHASE_MASK; | ||
| 629 | rx->delay_mask = CLK_RX_DELAY_MASK(host); | ||
| 630 | rx->delay_step_ps = CLK_DELAY_STEP_PS; | ||
| 631 | rx->hw.init = &init; | ||
| 632 | |||
| 633 | host->rx_clk = devm_clk_register(host->dev, &rx->hw); | ||
| 634 | if (WARN_ON(PTR_ERR_OR_ZERO(host->rx_clk))) | ||
| 635 | return PTR_ERR(host->rx_clk); | ||
| 636 | |||
| 637 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ | 482 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ |
| 638 | host->mmc->f_min = clk_round_rate(host->mmc_clk, 400000); | 483 | host->mmc->f_min = clk_round_rate(host->mmc_clk, 400000); |
| 639 | ret = clk_set_rate(host->mmc_clk, host->mmc->f_min); | 484 | ret = clk_set_rate(host->mmc_clk, host->mmc->f_min); |
| 640 | if (ret) | 485 | if (ret) |
| 641 | return ret; | 486 | return ret; |
| 642 | 487 | ||
| 643 | clk_set_phase(host->mmc_clk, 180); | ||
| 644 | clk_set_phase(host->tx_clk, 0); | ||
| 645 | clk_set_phase(host->rx_clk, 0); | ||
| 646 | |||
| 647 | return clk_prepare_enable(host->mmc_clk); | 488 | return clk_prepare_enable(host->mmc_clk); |
| 648 | } | 489 | } |
| 649 | 490 | ||
| 650 | static void meson_mmc_shift_map(unsigned long *map, unsigned long shift) | 491 | static void meson_mmc_disable_resampling(struct meson_host *host) |
| 651 | { | 492 | { |
| 652 | DECLARE_BITMAP(left, CLK_PHASE_POINT_NUM); | 493 | unsigned int val = readl(host->regs + host->data->adjust); |
| 653 | DECLARE_BITMAP(right, CLK_PHASE_POINT_NUM); | ||
| 654 | 494 | ||
| 655 | /* | 495 | val &= ~ADJUST_ADJ_EN; |
| 656 | * shift the bitmap right and reintroduce the dropped bits on the left | 496 | writel(val, host->regs + host->data->adjust); |
| 657 | * of the bitmap | ||
| 658 | */ | ||
| 659 | bitmap_shift_right(right, map, shift, CLK_PHASE_POINT_NUM); | ||
| 660 | bitmap_shift_left(left, map, CLK_PHASE_POINT_NUM - shift, | ||
| 661 | CLK_PHASE_POINT_NUM); | ||
| 662 | bitmap_or(map, left, right, CLK_PHASE_POINT_NUM); | ||
| 663 | } | 497 | } |
| 664 | 498 | ||
| 665 | static void meson_mmc_find_next_region(unsigned long *map, | 499 | static void meson_mmc_reset_resampling(struct meson_host *host) |
| 666 | unsigned long *start, | ||
| 667 | unsigned long *stop) | ||
| 668 | { | 500 | { |
| 669 | *start = find_next_bit(map, CLK_PHASE_POINT_NUM, *start); | 501 | unsigned int val; |
| 670 | *stop = find_next_zero_bit(map, CLK_PHASE_POINT_NUM, *start); | 502 | |
| 503 | meson_mmc_disable_resampling(host); | ||
| 504 | |||
| 505 | val = readl(host->regs + host->data->adjust); | ||
| 506 | val &= ~ADJUST_ADJ_DELAY_MASK; | ||
| 507 | writel(val, host->regs + host->data->adjust); | ||
| 671 | } | 508 | } |
| 672 | 509 | ||
| 673 | static int meson_mmc_find_tuning_point(unsigned long *test) | 510 | static int meson_mmc_resampling_tuning(struct mmc_host *mmc, u32 opcode) |
| 674 | { | 511 | { |
| 675 | unsigned long shift, stop, offset = 0, start = 0, size = 0; | 512 | struct meson_host *host = mmc_priv(mmc); |
| 513 | unsigned int val, dly, max_dly, i; | ||
| 514 | int ret; | ||
| 676 | 515 | ||
| 677 | /* Get the all good/all bad situation out the way */ | 516 | /* Resampling is done using the source clock */ |
| 678 | if (bitmap_full(test, CLK_PHASE_POINT_NUM)) | 517 | max_dly = DIV_ROUND_UP(clk_get_rate(host->mux_clk), |
| 679 | return 0; /* All points are good so point 0 will do */ | 518 | clk_get_rate(host->mmc_clk)); |
| 680 | else if (bitmap_empty(test, CLK_PHASE_POINT_NUM)) | ||
| 681 | return -EIO; /* No successful tuning point */ | ||
| 682 | 519 | ||
| 683 | /* | 520 | val = readl(host->regs + host->data->adjust); |
| 684 | * Now we know there is a least one region find. Make sure it does | 521 | val |= ADJUST_ADJ_EN; |
| 685 | * not wrap by the shifting the bitmap if necessary | 522 | writel(val, host->regs + host->data->adjust); |
| 686 | */ | ||
| 687 | shift = find_first_zero_bit(test, CLK_PHASE_POINT_NUM); | ||
| 688 | if (shift != 0) | ||
| 689 | meson_mmc_shift_map(test, shift); | ||
| 690 | 523 | ||
| 691 | while (start < CLK_PHASE_POINT_NUM) { | 524 | if (mmc->doing_retune) |
| 692 | meson_mmc_find_next_region(test, &start, &stop); | 525 | dly = FIELD_GET(ADJUST_ADJ_DELAY_MASK, val) + 1; |
| 526 | else | ||
| 527 | dly = 0; | ||
| 693 | 528 | ||
| 694 | if ((stop - start) > size) { | 529 | for (i = 0; i < max_dly; i++) { |
| 695 | offset = start; | 530 | val &= ~ADJUST_ADJ_DELAY_MASK; |
| 696 | size = stop - start; | 531 | val |= FIELD_PREP(ADJUST_ADJ_DELAY_MASK, (dly + i) % max_dly); |
| 697 | } | 532 | writel(val, host->regs + host->data->adjust); |
| 698 | 533 | ||
| 699 | start = stop; | 534 | ret = mmc_send_tuning(mmc, opcode, NULL); |
| 535 | if (!ret) { | ||
| 536 | dev_dbg(mmc_dev(mmc), "resampling delay: %u\n", | ||
| 537 | (dly + i) % max_dly); | ||
| 538 | return 0; | ||
| 539 | } | ||
| 700 | } | 540 | } |
| 701 | 541 | ||
| 702 | /* Get the center point of the region */ | 542 | meson_mmc_reset_resampling(host); |
| 703 | offset += (size / 2); | 543 | return -EIO; |
| 704 | |||
| 705 | /* Shift the result back */ | ||
| 706 | offset = (offset + shift) % CLK_PHASE_POINT_NUM; | ||
| 707 | |||
| 708 | return offset; | ||
| 709 | } | 544 | } |
| 710 | 545 | ||
| 711 | static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, | 546 | static int meson_mmc_prepare_ios_clock(struct meson_host *host, |
| 712 | struct clk *clk) | 547 | struct mmc_ios *ios) |
| 713 | { | 548 | { |
| 714 | int point, ret; | 549 | bool ddr; |
| 715 | DECLARE_BITMAP(test, CLK_PHASE_POINT_NUM); | ||
| 716 | 550 | ||
| 717 | dev_dbg(mmc_dev(mmc), "%s phase/delay tunning...\n", | 551 | switch (ios->timing) { |
| 718 | __clk_get_name(clk)); | 552 | case MMC_TIMING_MMC_DDR52: |
| 719 | bitmap_zero(test, CLK_PHASE_POINT_NUM); | 553 | case MMC_TIMING_UHS_DDR50: |
| 554 | ddr = true; | ||
| 555 | break; | ||
| 720 | 556 | ||
| 721 | /* Explore tuning points */ | 557 | default: |
| 722 | for (point = 0; point < CLK_PHASE_POINT_NUM; point++) { | 558 | ddr = false; |
| 723 | clk_set_phase(clk, point * CLK_PHASE_STEP); | 559 | break; |
| 724 | ret = mmc_send_tuning(mmc, opcode, NULL); | ||
| 725 | if (!ret) | ||
| 726 | set_bit(point, test); | ||
| 727 | } | 560 | } |
| 728 | 561 | ||
| 729 | /* Find the optimal tuning point and apply it */ | 562 | return meson_mmc_clk_set(host, ios->clock, ddr); |
| 730 | point = meson_mmc_find_tuning_point(test); | ||
| 731 | if (point < 0) | ||
| 732 | return point; /* tuning failed */ | ||
| 733 | |||
| 734 | clk_set_phase(clk, point * CLK_PHASE_STEP); | ||
| 735 | dev_dbg(mmc_dev(mmc), "success with phase: %d\n", | ||
| 736 | clk_get_phase(clk)); | ||
| 737 | return 0; | ||
| 738 | } | 563 | } |
| 739 | 564 | ||
| 740 | static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) | 565 | static void meson_mmc_check_resampling(struct meson_host *host, |
| 566 | struct mmc_ios *ios) | ||
| 741 | { | 567 | { |
| 742 | struct meson_host *host = mmc_priv(mmc); | 568 | switch (ios->timing) { |
| 743 | int adj = 0; | 569 | case MMC_TIMING_LEGACY: |
| 744 | 570 | case MMC_TIMING_MMC_HS: | |
| 745 | /* enable signal resampling w/o delay */ | 571 | case MMC_TIMING_SD_HS: |
| 746 | adj = ADJUST_ADJ_EN; | 572 | case MMC_TIMING_MMC_DDR52: |
| 747 | writel(adj, host->regs + host->data->adjust); | 573 | meson_mmc_disable_resampling(host); |
| 748 | 574 | break; | |
| 749 | return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); | 575 | } |
| 750 | } | 576 | } |
| 751 | 577 | ||
| 752 | static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 578 | static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| @@ -775,12 +601,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 775 | if (!IS_ERR(mmc->supply.vmmc)) | 601 | if (!IS_ERR(mmc->supply.vmmc)) |
| 776 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); | 602 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); |
| 777 | 603 | ||
| 778 | /* disable signal resampling */ | ||
| 779 | writel(0, host->regs + host->data->adjust); | ||
| 780 | |||
| 781 | /* Reset rx phase */ | ||
| 782 | clk_set_phase(host->rx_clk, 0); | ||
| 783 | |||
| 784 | break; | 604 | break; |
| 785 | 605 | ||
| 786 | case MMC_POWER_ON: | 606 | case MMC_POWER_ON: |
| @@ -817,20 +637,13 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 817 | val = readl(host->regs + SD_EMMC_CFG); | 637 | val = readl(host->regs + SD_EMMC_CFG); |
| 818 | val &= ~CFG_BUS_WIDTH_MASK; | 638 | val &= ~CFG_BUS_WIDTH_MASK; |
| 819 | val |= FIELD_PREP(CFG_BUS_WIDTH_MASK, bus_width); | 639 | val |= FIELD_PREP(CFG_BUS_WIDTH_MASK, bus_width); |
| 640 | writel(val, host->regs + SD_EMMC_CFG); | ||
| 820 | 641 | ||
| 821 | val &= ~CFG_DDR; | 642 | meson_mmc_check_resampling(host, ios); |
| 822 | if (meson_mmc_timing_is_ddr(ios)) | 643 | err = meson_mmc_prepare_ios_clock(host, ios); |
| 823 | val |= CFG_DDR; | ||
| 824 | |||
| 825 | val &= ~CFG_CHK_DS; | ||
| 826 | if (ios->timing == MMC_TIMING_MMC_HS400) | ||
| 827 | val |= CFG_CHK_DS; | ||
| 828 | |||
| 829 | err = meson_mmc_clk_set(host, ios); | ||
| 830 | if (err) | 644 | if (err) |
| 831 | dev_err(host->dev, "Failed to set clock: %d\n,", err); | 645 | dev_err(host->dev, "Failed to set clock: %d\n,", err); |
| 832 | 646 | ||
| 833 | writel(val, host->regs + SD_EMMC_CFG); | ||
| 834 | dev_dbg(host->dev, "SD_EMMC_CFG: 0x%08x\n", val); | 647 | dev_dbg(host->dev, "SD_EMMC_CFG: 0x%08x\n", val); |
| 835 | } | 648 | } |
| 836 | 649 | ||
| @@ -1081,9 +894,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) | |||
| 1081 | } | 894 | } |
| 1082 | 895 | ||
| 1083 | out: | 896 | out: |
| 1084 | /* ack all enabled interrupts */ | ||
| 1085 | writel(irq_en, host->regs + SD_EMMC_STATUS); | ||
| 1086 | |||
| 1087 | if (cmd->error) { | 897 | if (cmd->error) { |
| 1088 | /* Stop desc in case of errors */ | 898 | /* Stop desc in case of errors */ |
| 1089 | u32 start = readl(host->regs + SD_EMMC_START); | 899 | u32 start = readl(host->regs + SD_EMMC_START); |
| @@ -1095,12 +905,14 @@ out: | |||
| 1095 | if (ret == IRQ_HANDLED) | 905 | if (ret == IRQ_HANDLED) |
| 1096 | meson_mmc_request_done(host->mmc, cmd->mrq); | 906 | meson_mmc_request_done(host->mmc, cmd->mrq); |
| 1097 | 907 | ||
| 908 | /* ack all raised interrupts */ | ||
| 909 | writel(status, host->regs + SD_EMMC_STATUS); | ||
| 910 | |||
| 1098 | return ret; | 911 | return ret; |
| 1099 | } | 912 | } |
| 1100 | 913 | ||
| 1101 | static int meson_mmc_wait_desc_stop(struct meson_host *host) | 914 | static int meson_mmc_wait_desc_stop(struct meson_host *host) |
| 1102 | { | 915 | { |
| 1103 | int loop; | ||
| 1104 | u32 status; | 916 | u32 status; |
| 1105 | 917 | ||
| 1106 | /* | 918 | /* |
| @@ -1110,20 +922,10 @@ static int meson_mmc_wait_desc_stop(struct meson_host *host) | |||
| 1110 | * If we don't confirm the descriptor is stopped, it might raise new | 922 | * If we don't confirm the descriptor is stopped, it might raise new |
| 1111 | * IRQs after we have called mmc_request_done() which is bad. | 923 | * IRQs after we have called mmc_request_done() which is bad. |
| 1112 | */ | 924 | */ |
| 1113 | for (loop = 50; loop; loop--) { | ||
| 1114 | status = readl(host->regs + SD_EMMC_STATUS); | ||
| 1115 | if (status & (STATUS_BUSY | STATUS_DESC_BUSY)) | ||
| 1116 | udelay(100); | ||
| 1117 | else | ||
| 1118 | break; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | if (status & (STATUS_BUSY | STATUS_DESC_BUSY)) { | ||
| 1122 | dev_err(host->dev, "Timed out waiting for host to stop\n"); | ||
| 1123 | return -ETIMEDOUT; | ||
| 1124 | } | ||
| 1125 | 925 | ||
| 1126 | return 0; | 926 | return readl_poll_timeout(host->regs + SD_EMMC_STATUS, status, |
| 927 | !(status & (STATUS_BUSY | STATUS_DESC_BUSY)), | ||
| 928 | 100, 5000); | ||
| 1127 | } | 929 | } |
| 1128 | 930 | ||
| 1129 | static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) | 931 | static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) |
| @@ -1227,7 +1029,7 @@ static const struct mmc_host_ops meson_mmc_ops = { | |||
| 1227 | .get_cd = meson_mmc_get_cd, | 1029 | .get_cd = meson_mmc_get_cd, |
| 1228 | .pre_req = meson_mmc_pre_req, | 1030 | .pre_req = meson_mmc_pre_req, |
| 1229 | .post_req = meson_mmc_post_req, | 1031 | .post_req = meson_mmc_post_req, |
| 1230 | .execute_tuning = meson_mmc_execute_tuning, | 1032 | .execute_tuning = meson_mmc_resampling_tuning, |
| 1231 | .card_busy = meson_mmc_card_busy, | 1033 | .card_busy = meson_mmc_card_busy, |
| 1232 | .start_signal_voltage_switch = meson_mmc_voltage_switch, | 1034 | .start_signal_voltage_switch = meson_mmc_voltage_switch, |
| 1233 | }; | 1035 | }; |
| @@ -1338,7 +1140,7 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
| 1338 | host->regs + SD_EMMC_IRQ_EN); | 1140 | host->regs + SD_EMMC_IRQ_EN); |
| 1339 | 1141 | ||
| 1340 | ret = request_threaded_irq(host->irq, meson_mmc_irq, | 1142 | ret = request_threaded_irq(host->irq, meson_mmc_irq, |
| 1341 | meson_mmc_irq_thread, IRQF_SHARED, | 1143 | meson_mmc_irq_thread, IRQF_ONESHOT, |
| 1342 | dev_name(&pdev->dev), host); | 1144 | dev_name(&pdev->dev), host); |
| 1343 | if (ret) | 1145 | if (ret) |
| 1344 | goto err_init_clk; | 1146 | goto err_init_clk; |
| @@ -1349,6 +1151,13 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
| 1349 | mmc->max_segs = SD_EMMC_DESC_BUF_LEN / sizeof(struct sd_emmc_desc); | 1151 | mmc->max_segs = SD_EMMC_DESC_BUF_LEN / sizeof(struct sd_emmc_desc); |
| 1350 | mmc->max_seg_size = mmc->max_req_size; | 1152 | mmc->max_seg_size = mmc->max_req_size; |
| 1351 | 1153 | ||
| 1154 | /* | ||
| 1155 | * At the moment, we don't know how to reliably enable HS400. | ||
| 1156 | * From the different datasheets, it is not even clear if this mode | ||
| 1157 | * is officially supported by any of the SoCs | ||
| 1158 | */ | ||
| 1159 | mmc->caps2 &= ~MMC_CAP2_HS400; | ||
| 1160 | |||
| 1352 | /* data bounce buffer */ | 1161 | /* data bounce buffer */ |
| 1353 | host->bounce_buf_size = mmc->max_req_size; | 1162 | host->bounce_buf_size = mmc->max_req_size; |
| 1354 | host->bounce_buf = | 1163 | host->bounce_buf = |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 1b1498805972..19544b121276 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 1 | /* | 2 | /* |
| 2 | * mmc_spi.c - Access SD/MMC cards through SPI master controllers | 3 | * Access SD/MMC cards through SPI master controllers |
| 3 | * | 4 | * |
| 4 | * (C) Copyright 2005, Intec Automation, | 5 | * (C) Copyright 2005, Intec Automation, |
| 5 | * Mike Lavender (mike@steroidmicros) | 6 | * Mike Lavender (mike@steroidmicros) |
| @@ -8,21 +9,6 @@ | |||
| 8 | * Hans-Peter Nilsson (hp@axis.com) | 9 | * Hans-Peter Nilsson (hp@axis.com) |
| 9 | * (C) Copyright 2007, ATRON electronic GmbH, | 10 | * (C) Copyright 2007, ATRON electronic GmbH, |
| 10 | * Jan Nikitenko <jan.nikitenko@gmail.com> | 11 | * Jan Nikitenko <jan.nikitenko@gmail.com> |
| 11 | * | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | */ | 12 | */ |
| 27 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 28 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| @@ -197,7 +183,7 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len) | |||
| 197 | static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, | 183 | static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, |
| 198 | unsigned n, u8 byte) | 184 | unsigned n, u8 byte) |
| 199 | { | 185 | { |
| 200 | u8 *cp = host->data->status; | 186 | u8 *cp = host->data->status; |
| 201 | unsigned long start = jiffies; | 187 | unsigned long start = jiffies; |
| 202 | 188 | ||
| 203 | while (1) { | 189 | while (1) { |
| @@ -220,7 +206,7 @@ static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, | |||
| 220 | * We use jiffies here because we want to have a relation | 206 | * We use jiffies here because we want to have a relation |
| 221 | * between elapsed time and the blocking of the scheduler. | 207 | * between elapsed time and the blocking of the scheduler. |
| 222 | */ | 208 | */ |
| 223 | if (time_is_before_jiffies(start+1)) | 209 | if (time_is_before_jiffies(start + 1)) |
| 224 | schedule(); | 210 | schedule(); |
| 225 | } | 211 | } |
| 226 | return -ETIMEDOUT; | 212 | return -ETIMEDOUT; |
| @@ -415,7 +401,7 @@ checkstatus: | |||
| 415 | 401 | ||
| 416 | default: | 402 | default: |
| 417 | dev_dbg(&host->spi->dev, "bad response type %04x\n", | 403 | dev_dbg(&host->spi->dev, "bad response type %04x\n", |
| 418 | mmc_spi_resp_type(cmd)); | 404 | mmc_spi_resp_type(cmd)); |
| 419 | if (value >= 0) | 405 | if (value >= 0) |
| 420 | value = -EINVAL; | 406 | value = -EINVAL; |
| 421 | goto done; | 407 | goto done; |
| @@ -467,8 +453,8 @@ mmc_spi_command_send(struct mmc_spi_host *host, | |||
| 467 | memset(cp, 0xff, sizeof(data->status)); | 453 | memset(cp, 0xff, sizeof(data->status)); |
| 468 | 454 | ||
| 469 | cp[1] = 0x40 | cmd->opcode; | 455 | cp[1] = 0x40 | cmd->opcode; |
| 470 | put_unaligned_be32(cmd->arg, cp+2); | 456 | put_unaligned_be32(cmd->arg, cp + 2); |
| 471 | cp[6] = crc7_be(0, cp+1, 5) | 0x01; | 457 | cp[6] = crc7_be(0, cp + 1, 5) | 0x01; |
| 472 | cp += 7; | 458 | cp += 7; |
| 473 | 459 | ||
| 474 | /* Then, read up to 13 bytes (while writing all-ones): | 460 | /* Then, read up to 13 bytes (while writing all-ones): |
| @@ -642,9 +628,7 @@ mmc_spi_setup_data_message( | |||
| 642 | if (multiple || direction == DMA_TO_DEVICE) { | 628 | if (multiple || direction == DMA_TO_DEVICE) { |
| 643 | t = &host->early_status; | 629 | t = &host->early_status; |
| 644 | memset(t, 0, sizeof(*t)); | 630 | memset(t, 0, sizeof(*t)); |
| 645 | t->len = (direction == DMA_TO_DEVICE) | 631 | t->len = (direction == DMA_TO_DEVICE) ? sizeof(scratch->status) : 1; |
| 646 | ? sizeof(scratch->status) | ||
| 647 | : 1; | ||
| 648 | t->tx_buf = host->ones; | 632 | t->tx_buf = host->ones; |
| 649 | t->tx_dma = host->ones_dma; | 633 | t->tx_dma = host->ones_dma; |
| 650 | t->rx_buf = scratch->status; | 634 | t->rx_buf = scratch->status; |
| @@ -677,8 +661,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t, | |||
| 677 | u32 pattern; | 661 | u32 pattern; |
| 678 | 662 | ||
| 679 | if (host->mmc->use_spi_crc) | 663 | if (host->mmc->use_spi_crc) |
| 680 | scratch->crc_val = cpu_to_be16( | 664 | scratch->crc_val = cpu_to_be16(crc_itu_t(0, t->tx_buf, t->len)); |
| 681 | crc_itu_t(0, t->tx_buf, t->len)); | ||
| 682 | if (host->dma_dev) | 665 | if (host->dma_dev) |
| 683 | dma_sync_single_for_device(host->dma_dev, | 666 | dma_sync_single_for_device(host->dma_dev, |
| 684 | host->data_dma, sizeof(*scratch), | 667 | host->data_dma, sizeof(*scratch), |
| @@ -819,6 +802,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, | |||
| 819 | } | 802 | } |
| 820 | 803 | ||
| 821 | status = spi_sync_locked(spi, &host->m); | 804 | status = spi_sync_locked(spi, &host->m); |
| 805 | if (status < 0) { | ||
| 806 | dev_dbg(&spi->dev, "read error %d\n", status); | ||
| 807 | return status; | ||
| 808 | } | ||
| 822 | 809 | ||
| 823 | if (host->dma_dev) { | 810 | if (host->dma_dev) { |
| 824 | dma_sync_single_for_cpu(host->dma_dev, | 811 | dma_sync_single_for_cpu(host->dma_dev, |
| @@ -855,9 +842,9 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, | |||
| 855 | 842 | ||
| 856 | be16_to_cpus(&scratch->crc_val); | 843 | be16_to_cpus(&scratch->crc_val); |
| 857 | if (scratch->crc_val != crc) { | 844 | if (scratch->crc_val != crc) { |
| 858 | dev_dbg(&spi->dev, "read - crc error: crc_val=0x%04x, " | 845 | dev_dbg(&spi->dev, |
| 859 | "computed=0x%04x len=%d\n", | 846 | "read - crc error: crc_val=0x%04x, computed=0x%04x len=%d\n", |
| 860 | scratch->crc_val, crc, t->len); | 847 | scratch->crc_val, crc, t->len); |
| 861 | return -EILSEQ; | 848 | return -EILSEQ; |
| 862 | } | 849 | } |
| 863 | } | 850 | } |
| @@ -945,9 +932,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
| 945 | 932 | ||
| 946 | dev_dbg(&host->spi->dev, | 933 | dev_dbg(&host->spi->dev, |
| 947 | " mmc_spi: %s block, %d bytes\n", | 934 | " mmc_spi: %s block, %d bytes\n", |
| 948 | (direction == DMA_TO_DEVICE) | 935 | (direction == DMA_TO_DEVICE) ? "write" : "read", |
| 949 | ? "write" | ||
| 950 | : "read", | ||
| 951 | t->len); | 936 | t->len); |
| 952 | 937 | ||
| 953 | if (direction == DMA_TO_DEVICE) | 938 | if (direction == DMA_TO_DEVICE) |
| @@ -974,8 +959,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, | |||
| 974 | if (status < 0) { | 959 | if (status < 0) { |
| 975 | data->error = status; | 960 | data->error = status; |
| 976 | dev_dbg(&spi->dev, "%s status %d\n", | 961 | dev_dbg(&spi->dev, "%s status %d\n", |
| 977 | (direction == DMA_TO_DEVICE) | 962 | (direction == DMA_TO_DEVICE) ? "write" : "read", |
| 978 | ? "write" : "read", | ||
| 979 | status); | 963 | status); |
| 980 | break; | 964 | break; |
| 981 | } | 965 | } |
| @@ -1249,8 +1233,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 1249 | mres = spi_setup(host->spi); | 1233 | mres = spi_setup(host->spi); |
| 1250 | if (mres < 0) | 1234 | if (mres < 0) |
| 1251 | dev_dbg(&host->spi->dev, | 1235 | dev_dbg(&host->spi->dev, |
| 1252 | "switch back to SPI mode 3" | 1236 | "switch back to SPI mode 3 failed\n"); |
| 1253 | " failed\n"); | ||
| 1254 | } | 1237 | } |
| 1255 | } | 1238 | } |
| 1256 | 1239 | ||
| @@ -1470,7 +1453,7 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
| 1470 | return 0; | 1453 | return 0; |
| 1471 | 1454 | ||
| 1472 | fail_add_host: | 1455 | fail_add_host: |
| 1473 | mmc_remove_host (mmc); | 1456 | mmc_remove_host(mmc); |
| 1474 | fail_glue_init: | 1457 | fail_glue_init: |
| 1475 | if (host->dma_dev) | 1458 | if (host->dma_dev) |
| 1476 | dma_unmap_single(host->dma_dev, host->data_dma, | 1459 | dma_unmap_single(host->dma_dev, host->data_dma, |
| @@ -1485,7 +1468,6 @@ fail_ones_dma: | |||
| 1485 | fail_nobuf1: | 1468 | fail_nobuf1: |
| 1486 | mmc_free_host(mmc); | 1469 | mmc_free_host(mmc); |
| 1487 | mmc_spi_put_pdata(spi); | 1470 | mmc_spi_put_pdata(spi); |
| 1488 | dev_set_drvdata(&spi->dev, NULL); | ||
| 1489 | 1471 | ||
| 1490 | nomem: | 1472 | nomem: |
| 1491 | kfree(ones); | 1473 | kfree(ones); |
| @@ -1496,32 +1478,27 @@ nomem: | |||
| 1496 | static int mmc_spi_remove(struct spi_device *spi) | 1478 | static int mmc_spi_remove(struct spi_device *spi) |
| 1497 | { | 1479 | { |
| 1498 | struct mmc_host *mmc = dev_get_drvdata(&spi->dev); | 1480 | struct mmc_host *mmc = dev_get_drvdata(&spi->dev); |
| 1499 | struct mmc_spi_host *host; | 1481 | struct mmc_spi_host *host = mmc_priv(mmc); |
| 1500 | |||
| 1501 | if (mmc) { | ||
| 1502 | host = mmc_priv(mmc); | ||
| 1503 | 1482 | ||
| 1504 | /* prevent new mmc_detect_change() calls */ | 1483 | /* prevent new mmc_detect_change() calls */ |
| 1505 | if (host->pdata && host->pdata->exit) | 1484 | if (host->pdata && host->pdata->exit) |
| 1506 | host->pdata->exit(&spi->dev, mmc); | 1485 | host->pdata->exit(&spi->dev, mmc); |
| 1507 | 1486 | ||
| 1508 | mmc_remove_host(mmc); | 1487 | mmc_remove_host(mmc); |
| 1509 | 1488 | ||
| 1510 | if (host->dma_dev) { | 1489 | if (host->dma_dev) { |
| 1511 | dma_unmap_single(host->dma_dev, host->ones_dma, | 1490 | dma_unmap_single(host->dma_dev, host->ones_dma, |
| 1512 | MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); | 1491 | MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); |
| 1513 | dma_unmap_single(host->dma_dev, host->data_dma, | 1492 | dma_unmap_single(host->dma_dev, host->data_dma, |
| 1514 | sizeof(*host->data), DMA_BIDIRECTIONAL); | 1493 | sizeof(*host->data), DMA_BIDIRECTIONAL); |
| 1515 | } | 1494 | } |
| 1516 | 1495 | ||
| 1517 | kfree(host->data); | 1496 | kfree(host->data); |
| 1518 | kfree(host->ones); | 1497 | kfree(host->ones); |
| 1519 | 1498 | ||
| 1520 | spi->max_speed_hz = mmc->f_max; | 1499 | spi->max_speed_hz = mmc->f_max; |
| 1521 | mmc_free_host(mmc); | 1500 | mmc_free_host(mmc); |
| 1522 | mmc_spi_put_pdata(spi); | 1501 | mmc_spi_put_pdata(spi); |
| 1523 | dev_set_drvdata(&spi->dev, NULL); | ||
| 1524 | } | ||
| 1525 | return 0; | 1502 | return 0; |
| 1526 | } | 1503 | } |
| 1527 | 1504 | ||
| @@ -1542,8 +1519,7 @@ static struct spi_driver mmc_spi_driver = { | |||
| 1542 | 1519 | ||
| 1543 | module_spi_driver(mmc_spi_driver); | 1520 | module_spi_driver(mmc_spi_driver); |
| 1544 | 1521 | ||
| 1545 | MODULE_AUTHOR("Mike Lavender, David Brownell, " | 1522 | MODULE_AUTHOR("Mike Lavender, David Brownell, Hans-Peter Nilsson, Jan Nikitenko"); |
| 1546 | "Hans-Peter Nilsson, Jan Nikitenko"); | ||
| 1547 | MODULE_DESCRIPTION("SPI SD/MMC host driver"); | 1523 | MODULE_DESCRIPTION("SPI SD/MMC host driver"); |
| 1548 | MODULE_LICENSE("GPL"); | 1524 | MODULE_LICENSE("GPL"); |
| 1549 | MODULE_ALIAS("spi:mmc_spi"); | 1525 | MODULE_ALIAS("spi:mmc_spi"); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 387ff14587b8..356833a606d5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -43,21 +43,11 @@ | |||
| 43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| 44 | 44 | ||
| 45 | #include "mmci.h" | 45 | #include "mmci.h" |
| 46 | #include "mmci_qcom_dml.h" | ||
| 47 | 46 | ||
| 48 | #define DRIVER_NAME "mmci-pl18x" | 47 | #define DRIVER_NAME "mmci-pl18x" |
| 49 | 48 | ||
| 50 | #ifdef CONFIG_DMA_ENGINE | 49 | static void mmci_variant_init(struct mmci_host *host); |
| 51 | void mmci_variant_init(struct mmci_host *host); | 50 | static void ux500v2_variant_init(struct mmci_host *host); |
| 52 | #else | ||
| 53 | static inline void mmci_variant_init(struct mmci_host *host) {} | ||
| 54 | #endif | ||
| 55 | |||
| 56 | #ifdef CONFIG_MMC_STM32_SDMMC | ||
| 57 | void sdmmc_variant_init(struct mmci_host *host); | ||
| 58 | #else | ||
| 59 | static inline void sdmmc_variant_init(struct mmci_host *host) {} | ||
| 60 | #endif | ||
| 61 | 51 | ||
| 62 | static unsigned int fmax = 515633; | 52 | static unsigned int fmax = 515633; |
| 63 | 53 | ||
| @@ -70,7 +60,6 @@ static struct variant_data variant_arm = { | |||
| 70 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 60 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 71 | .datalength_bits = 16, | 61 | .datalength_bits = 16, |
| 72 | .datactrl_blocksz = 11, | 62 | .datactrl_blocksz = 11, |
| 73 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 74 | .pwrreg_powerup = MCI_PWR_UP, | 63 | .pwrreg_powerup = MCI_PWR_UP, |
| 75 | .f_max = 100000000, | 64 | .f_max = 100000000, |
| 76 | .reversed_irq_handling = true, | 65 | .reversed_irq_handling = true, |
| @@ -90,7 +79,6 @@ static struct variant_data variant_arm_extended_fifo = { | |||
| 90 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 79 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 91 | .datalength_bits = 16, | 80 | .datalength_bits = 16, |
| 92 | .datactrl_blocksz = 11, | 81 | .datactrl_blocksz = 11, |
| 93 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 94 | .pwrreg_powerup = MCI_PWR_UP, | 82 | .pwrreg_powerup = MCI_PWR_UP, |
| 95 | .f_max = 100000000, | 83 | .f_max = 100000000, |
| 96 | .mmcimask1 = true, | 84 | .mmcimask1 = true, |
| @@ -110,7 +98,6 @@ static struct variant_data variant_arm_extended_fifo_hwfc = { | |||
| 110 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 98 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 111 | .datalength_bits = 16, | 99 | .datalength_bits = 16, |
| 112 | .datactrl_blocksz = 11, | 100 | .datactrl_blocksz = 11, |
| 113 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 114 | .pwrreg_powerup = MCI_PWR_UP, | 101 | .pwrreg_powerup = MCI_PWR_UP, |
| 115 | .f_max = 100000000, | 102 | .f_max = 100000000, |
| 116 | .mmcimask1 = true, | 103 | .mmcimask1 = true, |
| @@ -131,7 +118,6 @@ static struct variant_data variant_u300 = { | |||
| 131 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 118 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 132 | .datalength_bits = 16, | 119 | .datalength_bits = 16, |
| 133 | .datactrl_blocksz = 11, | 120 | .datactrl_blocksz = 11, |
| 134 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 135 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, | 121 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, |
| 136 | .st_sdio = true, | 122 | .st_sdio = true, |
| 137 | .pwrreg_powerup = MCI_PWR_ON, | 123 | .pwrreg_powerup = MCI_PWR_ON, |
| @@ -157,7 +143,6 @@ static struct variant_data variant_nomadik = { | |||
| 157 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 143 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 158 | .datalength_bits = 24, | 144 | .datalength_bits = 24, |
| 159 | .datactrl_blocksz = 11, | 145 | .datactrl_blocksz = 11, |
| 160 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 161 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, | 146 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, |
| 162 | .st_sdio = true, | 147 | .st_sdio = true, |
| 163 | .st_clkdiv = true, | 148 | .st_clkdiv = true, |
| @@ -186,7 +171,6 @@ static struct variant_data variant_ux500 = { | |||
| 186 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 171 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 187 | .datalength_bits = 24, | 172 | .datalength_bits = 24, |
| 188 | .datactrl_blocksz = 11, | 173 | .datactrl_blocksz = 11, |
| 189 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 190 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, | 174 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, |
| 191 | .st_sdio = true, | 175 | .st_sdio = true, |
| 192 | .st_clkdiv = true, | 176 | .st_clkdiv = true, |
| @@ -220,11 +204,9 @@ static struct variant_data variant_ux500v2 = { | |||
| 220 | .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, | 204 | .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, |
| 221 | .datalength_bits = 24, | 205 | .datalength_bits = 24, |
| 222 | .datactrl_blocksz = 11, | 206 | .datactrl_blocksz = 11, |
| 223 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 224 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, | 207 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, |
| 225 | .st_sdio = true, | 208 | .st_sdio = true, |
| 226 | .st_clkdiv = true, | 209 | .st_clkdiv = true, |
| 227 | .blksz_datactrl16 = true, | ||
| 228 | .pwrreg_powerup = MCI_PWR_ON, | 210 | .pwrreg_powerup = MCI_PWR_ON, |
| 229 | .f_max = 100000000, | 211 | .f_max = 100000000, |
| 230 | .signal_direction = true, | 212 | .signal_direction = true, |
| @@ -238,7 +220,7 @@ static struct variant_data variant_ux500v2 = { | |||
| 238 | .irq_pio_mask = MCI_IRQ_PIO_MASK, | 220 | .irq_pio_mask = MCI_IRQ_PIO_MASK, |
| 239 | .start_err = MCI_STARTBITERR, | 221 | .start_err = MCI_STARTBITERR, |
| 240 | .opendrain = MCI_OD, | 222 | .opendrain = MCI_OD, |
| 241 | .init = mmci_variant_init, | 223 | .init = ux500v2_variant_init, |
| 242 | }; | 224 | }; |
| 243 | 225 | ||
| 244 | static struct variant_data variant_stm32 = { | 226 | static struct variant_data variant_stm32 = { |
| @@ -255,7 +237,6 @@ static struct variant_data variant_stm32 = { | |||
| 255 | .irq_pio_mask = MCI_IRQ_PIO_MASK, | 237 | .irq_pio_mask = MCI_IRQ_PIO_MASK, |
| 256 | .datalength_bits = 24, | 238 | .datalength_bits = 24, |
| 257 | .datactrl_blocksz = 11, | 239 | .datactrl_blocksz = 11, |
| 258 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 259 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, | 240 | .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, |
| 260 | .st_sdio = true, | 241 | .st_sdio = true, |
| 261 | .st_clkdiv = true, | 242 | .st_clkdiv = true, |
| @@ -299,10 +280,8 @@ static struct variant_data variant_qcom = { | |||
| 299 | .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, | 280 | .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, |
| 300 | .cmdreg_srsp = MCI_CPSM_RESPONSE, | 281 | .cmdreg_srsp = MCI_CPSM_RESPONSE, |
| 301 | .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, | 282 | .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, |
| 302 | .blksz_datactrl4 = true, | ||
| 303 | .datalength_bits = 24, | 283 | .datalength_bits = 24, |
| 304 | .datactrl_blocksz = 11, | 284 | .datactrl_blocksz = 11, |
| 305 | .datactrl_dpsm_enable = MCI_DPSM_ENABLE, | ||
| 306 | .pwrreg_powerup = MCI_PWR_UP, | 285 | .pwrreg_powerup = MCI_PWR_UP, |
| 307 | .f_max = 208000000, | 286 | .f_max = 208000000, |
| 308 | .explicit_mclk_control = true, | 287 | .explicit_mclk_control = true, |
| @@ -624,6 +603,16 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) | |||
| 624 | sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); | 603 | sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); |
| 625 | } | 604 | } |
| 626 | 605 | ||
| 606 | static u32 mmci_get_dctrl_cfg(struct mmci_host *host) | ||
| 607 | { | ||
| 608 | return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host); | ||
| 609 | } | ||
| 610 | |||
| 611 | static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host) | ||
| 612 | { | ||
| 613 | return MCI_DPSM_ENABLE | (host->data->blksz << 16); | ||
| 614 | } | ||
| 615 | |||
| 627 | /* | 616 | /* |
| 628 | * All the DMA operation mode stuff goes inside this ifdef. | 617 | * All the DMA operation mode stuff goes inside this ifdef. |
| 629 | * This assumes that you have a generic DMA device interface, | 618 | * This assumes that you have a generic DMA device interface, |
| @@ -886,15 +875,11 @@ int mmci_dmae_prep_data(struct mmci_host *host, | |||
| 886 | int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) | 875 | int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) |
| 887 | { | 876 | { |
| 888 | struct mmci_dmae_priv *dmae = host->dma_priv; | 877 | struct mmci_dmae_priv *dmae = host->dma_priv; |
| 889 | struct mmc_data *data = host->data; | ||
| 890 | 878 | ||
| 891 | host->dma_in_progress = true; | 879 | host->dma_in_progress = true; |
| 892 | dmaengine_submit(dmae->desc_current); | 880 | dmaengine_submit(dmae->desc_current); |
| 893 | dma_async_issue_pending(dmae->cur); | 881 | dma_async_issue_pending(dmae->cur); |
| 894 | 882 | ||
| 895 | if (host->variant->qcom_dml) | ||
| 896 | dml_start_xfer(host, data); | ||
| 897 | |||
| 898 | *datactrl |= MCI_DPSM_DMAENABLE; | 883 | *datactrl |= MCI_DPSM_DMAENABLE; |
| 899 | 884 | ||
| 900 | return 0; | 885 | return 0; |
| @@ -952,6 +937,7 @@ void mmci_dmae_unprep_data(struct mmci_host *host, | |||
| 952 | static struct mmci_host_ops mmci_variant_ops = { | 937 | static struct mmci_host_ops mmci_variant_ops = { |
| 953 | .prep_data = mmci_dmae_prep_data, | 938 | .prep_data = mmci_dmae_prep_data, |
| 954 | .unprep_data = mmci_dmae_unprep_data, | 939 | .unprep_data = mmci_dmae_unprep_data, |
| 940 | .get_datactrl_cfg = mmci_get_dctrl_cfg, | ||
| 955 | .get_next_data = mmci_dmae_get_next_data, | 941 | .get_next_data = mmci_dmae_get_next_data, |
| 956 | .dma_setup = mmci_dmae_setup, | 942 | .dma_setup = mmci_dmae_setup, |
| 957 | .dma_release = mmci_dmae_release, | 943 | .dma_release = mmci_dmae_release, |
| @@ -959,12 +945,22 @@ static struct mmci_host_ops mmci_variant_ops = { | |||
| 959 | .dma_finalize = mmci_dmae_finalize, | 945 | .dma_finalize = mmci_dmae_finalize, |
| 960 | .dma_error = mmci_dmae_error, | 946 | .dma_error = mmci_dmae_error, |
| 961 | }; | 947 | }; |
| 948 | #else | ||
| 949 | static struct mmci_host_ops mmci_variant_ops = { | ||
| 950 | .get_datactrl_cfg = mmci_get_dctrl_cfg, | ||
| 951 | }; | ||
| 952 | #endif | ||
| 962 | 953 | ||
| 963 | void mmci_variant_init(struct mmci_host *host) | 954 | void mmci_variant_init(struct mmci_host *host) |
| 964 | { | 955 | { |
| 965 | host->ops = &mmci_variant_ops; | 956 | host->ops = &mmci_variant_ops; |
| 966 | } | 957 | } |
| 967 | #endif | 958 | |
| 959 | void ux500v2_variant_init(struct mmci_host *host) | ||
| 960 | { | ||
| 961 | host->ops = &mmci_variant_ops; | ||
| 962 | host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg; | ||
| 963 | } | ||
| 968 | 964 | ||
| 969 | static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) | 965 | static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) |
| 970 | { | 966 | { |
| @@ -1000,7 +996,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
| 1000 | unsigned int datactrl, timeout, irqmask; | 996 | unsigned int datactrl, timeout, irqmask; |
| 1001 | unsigned long long clks; | 997 | unsigned long long clks; |
| 1002 | void __iomem *base; | 998 | void __iomem *base; |
| 1003 | int blksz_bits; | ||
| 1004 | 999 | ||
| 1005 | dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", | 1000 | dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", |
| 1006 | data->blksz, data->blocks, data->flags); | 1001 | data->blksz, data->blocks, data->flags); |
| @@ -1018,18 +1013,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
| 1018 | writel(timeout, base + MMCIDATATIMER); | 1013 | writel(timeout, base + MMCIDATATIMER); |
| 1019 | writel(host->size, base + MMCIDATALENGTH); | 1014 | writel(host->size, base + MMCIDATALENGTH); |
| 1020 | 1015 | ||
| 1021 | blksz_bits = ffs(data->blksz) - 1; | 1016 | datactrl = host->ops->get_datactrl_cfg(host); |
| 1022 | BUG_ON(1 << blksz_bits != data->blksz); | 1017 | datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0; |
| 1023 | |||
| 1024 | if (variant->blksz_datactrl16) | ||
| 1025 | datactrl = variant->datactrl_dpsm_enable | (data->blksz << 16); | ||
| 1026 | else if (variant->blksz_datactrl4) | ||
| 1027 | datactrl = variant->datactrl_dpsm_enable | (data->blksz << 4); | ||
| 1028 | else | ||
| 1029 | datactrl = variant->datactrl_dpsm_enable | blksz_bits << 4; | ||
| 1030 | |||
| 1031 | if (data->flags & MMC_DATA_READ) | ||
| 1032 | datactrl |= MCI_DPSM_DIRECTION; | ||
| 1033 | 1018 | ||
| 1034 | if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { | 1019 | if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { |
| 1035 | u32 clk; | 1020 | u32 clk; |
| @@ -1220,12 +1205,13 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
| 1220 | unsigned int status) | 1205 | unsigned int status) |
| 1221 | { | 1206 | { |
| 1222 | void __iomem *base = host->base; | 1207 | void __iomem *base = host->base; |
| 1223 | bool sbc; | 1208 | bool sbc, busy_resp; |
| 1224 | 1209 | ||
| 1225 | if (!cmd) | 1210 | if (!cmd) |
| 1226 | return; | 1211 | return; |
| 1227 | 1212 | ||
| 1228 | sbc = (cmd == host->mrq->sbc); | 1213 | sbc = (cmd == host->mrq->sbc); |
| 1214 | busy_resp = !!(cmd->flags & MMC_RSP_BUSY); | ||
| 1229 | 1215 | ||
| 1230 | /* | 1216 | /* |
| 1231 | * We need to be one of these interrupts to be considered worth | 1217 | * We need to be one of these interrupts to be considered worth |
| @@ -1239,8 +1225,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
| 1239 | /* | 1225 | /* |
| 1240 | * ST Micro variant: handle busy detection. | 1226 | * ST Micro variant: handle busy detection. |
| 1241 | */ | 1227 | */ |
| 1242 | if (host->variant->busy_detect) { | 1228 | if (busy_resp && host->variant->busy_detect) { |
| 1243 | bool busy_resp = !!(cmd->flags & MMC_RSP_BUSY); | ||
| 1244 | 1229 | ||
| 1245 | /* We are busy with a command, return */ | 1230 | /* We are busy with a command, return */ |
| 1246 | if (host->busy_status && | 1231 | if (host->busy_status && |
| @@ -1253,7 +1238,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
| 1253 | * that the special busy status bit is still set before | 1238 | * that the special busy status bit is still set before |
| 1254 | * proceeding. | 1239 | * proceeding. |
| 1255 | */ | 1240 | */ |
| 1256 | if (!host->busy_status && busy_resp && | 1241 | if (!host->busy_status && |
| 1257 | !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && | 1242 | !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && |
| 1258 | (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { | 1243 | (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { |
| 1259 | 1244 | ||
| @@ -1550,9 +1535,10 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
| 1550 | } | 1535 | } |
| 1551 | 1536 | ||
| 1552 | /* | 1537 | /* |
| 1553 | * Don't poll for busy completion in irq context. | 1538 | * Busy detection has been handled by mmci_cmd_irq() above. |
| 1539 | * Clear the status bit to prevent polling in IRQ context. | ||
| 1554 | */ | 1540 | */ |
| 1555 | if (host->variant->busy_detect && host->busy_status) | 1541 | if (host->variant->busy_detect_flag) |
| 1556 | status &= ~host->variant->busy_detect_flag; | 1542 | status &= ~host->variant->busy_detect_flag; |
| 1557 | 1543 | ||
| 1558 | ret = 1; | 1544 | ret = 1; |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 14df81054438..4f071bd34e59 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
| @@ -131,6 +131,11 @@ | |||
| 131 | /* Control register extensions in the Qualcomm versions */ | 131 | /* Control register extensions in the Qualcomm versions */ |
| 132 | #define MCI_DPSM_QCOM_DATA_PEND BIT(17) | 132 | #define MCI_DPSM_QCOM_DATA_PEND BIT(17) |
| 133 | #define MCI_DPSM_QCOM_RX_DATA_PEND BIT(20) | 133 | #define MCI_DPSM_QCOM_RX_DATA_PEND BIT(20) |
| 134 | /* Control register extensions in STM32 versions */ | ||
| 135 | #define MCI_DPSM_STM32_MODE_BLOCK (0 << 2) | ||
| 136 | #define MCI_DPSM_STM32_MODE_SDIO (1 << 2) | ||
| 137 | #define MCI_DPSM_STM32_MODE_STREAM (2 << 2) | ||
| 138 | #define MCI_DPSM_STM32_MODE_BLOCK_STOP (3 << 2) | ||
| 134 | 139 | ||
| 135 | #define MMCIDATACNT 0x030 | 140 | #define MMCIDATACNT 0x030 |
| 136 | #define MMCISTATUS 0x034 | 141 | #define MMCISTATUS 0x034 |
| @@ -275,12 +280,8 @@ struct mmci_host; | |||
| 275 | * @st_clkdiv: true if using a ST-specific clock divider algorithm | 280 | * @st_clkdiv: true if using a ST-specific clock divider algorithm |
| 276 | * @stm32_clkdiv: true if using a STM32-specific clock divider algorithm | 281 | * @stm32_clkdiv: true if using a STM32-specific clock divider algorithm |
| 277 | * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. | 282 | * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. |
| 278 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register | ||
| 279 | * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl | ||
| 280 | * register | ||
| 281 | * @datactrl_mask_sdio: SDIO enable mask in datactrl register | 283 | * @datactrl_mask_sdio: SDIO enable mask in datactrl register |
| 282 | * @datactrl_blksz: block size in power of two | 284 | * @datactrl_blksz: block size in power of two |
| 283 | * @datactrl_dpsm_enable: enable value for DPSM | ||
| 284 | * @datactrl_first: true if data must be setup before send command | 285 | * @datactrl_first: true if data must be setup before send command |
| 285 | * @datacnt_useless: true if you could not use datacnt register to read | 286 | * @datacnt_useless: true if you could not use datacnt register to read |
| 286 | * remaining data | 287 | * remaining data |
| @@ -325,14 +326,11 @@ struct variant_data { | |||
| 325 | unsigned int datactrl_mask_ddrmode; | 326 | unsigned int datactrl_mask_ddrmode; |
| 326 | unsigned int datactrl_mask_sdio; | 327 | unsigned int datactrl_mask_sdio; |
| 327 | unsigned int datactrl_blocksz; | 328 | unsigned int datactrl_blocksz; |
| 328 | unsigned int datactrl_dpsm_enable; | ||
| 329 | u8 datactrl_first:1; | 329 | u8 datactrl_first:1; |
| 330 | u8 datacnt_useless:1; | 330 | u8 datacnt_useless:1; |
| 331 | u8 st_sdio:1; | 331 | u8 st_sdio:1; |
| 332 | u8 st_clkdiv:1; | 332 | u8 st_clkdiv:1; |
| 333 | u8 stm32_clkdiv:1; | 333 | u8 stm32_clkdiv:1; |
| 334 | u8 blksz_datactrl16:1; | ||
| 335 | u8 blksz_datactrl4:1; | ||
| 336 | u32 pwrreg_powerup; | 334 | u32 pwrreg_powerup; |
| 337 | u32 f_max; | 335 | u32 f_max; |
| 338 | u8 signal_direction:1; | 336 | u8 signal_direction:1; |
| @@ -362,6 +360,7 @@ struct mmci_host_ops { | |||
| 362 | bool next); | 360 | bool next); |
| 363 | void (*unprep_data)(struct mmci_host *host, struct mmc_data *data, | 361 | void (*unprep_data)(struct mmci_host *host, struct mmc_data *data, |
| 364 | int err); | 362 | int err); |
| 363 | u32 (*get_datactrl_cfg)(struct mmci_host *host); | ||
| 365 | void (*get_next_data)(struct mmci_host *host, struct mmc_data *data); | 364 | void (*get_next_data)(struct mmci_host *host, struct mmc_data *data); |
| 366 | int (*dma_setup)(struct mmci_host *host); | 365 | int (*dma_setup)(struct mmci_host *host); |
| 367 | void (*dma_release)(struct mmci_host *host); | 366 | void (*dma_release)(struct mmci_host *host); |
| @@ -429,6 +428,12 @@ struct mmci_host { | |||
| 429 | void mmci_write_clkreg(struct mmci_host *host, u32 clk); | 428 | void mmci_write_clkreg(struct mmci_host *host, u32 clk); |
| 430 | void mmci_write_pwrreg(struct mmci_host *host, u32 pwr); | 429 | void mmci_write_pwrreg(struct mmci_host *host, u32 pwr); |
| 431 | 430 | ||
| 431 | static inline u32 mmci_dctrl_blksz(struct mmci_host *host) | ||
| 432 | { | ||
| 433 | return (ffs(host->data->blksz) - 1) << 4; | ||
| 434 | } | ||
| 435 | |||
| 436 | #ifdef CONFIG_DMA_ENGINE | ||
| 432 | int mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, | 437 | int mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, |
| 433 | bool next); | 438 | bool next); |
| 434 | void mmci_dmae_unprep_data(struct mmci_host *host, struct mmc_data *data, | 439 | void mmci_dmae_unprep_data(struct mmci_host *host, struct mmc_data *data, |
| @@ -439,3 +444,16 @@ void mmci_dmae_release(struct mmci_host *host); | |||
| 439 | int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl); | 444 | int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl); |
| 440 | void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data); | 445 | void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data); |
| 441 | void mmci_dmae_error(struct mmci_host *host); | 446 | void mmci_dmae_error(struct mmci_host *host); |
| 447 | #endif | ||
| 448 | |||
| 449 | #ifdef CONFIG_MMC_QCOM_DML | ||
| 450 | void qcom_variant_init(struct mmci_host *host); | ||
| 451 | #else | ||
| 452 | static inline void qcom_variant_init(struct mmci_host *host) {} | ||
| 453 | #endif | ||
| 454 | |||
| 455 | #ifdef CONFIG_MMC_STM32_SDMMC | ||
| 456 | void sdmmc_variant_init(struct mmci_host *host); | ||
| 457 | #else | ||
| 458 | static inline void sdmmc_variant_init(struct mmci_host *host) {} | ||
| 459 | #endif | ||
diff --git a/drivers/mmc/host/mmci_qcom_dml.c b/drivers/mmc/host/mmci_qcom_dml.c index 25d0a75533ea..3af396b3e0a0 100644 --- a/drivers/mmc/host/mmci_qcom_dml.c +++ b/drivers/mmc/host/mmci_qcom_dml.c | |||
| @@ -54,10 +54,15 @@ | |||
| 54 | 54 | ||
| 55 | #define DML_OFFSET 0x800 | 55 | #define DML_OFFSET 0x800 |
| 56 | 56 | ||
| 57 | void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) | 57 | static int qcom_dma_start(struct mmci_host *host, unsigned int *datactrl) |
| 58 | { | 58 | { |
| 59 | u32 config; | 59 | u32 config; |
| 60 | void __iomem *base = host->base + DML_OFFSET; | 60 | void __iomem *base = host->base + DML_OFFSET; |
| 61 | struct mmc_data *data = host->data; | ||
| 62 | int ret = mmci_dmae_start(host, datactrl); | ||
| 63 | |||
| 64 | if (ret) | ||
| 65 | return ret; | ||
| 61 | 66 | ||
| 62 | if (data->flags & MMC_DATA_READ) { | 67 | if (data->flags & MMC_DATA_READ) { |
| 63 | /* Read operation: configure DML for producer operation */ | 68 | /* Read operation: configure DML for producer operation */ |
| @@ -96,6 +101,7 @@ void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) | |||
| 96 | 101 | ||
| 97 | /* make sure the dml is configured before dma is triggered */ | 102 | /* make sure the dml is configured before dma is triggered */ |
| 98 | wmb(); | 103 | wmb(); |
| 104 | return 0; | ||
| 99 | } | 105 | } |
| 100 | 106 | ||
| 101 | static int of_get_dml_pipe_index(struct device_node *np, const char *name) | 107 | static int of_get_dml_pipe_index(struct device_node *np, const char *name) |
| @@ -133,7 +139,6 @@ static int qcom_dma_setup(struct mmci_host *host) | |||
| 133 | producer_id = of_get_dml_pipe_index(np, "rx"); | 139 | producer_id = of_get_dml_pipe_index(np, "rx"); |
| 134 | 140 | ||
| 135 | if (producer_id < 0 || consumer_id < 0) { | 141 | if (producer_id < 0 || consumer_id < 0) { |
| 136 | host->variant->qcom_dml = false; | ||
| 137 | mmci_dmae_release(host); | 142 | mmci_dmae_release(host); |
| 138 | return -EINVAL; | 143 | return -EINVAL; |
| 139 | } | 144 | } |
| @@ -183,13 +188,19 @@ static int qcom_dma_setup(struct mmci_host *host) | |||
| 183 | return 0; | 188 | return 0; |
| 184 | } | 189 | } |
| 185 | 190 | ||
| 191 | static u32 qcom_get_dctrl_cfg(struct mmci_host *host) | ||
| 192 | { | ||
| 193 | return MCI_DPSM_ENABLE | (host->data->blksz << 4); | ||
| 194 | } | ||
| 195 | |||
| 186 | static struct mmci_host_ops qcom_variant_ops = { | 196 | static struct mmci_host_ops qcom_variant_ops = { |
| 187 | .prep_data = mmci_dmae_prep_data, | 197 | .prep_data = mmci_dmae_prep_data, |
| 188 | .unprep_data = mmci_dmae_unprep_data, | 198 | .unprep_data = mmci_dmae_unprep_data, |
| 199 | .get_datactrl_cfg = qcom_get_dctrl_cfg, | ||
| 189 | .get_next_data = mmci_dmae_get_next_data, | 200 | .get_next_data = mmci_dmae_get_next_data, |
| 190 | .dma_setup = qcom_dma_setup, | 201 | .dma_setup = qcom_dma_setup, |
| 191 | .dma_release = mmci_dmae_release, | 202 | .dma_release = mmci_dmae_release, |
| 192 | .dma_start = mmci_dmae_start, | 203 | .dma_start = qcom_dma_start, |
| 193 | .dma_finalize = mmci_dmae_finalize, | 204 | .dma_finalize = mmci_dmae_finalize, |
| 194 | .dma_error = mmci_dmae_error, | 205 | .dma_error = mmci_dmae_error, |
| 195 | }; | 206 | }; |
diff --git a/drivers/mmc/host/mmci_qcom_dml.h b/drivers/mmc/host/mmci_qcom_dml.h deleted file mode 100644 index fa16f6f4d4ad..000000000000 --- a/drivers/mmc/host/mmci_qcom_dml.h +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright (c) 2011, The Linux Foundation. All rights reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 and | ||
| 7 | * only version 2 as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | #ifndef __MMC_QCOM_DML_H__ | ||
| 16 | #define __MMC_QCOM_DML_H__ | ||
| 17 | |||
| 18 | #ifdef CONFIG_MMC_QCOM_DML | ||
| 19 | void qcom_variant_init(struct mmci_host *host); | ||
| 20 | void dml_start_xfer(struct mmci_host *host, struct mmc_data *data); | ||
| 21 | #else | ||
| 22 | static inline void qcom_variant_init(struct mmci_host *host) | ||
| 23 | { | ||
| 24 | } | ||
| 25 | static inline void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) | ||
| 26 | { | ||
| 27 | } | ||
| 28 | #endif /* CONFIG_MMC_QCOM_DML */ | ||
| 29 | |||
| 30 | #endif /* __MMC_QCOM_DML_H__ */ | ||
diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c index cfbfc6f1048f..8e83ae6920ae 100644 --- a/drivers/mmc/host/mmci_stm32_sdmmc.c +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c | |||
| @@ -265,10 +265,28 @@ static void mmci_sdmmc_set_pwrreg(struct mmci_host *host, unsigned int pwr) | |||
| 265 | } | 265 | } |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | static u32 sdmmc_get_dctrl_cfg(struct mmci_host *host) | ||
| 269 | { | ||
| 270 | u32 datactrl; | ||
| 271 | |||
| 272 | datactrl = mmci_dctrl_blksz(host); | ||
| 273 | |||
| 274 | if (host->mmc->card && mmc_card_sdio(host->mmc->card) && | ||
| 275 | host->data->blocks == 1) | ||
| 276 | datactrl |= MCI_DPSM_STM32_MODE_SDIO; | ||
| 277 | else if (host->data->stop && !host->mrq->sbc) | ||
| 278 | datactrl |= MCI_DPSM_STM32_MODE_BLOCK_STOP; | ||
| 279 | else | ||
| 280 | datactrl |= MCI_DPSM_STM32_MODE_BLOCK; | ||
| 281 | |||
| 282 | return datactrl; | ||
| 283 | } | ||
| 284 | |||
| 268 | static struct mmci_host_ops sdmmc_variant_ops = { | 285 | static struct mmci_host_ops sdmmc_variant_ops = { |
| 269 | .validate_data = sdmmc_idma_validate_data, | 286 | .validate_data = sdmmc_idma_validate_data, |
| 270 | .prep_data = sdmmc_idma_prep_data, | 287 | .prep_data = sdmmc_idma_prep_data, |
| 271 | .unprep_data = sdmmc_idma_unprep_data, | 288 | .unprep_data = sdmmc_idma_unprep_data, |
| 289 | .get_datactrl_cfg = sdmmc_get_dctrl_cfg, | ||
| 272 | .dma_setup = sdmmc_idma_setup, | 290 | .dma_setup = sdmmc_idma_setup, |
| 273 | .dma_start = sdmmc_idma_start, | 291 | .dma_start = sdmmc_idma_start, |
| 274 | .dma_finalize = sdmmc_idma_finalize, | 292 | .dma_finalize = sdmmc_idma_finalize, |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 833ef0590af8..c518cc208a1f 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
| @@ -300,6 +300,8 @@ | |||
| 300 | #define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */ | 300 | #define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */ |
| 301 | #define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */ | 301 | #define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */ |
| 302 | 302 | ||
| 303 | #define DEFAULT_DEBOUNCE (8) /* 8 cycles CD debounce */ | ||
| 304 | |||
| 303 | #define PAD_DELAY_MAX 32 /* PAD delay cells */ | 305 | #define PAD_DELAY_MAX 32 /* PAD delay cells */ |
| 304 | /*--------------------------------------------------------------------------*/ | 306 | /*--------------------------------------------------------------------------*/ |
| 305 | /* Descriptor Structure */ | 307 | /* Descriptor Structure */ |
| @@ -372,6 +374,7 @@ struct mtk_mmc_compatible { | |||
| 372 | bool stop_clk_fix; | 374 | bool stop_clk_fix; |
| 373 | bool enhance_rx; | 375 | bool enhance_rx; |
| 374 | bool support_64g; | 376 | bool support_64g; |
| 377 | bool use_internal_cd; | ||
| 375 | }; | 378 | }; |
| 376 | 379 | ||
| 377 | struct msdc_tune_para { | 380 | struct msdc_tune_para { |
| @@ -430,6 +433,7 @@ struct msdc_host { | |||
| 430 | bool hs400_cmd_resp_sel_rising; | 433 | bool hs400_cmd_resp_sel_rising; |
| 431 | /* cmd response sample selection for HS400 */ | 434 | /* cmd response sample selection for HS400 */ |
| 432 | bool hs400_mode; /* current eMMC will run at hs400 mode */ | 435 | bool hs400_mode; /* current eMMC will run at hs400 mode */ |
| 436 | bool internal_cd; /* Use internal card-detect logic */ | ||
| 433 | struct msdc_save_para save_para; /* used when gate HCLK */ | 437 | struct msdc_save_para save_para; /* used when gate HCLK */ |
| 434 | struct msdc_tune_para def_tune_para; /* default tune setting */ | 438 | struct msdc_tune_para def_tune_para; /* default tune setting */ |
| 435 | struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */ | 439 | struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */ |
| @@ -507,6 +511,28 @@ static const struct mtk_mmc_compatible mt7622_compat = { | |||
| 507 | .support_64g = false, | 511 | .support_64g = false, |
| 508 | }; | 512 | }; |
| 509 | 513 | ||
| 514 | static const struct mtk_mmc_compatible mt8516_compat = { | ||
| 515 | .clk_div_bits = 12, | ||
| 516 | .hs400_tune = false, | ||
| 517 | .pad_tune_reg = MSDC_PAD_TUNE0, | ||
| 518 | .async_fifo = true, | ||
| 519 | .data_tune = true, | ||
| 520 | .busy_check = true, | ||
| 521 | .stop_clk_fix = true, | ||
| 522 | }; | ||
| 523 | |||
| 524 | static const struct mtk_mmc_compatible mt7620_compat = { | ||
| 525 | .clk_div_bits = 8, | ||
| 526 | .hs400_tune = false, | ||
| 527 | .pad_tune_reg = MSDC_PAD_TUNE, | ||
| 528 | .async_fifo = false, | ||
| 529 | .data_tune = false, | ||
| 530 | .busy_check = false, | ||
| 531 | .stop_clk_fix = false, | ||
| 532 | .enhance_rx = false, | ||
| 533 | .use_internal_cd = true, | ||
| 534 | }; | ||
| 535 | |||
| 510 | static const struct of_device_id msdc_of_ids[] = { | 536 | static const struct of_device_id msdc_of_ids[] = { |
| 511 | { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat}, | 537 | { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat}, |
| 512 | { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat}, | 538 | { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat}, |
| @@ -514,6 +540,8 @@ static const struct of_device_id msdc_of_ids[] = { | |||
| 514 | { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat}, | 540 | { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat}, |
| 515 | { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat}, | 541 | { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat}, |
| 516 | { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat}, | 542 | { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat}, |
| 543 | { .compatible = "mediatek,mt8516-mmc", .data = &mt8516_compat}, | ||
| 544 | { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat}, | ||
| 517 | {} | 545 | {} |
| 518 | }; | 546 | }; |
| 519 | MODULE_DEVICE_TABLE(of, msdc_of_ids); | 547 | MODULE_DEVICE_TABLE(of, msdc_of_ids); |
| @@ -1407,6 +1435,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) | |||
| 1407 | sdio_signal_irq(host->mmc); | 1435 | sdio_signal_irq(host->mmc); |
| 1408 | } | 1436 | } |
| 1409 | 1437 | ||
| 1438 | if ((events & event_mask) & MSDC_INT_CDSC) { | ||
| 1439 | if (host->internal_cd) | ||
| 1440 | mmc_detect_change(host->mmc, msecs_to_jiffies(20)); | ||
| 1441 | events &= ~MSDC_INT_CDSC; | ||
| 1442 | } | ||
| 1443 | |||
| 1410 | if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ))) | 1444 | if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ))) |
| 1411 | break; | 1445 | break; |
| 1412 | 1446 | ||
| @@ -1440,14 +1474,24 @@ static void msdc_init_hw(struct msdc_host *host) | |||
| 1440 | /* Reset */ | 1474 | /* Reset */ |
| 1441 | msdc_reset_hw(host); | 1475 | msdc_reset_hw(host); |
| 1442 | 1476 | ||
| 1443 | /* Disable card detection */ | ||
| 1444 | sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); | ||
| 1445 | |||
| 1446 | /* Disable and clear all interrupts */ | 1477 | /* Disable and clear all interrupts */ |
| 1447 | writel(0, host->base + MSDC_INTEN); | 1478 | writel(0, host->base + MSDC_INTEN); |
| 1448 | val = readl(host->base + MSDC_INT); | 1479 | val = readl(host->base + MSDC_INT); |
| 1449 | writel(val, host->base + MSDC_INT); | 1480 | writel(val, host->base + MSDC_INT); |
| 1450 | 1481 | ||
| 1482 | /* Configure card detection */ | ||
| 1483 | if (host->internal_cd) { | ||
| 1484 | sdr_set_field(host->base + MSDC_PS, MSDC_PS_CDDEBOUNCE, | ||
| 1485 | DEFAULT_DEBOUNCE); | ||
| 1486 | sdr_set_bits(host->base + MSDC_PS, MSDC_PS_CDEN); | ||
| 1487 | sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); | ||
| 1488 | sdr_set_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); | ||
| 1489 | } else { | ||
| 1490 | sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); | ||
| 1491 | sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); | ||
| 1492 | sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); | ||
| 1493 | } | ||
| 1494 | |||
| 1451 | if (host->top_base) { | 1495 | if (host->top_base) { |
| 1452 | writel(0, host->top_base + EMMC_TOP_CONTROL); | 1496 | writel(0, host->top_base + EMMC_TOP_CONTROL); |
| 1453 | writel(0, host->top_base + EMMC_TOP_CMD); | 1497 | writel(0, host->top_base + EMMC_TOP_CMD); |
| @@ -1557,6 +1601,13 @@ static void msdc_init_hw(struct msdc_host *host) | |||
| 1557 | static void msdc_deinit_hw(struct msdc_host *host) | 1601 | static void msdc_deinit_hw(struct msdc_host *host) |
| 1558 | { | 1602 | { |
| 1559 | u32 val; | 1603 | u32 val; |
| 1604 | |||
| 1605 | if (host->internal_cd) { | ||
| 1606 | /* Disabled card-detect */ | ||
| 1607 | sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); | ||
| 1608 | sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); | ||
| 1609 | } | ||
| 1610 | |||
| 1560 | /* Disable and clear all interrupts */ | 1611 | /* Disable and clear all interrupts */ |
| 1561 | writel(0, host->base + MSDC_INTEN); | 1612 | writel(0, host->base + MSDC_INTEN); |
| 1562 | 1613 | ||
| @@ -2055,13 +2106,31 @@ static void msdc_ack_sdio_irq(struct mmc_host *mmc) | |||
| 2055 | __msdc_enable_sdio_irq(mmc, 1); | 2106 | __msdc_enable_sdio_irq(mmc, 1); |
| 2056 | } | 2107 | } |
| 2057 | 2108 | ||
| 2109 | static int msdc_get_cd(struct mmc_host *mmc) | ||
| 2110 | { | ||
| 2111 | struct msdc_host *host = mmc_priv(mmc); | ||
| 2112 | int val; | ||
| 2113 | |||
| 2114 | if (mmc->caps & MMC_CAP_NONREMOVABLE) | ||
| 2115 | return 1; | ||
| 2116 | |||
| 2117 | if (!host->internal_cd) | ||
| 2118 | return mmc_gpio_get_cd(mmc); | ||
| 2119 | |||
| 2120 | val = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS; | ||
| 2121 | if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) | ||
| 2122 | return !!val; | ||
| 2123 | else | ||
| 2124 | return !val; | ||
| 2125 | } | ||
| 2126 | |||
| 2058 | static const struct mmc_host_ops mt_msdc_ops = { | 2127 | static const struct mmc_host_ops mt_msdc_ops = { |
| 2059 | .post_req = msdc_post_req, | 2128 | .post_req = msdc_post_req, |
| 2060 | .pre_req = msdc_pre_req, | 2129 | .pre_req = msdc_pre_req, |
| 2061 | .request = msdc_ops_request, | 2130 | .request = msdc_ops_request, |
| 2062 | .set_ios = msdc_ops_set_ios, | 2131 | .set_ios = msdc_ops_set_ios, |
| 2063 | .get_ro = mmc_gpio_get_ro, | 2132 | .get_ro = mmc_gpio_get_ro, |
| 2064 | .get_cd = mmc_gpio_get_cd, | 2133 | .get_cd = msdc_get_cd, |
| 2065 | .enable_sdio_irq = msdc_enable_sdio_irq, | 2134 | .enable_sdio_irq = msdc_enable_sdio_irq, |
| 2066 | .ack_sdio_irq = msdc_ack_sdio_irq, | 2135 | .ack_sdio_irq = msdc_ack_sdio_irq, |
| 2067 | .start_signal_voltage_switch = msdc_ops_switch_volt, | 2136 | .start_signal_voltage_switch = msdc_ops_switch_volt, |
| @@ -2123,9 +2192,11 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 2123 | } | 2192 | } |
| 2124 | 2193 | ||
| 2125 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2194 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 2126 | host->top_base = devm_ioremap_resource(&pdev->dev, res); | 2195 | if (res) { |
| 2127 | if (IS_ERR(host->top_base)) | 2196 | host->top_base = devm_ioremap_resource(&pdev->dev, res); |
| 2128 | host->top_base = NULL; | 2197 | if (IS_ERR(host->top_base)) |
| 2198 | host->top_base = NULL; | ||
| 2199 | } | ||
| 2129 | 2200 | ||
| 2130 | ret = mmc_regulator_get_supply(mmc); | 2201 | ret = mmc_regulator_get_supply(mmc); |
| 2131 | if (ret) | 2202 | if (ret) |
| @@ -2191,6 +2262,16 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 2191 | else | 2262 | else |
| 2192 | mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095); | 2263 | mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095); |
| 2193 | 2264 | ||
| 2265 | if (!(mmc->caps & MMC_CAP_NONREMOVABLE) && | ||
| 2266 | !mmc_can_gpio_cd(mmc) && | ||
| 2267 | host->dev_comp->use_internal_cd) { | ||
| 2268 | /* | ||
| 2269 | * Is removable but no GPIO declared, so | ||
| 2270 | * use internal functionality. | ||
| 2271 | */ | ||
| 2272 | host->internal_cd = true; | ||
| 2273 | } | ||
| 2274 | |||
| 2194 | if (mmc->caps & MMC_CAP_SDIO_IRQ) | 2275 | if (mmc->caps & MMC_CAP_SDIO_IRQ) |
| 2195 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; | 2276 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; |
| 2196 | 2277 | ||
| @@ -2227,7 +2308,7 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 2227 | msdc_init_hw(host); | 2308 | msdc_init_hw(host); |
| 2228 | 2309 | ||
| 2229 | ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, | 2310 | ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, |
| 2230 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, pdev->name, host); | 2311 | IRQF_TRIGGER_NONE, pdev->name, host); |
| 2231 | if (ret) | 2312 | if (ret) |
| 2232 | goto release; | 2313 | goto release; |
| 2233 | 2314 | ||
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 4f06fb03c0a2..c021d433b04f 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
| @@ -648,7 +648,8 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
| 648 | /* set mmc core parameters */ | 648 | /* set mmc core parameters */ |
| 649 | mmc->ops = &mxs_mmc_ops; | 649 | mmc->ops = &mxs_mmc_ops; |
| 650 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | | 650 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | |
| 651 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL | MMC_CAP_CMD23; | 651 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL | MMC_CAP_CMD23 | |
| 652 | MMC_CAP_ERASE; | ||
| 652 | 653 | ||
| 653 | host->broken_cd = of_property_read_bool(np, "broken-cd"); | 654 | host->broken_cd = of_property_read_bool(np, "broken-cd"); |
| 654 | 655 | ||
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 8a274b91804e..3c4d950a4755 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c | |||
| @@ -1,14 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 1 | /* | 2 | /* |
| 2 | * OpenFirmware bindings for the MMC-over-SPI driver | 3 | * OpenFirmware bindings for the MMC-over-SPI driver |
| 3 | * | 4 | * |
| 4 | * Copyright (c) MontaVista Software, Inc. 2008. | 5 | * Copyright (c) MontaVista Software, Inc. 2008. |
| 5 | * | 6 | * |
| 6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | 7 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | 8 | */ |
| 13 | 9 | ||
| 14 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 29a1ddaa7466..952fa4063ff8 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -2077,7 +2077,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) | |||
| 2077 | unsigned long flags; | 2077 | unsigned long flags; |
| 2078 | int ret = 0; | 2078 | int ret = 0; |
| 2079 | 2079 | ||
| 2080 | host = platform_get_drvdata(to_platform_device(dev)); | 2080 | host = dev_get_drvdata(dev); |
| 2081 | omap_hsmmc_context_save(host); | 2081 | omap_hsmmc_context_save(host); |
| 2082 | dev_dbg(dev, "disabled\n"); | 2082 | dev_dbg(dev, "disabled\n"); |
| 2083 | 2083 | ||
| @@ -2118,7 +2118,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev) | |||
| 2118 | struct omap_hsmmc_host *host; | 2118 | struct omap_hsmmc_host *host; |
| 2119 | unsigned long flags; | 2119 | unsigned long flags; |
| 2120 | 2120 | ||
| 2121 | host = platform_get_drvdata(to_platform_device(dev)); | 2121 | host = dev_get_drvdata(dev); |
| 2122 | omap_hsmmc_context_restore(host); | 2122 | omap_hsmmc_context_restore(host); |
| 2123 | dev_dbg(dev, "enabled\n"); | 2123 | dev_dbg(dev, "enabled\n"); |
| 2124 | 2124 | ||
diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index 8394a7bb1fc1..c0504aa90857 100644 --- a/drivers/mmc/host/renesas_sdhi.h +++ b/drivers/mmc/host/renesas_sdhi.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * Renesas Mobile SDHI | 3 | * Renesas Mobile SDHI |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2017 Horms Solutions Ltd., Simon Horman | 5 | * Copyright (C) 2017 Horms Solutions Ltd., Simon Horman |
| 6 | * Copyright (C) 2017 Renesas Electronics Corporation | 6 | * Copyright (C) 2017-19 Renesas Electronics Corporation |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #ifndef RENESAS_SDHI_H | 9 | #ifndef RENESAS_SDHI_H |
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 8742e27e4e8b..5e9e36ed2107 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | /* | 2 | /* |
| 3 | * Renesas SDHI | 3 | * Renesas SDHI |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2015-17 Renesas Electronics Corporation | 5 | * Copyright (C) 2015-19 Renesas Electronics Corporation |
| 6 | * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang | 6 | * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang |
| 7 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman | 7 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman |
| 8 | * Copyright (C) 2009 Magnus Damm | 8 | * Copyright (C) 2009 Magnus Damm |
| 9 | * | 9 | * |
| @@ -779,14 +779,14 @@ int renesas_sdhi_probe(struct platform_device *pdev, | |||
| 779 | if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX) | 779 | if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX) |
| 780 | mmc_data->max_blk_count = U16_MAX; | 780 | mmc_data->max_blk_count = U16_MAX; |
| 781 | 781 | ||
| 782 | ret = tmio_mmc_host_probe(host); | ||
| 783 | if (ret < 0) | ||
| 784 | goto edisclk; | ||
| 785 | |||
| 786 | /* One Gen2 SDHI incarnation does NOT have a CBSY bit */ | 782 | /* One Gen2 SDHI incarnation does NOT have a CBSY bit */ |
| 787 | if (ver == SDHI_VER_GEN2_SDR50) | 783 | if (ver == SDHI_VER_GEN2_SDR50) |
| 788 | mmc_data->flags &= ~TMIO_MMC_HAVE_CBSY; | 784 | mmc_data->flags &= ~TMIO_MMC_HAVE_CBSY; |
| 789 | 785 | ||
| 786 | ret = tmio_mmc_host_probe(host); | ||
| 787 | if (ret < 0) | ||
| 788 | goto edisclk; | ||
| 789 | |||
| 790 | /* Enable tuning iff we have an SCC and a supported mode */ | 790 | /* Enable tuning iff we have an SCC and a supported mode */ |
| 791 | if (of_data && of_data->scc_offset && | 791 | if (of_data && of_data->scc_offset && |
| 792 | (host->mmc->caps & MMC_CAP_UHS_SDR104 || | 792 | (host->mmc->caps & MMC_CAP_UHS_SDR104 || |
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 9dfafa2a90a3..751fe91c7571 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | /* | 2 | /* |
| 3 | * DMA support for Internal DMAC with SDHI SD/SDIO controller | 3 | * DMA support for Internal DMAC with SDHI SD/SDIO controller |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2016-17 Renesas Electronics Corporation | 5 | * Copyright (C) 2016-19 Renesas Electronics Corporation |
| 6 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman | 6 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman |
| 7 | * Copyright (C) 2018-19 Sang Engineering, Wolfram Sang | ||
| 7 | */ | 8 | */ |
| 8 | 9 | ||
| 9 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
| @@ -95,8 +96,8 @@ static const struct renesas_sdhi_of_data of_rza2_compatible = { | |||
| 95 | .scc_offset = 0 - 0x1000, | 96 | .scc_offset = 0 - 0x1000, |
| 96 | .taps = rcar_gen3_scc_taps, | 97 | .taps = rcar_gen3_scc_taps, |
| 97 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), | 98 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
| 98 | /* DMAC can handle 0xffffffff blk count but only 1 segment */ | 99 | /* DMAC can handle 32bit blk count but only 1 segment */ |
| 99 | .max_blk_count = 0xffffffff, | 100 | .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE, |
| 100 | .max_segs = 1, | 101 | .max_segs = 1, |
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| @@ -110,8 +111,8 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
| 110 | .scc_offset = 0x1000, | 111 | .scc_offset = 0x1000, |
| 111 | .taps = rcar_gen3_scc_taps, | 112 | .taps = rcar_gen3_scc_taps, |
| 112 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), | 113 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
| 113 | /* DMAC can handle 0xffffffff blk count but only 1 segment */ | 114 | /* DMAC can handle 32bit blk count but only 1 segment */ |
| 114 | .max_blk_count = 0xffffffff, | 115 | .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE, |
| 115 | .max_segs = 1, | 116 | .max_segs = 1, |
| 116 | }; | 117 | }; |
| 117 | 118 | ||
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index 02cd878e209f..1d29b822efb8 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | /* | 2 | /* |
| 3 | * DMA support use of SYS DMAC with SDHI SD/SDIO controller | 3 | * DMA support use of SYS DMAC with SDHI SD/SDIO controller |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2016-17 Renesas Electronics Corporation | 5 | * Copyright (C) 2016-19 Renesas Electronics Corporation |
| 6 | * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang | 6 | * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang |
| 7 | * Copyright (C) 2017 Horms Solutions, Simon Horman | 7 | * Copyright (C) 2017 Horms Solutions, Simon Horman |
| 8 | * Copyright (C) 2010-2011 Guennadi Liakhovetski | 8 | * Copyright (C) 2010-2011 Guennadi Liakhovetski |
| 9 | */ | 9 | */ |
| @@ -65,7 +65,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen2_compatible = { | |||
| 65 | .scc_offset = 0x0300, | 65 | .scc_offset = 0x0300, |
| 66 | .taps = rcar_gen2_scc_taps, | 66 | .taps = rcar_gen2_scc_taps, |
| 67 | .taps_num = ARRAY_SIZE(rcar_gen2_scc_taps), | 67 | .taps_num = ARRAY_SIZE(rcar_gen2_scc_taps), |
| 68 | .max_blk_count = 0xffffffff, | 68 | .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE, |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | /* Definitions for sampling clocks */ | 71 | /* Definitions for sampling clocks */ |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 8dbbc1f62b70..c391510e9ef4 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/pm_qos.h> | ||
| 17 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
| 18 | #include <linux/mmc/mmc.h> | 19 | #include <linux/mmc/mmc.h> |
| 19 | #include <linux/mmc/sdio.h> | 20 | #include <linux/mmc/sdio.h> |
| @@ -73,6 +74,7 @@ | |||
| 73 | #define ESDHC_STROBE_DLL_CTRL_ENABLE (1 << 0) | 74 | #define ESDHC_STROBE_DLL_CTRL_ENABLE (1 << 0) |
| 74 | #define ESDHC_STROBE_DLL_CTRL_RESET (1 << 1) | 75 | #define ESDHC_STROBE_DLL_CTRL_RESET (1 << 1) |
| 75 | #define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 | 76 | #define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 |
| 77 | #define ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT (4 << 20) | ||
| 76 | 78 | ||
| 77 | #define ESDHC_STROBE_DLL_STATUS 0x74 | 79 | #define ESDHC_STROBE_DLL_STATUS 0x74 |
| 78 | #define ESDHC_STROBE_DLL_STS_REF_LOCK (1 << 1) | 80 | #define ESDHC_STROBE_DLL_STS_REF_LOCK (1 << 1) |
| @@ -156,6 +158,8 @@ | |||
| 156 | #define ESDHC_FLAG_HS400_ES BIT(11) | 158 | #define ESDHC_FLAG_HS400_ES BIT(11) |
| 157 | /* The IP has Host Controller Interface for Command Queuing */ | 159 | /* The IP has Host Controller Interface for Command Queuing */ |
| 158 | #define ESDHC_FLAG_CQHCI BIT(12) | 160 | #define ESDHC_FLAG_CQHCI BIT(12) |
| 161 | /* need request pmqos during low power */ | ||
| 162 | #define ESDHC_FLAG_PMQOS BIT(13) | ||
| 159 | 163 | ||
| 160 | struct esdhc_soc_data { | 164 | struct esdhc_soc_data { |
| 161 | u32 flags; | 165 | u32 flags; |
| @@ -204,6 +208,12 @@ static const struct esdhc_soc_data usdhc_imx7d_data = { | |||
| 204 | | ESDHC_FLAG_HS400, | 208 | | ESDHC_FLAG_HS400, |
| 205 | }; | 209 | }; |
| 206 | 210 | ||
| 211 | static struct esdhc_soc_data usdhc_imx7ulp_data = { | ||
| 212 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | ||
| 213 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ||
| 214 | | ESDHC_FLAG_PMQOS | ESDHC_FLAG_HS400, | ||
| 215 | }; | ||
| 216 | |||
| 207 | static struct esdhc_soc_data usdhc_imx8qxp_data = { | 217 | static struct esdhc_soc_data usdhc_imx8qxp_data = { |
| 208 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | 218 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
| 209 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | 219 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
| @@ -229,6 +239,7 @@ struct pltfm_imx_data { | |||
| 229 | WAIT_FOR_INT, /* sent CMD12, waiting for response INT */ | 239 | WAIT_FOR_INT, /* sent CMD12, waiting for response INT */ |
| 230 | } multiblock_status; | 240 | } multiblock_status; |
| 231 | u32 is_ddr; | 241 | u32 is_ddr; |
| 242 | struct pm_qos_request pm_qos_req; | ||
| 232 | }; | 243 | }; |
| 233 | 244 | ||
| 234 | static const struct platform_device_id imx_esdhc_devtype[] = { | 245 | static const struct platform_device_id imx_esdhc_devtype[] = { |
| @@ -257,6 +268,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = { | |||
| 257 | { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, }, | 268 | { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, }, |
| 258 | { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, }, | 269 | { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, }, |
| 259 | { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, }, | 270 | { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, }, |
| 271 | { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, }, | ||
| 260 | { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, }, | 272 | { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, }, |
| 261 | { /* sentinel */ } | 273 | { /* sentinel */ } |
| 262 | }; | 274 | }; |
| @@ -983,15 +995,19 @@ static void esdhc_set_strobe_dll(struct sdhci_host *host) | |||
| 983 | /* force a reset on strobe dll */ | 995 | /* force a reset on strobe dll */ |
| 984 | writel(ESDHC_STROBE_DLL_CTRL_RESET, | 996 | writel(ESDHC_STROBE_DLL_CTRL_RESET, |
| 985 | host->ioaddr + ESDHC_STROBE_DLL_CTRL); | 997 | host->ioaddr + ESDHC_STROBE_DLL_CTRL); |
| 998 | /* clear the reset bit on strobe dll before any setting */ | ||
| 999 | writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL); | ||
| 1000 | |||
| 986 | /* | 1001 | /* |
| 987 | * enable strobe dll ctrl and adjust the delay target | 1002 | * enable strobe dll ctrl and adjust the delay target |
| 988 | * for the uSDHC loopback read clock | 1003 | * for the uSDHC loopback read clock |
| 989 | */ | 1004 | */ |
| 990 | v = ESDHC_STROBE_DLL_CTRL_ENABLE | | 1005 | v = ESDHC_STROBE_DLL_CTRL_ENABLE | |
| 1006 | ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT | | ||
| 991 | (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); | 1007 | (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); |
| 992 | writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); | 1008 | writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); |
| 993 | /* wait 1us to make sure strobe dll status register stable */ | 1009 | /* wait 5us to make sure strobe dll status register stable */ |
| 994 | udelay(1); | 1010 | udelay(5); |
| 995 | v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS); | 1011 | v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS); |
| 996 | if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK)) | 1012 | if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK)) |
| 997 | dev_warn(mmc_dev(host->mmc), | 1013 | dev_warn(mmc_dev(host->mmc), |
| @@ -1436,6 +1452,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
| 1436 | imx_data->socdata = of_id ? of_id->data : (struct esdhc_soc_data *) | 1452 | imx_data->socdata = of_id ? of_id->data : (struct esdhc_soc_data *) |
| 1437 | pdev->id_entry->driver_data; | 1453 | pdev->id_entry->driver_data; |
| 1438 | 1454 | ||
| 1455 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1456 | pm_qos_add_request(&imx_data->pm_qos_req, | ||
| 1457 | PM_QOS_CPU_DMA_LATENCY, 0); | ||
| 1458 | |||
| 1439 | imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1459 | imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
| 1440 | if (IS_ERR(imx_data->clk_ipg)) { | 1460 | if (IS_ERR(imx_data->clk_ipg)) { |
| 1441 | err = PTR_ERR(imx_data->clk_ipg); | 1461 | err = PTR_ERR(imx_data->clk_ipg); |
| @@ -1557,6 +1577,8 @@ disable_ipg_clk: | |||
| 1557 | disable_per_clk: | 1577 | disable_per_clk: |
| 1558 | clk_disable_unprepare(imx_data->clk_per); | 1578 | clk_disable_unprepare(imx_data->clk_per); |
| 1559 | free_sdhci: | 1579 | free_sdhci: |
| 1580 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1581 | pm_qos_remove_request(&imx_data->pm_qos_req); | ||
| 1560 | sdhci_pltfm_free(pdev); | 1582 | sdhci_pltfm_free(pdev); |
| 1561 | return err; | 1583 | return err; |
| 1562 | } | 1584 | } |
| @@ -1578,6 +1600,9 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev) | |||
| 1578 | clk_disable_unprepare(imx_data->clk_ipg); | 1600 | clk_disable_unprepare(imx_data->clk_ipg); |
| 1579 | clk_disable_unprepare(imx_data->clk_ahb); | 1601 | clk_disable_unprepare(imx_data->clk_ahb); |
| 1580 | 1602 | ||
| 1603 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1604 | pm_qos_remove_request(&imx_data->pm_qos_req); | ||
| 1605 | |||
| 1581 | sdhci_pltfm_free(pdev); | 1606 | sdhci_pltfm_free(pdev); |
| 1582 | 1607 | ||
| 1583 | return 0; | 1608 | return 0; |
| @@ -1649,6 +1674,9 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev) | |||
| 1649 | } | 1674 | } |
| 1650 | clk_disable_unprepare(imx_data->clk_ahb); | 1675 | clk_disable_unprepare(imx_data->clk_ahb); |
| 1651 | 1676 | ||
| 1677 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1678 | pm_qos_remove_request(&imx_data->pm_qos_req); | ||
| 1679 | |||
| 1652 | return ret; | 1680 | return ret; |
| 1653 | } | 1681 | } |
| 1654 | 1682 | ||
| @@ -1659,9 +1687,13 @@ static int sdhci_esdhc_runtime_resume(struct device *dev) | |||
| 1659 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); | 1687 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); |
| 1660 | int err; | 1688 | int err; |
| 1661 | 1689 | ||
| 1690 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1691 | pm_qos_add_request(&imx_data->pm_qos_req, | ||
| 1692 | PM_QOS_CPU_DMA_LATENCY, 0); | ||
| 1693 | |||
| 1662 | err = clk_prepare_enable(imx_data->clk_ahb); | 1694 | err = clk_prepare_enable(imx_data->clk_ahb); |
| 1663 | if (err) | 1695 | if (err) |
| 1664 | return err; | 1696 | goto remove_pm_qos_request; |
| 1665 | 1697 | ||
| 1666 | if (!sdhci_sdio_irq_enabled(host)) { | 1698 | if (!sdhci_sdio_irq_enabled(host)) { |
| 1667 | err = clk_prepare_enable(imx_data->clk_per); | 1699 | err = clk_prepare_enable(imx_data->clk_per); |
| @@ -1690,6 +1722,9 @@ disable_per_clk: | |||
| 1690 | clk_disable_unprepare(imx_data->clk_per); | 1722 | clk_disable_unprepare(imx_data->clk_per); |
| 1691 | disable_ahb_clk: | 1723 | disable_ahb_clk: |
| 1692 | clk_disable_unprepare(imx_data->clk_ahb); | 1724 | clk_disable_unprepare(imx_data->clk_ahb); |
| 1725 | remove_pm_qos_request: | ||
| 1726 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) | ||
| 1727 | pm_qos_remove_request(&imx_data->pm_qos_req); | ||
| 1693 | return err; | 1728 | return err; |
| 1694 | } | 1729 | } |
| 1695 | #endif | 1730 | #endif |
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index c9e3e050ccc8..88dc3f00a5be 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c | |||
| @@ -832,7 +832,10 @@ static int sdhci_arasan_probe(struct platform_device *pdev) | |||
| 832 | host->mmc_host_ops.start_signal_voltage_switch = | 832 | host->mmc_host_ops.start_signal_voltage_switch = |
| 833 | sdhci_arasan_voltage_switch; | 833 | sdhci_arasan_voltage_switch; |
| 834 | sdhci_arasan->has_cqe = true; | 834 | sdhci_arasan->has_cqe = true; |
| 835 | host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; | 835 | host->mmc->caps2 |= MMC_CAP2_CQE; |
| 836 | |||
| 837 | if (!of_property_read_bool(np, "disable-cqe-dcmd")) | ||
| 838 | host->mmc->caps2 |= MMC_CAP2_CQE_DCMD; | ||
| 836 | } | 839 | } |
| 837 | 840 | ||
| 838 | ret = sdhci_arasan_add_host(sdhci_arasan); | 841 | ret = sdhci_arasan_add_host(sdhci_arasan); |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 4e669b4edfc1..e20c00f14109 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/ktime.h> | 24 | #include <linux/ktime.h> |
| 25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
| 26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
| 27 | #include <linux/mmc/mmc.h> | ||
| 27 | #include "sdhci-pltfm.h" | 28 | #include "sdhci-pltfm.h" |
| 28 | #include "sdhci-esdhc.h" | 29 | #include "sdhci-esdhc.h" |
| 29 | 30 | ||
| @@ -81,6 +82,7 @@ struct sdhci_esdhc { | |||
| 81 | bool quirk_limited_clk_division; | 82 | bool quirk_limited_clk_division; |
| 82 | bool quirk_unreliable_pulse_detection; | 83 | bool quirk_unreliable_pulse_detection; |
| 83 | bool quirk_fixup_tuning; | 84 | bool quirk_fixup_tuning; |
| 85 | bool quirk_ignore_data_inhibit; | ||
| 84 | unsigned int peripheral_clock; | 86 | unsigned int peripheral_clock; |
| 85 | const struct esdhc_clk_fixup *clk_fixup; | 87 | const struct esdhc_clk_fixup *clk_fixup; |
| 86 | u32 div_ratio; | 88 | u32 div_ratio; |
| @@ -147,6 +149,19 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, | |||
| 147 | return ret; | 149 | return ret; |
| 148 | } | 150 | } |
| 149 | 151 | ||
| 152 | /* | ||
| 153 | * Some controllers have unreliable Data Line Active | ||
| 154 | * bit for commands with busy signal. This affects | ||
| 155 | * Command Inhibit (data) bit. Just ignore it since | ||
| 156 | * MMC core driver has already polled card status | ||
| 157 | * with CMD13 after any command with busy siganl. | ||
| 158 | */ | ||
| 159 | if ((spec_reg == SDHCI_PRESENT_STATE) && | ||
| 160 | (esdhc->quirk_ignore_data_inhibit == true)) { | ||
| 161 | ret = value & ~SDHCI_DATA_INHIBIT; | ||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 150 | ret = value; | 165 | ret = value; |
| 151 | return ret; | 166 | return ret; |
| 152 | } | 167 | } |
| @@ -694,6 +709,9 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask) | |||
| 694 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | 709 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); |
| 695 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 710 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
| 696 | 711 | ||
| 712 | if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) | ||
| 713 | mdelay(5); | ||
| 714 | |||
| 697 | if (mask & SDHCI_RESET_ALL) { | 715 | if (mask & SDHCI_RESET_ALL) { |
| 698 | val = sdhci_readl(host, ESDHC_TBCTL); | 716 | val = sdhci_readl(host, ESDHC_TBCTL); |
| 699 | val &= ~ESDHC_TB_EN; | 717 | val &= ~ESDHC_TB_EN; |
| @@ -864,6 +882,25 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, | |||
| 864 | sdhci_set_uhs_signaling(host, timing); | 882 | sdhci_set_uhs_signaling(host, timing); |
| 865 | } | 883 | } |
| 866 | 884 | ||
| 885 | static u32 esdhc_irq(struct sdhci_host *host, u32 intmask) | ||
| 886 | { | ||
| 887 | u32 command; | ||
| 888 | |||
| 889 | if (of_find_compatible_node(NULL, NULL, | ||
| 890 | "fsl,p2020-esdhc")) { | ||
| 891 | command = SDHCI_GET_CMD(sdhci_readw(host, | ||
| 892 | SDHCI_COMMAND)); | ||
| 893 | if (command == MMC_WRITE_MULTIPLE_BLOCK && | ||
| 894 | sdhci_readw(host, SDHCI_BLOCK_COUNT) && | ||
| 895 | intmask & SDHCI_INT_DATA_END) { | ||
| 896 | intmask &= ~SDHCI_INT_DATA_END; | ||
| 897 | sdhci_writel(host, SDHCI_INT_DATA_END, | ||
| 898 | SDHCI_INT_STATUS); | ||
| 899 | } | ||
| 900 | } | ||
| 901 | return intmask; | ||
| 902 | } | ||
| 903 | |||
| 867 | #ifdef CONFIG_PM_SLEEP | 904 | #ifdef CONFIG_PM_SLEEP |
| 868 | static u32 esdhc_proctl; | 905 | static u32 esdhc_proctl; |
| 869 | static int esdhc_of_suspend(struct device *dev) | 906 | static int esdhc_of_suspend(struct device *dev) |
| @@ -911,6 +948,7 @@ static const struct sdhci_ops sdhci_esdhc_be_ops = { | |||
| 911 | .set_bus_width = esdhc_pltfm_set_bus_width, | 948 | .set_bus_width = esdhc_pltfm_set_bus_width, |
| 912 | .reset = esdhc_reset, | 949 | .reset = esdhc_reset, |
| 913 | .set_uhs_signaling = esdhc_set_uhs_signaling, | 950 | .set_uhs_signaling = esdhc_set_uhs_signaling, |
| 951 | .irq = esdhc_irq, | ||
| 914 | }; | 952 | }; |
| 915 | 953 | ||
| 916 | static const struct sdhci_ops sdhci_esdhc_le_ops = { | 954 | static const struct sdhci_ops sdhci_esdhc_le_ops = { |
| @@ -928,6 +966,7 @@ static const struct sdhci_ops sdhci_esdhc_le_ops = { | |||
| 928 | .set_bus_width = esdhc_pltfm_set_bus_width, | 966 | .set_bus_width = esdhc_pltfm_set_bus_width, |
| 929 | .reset = esdhc_reset, | 967 | .reset = esdhc_reset, |
| 930 | .set_uhs_signaling = esdhc_set_uhs_signaling, | 968 | .set_uhs_signaling = esdhc_set_uhs_signaling, |
| 969 | .irq = esdhc_irq, | ||
| 931 | }; | 970 | }; |
| 932 | 971 | ||
| 933 | static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { | 972 | static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { |
| @@ -955,6 +994,7 @@ static struct soc_device_attribute soc_incorrect_hostver[] = { | |||
| 955 | 994 | ||
| 956 | static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { | 995 | static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { |
| 957 | { .family = "QorIQ LX2160A", .revision = "1.0", }, | 996 | { .family = "QorIQ LX2160A", .revision = "1.0", }, |
| 997 | { .family = "QorIQ LX2160A", .revision = "2.0", }, | ||
| 958 | { }, | 998 | { }, |
| 959 | }; | 999 | }; |
| 960 | 1000 | ||
| @@ -1074,6 +1114,11 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) | |||
| 1074 | if (esdhc->vendor_ver > VENDOR_V_22) | 1114 | if (esdhc->vendor_ver > VENDOR_V_22) |
| 1075 | host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; | 1115 | host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; |
| 1076 | 1116 | ||
| 1117 | if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) { | ||
| 1118 | host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST; | ||
| 1119 | host->quirks2 |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | ||
| 1120 | } | ||
| 1121 | |||
| 1077 | if (of_device_is_compatible(np, "fsl,p5040-esdhc") || | 1122 | if (of_device_is_compatible(np, "fsl,p5040-esdhc") || |
| 1078 | of_device_is_compatible(np, "fsl,p5020-esdhc") || | 1123 | of_device_is_compatible(np, "fsl,p5020-esdhc") || |
| 1079 | of_device_is_compatible(np, "fsl,p4080-esdhc") || | 1124 | of_device_is_compatible(np, "fsl,p4080-esdhc") || |
| @@ -1084,12 +1129,14 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) | |||
| 1084 | if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) | 1129 | if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) |
| 1085 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | 1130 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; |
| 1086 | 1131 | ||
| 1132 | esdhc->quirk_ignore_data_inhibit = false; | ||
| 1087 | if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { | 1133 | if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { |
| 1088 | /* | 1134 | /* |
| 1089 | * Freescale messed up with P2020 as it has a non-standard | 1135 | * Freescale messed up with P2020 as it has a non-standard |
| 1090 | * host control register | 1136 | * host control register |
| 1091 | */ | 1137 | */ |
| 1092 | host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; | 1138 | host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; |
| 1139 | esdhc->quirk_ignore_data_inhibit = true; | ||
| 1093 | } | 1140 | } |
| 1094 | 1141 | ||
| 1095 | /* call to generic mmc_of_parse to support additional capabilities */ | 1142 | /* call to generic mmc_of_parse to support additional capabilities */ |
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 9f20fff9781b..bdb80c503fde 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c | |||
| @@ -785,7 +785,7 @@ static void sdhci_omap_set_uhs_signaling(struct sdhci_host *host, | |||
| 785 | sdhci_omap_start_clock(omap_host); | 785 | sdhci_omap_start_clock(omap_host); |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | void sdhci_omap_reset(struct sdhci_host *host, u8 mask) | 788 | static void sdhci_omap_reset(struct sdhci_host *host, u8 mask) |
| 789 | { | 789 | { |
| 790 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 790 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 791 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | 791 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); |
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 99b0fec2836b..ab9e2b901094 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
| @@ -31,6 +31,10 @@ | |||
| 31 | #include <linux/mmc/sdhci-pci-data.h> | 31 | #include <linux/mmc/sdhci-pci-data.h> |
| 32 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_X86 | ||
| 35 | #include <asm/iosf_mbi.h> | ||
| 36 | #endif | ||
| 37 | |||
| 34 | #include "cqhci.h" | 38 | #include "cqhci.h" |
| 35 | 39 | ||
| 36 | #include "sdhci.h" | 40 | #include "sdhci.h" |
| @@ -451,6 +455,50 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { | |||
| 451 | .probe_slot = pch_hc_probe_slot, | 455 | .probe_slot = pch_hc_probe_slot, |
| 452 | }; | 456 | }; |
| 453 | 457 | ||
| 458 | #ifdef CONFIG_X86 | ||
| 459 | |||
| 460 | #define BYT_IOSF_SCCEP 0x63 | ||
| 461 | #define BYT_IOSF_OCP_NETCTRL0 0x1078 | ||
| 462 | #define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) | ||
| 463 | |||
| 464 | static void byt_ocp_setting(struct pci_dev *pdev) | ||
| 465 | { | ||
| 466 | u32 val = 0; | ||
| 467 | |||
| 468 | if (pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC && | ||
| 469 | pdev->device != PCI_DEVICE_ID_INTEL_BYT_SDIO && | ||
| 470 | pdev->device != PCI_DEVICE_ID_INTEL_BYT_SD && | ||
| 471 | pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC2) | ||
| 472 | return; | ||
| 473 | |||
| 474 | if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, | ||
| 475 | &val)) { | ||
| 476 | dev_err(&pdev->dev, "%s read error\n", __func__); | ||
| 477 | return; | ||
| 478 | } | ||
| 479 | |||
| 480 | if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) | ||
| 481 | return; | ||
| 482 | |||
| 483 | val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; | ||
| 484 | |||
| 485 | if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, | ||
| 486 | val)) { | ||
| 487 | dev_err(&pdev->dev, "%s write error\n", __func__); | ||
| 488 | return; | ||
| 489 | } | ||
| 490 | |||
| 491 | dev_dbg(&pdev->dev, "%s completed\n", __func__); | ||
| 492 | } | ||
| 493 | |||
| 494 | #else | ||
| 495 | |||
| 496 | static inline void byt_ocp_setting(struct pci_dev *pdev) | ||
| 497 | { | ||
| 498 | } | ||
| 499 | |||
| 500 | #endif | ||
| 501 | |||
| 454 | enum { | 502 | enum { |
| 455 | INTEL_DSM_FNS = 0, | 503 | INTEL_DSM_FNS = 0, |
| 456 | INTEL_DSM_V18_SWITCH = 3, | 504 | INTEL_DSM_V18_SWITCH = 3, |
| @@ -715,6 +763,8 @@ static void byt_probe_slot(struct sdhci_pci_slot *slot) | |||
| 715 | 763 | ||
| 716 | byt_read_dsm(slot); | 764 | byt_read_dsm(slot); |
| 717 | 765 | ||
| 766 | byt_ocp_setting(slot->chip->pdev); | ||
| 767 | |||
| 718 | ops->execute_tuning = intel_execute_tuning; | 768 | ops->execute_tuning = intel_execute_tuning; |
| 719 | ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; | 769 | ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; |
| 720 | 770 | ||
| @@ -938,7 +988,35 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
| 938 | return 0; | 988 | return 0; |
| 939 | } | 989 | } |
| 940 | 990 | ||
| 991 | #ifdef CONFIG_PM_SLEEP | ||
| 992 | |||
| 993 | static int byt_resume(struct sdhci_pci_chip *chip) | ||
| 994 | { | ||
| 995 | byt_ocp_setting(chip->pdev); | ||
| 996 | |||
| 997 | return sdhci_pci_resume_host(chip); | ||
| 998 | } | ||
| 999 | |||
| 1000 | #endif | ||
| 1001 | |||
| 1002 | #ifdef CONFIG_PM | ||
| 1003 | |||
| 1004 | static int byt_runtime_resume(struct sdhci_pci_chip *chip) | ||
| 1005 | { | ||
| 1006 | byt_ocp_setting(chip->pdev); | ||
| 1007 | |||
| 1008 | return sdhci_pci_runtime_resume_host(chip); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | #endif | ||
| 1012 | |||
| 941 | static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { | 1013 | static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { |
| 1014 | #ifdef CONFIG_PM_SLEEP | ||
| 1015 | .resume = byt_resume, | ||
| 1016 | #endif | ||
| 1017 | #ifdef CONFIG_PM | ||
| 1018 | .runtime_resume = byt_runtime_resume, | ||
| 1019 | #endif | ||
| 942 | .allow_runtime_pm = true, | 1020 | .allow_runtime_pm = true, |
| 943 | .probe_slot = byt_emmc_probe_slot, | 1021 | .probe_slot = byt_emmc_probe_slot, |
| 944 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | 1022 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
| @@ -972,6 +1050,12 @@ static const struct sdhci_pci_fixes sdhci_intel_glk_emmc = { | |||
| 972 | }; | 1050 | }; |
| 973 | 1051 | ||
| 974 | static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { | 1052 | static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { |
| 1053 | #ifdef CONFIG_PM_SLEEP | ||
| 1054 | .resume = byt_resume, | ||
| 1055 | #endif | ||
| 1056 | #ifdef CONFIG_PM | ||
| 1057 | .runtime_resume = byt_runtime_resume, | ||
| 1058 | #endif | ||
| 975 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | 1059 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
| 976 | SDHCI_QUIRK_NO_LED, | 1060 | SDHCI_QUIRK_NO_LED, |
| 977 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | | 1061 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | |
| @@ -983,6 +1067,12 @@ static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { | |||
| 983 | }; | 1067 | }; |
| 984 | 1068 | ||
| 985 | static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { | 1069 | static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { |
| 1070 | #ifdef CONFIG_PM_SLEEP | ||
| 1071 | .resume = byt_resume, | ||
| 1072 | #endif | ||
| 1073 | #ifdef CONFIG_PM | ||
| 1074 | .runtime_resume = byt_runtime_resume, | ||
| 1075 | #endif | ||
| 986 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | 1076 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
| 987 | SDHCI_QUIRK_NO_LED, | 1077 | SDHCI_QUIRK_NO_LED, |
| 988 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | | 1078 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | |
| @@ -994,6 +1084,12 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { | |||
| 994 | }; | 1084 | }; |
| 995 | 1085 | ||
| 996 | static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { | 1086 | static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { |
| 1087 | #ifdef CONFIG_PM_SLEEP | ||
| 1088 | .resume = byt_resume, | ||
| 1089 | #endif | ||
| 1090 | #ifdef CONFIG_PM | ||
| 1091 | .runtime_resume = byt_runtime_resume, | ||
| 1092 | #endif | ||
| 997 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | 1093 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
| 998 | SDHCI_QUIRK_NO_LED, | 1094 | SDHCI_QUIRK_NO_LED, |
| 999 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | | 1095 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | |
| @@ -1576,6 +1672,8 @@ static const struct pci_device_id pci_ids[] = { | |||
| 1576 | SDHCI_PCI_DEVICE(INTEL, CNPH_SD, intel_byt_sd), | 1672 | SDHCI_PCI_DEVICE(INTEL, CNPH_SD, intel_byt_sd), |
| 1577 | SDHCI_PCI_DEVICE(INTEL, ICP_EMMC, intel_glk_emmc), | 1673 | SDHCI_PCI_DEVICE(INTEL, ICP_EMMC, intel_glk_emmc), |
| 1578 | SDHCI_PCI_DEVICE(INTEL, ICP_SD, intel_byt_sd), | 1674 | SDHCI_PCI_DEVICE(INTEL, ICP_SD, intel_byt_sd), |
| 1675 | SDHCI_PCI_DEVICE(INTEL, CML_EMMC, intel_glk_emmc), | ||
| 1676 | SDHCI_PCI_DEVICE(INTEL, CML_SD, intel_byt_sd), | ||
| 1579 | SDHCI_PCI_DEVICE(O2, 8120, o2), | 1677 | SDHCI_PCI_DEVICE(O2, 8120, o2), |
| 1580 | SDHCI_PCI_DEVICE(O2, 8220, o2), | 1678 | SDHCI_PCI_DEVICE(O2, 8220, o2), |
| 1581 | SDHCI_PCI_DEVICE(O2, 8221, o2), | 1679 | SDHCI_PCI_DEVICE(O2, 8221, o2), |
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 4ddb69a15cd7..e5dc6e44c7a4 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
| @@ -50,6 +50,8 @@ | |||
| 50 | #define PCI_DEVICE_ID_INTEL_CNPH_SD 0xa375 | 50 | #define PCI_DEVICE_ID_INTEL_CNPH_SD 0xa375 |
| 51 | #define PCI_DEVICE_ID_INTEL_ICP_EMMC 0x34c4 | 51 | #define PCI_DEVICE_ID_INTEL_ICP_EMMC 0x34c4 |
| 52 | #define PCI_DEVICE_ID_INTEL_ICP_SD 0x34f8 | 52 | #define PCI_DEVICE_ID_INTEL_ICP_SD 0x34f8 |
| 53 | #define PCI_DEVICE_ID_INTEL_CML_EMMC 0x02c4 | ||
| 54 | #define PCI_DEVICE_ID_INTEL_CML_SD 0x02f5 | ||
| 53 | 55 | ||
| 54 | #define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000 | 56 | #define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000 |
| 55 | #define PCI_DEVICE_ID_VIA_95D0 0x95d0 | 57 | #define PCI_DEVICE_ID_VIA_95D0 0x95d0 |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 32e62904c0d3..f608417ae967 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
| @@ -66,6 +66,22 @@ | |||
| 66 | 66 | ||
| 67 | #define SDHCI_VNDR_TUN_CTRL0_0 0x1c0 | 67 | #define SDHCI_VNDR_TUN_CTRL0_0 0x1c0 |
| 68 | #define SDHCI_VNDR_TUN_CTRL0_TUN_HW_TAP 0x20000 | 68 | #define SDHCI_VNDR_TUN_CTRL0_TUN_HW_TAP 0x20000 |
| 69 | #define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_MASK 0x03fc0000 | ||
| 70 | #define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_SHIFT 18 | ||
| 71 | #define SDHCI_VNDR_TUN_CTRL0_MUL_M_MASK 0x00001fc0 | ||
| 72 | #define SDHCI_VNDR_TUN_CTRL0_MUL_M_SHIFT 6 | ||
| 73 | #define SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK 0x000e000 | ||
| 74 | #define SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT 13 | ||
| 75 | #define TRIES_128 2 | ||
| 76 | #define TRIES_256 4 | ||
| 77 | #define SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK 0x7 | ||
| 78 | |||
| 79 | #define SDHCI_TEGRA_VNDR_TUN_CTRL1_0 0x1c4 | ||
| 80 | #define SDHCI_TEGRA_VNDR_TUN_STATUS0 0x1C8 | ||
| 81 | #define SDHCI_TEGRA_VNDR_TUN_STATUS1 0x1CC | ||
| 82 | #define SDHCI_TEGRA_VNDR_TUN_STATUS1_TAP_MASK 0xFF | ||
| 83 | #define SDHCI_TEGRA_VNDR_TUN_STATUS1_END_TAP_SHIFT 0x8 | ||
| 84 | #define TUNING_WORD_BIT_SIZE 32 | ||
| 69 | 85 | ||
| 70 | #define SDHCI_TEGRA_AUTO_CAL_CONFIG 0x1e4 | 86 | #define SDHCI_TEGRA_AUTO_CAL_CONFIG 0x1e4 |
| 71 | #define SDHCI_AUTO_CAL_START BIT(31) | 87 | #define SDHCI_AUTO_CAL_START BIT(31) |
| @@ -90,6 +106,7 @@ | |||
| 90 | #define NVQUIRK_HAS_PADCALIB BIT(6) | 106 | #define NVQUIRK_HAS_PADCALIB BIT(6) |
| 91 | #define NVQUIRK_NEEDS_PAD_CONTROL BIT(7) | 107 | #define NVQUIRK_NEEDS_PAD_CONTROL BIT(7) |
| 92 | #define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP BIT(8) | 108 | #define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP BIT(8) |
| 109 | #define NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING BIT(9) | ||
| 93 | 110 | ||
| 94 | /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ | 111 | /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ |
| 95 | #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 | 112 | #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 |
| @@ -97,6 +114,8 @@ | |||
| 97 | struct sdhci_tegra_soc_data { | 114 | struct sdhci_tegra_soc_data { |
| 98 | const struct sdhci_pltfm_data *pdata; | 115 | const struct sdhci_pltfm_data *pdata; |
| 99 | u32 nvquirks; | 116 | u32 nvquirks; |
| 117 | u8 min_tap_delay; | ||
| 118 | u8 max_tap_delay; | ||
| 100 | }; | 119 | }; |
| 101 | 120 | ||
| 102 | /* Magic pull up and pull down pad calibration offsets */ | 121 | /* Magic pull up and pull down pad calibration offsets */ |
| @@ -136,6 +155,8 @@ struct sdhci_tegra { | |||
| 136 | u32 default_trim; | 155 | u32 default_trim; |
| 137 | u32 dqs_trim; | 156 | u32 dqs_trim; |
| 138 | bool enable_hwcq; | 157 | bool enable_hwcq; |
| 158 | unsigned long curr_clk_rate; | ||
| 159 | u8 tuned_tap_delay; | ||
| 139 | }; | 160 | }; |
| 140 | 161 | ||
| 141 | static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) | 162 | static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) |
| @@ -241,6 +262,7 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg) | |||
| 241 | 262 | ||
| 242 | if (is_tuning_cmd) { | 263 | if (is_tuning_cmd) { |
| 243 | udelay(1); | 264 | udelay(1); |
| 265 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | ||
| 244 | tegra_sdhci_configure_card_clk(host, clk_enabled); | 266 | tegra_sdhci_configure_card_clk(host, clk_enabled); |
| 245 | } | 267 | } |
| 246 | } | 268 | } |
| @@ -722,6 +744,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 722 | */ | 744 | */ |
| 723 | host_clk = tegra_host->ddr_signaling ? clock * 2 : clock; | 745 | host_clk = tegra_host->ddr_signaling ? clock * 2 : clock; |
| 724 | clk_set_rate(pltfm_host->clk, host_clk); | 746 | clk_set_rate(pltfm_host->clk, host_clk); |
| 747 | tegra_host->curr_clk_rate = host_clk; | ||
| 725 | if (tegra_host->ddr_signaling) | 748 | if (tegra_host->ddr_signaling) |
| 726 | host->max_clk = host_clk; | 749 | host->max_clk = host_clk; |
| 727 | else | 750 | else |
| @@ -770,6 +793,159 @@ static void tegra_sdhci_hs400_dll_cal(struct sdhci_host *host) | |||
| 770 | "HS400 delay line calibration timed out\n"); | 793 | "HS400 delay line calibration timed out\n"); |
| 771 | } | 794 | } |
| 772 | 795 | ||
| 796 | static void tegra_sdhci_tap_correction(struct sdhci_host *host, u8 thd_up, | ||
| 797 | u8 thd_low, u8 fixed_tap) | ||
| 798 | { | ||
| 799 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 800 | struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); | ||
| 801 | u32 val, tun_status; | ||
| 802 | u8 word, bit, edge1, tap, window; | ||
| 803 | bool tap_result; | ||
| 804 | bool start_fail = false; | ||
| 805 | bool start_pass = false; | ||
| 806 | bool end_pass = false; | ||
| 807 | bool first_fail = false; | ||
| 808 | bool first_pass = false; | ||
| 809 | u8 start_pass_tap = 0; | ||
| 810 | u8 end_pass_tap = 0; | ||
| 811 | u8 first_fail_tap = 0; | ||
| 812 | u8 first_pass_tap = 0; | ||
| 813 | u8 total_tuning_words = host->tuning_loop_count / TUNING_WORD_BIT_SIZE; | ||
| 814 | |||
| 815 | /* | ||
| 816 | * Read auto-tuned results and extract good valid passing window by | ||
| 817 | * filtering out un-wanted bubble/partial/merged windows. | ||
| 818 | */ | ||
| 819 | for (word = 0; word < total_tuning_words; word++) { | ||
| 820 | val = sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0); | ||
| 821 | val &= ~SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK; | ||
| 822 | val |= word; | ||
| 823 | sdhci_writel(host, val, SDHCI_VNDR_TUN_CTRL0_0); | ||
| 824 | tun_status = sdhci_readl(host, SDHCI_TEGRA_VNDR_TUN_STATUS0); | ||
| 825 | bit = 0; | ||
| 826 | while (bit < TUNING_WORD_BIT_SIZE) { | ||
| 827 | tap = word * TUNING_WORD_BIT_SIZE + bit; | ||
| 828 | tap_result = tun_status & (1 << bit); | ||
| 829 | if (!tap_result && !start_fail) { | ||
| 830 | start_fail = true; | ||
| 831 | if (!first_fail) { | ||
| 832 | first_fail_tap = tap; | ||
| 833 | first_fail = true; | ||
| 834 | } | ||
| 835 | |||
| 836 | } else if (tap_result && start_fail && !start_pass) { | ||
| 837 | start_pass_tap = tap; | ||
| 838 | start_pass = true; | ||
| 839 | if (!first_pass) { | ||
| 840 | first_pass_tap = tap; | ||
| 841 | first_pass = true; | ||
| 842 | } | ||
| 843 | |||
| 844 | } else if (!tap_result && start_fail && start_pass && | ||
| 845 | !end_pass) { | ||
| 846 | end_pass_tap = tap - 1; | ||
| 847 | end_pass = true; | ||
| 848 | } else if (tap_result && start_pass && start_fail && | ||
| 849 | end_pass) { | ||
| 850 | window = end_pass_tap - start_pass_tap; | ||
| 851 | /* discard merged window and bubble window */ | ||
| 852 | if (window >= thd_up || window < thd_low) { | ||
| 853 | start_pass_tap = tap; | ||
| 854 | end_pass = false; | ||
| 855 | } else { | ||
| 856 | /* set tap at middle of valid window */ | ||
| 857 | tap = start_pass_tap + window / 2; | ||
| 858 | tegra_host->tuned_tap_delay = tap; | ||
| 859 | return; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | bit++; | ||
| 864 | } | ||
| 865 | } | ||
| 866 | |||
| 867 | if (!first_fail) { | ||
| 868 | WARN_ON("no edge detected, continue with hw tuned delay.\n"); | ||
| 869 | } else if (first_pass) { | ||
| 870 | /* set tap location at fixed tap relative to the first edge */ | ||
| 871 | edge1 = first_fail_tap + (first_pass_tap - first_fail_tap) / 2; | ||
| 872 | if (edge1 - 1 > fixed_tap) | ||
| 873 | tegra_host->tuned_tap_delay = edge1 - fixed_tap; | ||
| 874 | else | ||
| 875 | tegra_host->tuned_tap_delay = edge1 + fixed_tap; | ||
| 876 | } | ||
| 877 | } | ||
| 878 | |||
| 879 | static void tegra_sdhci_post_tuning(struct sdhci_host *host) | ||
| 880 | { | ||
| 881 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 882 | struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); | ||
| 883 | const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; | ||
| 884 | u32 avg_tap_dly, val, min_tap_dly, max_tap_dly; | ||
| 885 | u8 fixed_tap, start_tap, end_tap, window_width; | ||
| 886 | u8 thdupper, thdlower; | ||
| 887 | u8 num_iter; | ||
| 888 | u32 clk_rate_mhz, period_ps, bestcase, worstcase; | ||
| 889 | |||
| 890 | /* retain HW tuned tap to use incase if no correction is needed */ | ||
| 891 | val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_CLOCK_CTRL); | ||
| 892 | tegra_host->tuned_tap_delay = (val & SDHCI_CLOCK_CTRL_TAP_MASK) >> | ||
| 893 | SDHCI_CLOCK_CTRL_TAP_SHIFT; | ||
| 894 | if (soc_data->min_tap_delay && soc_data->max_tap_delay) { | ||
| 895 | min_tap_dly = soc_data->min_tap_delay; | ||
| 896 | max_tap_dly = soc_data->max_tap_delay; | ||
| 897 | clk_rate_mhz = tegra_host->curr_clk_rate / USEC_PER_SEC; | ||
| 898 | period_ps = USEC_PER_SEC / clk_rate_mhz; | ||
| 899 | bestcase = period_ps / min_tap_dly; | ||
| 900 | worstcase = period_ps / max_tap_dly; | ||
| 901 | /* | ||
| 902 | * Upper and Lower bound thresholds used to detect merged and | ||
| 903 | * bubble windows | ||
| 904 | */ | ||
| 905 | thdupper = (2 * worstcase + bestcase) / 2; | ||
| 906 | thdlower = worstcase / 4; | ||
| 907 | /* | ||
| 908 | * fixed tap is used when HW tuning result contains single edge | ||
| 909 | * and tap is set at fixed tap delay relative to the first edge | ||
| 910 | */ | ||
| 911 | avg_tap_dly = (period_ps * 2) / (min_tap_dly + max_tap_dly); | ||
| 912 | fixed_tap = avg_tap_dly / 2; | ||
| 913 | |||
| 914 | val = sdhci_readl(host, SDHCI_TEGRA_VNDR_TUN_STATUS1); | ||
| 915 | start_tap = val & SDHCI_TEGRA_VNDR_TUN_STATUS1_TAP_MASK; | ||
| 916 | end_tap = (val >> SDHCI_TEGRA_VNDR_TUN_STATUS1_END_TAP_SHIFT) & | ||
| 917 | SDHCI_TEGRA_VNDR_TUN_STATUS1_TAP_MASK; | ||
| 918 | window_width = end_tap - start_tap; | ||
| 919 | num_iter = host->tuning_loop_count; | ||
| 920 | /* | ||
| 921 | * partial window includes edges of the tuning range. | ||
| 922 | * merged window includes more taps so window width is higher | ||
| 923 | * than upper threshold. | ||
| 924 | */ | ||
| 925 | if (start_tap == 0 || (end_tap == (num_iter - 1)) || | ||
| 926 | (end_tap == num_iter - 2) || window_width >= thdupper) { | ||
| 927 | pr_debug("%s: Apply tuning correction\n", | ||
| 928 | mmc_hostname(host->mmc)); | ||
| 929 | tegra_sdhci_tap_correction(host, thdupper, thdlower, | ||
| 930 | fixed_tap); | ||
| 931 | } | ||
| 932 | } | ||
| 933 | |||
| 934 | tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); | ||
| 935 | } | ||
| 936 | |||
| 937 | static int tegra_sdhci_execute_hw_tuning(struct mmc_host *mmc, u32 opcode) | ||
| 938 | { | ||
| 939 | struct sdhci_host *host = mmc_priv(mmc); | ||
| 940 | int err; | ||
| 941 | |||
| 942 | err = sdhci_execute_tuning(mmc, opcode); | ||
| 943 | if (!err && !host->tuning_err) | ||
| 944 | tegra_sdhci_post_tuning(host); | ||
| 945 | |||
| 946 | return err; | ||
| 947 | } | ||
| 948 | |||
| 773 | static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, | 949 | static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, |
| 774 | unsigned timing) | 950 | unsigned timing) |
| 775 | { | 951 | { |
| @@ -778,16 +954,22 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, | |||
| 778 | bool set_default_tap = false; | 954 | bool set_default_tap = false; |
| 779 | bool set_dqs_trim = false; | 955 | bool set_dqs_trim = false; |
| 780 | bool do_hs400_dll_cal = false; | 956 | bool do_hs400_dll_cal = false; |
| 957 | u8 iter = TRIES_256; | ||
| 958 | u32 val; | ||
| 781 | 959 | ||
| 960 | tegra_host->ddr_signaling = false; | ||
| 782 | switch (timing) { | 961 | switch (timing) { |
| 783 | case MMC_TIMING_UHS_SDR50: | 962 | case MMC_TIMING_UHS_SDR50: |
| 963 | break; | ||
| 784 | case MMC_TIMING_UHS_SDR104: | 964 | case MMC_TIMING_UHS_SDR104: |
| 785 | case MMC_TIMING_MMC_HS200: | 965 | case MMC_TIMING_MMC_HS200: |
| 786 | /* Don't set default tap on tunable modes. */ | 966 | /* Don't set default tap on tunable modes. */ |
| 967 | iter = TRIES_128; | ||
| 787 | break; | 968 | break; |
| 788 | case MMC_TIMING_MMC_HS400: | 969 | case MMC_TIMING_MMC_HS400: |
| 789 | set_dqs_trim = true; | 970 | set_dqs_trim = true; |
| 790 | do_hs400_dll_cal = true; | 971 | do_hs400_dll_cal = true; |
| 972 | iter = TRIES_128; | ||
| 791 | break; | 973 | break; |
| 792 | case MMC_TIMING_MMC_DDR52: | 974 | case MMC_TIMING_MMC_DDR52: |
| 793 | case MMC_TIMING_UHS_DDR50: | 975 | case MMC_TIMING_UHS_DDR50: |
| @@ -799,11 +981,25 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, | |||
| 799 | break; | 981 | break; |
| 800 | } | 982 | } |
| 801 | 983 | ||
| 984 | val = sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0); | ||
| 985 | val &= ~(SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK | | ||
| 986 | SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_MASK | | ||
| 987 | SDHCI_VNDR_TUN_CTRL0_MUL_M_MASK); | ||
| 988 | val |= (iter << SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT | | ||
| 989 | 0 << SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_SHIFT | | ||
| 990 | 1 << SDHCI_VNDR_TUN_CTRL0_MUL_M_SHIFT); | ||
| 991 | sdhci_writel(host, val, SDHCI_VNDR_TUN_CTRL0_0); | ||
| 992 | sdhci_writel(host, 0, SDHCI_TEGRA_VNDR_TUN_CTRL1_0); | ||
| 993 | |||
| 994 | host->tuning_loop_count = (iter == TRIES_128) ? 128 : 256; | ||
| 995 | |||
| 802 | sdhci_set_uhs_signaling(host, timing); | 996 | sdhci_set_uhs_signaling(host, timing); |
| 803 | 997 | ||
| 804 | tegra_sdhci_pad_autocalib(host); | 998 | tegra_sdhci_pad_autocalib(host); |
| 805 | 999 | ||
| 806 | if (set_default_tap) | 1000 | if (tegra_host->tuned_tap_delay && !set_default_tap) |
| 1001 | tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); | ||
| 1002 | else | ||
| 807 | tegra_sdhci_set_tap(host, tegra_host->default_tap); | 1003 | tegra_sdhci_set_tap(host, tegra_host->default_tap); |
| 808 | 1004 | ||
| 809 | if (set_dqs_trim) | 1005 | if (set_dqs_trim) |
| @@ -928,23 +1124,86 @@ static void tegra_sdhci_voltage_switch(struct sdhci_host *host) | |||
| 928 | tegra_host->pad_calib_required = true; | 1124 | tegra_host->pad_calib_required = true; |
| 929 | } | 1125 | } |
| 930 | 1126 | ||
| 1127 | static void tegra_cqhci_writel(struct cqhci_host *cq_host, u32 val, int reg) | ||
| 1128 | { | ||
| 1129 | struct mmc_host *mmc = cq_host->mmc; | ||
| 1130 | u8 ctrl; | ||
| 1131 | ktime_t timeout; | ||
| 1132 | bool timed_out; | ||
| 1133 | |||
| 1134 | /* | ||
| 1135 | * During CQE resume/unhalt, CQHCI driver unhalts CQE prior to | ||
| 1136 | * cqhci_host_ops enable where SDHCI DMA and BLOCK_SIZE registers need | ||
| 1137 | * to be re-configured. | ||
| 1138 | * Tegra CQHCI/SDHCI prevents write access to block size register when | ||
| 1139 | * CQE is unhalted. So handling CQE resume sequence here to configure | ||
| 1140 | * SDHCI block registers prior to exiting CQE halt state. | ||
| 1141 | */ | ||
| 1142 | if (reg == CQHCI_CTL && !(val & CQHCI_HALT) && | ||
| 1143 | cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) { | ||
| 1144 | sdhci_cqe_enable(mmc); | ||
| 1145 | writel(val, cq_host->mmio + reg); | ||
| 1146 | timeout = ktime_add_us(ktime_get(), 50); | ||
| 1147 | while (1) { | ||
| 1148 | timed_out = ktime_compare(ktime_get(), timeout) > 0; | ||
| 1149 | ctrl = cqhci_readl(cq_host, CQHCI_CTL); | ||
| 1150 | if (!(ctrl & CQHCI_HALT) || timed_out) | ||
| 1151 | break; | ||
| 1152 | } | ||
| 1153 | /* | ||
| 1154 | * CQE usually resumes very quick, but incase if Tegra CQE | ||
| 1155 | * doesn't resume retry unhalt. | ||
| 1156 | */ | ||
| 1157 | if (timed_out) | ||
| 1158 | writel(val, cq_host->mmio + reg); | ||
| 1159 | } else { | ||
| 1160 | writel(val, cq_host->mmio + reg); | ||
| 1161 | } | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | static void sdhci_tegra_update_dcmd_desc(struct mmc_host *mmc, | ||
| 1165 | struct mmc_request *mrq, u64 *data) | ||
| 1166 | { | ||
| 1167 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(mmc_priv(mmc)); | ||
| 1168 | struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); | ||
| 1169 | const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; | ||
| 1170 | |||
| 1171 | if (soc_data->nvquirks & NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING && | ||
| 1172 | mrq->cmd->flags & MMC_RSP_R1B) | ||
| 1173 | *data |= CQHCI_CMD_TIMING(1); | ||
| 1174 | } | ||
| 1175 | |||
| 931 | static void sdhci_tegra_cqe_enable(struct mmc_host *mmc) | 1176 | static void sdhci_tegra_cqe_enable(struct mmc_host *mmc) |
| 932 | { | 1177 | { |
| 933 | struct cqhci_host *cq_host = mmc->cqe_private; | 1178 | struct cqhci_host *cq_host = mmc->cqe_private; |
| 934 | u32 cqcfg = 0; | 1179 | u32 val; |
| 935 | 1180 | ||
| 936 | /* | 1181 | /* |
| 937 | * Tegra SDMMC Controller design prevents write access to BLOCK_COUNT | 1182 | * Tegra CQHCI/SDMMC design prevents write access to sdhci block size |
| 938 | * registers when CQE is enabled. | 1183 | * register when CQE is enabled and unhalted. |
| 1184 | * CQHCI driver enables CQE prior to activation, so disable CQE before | ||
| 1185 | * programming block size in sdhci controller and enable it back. | ||
| 939 | */ | 1186 | */ |
| 940 | cqcfg = cqhci_readl(cq_host, CQHCI_CFG); | 1187 | if (!cq_host->activated) { |
| 941 | if (cqcfg & CQHCI_ENABLE) | 1188 | val = cqhci_readl(cq_host, CQHCI_CFG); |
| 942 | cqhci_writel(cq_host, (cqcfg & ~CQHCI_ENABLE), CQHCI_CFG); | 1189 | if (val & CQHCI_ENABLE) |
| 943 | 1190 | cqhci_writel(cq_host, (val & ~CQHCI_ENABLE), | |
| 944 | sdhci_cqe_enable(mmc); | 1191 | CQHCI_CFG); |
| 1192 | sdhci_cqe_enable(mmc); | ||
| 1193 | if (val & CQHCI_ENABLE) | ||
| 1194 | cqhci_writel(cq_host, val, CQHCI_CFG); | ||
| 1195 | } | ||
| 945 | 1196 | ||
| 946 | if (cqcfg & CQHCI_ENABLE) | 1197 | /* |
| 947 | cqhci_writel(cq_host, cqcfg, CQHCI_CFG); | 1198 | * CMD CRC errors are seen sometimes with some eMMC devices when status |
| 1199 | * command is sent during transfer of last data block which is the | ||
| 1200 | * default case as send status command block counter (CBC) is 1. | ||
| 1201 | * Recommended fix to set CBC to 0 allowing send status command only | ||
| 1202 | * when data lines are idle. | ||
| 1203 | */ | ||
| 1204 | val = cqhci_readl(cq_host, CQHCI_SSC1); | ||
| 1205 | val &= ~CQHCI_SSC1_CBC_MASK; | ||
| 1206 | cqhci_writel(cq_host, val, CQHCI_SSC1); | ||
| 948 | } | 1207 | } |
| 949 | 1208 | ||
| 950 | static void sdhci_tegra_dumpregs(struct mmc_host *mmc) | 1209 | static void sdhci_tegra_dumpregs(struct mmc_host *mmc) |
| @@ -966,9 +1225,11 @@ static u32 sdhci_tegra_cqhci_irq(struct sdhci_host *host, u32 intmask) | |||
| 966 | } | 1225 | } |
| 967 | 1226 | ||
| 968 | static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { | 1227 | static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { |
| 1228 | .write_l = tegra_cqhci_writel, | ||
| 969 | .enable = sdhci_tegra_cqe_enable, | 1229 | .enable = sdhci_tegra_cqe_enable, |
| 970 | .disable = sdhci_cqe_disable, | 1230 | .disable = sdhci_cqe_disable, |
| 971 | .dumpregs = sdhci_tegra_dumpregs, | 1231 | .dumpregs = sdhci_tegra_dumpregs, |
| 1232 | .update_dcmd_desc = sdhci_tegra_update_dcmd_desc, | ||
| 972 | }; | 1233 | }; |
| 973 | 1234 | ||
| 974 | static const struct sdhci_ops tegra_sdhci_ops = { | 1235 | static const struct sdhci_ops tegra_sdhci_ops = { |
| @@ -1109,6 +1370,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = { | |||
| 1109 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | 1370 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | |
| 1110 | NVQUIRK_ENABLE_SDR50 | | 1371 | NVQUIRK_ENABLE_SDR50 | |
| 1111 | NVQUIRK_ENABLE_SDR104, | 1372 | NVQUIRK_ENABLE_SDR104, |
| 1373 | .min_tap_delay = 106, | ||
| 1374 | .max_tap_delay = 185, | ||
| 1112 | }; | 1375 | }; |
| 1113 | 1376 | ||
| 1114 | static const struct sdhci_ops tegra186_sdhci_ops = { | 1377 | static const struct sdhci_ops tegra186_sdhci_ops = { |
| @@ -1148,10 +1411,25 @@ static const struct sdhci_tegra_soc_data soc_data_tegra186 = { | |||
| 1148 | NVQUIRK_HAS_PADCALIB | | 1411 | NVQUIRK_HAS_PADCALIB | |
| 1149 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | 1412 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | |
| 1150 | NVQUIRK_ENABLE_SDR50 | | 1413 | NVQUIRK_ENABLE_SDR50 | |
| 1414 | NVQUIRK_ENABLE_SDR104 | | ||
| 1415 | NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING, | ||
| 1416 | .min_tap_delay = 84, | ||
| 1417 | .max_tap_delay = 136, | ||
| 1418 | }; | ||
| 1419 | |||
| 1420 | static const struct sdhci_tegra_soc_data soc_data_tegra194 = { | ||
| 1421 | .pdata = &sdhci_tegra186_pdata, | ||
| 1422 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | | ||
| 1423 | NVQUIRK_HAS_PADCALIB | | ||
| 1424 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | ||
| 1425 | NVQUIRK_ENABLE_SDR50 | | ||
| 1151 | NVQUIRK_ENABLE_SDR104, | 1426 | NVQUIRK_ENABLE_SDR104, |
| 1427 | .min_tap_delay = 96, | ||
| 1428 | .max_tap_delay = 139, | ||
| 1152 | }; | 1429 | }; |
| 1153 | 1430 | ||
| 1154 | static const struct of_device_id sdhci_tegra_dt_match[] = { | 1431 | static const struct of_device_id sdhci_tegra_dt_match[] = { |
| 1432 | { .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 }, | ||
| 1155 | { .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 }, | 1433 | { .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 }, |
| 1156 | { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 }, | 1434 | { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 }, |
| 1157 | { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 }, | 1435 | { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 }, |
| @@ -1250,6 +1528,10 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
| 1250 | host->mmc_host_ops.hs400_enhanced_strobe = | 1528 | host->mmc_host_ops.hs400_enhanced_strobe = |
| 1251 | tegra_sdhci_hs400_enhanced_strobe; | 1529 | tegra_sdhci_hs400_enhanced_strobe; |
| 1252 | 1530 | ||
| 1531 | if (!host->ops->platform_execute_tuning) | ||
| 1532 | host->mmc_host_ops.execute_tuning = | ||
| 1533 | tegra_sdhci_execute_hw_tuning; | ||
| 1534 | |||
| 1253 | rc = mmc_of_parse(host->mmc); | 1535 | rc = mmc_of_parse(host->mmc); |
| 1254 | if (rc) | 1536 | if (rc) |
| 1255 | goto err_parse_dt; | 1537 | goto err_parse_dt; |
| @@ -1329,11 +1611,67 @@ static int sdhci_tegra_remove(struct platform_device *pdev) | |||
| 1329 | return 0; | 1611 | return 0; |
| 1330 | } | 1612 | } |
| 1331 | 1613 | ||
| 1614 | #ifdef CONFIG_PM_SLEEP | ||
| 1615 | static int __maybe_unused sdhci_tegra_suspend(struct device *dev) | ||
| 1616 | { | ||
| 1617 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
| 1618 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 1619 | int ret; | ||
| 1620 | |||
| 1621 | if (host->mmc->caps2 & MMC_CAP2_CQE) { | ||
| 1622 | ret = cqhci_suspend(host->mmc); | ||
| 1623 | if (ret) | ||
| 1624 | return ret; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | ret = sdhci_suspend_host(host); | ||
| 1628 | if (ret) { | ||
| 1629 | cqhci_resume(host->mmc); | ||
| 1630 | return ret; | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | clk_disable_unprepare(pltfm_host->clk); | ||
| 1634 | return 0; | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | static int __maybe_unused sdhci_tegra_resume(struct device *dev) | ||
| 1638 | { | ||
| 1639 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
| 1640 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 1641 | int ret; | ||
| 1642 | |||
| 1643 | ret = clk_prepare_enable(pltfm_host->clk); | ||
| 1644 | if (ret) | ||
| 1645 | return ret; | ||
| 1646 | |||
| 1647 | ret = sdhci_resume_host(host); | ||
| 1648 | if (ret) | ||
| 1649 | goto disable_clk; | ||
| 1650 | |||
| 1651 | if (host->mmc->caps2 & MMC_CAP2_CQE) { | ||
| 1652 | ret = cqhci_resume(host->mmc); | ||
| 1653 | if (ret) | ||
| 1654 | goto suspend_host; | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | return 0; | ||
| 1658 | |||
| 1659 | suspend_host: | ||
| 1660 | sdhci_suspend_host(host); | ||
| 1661 | disable_clk: | ||
| 1662 | clk_disable_unprepare(pltfm_host->clk); | ||
| 1663 | return ret; | ||
| 1664 | } | ||
| 1665 | #endif | ||
| 1666 | |||
| 1667 | static SIMPLE_DEV_PM_OPS(sdhci_tegra_dev_pm_ops, sdhci_tegra_suspend, | ||
| 1668 | sdhci_tegra_resume); | ||
| 1669 | |||
| 1332 | static struct platform_driver sdhci_tegra_driver = { | 1670 | static struct platform_driver sdhci_tegra_driver = { |
| 1333 | .driver = { | 1671 | .driver = { |
| 1334 | .name = "sdhci-tegra", | 1672 | .name = "sdhci-tegra", |
| 1335 | .of_match_table = sdhci_tegra_dt_match, | 1673 | .of_match_table = sdhci_tegra_dt_match, |
| 1336 | .pm = &sdhci_pltfm_pmops, | 1674 | .pm = &sdhci_tegra_dev_pm_ops, |
| 1337 | }, | 1675 | }, |
| 1338 | .probe = sdhci_tegra_probe, | 1676 | .probe = sdhci_tegra_probe, |
| 1339 | .remove = sdhci_tegra_remove, | 1677 | .remove = sdhci_tegra_remove, |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 42e1bad024f4..97158344b862 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -446,6 +446,28 @@ static inline void sdhci_led_deactivate(struct sdhci_host *host) | |||
| 446 | 446 | ||
| 447 | #endif | 447 | #endif |
| 448 | 448 | ||
| 449 | static void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, | ||
| 450 | unsigned long timeout) | ||
| 451 | { | ||
| 452 | if (sdhci_data_line_cmd(mrq->cmd)) | ||
| 453 | mod_timer(&host->data_timer, timeout); | ||
| 454 | else | ||
| 455 | mod_timer(&host->timer, timeout); | ||
| 456 | } | ||
| 457 | |||
| 458 | static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq) | ||
| 459 | { | ||
| 460 | if (sdhci_data_line_cmd(mrq->cmd)) | ||
| 461 | del_timer(&host->data_timer); | ||
| 462 | else | ||
| 463 | del_timer(&host->timer); | ||
| 464 | } | ||
| 465 | |||
| 466 | static inline bool sdhci_has_requests(struct sdhci_host *host) | ||
| 467 | { | ||
| 468 | return host->cmd || host->data_cmd; | ||
| 469 | } | ||
| 470 | |||
| 449 | /*****************************************************************************\ | 471 | /*****************************************************************************\ |
| 450 | * * | 472 | * * |
| 451 | * Core functions * | 473 | * Core functions * |
| @@ -1221,6 +1243,18 @@ static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) | |||
| 1221 | { | 1243 | { |
| 1222 | int i; | 1244 | int i; |
| 1223 | 1245 | ||
| 1246 | if (host->cmd && host->cmd->mrq == mrq) | ||
| 1247 | host->cmd = NULL; | ||
| 1248 | |||
| 1249 | if (host->data_cmd && host->data_cmd->mrq == mrq) | ||
| 1250 | host->data_cmd = NULL; | ||
| 1251 | |||
| 1252 | if (host->data && host->data->mrq == mrq) | ||
| 1253 | host->data = NULL; | ||
| 1254 | |||
| 1255 | if (sdhci_needs_reset(host, mrq)) | ||
| 1256 | host->pending_reset = true; | ||
| 1257 | |||
| 1224 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { | 1258 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { |
| 1225 | if (host->mrqs_done[i] == mrq) { | 1259 | if (host->mrqs_done[i] == mrq) { |
| 1226 | WARN_ON(1); | 1260 | WARN_ON(1); |
| @@ -1237,24 +1271,17 @@ static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) | |||
| 1237 | 1271 | ||
| 1238 | WARN_ON(i >= SDHCI_MAX_MRQS); | 1272 | WARN_ON(i >= SDHCI_MAX_MRQS); |
| 1239 | 1273 | ||
| 1240 | tasklet_schedule(&host->finish_tasklet); | 1274 | sdhci_del_timer(host, mrq); |
| 1275 | |||
| 1276 | if (!sdhci_has_requests(host)) | ||
| 1277 | sdhci_led_deactivate(host); | ||
| 1241 | } | 1278 | } |
| 1242 | 1279 | ||
| 1243 | static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) | 1280 | static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) |
| 1244 | { | 1281 | { |
| 1245 | if (host->cmd && host->cmd->mrq == mrq) | ||
| 1246 | host->cmd = NULL; | ||
| 1247 | |||
| 1248 | if (host->data_cmd && host->data_cmd->mrq == mrq) | ||
| 1249 | host->data_cmd = NULL; | ||
| 1250 | |||
| 1251 | if (host->data && host->data->mrq == mrq) | ||
| 1252 | host->data = NULL; | ||
| 1253 | |||
| 1254 | if (sdhci_needs_reset(host, mrq)) | ||
| 1255 | host->pending_reset = true; | ||
| 1256 | |||
| 1257 | __sdhci_finish_mrq(host, mrq); | 1282 | __sdhci_finish_mrq(host, mrq); |
| 1283 | |||
| 1284 | queue_work(host->complete_wq, &host->complete_work); | ||
| 1258 | } | 1285 | } |
| 1259 | 1286 | ||
| 1260 | static void sdhci_finish_data(struct sdhci_host *host) | 1287 | static void sdhci_finish_data(struct sdhci_host *host) |
| @@ -1305,34 +1332,17 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
| 1305 | * responsibility to send the stop command if required. | 1332 | * responsibility to send the stop command if required. |
| 1306 | */ | 1333 | */ |
| 1307 | if (data->mrq->cap_cmd_during_tfr) { | 1334 | if (data->mrq->cap_cmd_during_tfr) { |
| 1308 | sdhci_finish_mrq(host, data->mrq); | 1335 | __sdhci_finish_mrq(host, data->mrq); |
| 1309 | } else { | 1336 | } else { |
| 1310 | /* Avoid triggering warning in sdhci_send_command() */ | 1337 | /* Avoid triggering warning in sdhci_send_command() */ |
| 1311 | host->cmd = NULL; | 1338 | host->cmd = NULL; |
| 1312 | sdhci_send_command(host, data->stop); | 1339 | sdhci_send_command(host, data->stop); |
| 1313 | } | 1340 | } |
| 1314 | } else { | 1341 | } else { |
| 1315 | sdhci_finish_mrq(host, data->mrq); | 1342 | __sdhci_finish_mrq(host, data->mrq); |
| 1316 | } | 1343 | } |
| 1317 | } | 1344 | } |
| 1318 | 1345 | ||
| 1319 | static void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, | ||
| 1320 | unsigned long timeout) | ||
| 1321 | { | ||
| 1322 | if (sdhci_data_line_cmd(mrq->cmd)) | ||
| 1323 | mod_timer(&host->data_timer, timeout); | ||
| 1324 | else | ||
| 1325 | mod_timer(&host->timer, timeout); | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq) | ||
| 1329 | { | ||
| 1330 | if (sdhci_data_line_cmd(mrq->cmd)) | ||
| 1331 | del_timer(&host->data_timer); | ||
| 1332 | else | ||
| 1333 | del_timer(&host->timer); | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | 1346 | void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) |
| 1337 | { | 1347 | { |
| 1338 | int flags; | 1348 | int flags; |
| @@ -1492,7 +1502,7 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
| 1492 | sdhci_finish_data(host); | 1502 | sdhci_finish_data(host); |
| 1493 | 1503 | ||
| 1494 | if (!cmd->data) | 1504 | if (!cmd->data) |
| 1495 | sdhci_finish_mrq(host, cmd->mrq); | 1505 | __sdhci_finish_mrq(host, cmd->mrq); |
| 1496 | } | 1506 | } |
| 1497 | } | 1507 | } |
| 1498 | 1508 | ||
| @@ -2364,9 +2374,9 @@ static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) | |||
| 2364 | 2374 | ||
| 2365 | /* | 2375 | /* |
| 2366 | * Issue opcode repeatedly till Execute Tuning is set to 0 or the number | 2376 | * Issue opcode repeatedly till Execute Tuning is set to 0 or the number |
| 2367 | * of loops reaches 40 times. | 2377 | * of loops reaches tuning loop count. |
| 2368 | */ | 2378 | */ |
| 2369 | for (i = 0; i < MAX_TUNING_LOOP; i++) { | 2379 | for (i = 0; i < host->tuning_loop_count; i++) { |
| 2370 | u16 ctrl; | 2380 | u16 ctrl; |
| 2371 | 2381 | ||
| 2372 | sdhci_send_tuning(host, opcode); | 2382 | sdhci_send_tuning(host, opcode); |
| @@ -2523,11 +2533,6 @@ static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 2523 | sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED); | 2533 | sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED); |
| 2524 | } | 2534 | } |
| 2525 | 2535 | ||
| 2526 | static inline bool sdhci_has_requests(struct sdhci_host *host) | ||
| 2527 | { | ||
| 2528 | return host->cmd || host->data_cmd; | ||
| 2529 | } | ||
| 2530 | |||
| 2531 | static void sdhci_error_out_mrqs(struct sdhci_host *host, int err) | 2536 | static void sdhci_error_out_mrqs(struct sdhci_host *host, int err) |
| 2532 | { | 2537 | { |
| 2533 | if (host->data_cmd) { | 2538 | if (host->data_cmd) { |
| @@ -2589,7 +2594,7 @@ static const struct mmc_host_ops sdhci_ops = { | |||
| 2589 | 2594 | ||
| 2590 | /*****************************************************************************\ | 2595 | /*****************************************************************************\ |
| 2591 | * * | 2596 | * * |
| 2592 | * Tasklets * | 2597 | * Request done * |
| 2593 | * * | 2598 | * * |
| 2594 | \*****************************************************************************/ | 2599 | \*****************************************************************************/ |
| 2595 | 2600 | ||
| @@ -2612,8 +2617,6 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
| 2612 | return true; | 2617 | return true; |
| 2613 | } | 2618 | } |
| 2614 | 2619 | ||
| 2615 | sdhci_del_timer(host, mrq); | ||
| 2616 | |||
| 2617 | /* | 2620 | /* |
| 2618 | * Always unmap the data buffers if they were mapped by | 2621 | * Always unmap the data buffers if they were mapped by |
| 2619 | * sdhci_prepare_data() whenever we finish with a request. | 2622 | * sdhci_prepare_data() whenever we finish with a request. |
| @@ -2695,9 +2698,6 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
| 2695 | host->pending_reset = false; | 2698 | host->pending_reset = false; |
| 2696 | } | 2699 | } |
| 2697 | 2700 | ||
| 2698 | if (!sdhci_has_requests(host)) | ||
| 2699 | sdhci_led_deactivate(host); | ||
| 2700 | |||
| 2701 | host->mrqs_done[i] = NULL; | 2701 | host->mrqs_done[i] = NULL; |
| 2702 | 2702 | ||
| 2703 | spin_unlock_irqrestore(&host->lock, flags); | 2703 | spin_unlock_irqrestore(&host->lock, flags); |
| @@ -2707,9 +2707,10 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
| 2707 | return false; | 2707 | return false; |
| 2708 | } | 2708 | } |
| 2709 | 2709 | ||
| 2710 | static void sdhci_tasklet_finish(unsigned long param) | 2710 | static void sdhci_complete_work(struct work_struct *work) |
| 2711 | { | 2711 | { |
| 2712 | struct sdhci_host *host = (struct sdhci_host *)param; | 2712 | struct sdhci_host *host = container_of(work, struct sdhci_host, |
| 2713 | complete_work); | ||
| 2713 | 2714 | ||
| 2714 | while (!sdhci_request_done(host)) | 2715 | while (!sdhci_request_done(host)) |
| 2715 | ; | 2716 | ; |
| @@ -2754,6 +2755,7 @@ static void sdhci_timeout_data_timer(struct timer_list *t) | |||
| 2754 | if (host->data) { | 2755 | if (host->data) { |
| 2755 | host->data->error = -ETIMEDOUT; | 2756 | host->data->error = -ETIMEDOUT; |
| 2756 | sdhci_finish_data(host); | 2757 | sdhci_finish_data(host); |
| 2758 | queue_work(host->complete_wq, &host->complete_work); | ||
| 2757 | } else if (host->data_cmd) { | 2759 | } else if (host->data_cmd) { |
| 2758 | host->data_cmd->error = -ETIMEDOUT; | 2760 | host->data_cmd->error = -ETIMEDOUT; |
| 2759 | sdhci_finish_mrq(host, host->data_cmd->mrq); | 2761 | sdhci_finish_mrq(host, host->data_cmd->mrq); |
| @@ -2819,7 +2821,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) | |||
| 2819 | return; | 2821 | return; |
| 2820 | } | 2822 | } |
| 2821 | 2823 | ||
| 2822 | sdhci_finish_mrq(host, host->cmd->mrq); | 2824 | __sdhci_finish_mrq(host, host->cmd->mrq); |
| 2823 | return; | 2825 | return; |
| 2824 | } | 2826 | } |
| 2825 | 2827 | ||
| @@ -2833,7 +2835,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) | |||
| 2833 | 2835 | ||
| 2834 | if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { | 2836 | if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { |
| 2835 | mrq->sbc->error = err; | 2837 | mrq->sbc->error = err; |
| 2836 | sdhci_finish_mrq(host, mrq); | 2838 | __sdhci_finish_mrq(host, mrq); |
| 2837 | return; | 2839 | return; |
| 2838 | } | 2840 | } |
| 2839 | } | 2841 | } |
| @@ -2897,7 +2899,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
| 2897 | if (intmask & SDHCI_INT_DATA_TIMEOUT) { | 2899 | if (intmask & SDHCI_INT_DATA_TIMEOUT) { |
| 2898 | host->data_cmd = NULL; | 2900 | host->data_cmd = NULL; |
| 2899 | data_cmd->error = -ETIMEDOUT; | 2901 | data_cmd->error = -ETIMEDOUT; |
| 2900 | sdhci_finish_mrq(host, data_cmd->mrq); | 2902 | __sdhci_finish_mrq(host, data_cmd->mrq); |
| 2901 | return; | 2903 | return; |
| 2902 | } | 2904 | } |
| 2903 | if (intmask & SDHCI_INT_DATA_END) { | 2905 | if (intmask & SDHCI_INT_DATA_END) { |
| @@ -2910,7 +2912,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
| 2910 | if (host->cmd == data_cmd) | 2912 | if (host->cmd == data_cmd) |
| 2911 | return; | 2913 | return; |
| 2912 | 2914 | ||
| 2913 | sdhci_finish_mrq(host, data_cmd->mrq); | 2915 | __sdhci_finish_mrq(host, data_cmd->mrq); |
| 2914 | return; | 2916 | return; |
| 2915 | } | 2917 | } |
| 2916 | } | 2918 | } |
| @@ -2993,12 +2995,24 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
| 2993 | } | 2995 | } |
| 2994 | } | 2996 | } |
| 2995 | 2997 | ||
| 2998 | static inline bool sdhci_defer_done(struct sdhci_host *host, | ||
| 2999 | struct mmc_request *mrq) | ||
| 3000 | { | ||
| 3001 | struct mmc_data *data = mrq->data; | ||
| 3002 | |||
| 3003 | return host->pending_reset || | ||
| 3004 | ((host->flags & SDHCI_REQ_USE_DMA) && data && | ||
| 3005 | data->host_cookie == COOKIE_MAPPED); | ||
| 3006 | } | ||
| 3007 | |||
| 2996 | static irqreturn_t sdhci_irq(int irq, void *dev_id) | 3008 | static irqreturn_t sdhci_irq(int irq, void *dev_id) |
| 2997 | { | 3009 | { |
| 3010 | struct mmc_request *mrqs_done[SDHCI_MAX_MRQS] = {0}; | ||
| 2998 | irqreturn_t result = IRQ_NONE; | 3011 | irqreturn_t result = IRQ_NONE; |
| 2999 | struct sdhci_host *host = dev_id; | 3012 | struct sdhci_host *host = dev_id; |
| 3000 | u32 intmask, mask, unexpected = 0; | 3013 | u32 intmask, mask, unexpected = 0; |
| 3001 | int max_loops = 16; | 3014 | int max_loops = 16; |
| 3015 | int i; | ||
| 3002 | 3016 | ||
| 3003 | spin_lock(&host->lock); | 3017 | spin_lock(&host->lock); |
| 3004 | 3018 | ||
| @@ -3092,9 +3106,30 @@ cont: | |||
| 3092 | 3106 | ||
| 3093 | intmask = sdhci_readl(host, SDHCI_INT_STATUS); | 3107 | intmask = sdhci_readl(host, SDHCI_INT_STATUS); |
| 3094 | } while (intmask && --max_loops); | 3108 | } while (intmask && --max_loops); |
| 3109 | |||
| 3110 | /* Determine if mrqs can be completed immediately */ | ||
| 3111 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { | ||
| 3112 | struct mmc_request *mrq = host->mrqs_done[i]; | ||
| 3113 | |||
| 3114 | if (!mrq) | ||
| 3115 | continue; | ||
| 3116 | |||
| 3117 | if (sdhci_defer_done(host, mrq)) { | ||
| 3118 | result = IRQ_WAKE_THREAD; | ||
| 3119 | } else { | ||
| 3120 | mrqs_done[i] = mrq; | ||
| 3121 | host->mrqs_done[i] = NULL; | ||
| 3122 | } | ||
| 3123 | } | ||
| 3095 | out: | 3124 | out: |
| 3096 | spin_unlock(&host->lock); | 3125 | spin_unlock(&host->lock); |
| 3097 | 3126 | ||
| 3127 | /* Process mrqs ready for immediate completion */ | ||
| 3128 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { | ||
| 3129 | if (mrqs_done[i]) | ||
| 3130 | mmc_request_done(host->mmc, mrqs_done[i]); | ||
| 3131 | } | ||
| 3132 | |||
| 3098 | if (unexpected) { | 3133 | if (unexpected) { |
| 3099 | pr_err("%s: Unexpected interrupt 0x%08x.\n", | 3134 | pr_err("%s: Unexpected interrupt 0x%08x.\n", |
| 3100 | mmc_hostname(host->mmc), unexpected); | 3135 | mmc_hostname(host->mmc), unexpected); |
| @@ -3110,6 +3145,9 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) | |||
| 3110 | unsigned long flags; | 3145 | unsigned long flags; |
| 3111 | u32 isr; | 3146 | u32 isr; |
| 3112 | 3147 | ||
| 3148 | while (!sdhci_request_done(host)) | ||
| 3149 | ; | ||
| 3150 | |||
| 3113 | spin_lock_irqsave(&host->lock, flags); | 3151 | spin_lock_irqsave(&host->lock, flags); |
| 3114 | isr = host->thread_isr; | 3152 | isr = host->thread_isr; |
| 3115 | host->thread_isr = 0; | 3153 | host->thread_isr = 0; |
| @@ -3131,7 +3169,7 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) | |||
| 3131 | spin_unlock_irqrestore(&host->lock, flags); | 3169 | spin_unlock_irqrestore(&host->lock, flags); |
| 3132 | } | 3170 | } |
| 3133 | 3171 | ||
| 3134 | return isr ? IRQ_HANDLED : IRQ_NONE; | 3172 | return IRQ_HANDLED; |
| 3135 | } | 3173 | } |
| 3136 | 3174 | ||
| 3137 | /*****************************************************************************\ | 3175 | /*****************************************************************************\ |
| @@ -3483,6 +3521,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, | |||
| 3483 | host->cqe_err_ier = SDHCI_CQE_INT_ERR_MASK; | 3521 | host->cqe_err_ier = SDHCI_CQE_INT_ERR_MASK; |
| 3484 | 3522 | ||
| 3485 | host->tuning_delay = -1; | 3523 | host->tuning_delay = -1; |
| 3524 | host->tuning_loop_count = MAX_TUNING_LOOP; | ||
| 3486 | 3525 | ||
| 3487 | host->sdma_boundary = SDHCI_DEFAULT_BOUNDARY_ARG; | 3526 | host->sdma_boundary = SDHCI_DEFAULT_BOUNDARY_ARG; |
| 3488 | 3527 | ||
| @@ -4213,14 +4252,15 @@ EXPORT_SYMBOL_GPL(sdhci_cleanup_host); | |||
| 4213 | 4252 | ||
| 4214 | int __sdhci_add_host(struct sdhci_host *host) | 4253 | int __sdhci_add_host(struct sdhci_host *host) |
| 4215 | { | 4254 | { |
| 4255 | unsigned int flags = WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI; | ||
| 4216 | struct mmc_host *mmc = host->mmc; | 4256 | struct mmc_host *mmc = host->mmc; |
| 4217 | int ret; | 4257 | int ret; |
| 4218 | 4258 | ||
| 4219 | /* | 4259 | host->complete_wq = alloc_workqueue("sdhci", flags, 0); |
| 4220 | * Init tasklets. | 4260 | if (!host->complete_wq) |
| 4221 | */ | 4261 | return -ENOMEM; |
| 4222 | tasklet_init(&host->finish_tasklet, | 4262 | |
| 4223 | sdhci_tasklet_finish, (unsigned long)host); | 4263 | INIT_WORK(&host->complete_work, sdhci_complete_work); |
| 4224 | 4264 | ||
| 4225 | timer_setup(&host->timer, sdhci_timeout_timer, 0); | 4265 | timer_setup(&host->timer, sdhci_timeout_timer, 0); |
| 4226 | timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0); | 4266 | timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0); |
| @@ -4234,7 +4274,7 @@ int __sdhci_add_host(struct sdhci_host *host) | |||
| 4234 | if (ret) { | 4274 | if (ret) { |
| 4235 | pr_err("%s: Failed to request IRQ %d: %d\n", | 4275 | pr_err("%s: Failed to request IRQ %d: %d\n", |
| 4236 | mmc_hostname(mmc), host->irq, ret); | 4276 | mmc_hostname(mmc), host->irq, ret); |
| 4237 | goto untasklet; | 4277 | goto unwq; |
| 4238 | } | 4278 | } |
| 4239 | 4279 | ||
| 4240 | ret = sdhci_led_register(host); | 4280 | ret = sdhci_led_register(host); |
| @@ -4265,8 +4305,8 @@ unirq: | |||
| 4265 | sdhci_writel(host, 0, SDHCI_INT_ENABLE); | 4305 | sdhci_writel(host, 0, SDHCI_INT_ENABLE); |
| 4266 | sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); | 4306 | sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); |
| 4267 | free_irq(host->irq, host); | 4307 | free_irq(host->irq, host); |
| 4268 | untasklet: | 4308 | unwq: |
| 4269 | tasklet_kill(&host->finish_tasklet); | 4309 | destroy_workqueue(host->complete_wq); |
| 4270 | 4310 | ||
| 4271 | return ret; | 4311 | return ret; |
| 4272 | } | 4312 | } |
| @@ -4328,7 +4368,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
| 4328 | del_timer_sync(&host->timer); | 4368 | del_timer_sync(&host->timer); |
| 4329 | del_timer_sync(&host->data_timer); | 4369 | del_timer_sync(&host->data_timer); |
| 4330 | 4370 | ||
| 4331 | tasklet_kill(&host->finish_tasklet); | 4371 | destroy_workqueue(host->complete_wq); |
| 4332 | 4372 | ||
| 4333 | if (!IS_ERR(mmc->supply.vqmmc)) | 4373 | if (!IS_ERR(mmc->supply.vqmmc)) |
| 4334 | regulator_disable(mmc->supply.vqmmc); | 4374 | regulator_disable(mmc->supply.vqmmc); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 01002cba1359..d6bcc584c92b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -560,7 +560,8 @@ struct sdhci_host { | |||
| 560 | 560 | ||
| 561 | unsigned int desc_sz; /* ADMA descriptor size */ | 561 | unsigned int desc_sz; /* ADMA descriptor size */ |
| 562 | 562 | ||
| 563 | struct tasklet_struct finish_tasklet; /* Tasklet structures */ | 563 | struct workqueue_struct *complete_wq; /* Request completion wq */ |
| 564 | struct work_struct complete_work; /* Request completion work */ | ||
| 564 | 565 | ||
| 565 | struct timer_list timer; /* Timer for timeouts */ | 566 | struct timer_list timer; /* Timer for timeouts */ |
| 566 | struct timer_list data_timer; /* Timer for data timeouts */ | 567 | struct timer_list data_timer; /* Timer for data timeouts */ |
| @@ -596,6 +597,7 @@ struct sdhci_host { | |||
| 596 | #define SDHCI_TUNING_MODE_3 2 | 597 | #define SDHCI_TUNING_MODE_3 2 |
| 597 | /* Delay (ms) between tuning commands */ | 598 | /* Delay (ms) between tuning commands */ |
| 598 | int tuning_delay; | 599 | int tuning_delay; |
| 600 | int tuning_loop_count; | ||
| 599 | 601 | ||
| 600 | /* Host SDMA buffer boundary. */ | 602 | /* Host SDMA buffer boundary. */ |
| 601 | u32 sdma_boundary; | 603 | u32 sdma_boundary; |
diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index eea183e90f1b..a91c0b45c48d 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c | |||
| @@ -158,6 +158,27 @@ static void sdhci_am654_set_power(struct sdhci_host *host, unsigned char mode, | |||
| 158 | sdhci_set_power_noreg(host, mode, vdd); | 158 | sdhci_set_power_noreg(host, mode, vdd); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg) | ||
| 162 | { | ||
| 163 | unsigned char timing = host->mmc->ios.timing; | ||
| 164 | |||
| 165 | if (reg == SDHCI_HOST_CONTROL) { | ||
| 166 | switch (timing) { | ||
| 167 | /* | ||
| 168 | * According to the data manual, HISPD bit | ||
| 169 | * should not be set in these speed modes. | ||
| 170 | */ | ||
| 171 | case MMC_TIMING_SD_HS: | ||
| 172 | case MMC_TIMING_MMC_HS: | ||
| 173 | case MMC_TIMING_UHS_SDR12: | ||
| 174 | case MMC_TIMING_UHS_SDR25: | ||
| 175 | val &= ~SDHCI_CTRL_HISPD; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | writeb(val, host->ioaddr + reg); | ||
| 180 | } | ||
| 181 | |||
| 161 | static struct sdhci_ops sdhci_am654_ops = { | 182 | static struct sdhci_ops sdhci_am654_ops = { |
| 162 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, | 183 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, |
| 163 | .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, | 184 | .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, |
| @@ -165,6 +186,7 @@ static struct sdhci_ops sdhci_am654_ops = { | |||
| 165 | .set_bus_width = sdhci_set_bus_width, | 186 | .set_bus_width = sdhci_set_bus_width, |
| 166 | .set_power = sdhci_am654_set_power, | 187 | .set_power = sdhci_am654_set_power, |
| 167 | .set_clock = sdhci_am654_set_clock, | 188 | .set_clock = sdhci_am654_set_clock, |
| 189 | .write_b = sdhci_am654_write_b, | ||
| 168 | .reset = sdhci_reset, | 190 | .reset = sdhci_reset, |
| 169 | }; | 191 | }; |
| 170 | 192 | ||
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 2adb0d24360f..c5ba13fae399 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | * | 4 | * |
| 5 | * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3 | 5 | * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3 |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2015-17 Renesas Electronics Corporation | 7 | * Copyright (C) 2015-19 Renesas Electronics Corporation |
| 8 | * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang | 8 | * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang |
| 9 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman | 9 | * Copyright (C) 2016-17 Horms Solutions, Simon Horman |
| 10 | * Copyright (C) 2007 Ian Molton | 10 | * Copyright (C) 2007 Ian Molton |
| 11 | * Copyright (C) 2004 Ian Molton | 11 | * Copyright (C) 2004 Ian Molton |
| @@ -105,6 +105,8 @@ | |||
| 105 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 105 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) |
| 106 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 106 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
| 107 | 107 | ||
| 108 | #define TMIO_MAX_BLK_SIZE 512 | ||
| 109 | |||
| 108 | struct tmio_mmc_data; | 110 | struct tmio_mmc_data; |
| 109 | struct tmio_mmc_host; | 111 | struct tmio_mmc_host; |
| 110 | 112 | ||
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index 595949f1f001..130b91cb0f8a 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | * | 4 | * |
| 5 | * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs | 5 | * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2015-17 Renesas Electronics Corporation | 7 | * Copyright (C) 2015-19 Renesas Electronics Corporation |
| 8 | * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang | 8 | * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang |
| 9 | * Copyright (C) 2017 Horms Solutions, Simon Horman | 9 | * Copyright (C) 2017 Horms Solutions, Simon Horman |
| 10 | * Copyright (C) 2011 Guennadi Liakhovetski | 10 | * Copyright (C) 2011 Guennadi Liakhovetski |
| 11 | * Copyright (C) 2007 Ian Molton | 11 | * Copyright (C) 2007 Ian Molton |
| @@ -1186,7 +1186,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) | |||
| 1186 | mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities; | 1186 | mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities; |
| 1187 | mmc->caps2 |= pdata->capabilities2; | 1187 | mmc->caps2 |= pdata->capabilities2; |
| 1188 | mmc->max_segs = pdata->max_segs ? : 32; | 1188 | mmc->max_segs = pdata->max_segs ? : 32; |
| 1189 | mmc->max_blk_size = 512; | 1189 | mmc->max_blk_size = TMIO_MAX_BLK_SIZE; |
| 1190 | mmc->max_blk_count = pdata->max_blk_count ? : | 1190 | mmc->max_blk_count = pdata->max_blk_count ? : |
| 1191 | (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; | 1191 | (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; |
| 1192 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 1192 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index cd8b1b9d4d8a..b11ac2314328 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c | |||
| @@ -1339,7 +1339,7 @@ static int usdhi6_stop_cmd(struct usdhi6_host *host) | |||
| 1339 | host->wait = USDHI6_WAIT_FOR_STOP; | 1339 | host->wait = USDHI6_WAIT_FOR_STOP; |
| 1340 | return 0; | 1340 | return 0; |
| 1341 | } | 1341 | } |
| 1342 | /* Unsupported STOP command */ | 1342 | /* fall through - Unsupported STOP command. */ |
| 1343 | default: | 1343 | default: |
| 1344 | dev_err(mmc_dev(host->mmc), | 1344 | dev_err(mmc_dev(host->mmc), |
| 1345 | "unsupported stop CMD%d for CMD%d\n", | 1345 | "unsupported stop CMD%d for CMD%d\n", |
| @@ -1687,7 +1687,7 @@ static void usdhi6_timeout_work(struct work_struct *work) | |||
| 1687 | switch (host->wait) { | 1687 | switch (host->wait) { |
| 1688 | default: | 1688 | default: |
| 1689 | dev_err(mmc_dev(host->mmc), "Invalid state %u\n", host->wait); | 1689 | dev_err(mmc_dev(host->mmc), "Invalid state %u\n", host->wait); |
| 1690 | /* mrq can be NULL in this actually impossible case */ | 1690 | /* fall through - mrq can be NULL, but is impossible. */ |
| 1691 | case USDHI6_WAIT_FOR_CMD: | 1691 | case USDHI6_WAIT_FOR_CMD: |
| 1692 | usdhi6_error_code(host); | 1692 | usdhi6_error_code(host); |
| 1693 | if (mrq) | 1693 | if (mrq) |
| @@ -1709,10 +1709,7 @@ static void usdhi6_timeout_work(struct work_struct *work) | |||
| 1709 | host->offset, data->blocks, data->blksz, data->sg_len, | 1709 | host->offset, data->blocks, data->blksz, data->sg_len, |
| 1710 | sg_dma_len(sg), sg->offset); | 1710 | sg_dma_len(sg), sg->offset); |
| 1711 | usdhi6_sg_unmap(host, true); | 1711 | usdhi6_sg_unmap(host, true); |
| 1712 | /* | 1712 | /* fall through - page unmapped in USDHI6_WAIT_FOR_DATA_END. */ |
| 1713 | * If USDHI6_WAIT_FOR_DATA_END times out, we have already unmapped | ||
| 1714 | * the page | ||
| 1715 | */ | ||
| 1716 | case USDHI6_WAIT_FOR_DATA_END: | 1713 | case USDHI6_WAIT_FOR_DATA_END: |
| 1717 | usdhi6_error_code(host); | 1714 | usdhi6_error_code(host); |
| 1718 | data->error = -ETIMEDOUT; | 1715 | data->error = -ETIMEDOUT; |
diff --git a/include/linux/alcor_pci.h b/include/linux/alcor_pci.h index da973e8a2da8..4416df597526 100644 --- a/include/linux/alcor_pci.h +++ b/include/linux/alcor_pci.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #define AU6601_BASE_CLOCK 31000000 | 23 | #define AU6601_BASE_CLOCK 31000000 |
| 24 | #define AU6601_MIN_CLOCK 150000 | 24 | #define AU6601_MIN_CLOCK 150000 |
| 25 | #define AU6601_MAX_CLOCK 208000000 | 25 | #define AU6601_MAX_CLOCK 208000000 |
| 26 | #define AU6601_MAX_DMA_SEGMENTS 1 | 26 | #define AU6601_MAX_DMA_SEGMENTS 64 |
| 27 | #define AU6601_MAX_PIO_SEGMENTS 1 | 27 | #define AU6601_MAX_PIO_SEGMENTS 1 |
| 28 | #define AU6601_MAX_DMA_BLOCK_SIZE 0x1000 | 28 | #define AU6601_MAX_DMA_BLOCK_SIZE 0x1000 |
| 29 | #define AU6601_MAX_PIO_BLOCK_SIZE 0x200 | 29 | #define AU6601_MAX_PIO_BLOCK_SIZE 0x200 |
