From 2b06e1597ac200de8e5cffc3b2a3e287f62258a1 Mon Sep 17 00:00:00 2001 From: BOUGH CHEN Date: Fri, 28 Dec 2018 08:35:49 +0000 Subject: mmc: sdhci: add delay after the last tuning command When host set the host->tuning_delay, even the last tuning command need a delay, otherwise the first command after the tuning will meet issue. Take i.MX7D as an example, there will be the following log: mmc2: switch to high-speed from hs200 failed, err:-110 mmc2: error -110 whilst initialising MMC card Signed-off-by: Haibo Chen Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/host/sdhci.c') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index eba9bcc92ad3..283dab5fc8d4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2376,6 +2376,10 @@ static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) return -ETIMEDOUT; } + /* Spec does not require a delay between tuning cycles */ + if (host->tuning_delay > 0) + mdelay(host->tuning_delay); + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) { if (ctrl & SDHCI_CTRL_TUNED_CLK) @@ -2383,9 +2387,6 @@ static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) break; } - /* Spec does not require a delay between tuning cycles */ - if (host->tuning_delay > 0) - mdelay(host->tuning_delay); } pr_info("%s: Tuning failed, falling back to fixed sampling clock\n", -- cgit v1.2.3-59-g8ed1b From 401059df9b62e11f1544bd106cc4a21c398c0de9 Mon Sep 17 00:00:00 2001 From: BOUGH CHEN Date: Mon, 7 Jan 2019 10:11:36 +0000 Subject: mmc: sdhci: correct the maximum timeout when enable CMDQ Change to use sdhci_set_timeout() to set the maximum timeout, so that the host can use it's own set_timeout() callback to set the maximum timeout if the host has. Signed-off-by: Haibo Chen Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/mmc/host/sdhci.c') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 283dab5fc8d4..c8ca3ce316c4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -883,7 +883,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, bool *too_big) { u8 count; - struct mmc_data *data = cmd->data; + struct mmc_data *data; unsigned target_timeout, current_timeout; *too_big = true; @@ -897,6 +897,11 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) return 0xE; + /* Unspecified command, asume max */ + if (cmd == NULL) + return 0xE; + + data = cmd->data; /* Unspecified timeout, assume max */ if (!data && !cmd->busy_timeout) return 0xE; @@ -3364,7 +3369,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc) SDHCI_BLOCK_SIZE); /* Set maximum timeout */ - sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL); + sdhci_set_timeout(host, NULL); host->ier = host->cqe_ier; -- cgit v1.2.3-59-g8ed1b From 4c4faff62bf59e64c5175b7704727e6b9db361f2 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Wed, 23 Jan 2019 11:30:53 -0800 Subject: mmc: sdhci: Add ADMA3 DMA support for V4 enabled host Below are the supported DMA types in Host Control1 Register with Version 4 enable b'00 - SDMA b'01 - Not Used b'10 - ADMA2 b'11 - ADMA2 or ADMA3 ADMA3 uses Command Descriptor to issue an SD command. A multi-block data transfer is performed by using a pair of CMD descriptor and ADMA2 descriptor. ADMA3 performs multiple of multi-block data transfer by using Integrated Descriptor which is more suitable for Command Queuing to fetch both Command and Transfer descriptors. Host Capabilities register indicates the supports of ADMA3 DMA. Signed-off-by: Sowjanya Komatineni Acked-by: Adrian Hunter Reviewed-by: Thierry Reding Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 9 ++++++++- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/mmc/host/sdhci.c') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c8ca3ce316c4..39bbbd754781 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3359,7 +3359,14 @@ void sdhci_cqe_enable(struct mmc_host *mmc) ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl &= ~SDHCI_CTRL_DMA_MASK; - if (host->flags & SDHCI_USE_64_BIT_DMA) + /* + * Host from V4.10 supports ADMA3 DMA type. + * ADMA3 performs integrated descriptor which is more suitable + * for cmd queuing to fetch both command and transfer descriptors. + */ + if (host->v4_mode && (host->caps1 & SDHCI_CAN_DO_ADMA3)) + ctrl |= SDHCI_CTRL_ADMA3; + else if (host->flags & SDHCI_USE_64_BIT_DMA) ctrl |= SDHCI_CTRL_ADMA64; else ctrl |= SDHCI_CTRL_ADMA32; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 924e03332cf7..01002cba1359 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -92,6 +92,7 @@ #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 +#define SDHCI_CTRL_ADMA3 0x18 #define SDHCI_CTRL_8BITBUS 0x20 #define SDHCI_CTRL_CDTEST_INS 0x40 #define SDHCI_CTRL_CDTEST_EN 0x80 @@ -234,6 +235,7 @@ #define SDHCI_RETUNING_MODE_SHIFT 14 #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 #define SDHCI_CLOCK_MUL_SHIFT 16 +#define SDHCI_CAN_DO_ADMA3 0x08000000 #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ #define SDHCI_CAPABILITIES_1 0x44 -- cgit v1.2.3-59-g8ed1b From 6d5cd068ee59fba58f49bed2fcea3634bc22f4b3 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 12 Feb 2019 15:07:35 +0100 Subject: mmc: sdhci: use WP GPIO in sdhci_check_ro() Even though SDHCI controllers may have a dedicated WP pin that can be queried using the SDHCI_PRESENT_STATE register, some platforms may chose to use a separate regular GPIO to route the WP signal. Such a GPIO is typically represented using the wp-gpios property in the Device Tree. Unfortunately, the current sdhci_check_ro() function does not make use of such GPIO when available: it either uses a host controller specific ->get_ro() operation, or uses the SDHCI_PRESENT_STATE. Several host controller specific ->get_ro() functions are implemented just to check a WP GPIO state. Instead of pushing this to more controller-specific implementations, let's handle this in the core SDHCI code, just like it is already done for the CD GPIO in sdhci_get_cd(). The below patch simply changes sdhci_check_ro() to use the value of the WP GPIO if available. Signed-off-by: Thomas Petazzoni Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mmc/host/sdhci.c') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 39bbbd754781..a8141ff9be03 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2053,6 +2053,8 @@ static int sdhci_check_ro(struct sdhci_host *host) is_readonly = 0; else if (host->ops->get_ro) is_readonly = host->ops->get_ro(host); + else if (mmc_can_gpio_ro(host->mmc)) + is_readonly = mmc_gpio_get_ro(host->mmc); else is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT); -- cgit v1.2.3-59-g8ed1b