hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
u-boot/drivers/mmc/dw_mmc.c
....@@ -8,6 +8,7 @@
88
99 #include <common.h>
1010 #include <bouncebuf.h>
11
+#include <div64.h>
1112 #include <errno.h>
1213 #include <malloc.h>
1314 #include <memalign.h>
....@@ -19,6 +20,7 @@
1920 #endif
2021
2122 #define PAGE_SIZE 4096
23
+#define MSEC_PER_SEC 1000ULL
2224
2325 /*
2426 * Currently it supports read/write up to 8*8*4 Bytes per
....@@ -159,18 +161,62 @@
159161 dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
160162 }
161163
162
-static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
164
+#ifdef CONFIG_SPL_BUILD
165
+static unsigned int dwmci_get_drto(struct dwmci_host *host,
166
+ const unsigned int size)
167
+{
168
+ unsigned int drto_clks;
169
+ unsigned int drto_div;
170
+ unsigned int drto_ms;
171
+
172
+ drto_clks = dwmci_readl(host, DWMCI_TMOUT) >> 8;
173
+ drto_div = (dwmci_readl(host, DWMCI_CLKDIV) & 0xff) * 2;
174
+ if (drto_div == 0)
175
+ drto_div = 1;
176
+
177
+ drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div,
178
+ host->mmc->clock);
179
+
180
+ /* add a bit spare time */
181
+ drto_ms += 10;
182
+
183
+ return drto_ms;
184
+}
185
+#else
186
+static unsigned int dwmci_get_drto(struct dwmci_host *host,
187
+ const unsigned int size)
163188 {
164189 unsigned int timeout;
165190
166191 timeout = size * 8; /* counting in bits */
167192 timeout *= 10; /* wait 10 times as long */
168
- timeout /= mmc->clock;
169
- timeout /= mmc->bus_width;
193
+ timeout /= host->mmc->clock;
194
+ timeout /= host->mmc->bus_width;
170195 timeout *= 1000; /* counting in msec */
171196 timeout = (timeout < 10000) ? 10000 : timeout;
172197
173198 return timeout;
199
+}
200
+#endif
201
+
202
+static unsigned int dwmci_get_cto(struct dwmci_host *host)
203
+{
204
+ unsigned int cto_clks;
205
+ unsigned int cto_div;
206
+ unsigned int cto_ms;
207
+
208
+ cto_clks = dwmci_readl(host, DWMCI_TMOUT) & 0xff;
209
+ cto_div = (dwmci_readl(host, DWMCI_CLKDIV) & 0xff) * 2;
210
+ if (cto_div == 0)
211
+ cto_div = 1;
212
+
213
+ cto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * cto_clks * cto_div,
214
+ host->mmc->clock);
215
+
216
+ /* add a bit spare time */
217
+ cto_ms += 10;
218
+
219
+ return cto_ms;
174220 }
175221
176222 static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
....@@ -192,7 +238,7 @@
192238 else
193239 buf = (unsigned int *)data->src;
194240
195
- timeout = dwmci_get_timeout(host->mmc, size);
241
+ timeout = dwmci_get_drto(host, size);
196242 size /= 4;
197243
198244 for (;;) {
....@@ -252,6 +298,7 @@
252298 }
253299 dwmci_writel(host, DWMCI_RINTSTS,
254300 DWMCI_INTMSK_RXDR);
301
+ start = get_timer(0);
255302 } else if (data->flags == MMC_DATA_WRITE &&
256303 (mask & DWMCI_INTMSK_TXDR)) {
257304 while (size) {
....@@ -281,6 +328,7 @@
281328 }
282329 dwmci_writel(host, DWMCI_RINTSTS,
283330 DWMCI_INTMSK_TXDR);
331
+ start = get_timer(0);
284332 }
285333 }
286334
....@@ -329,9 +377,8 @@
329377 struct dwmci_host *host = mmc->priv;
330378 ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
331379 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
332
- int ret = 0, flags = 0, i;
380
+ int ret = 0, flags = 0;
333381 unsigned int timeout = 500;
334
- u32 retry = 100000;
335382 u32 mask, ctrl;
336383 ulong start = get_timer(0);
337384 struct bounce_buffer bbstate;
....@@ -400,16 +447,18 @@
400447
401448 dwmci_writel(host, DWMCI_CMD, flags);
402449
403
- for (i = 0; i < retry; i++) {
450
+ timeout = dwmci_get_cto(host);
451
+ start = get_timer(0);
452
+ do {
404453 mask = dwmci_readl(host, DWMCI_RINTSTS);
405454 if (mask & DWMCI_INTMSK_CDONE) {
406455 if (!data)
407456 dwmci_writel(host, DWMCI_RINTSTS, mask);
408457 break;
409458 }
410
- }
459
+ } while (!(get_timer(start) > timeout));
411460
412
- if (i == retry) {
461
+ if (get_timer(start) > timeout) {
413462 debug("%s: Timeout.\n", __func__);
414463 return -ETIMEDOUT;
415464 }
....@@ -470,9 +519,8 @@
470519 #endif
471520 struct dwmci_host *host = mmc->priv;
472521 struct dwmci_idmac *cur_idmac;
473
- int ret = 0, flags = 0, i;
522
+ int ret = 0, flags = 0;
474523 unsigned int timeout = 500;
475
- u32 retry = 100000;
476524 u32 mask;
477525 ulong start = get_timer(0);
478526 struct bounce_buffer bbstate;
....@@ -541,16 +589,18 @@
541589
542590 dwmci_writel(host, DWMCI_CMD, flags);
543591
544
- for (i = 0; i < retry; i++) {
592
+ timeout = dwmci_get_cto(host);
593
+ start = get_timer(0);
594
+ do {
545595 mask = dwmci_readl(host, DWMCI_RINTSTS);
546596 if (mask & DWMCI_INTMSK_CDONE) {
547597 if (!data)
548598 dwmci_writel(host, DWMCI_RINTSTS, mask);
549599 break;
550600 }
551
- }
601
+ } while (!(get_timer(start) > timeout));
552602
553
- if (i == retry) {
603
+ if (get_timer(start) > timeout) {
554604 debug("%s: Timeout.\n", __func__);
555605 return -ETIMEDOUT;
556606 }