1 From d1d692081ec333f981b892cac660ac73977923d2 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Mon, 4 Apr 2016 12:35:32 +0100
4 Subject: [PATCH] Revert "bcm2835-sdhost: Precalc divisors and overclocks"
6 This reverts commit 20260462773366a5734e5268dae0a4c179a21a2d.
8 drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++----------------------
9 1 file changed, 64 insertions(+), 88 deletions(-)
11 --- a/drivers/mmc/host/bcm2835-sdhost.c
12 +++ b/drivers/mmc/host/bcm2835-sdhost.c
13 @@ -154,15 +154,12 @@ struct bcm2835_host {
14 u32 pio_timeout; /* In jiffies */
16 int clock; /* Current clock speed */
19 bool slow_card; /* Force 11-bit divisor */
21 unsigned int max_clk; /* Max src clock freq */
22 - unsigned int src_clks[2]; /* Min/max src clock freqs */
23 - unsigned int cur_clk_idx; /* Index of current clock */
24 - unsigned int next_clk_idx; /* Next clock index */
25 - unsigned int cdivs[2];
26 + unsigned int min_clk; /* Min src clock freq */
27 + unsigned int cur_clk; /* Current src clock freq */
29 struct tasklet_struct finish_tasklet; /* Tasklet structures */
31 @@ -216,7 +213,7 @@ struct bcm2835_host {
32 u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */
33 u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */
34 u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */
35 - u32 prev_overclock_50;
36 + u32 overclock; /* Current frequency if overclocked, else zero */
37 u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */
39 u32 sectors; /* Cached card size in sectors */
40 @@ -1512,35 +1509,10 @@ static irqreturn_t bcm2835_sdhost_irq(in
44 -static void bcm2835_sdhost_select_clock(struct bcm2835_host *host, int idx)
46 - unsigned int clock = host->clocks[idx];
47 - unsigned int cdiv = host->cdivs[idx];
49 - host->mmc->actual_clock = clock;
50 - host->ns_per_fifo_word = (1000000000/clock) *
51 - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32);
54 - bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
56 - /* Set the timeout to 500ms */
57 - bcm2835_sdhost_write(host, clock/2, SDTOUT);
59 - host->cur_clk_idx = host->next_clk_idx = idx;
62 - pr_info("%s: clock=%d -> src_clk=%d, cdiv=%x (actual %d)\n",
63 - mmc_hostname(host->mmc), host->clock,
64 - host->src_clks[idx], host->cdiv,
65 - host->mmc->actual_clock);
68 void bcm2835_sdhost_set_clock(struct bcm2835_host *host)
70 int div = 0; /* Initialized for compiler warning */
71 unsigned int clock = host->clock;
75 pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock);
76 @@ -1581,45 +1553,53 @@ void bcm2835_sdhost_set_clock(struct bcm
80 - /* Calculate the clock divisors */
81 - for (clk_idx = 0; clk_idx <= host->variable_clock; clk_idx++)
83 - unsigned int cur_clk = host->src_clks[clk_idx];
84 - unsigned int actual_clock;
85 + div = host->cur_clk / clock;
88 + if ((host->cur_clk / div) > clock)
92 + if (div > SDCDIV_MAX_CDIV)
93 + div = SDCDIV_MAX_CDIV;
95 + clock = host->cur_clk / (div + 2);
96 + host->mmc->actual_clock = clock;
98 + /* Calibrate some delays */
100 + host->ns_per_fifo_word = (1000000000/clock) *
101 + ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32);
103 - div = cur_clk / clock;
106 - if ((cur_clk / div) > clock)
110 - if (div > SDCDIV_MAX_CDIV)
111 - div = SDCDIV_MAX_CDIV;
112 - actual_clock = cur_clk / (div + 2);
114 - host->cdivs[clk_idx] = div;
115 - host->clocks[clk_idx] = actual_clock;
117 - if (host->overclock_50 != host->prev_overclock_50) {
118 - const char *clk_name = "";
119 - if (host->variable_clock)
120 - clk_name = clk_idx ? " (turbo)" : " (normal)";
121 - if (actual_clock > host->clock)
122 - pr_info("%s: overclocking to %dHz%s\n",
123 - mmc_hostname(host->mmc),
124 - actual_clock, clk_name);
125 - else if ((host->overclock_50 < 50) && (clk_idx == 0))
126 - pr_info("%s: cancelling overclock%s\n",
127 - mmc_hostname(host->mmc),
128 - host->variable_clock ? "s" : "");
129 + if (clock > host->clock) {
130 + /* Save the closest value, to make it easier
131 + to reduce in the event of error */
132 + host->overclock_50 = (clock/MHZ);
134 + if (clock != host->overclock) {
135 + pr_warn("%s: overclocking to %dHz\n",
136 + mmc_hostname(host->mmc), clock);
137 + host->overclock = clock;
140 + else if (host->overclock)
142 + host->overclock = 0;
143 + if (clock == 50 * MHZ)
144 + pr_warn("%s: cancelling overclock\n",
145 + mmc_hostname(host->mmc));
148 - if (host->clock == 50*MHZ)
149 - host->prev_overclock_50 = host->overclock_50;
151 + bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
153 - bcm2835_sdhost_select_clock(host, host->cur_clk_idx);
154 + /* Set the timeout to 500ms */
155 + bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT);
158 + pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n",
159 + mmc_hostname(host->mmc), host->clock,
160 + host->cur_clk, host->cdiv, host->mmc->actual_clock);
163 static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
164 @@ -1677,9 +1657,6 @@ static void bcm2835_sdhost_request(struc
166 spin_lock_irqsave(&host->lock, flags);
168 - if (host->next_clk_idx != host->cur_clk_idx)
169 - bcm2835_sdhost_select_clock(host, host->next_clk_idx);
171 WARN_ON(host->mrq != NULL);
174 @@ -1742,7 +1719,11 @@ static int bcm2835_sdhost_cpufreq_callba
177 case CPUFREQ_POSTCHANGE:
178 - host->next_clk_idx = (freq->new > freq->old);
179 + if (freq->new > freq->old)
180 + host->cur_clk = host->max_clk;
182 + host->cur_clk = host->min_clk;
183 + bcm2835_sdhost_set_clock(host);
184 up(&host->cpufreq_semaphore);
187 @@ -1782,11 +1763,8 @@ static void bcm2835_sdhost_set_ios(struc
188 ios->clock, ios->power_mode, ios->bus_width,
189 ios->timing, ios->signal_voltage, ios->drv_type);
191 - if (ios->clock && (host->cur_clk_idx == -1)) {
192 - unsigned int cur_clk =
193 - get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE);
194 - host->cur_clk_idx = (cur_clk == host->src_clks[0]) ? 0 : 1;
196 + if (ios->clock && !host->cur_clk)
197 + host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE);
199 spin_lock_irqsave(&host->lock, flags);
201 @@ -1876,12 +1854,11 @@ static void bcm2835_sdhost_tasklet_finis
203 /* Drop the overclock after any data corruption, or after any
205 - if (host->clock > 50*MHZ) {
206 + if (host->overclock) {
207 if ((mrq->cmd && mrq->cmd->error) ||
208 (mrq->data && mrq->data->error) ||
209 (mrq->stop && mrq->stop->error)) {
210 - host->overclock_50 = (host->clock/MHZ) - 1;
212 + host->overclock_50--;
213 pr_warn("%s: reducing overclock due to errors\n",
214 mmc_hostname(host->mmc));
215 bcm2835_sdhost_set_clock(host);
216 @@ -2045,7 +2022,7 @@ static int bcm2835_sdhost_probe(struct p
217 struct bcm2835_host *host;
218 struct mmc_host *mmc;
220 - unsigned int max_clk, min_clk;
221 + unsigned int max_clk;
224 pr_debug("bcm2835_sdhost_probe\n");
225 @@ -2151,8 +2128,12 @@ static int bcm2835_sdhost_probe(struct p
227 mmc->caps |= MMC_CAP_4_BIT_DATA;
229 + ret = bcm2835_sdhost_add_host(host);
233 /* Query the core clock frequencies */
234 - min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE);
235 + host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE);
236 max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE);
237 if (max_clk != host->max_clk) {
238 pr_warn("%s: Expected max clock %d, found %d\n",
239 @@ -2160,24 +2141,19 @@ static int bcm2835_sdhost_probe(struct p
240 host->max_clk = max_clk;
243 - host->src_clks[0] = min_clk;
244 - host->cur_clk_idx = -1;
245 - if (max_clk != min_clk) {
246 - host->src_clks[1] = max_clk;
247 + if (host->min_clk != host->max_clk) {
248 host->cpufreq_nb.notifier_call =
249 bcm2835_sdhost_cpufreq_callback;
250 sema_init(&host->cpufreq_semaphore, 1);
251 cpufreq_register_notifier(&host->cpufreq_nb,
252 CPUFREQ_TRANSITION_NOTIFIER);
253 host->variable_clock = 1;
254 + host->cur_clk = 0; /* Get this later */
256 host->variable_clock = 0;
257 + host->cur_clk = host->max_clk;
260 - ret = bcm2835_sdhost_add_host(host);
264 platform_set_drvdata(pdev, host);
266 pr_debug("bcm2835_sdhost_probe -> OK\n");