diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2016-12-02 08:14:27 -0500 |
|---|---|---|
| committer | Ulf Hansson <ulf.hansson@linaro.org> | 2016-12-05 08:16:24 -0500 |
| commit | 6b11e70bb72c5bfbd7d1544518d26d4b1100aae1 (patch) | |
| tree | 10aae524bf25f2be2e82ad0cb4b3a8c48039bb79 | |
| parent | 85336109c0b272d8d0b4509872e1247d948ddfa9 (diff) | |
mmc: sdhci: Tidy tuning loop
Tidy the tuning loop by moving it to a separate function and making it a
for-loop.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 81 |
1 files changed, 43 insertions, 38 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6fdec4ad4ad4..2b89fb9e9a6b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -2062,11 +2062,47 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode, | |||
| 2062 | spin_lock_irqsave(&host->lock, flags); | 2062 | spin_lock_irqsave(&host->lock, flags); |
| 2063 | } | 2063 | } |
| 2064 | 2064 | ||
| 2065 | static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode, | ||
| 2066 | unsigned long flags) | ||
| 2067 | { | ||
| 2068 | int i; | ||
| 2069 | |||
| 2070 | /* | ||
| 2071 | * Issue opcode repeatedly till Execute Tuning is set to 0 or the number | ||
| 2072 | * of loops reaches 40 times. | ||
| 2073 | */ | ||
| 2074 | for (i = 0; i < MAX_TUNING_LOOP; i++) { | ||
| 2075 | u16 ctrl; | ||
| 2076 | |||
| 2077 | sdhci_send_tuning(host, opcode, flags); | ||
| 2078 | |||
| 2079 | if (!host->tuning_done) { | ||
| 2080 | pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n", | ||
| 2081 | mmc_hostname(host->mmc)); | ||
| 2082 | sdhci_abort_tuning(host, opcode, flags); | ||
| 2083 | return; | ||
| 2084 | } | ||
| 2085 | |||
| 2086 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
| 2087 | if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) { | ||
| 2088 | if (ctrl & SDHCI_CTRL_TUNED_CLK) | ||
| 2089 | return; /* Success! */ | ||
| 2090 | break; | ||
| 2091 | } | ||
| 2092 | |||
| 2093 | /* eMMC spec does not require a delay between tuning cycles */ | ||
| 2094 | if (opcode == MMC_SEND_TUNING_BLOCK) | ||
| 2095 | mdelay(1); | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | pr_info("%s: Tuning failed, falling back to fixed sampling clock\n", | ||
| 2099 | mmc_hostname(host->mmc)); | ||
| 2100 | sdhci_reset_tuning(host); | ||
| 2101 | } | ||
| 2102 | |||
| 2065 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | 2103 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
| 2066 | { | 2104 | { |
| 2067 | struct sdhci_host *host = mmc_priv(mmc); | 2105 | struct sdhci_host *host = mmc_priv(mmc); |
| 2068 | u16 ctrl; | ||
| 2069 | int tuning_loop_counter = MAX_TUNING_LOOP; | ||
| 2070 | int err = 0; | 2106 | int err = 0; |
| 2071 | unsigned long flags; | 2107 | unsigned long flags; |
| 2072 | unsigned int tuning_count = 0; | 2108 | unsigned int tuning_count = 0; |
| @@ -2117,50 +2153,19 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
| 2117 | 2153 | ||
| 2118 | if (host->ops->platform_execute_tuning) { | 2154 | if (host->ops->platform_execute_tuning) { |
| 2119 | spin_unlock_irqrestore(&host->lock, flags); | 2155 | spin_unlock_irqrestore(&host->lock, flags); |
| 2120 | err = host->ops->platform_execute_tuning(host, opcode); | 2156 | return host->ops->platform_execute_tuning(host, opcode); |
| 2121 | return err; | ||
| 2122 | } | 2157 | } |
| 2123 | 2158 | ||
| 2124 | sdhci_start_tuning(host); | 2159 | host->mmc->retune_period = tuning_count; |
| 2125 | |||
| 2126 | /* | ||
| 2127 | * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number | ||
| 2128 | * of loops reaches 40 times. | ||
| 2129 | */ | ||
| 2130 | do { | ||
| 2131 | if (tuning_loop_counter-- == 0) | ||
| 2132 | break; | ||
| 2133 | |||
| 2134 | sdhci_send_tuning(host, opcode, flags); | ||
| 2135 | |||
| 2136 | if (!host->tuning_done) { | ||
| 2137 | pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n"); | ||
| 2138 | sdhci_abort_tuning(host, opcode, flags); | ||
| 2139 | goto out; | ||
| 2140 | } | ||
| 2141 | |||
| 2142 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
| 2143 | |||
| 2144 | /* eMMC spec does not require a delay between tuning cycles */ | ||
| 2145 | if (opcode == MMC_SEND_TUNING_BLOCK) | ||
| 2146 | mdelay(1); | ||
| 2147 | } while (ctrl & SDHCI_CTRL_EXEC_TUNING); | ||
| 2148 | 2160 | ||
| 2149 | /* | 2161 | sdhci_start_tuning(host); |
| 2150 | * The Host Driver has exhausted the maximum number of loops allowed, | ||
| 2151 | * so use fixed sampling frequency. | ||
| 2152 | */ | ||
| 2153 | if (tuning_loop_counter < 0) | ||
| 2154 | sdhci_reset_tuning(host); | ||
| 2155 | 2162 | ||
| 2156 | if (tuning_loop_counter < 0 || !(ctrl & SDHCI_CTRL_TUNED_CLK)) | 2163 | __sdhci_execute_tuning(host, opcode, flags); |
| 2157 | pr_info(DRIVER_NAME ": Tuning procedure failed, falling back to fixed sampling clock\n"); | ||
| 2158 | out: | ||
| 2159 | host->mmc->retune_period = tuning_count; | ||
| 2160 | 2164 | ||
| 2161 | sdhci_end_tuning(host); | 2165 | sdhci_end_tuning(host); |
| 2162 | out_unlock: | 2166 | out_unlock: |
| 2163 | spin_unlock_irqrestore(&host->lock, flags); | 2167 | spin_unlock_irqrestore(&host->lock, flags); |
| 2168 | |||
| 2164 | return err; | 2169 | return err; |
| 2165 | } | 2170 | } |
| 2166 | 2171 | ||
