.. | .. |
---|
178 | 178 | } else { |
---|
179 | 179 | puts("timeout.\n"); |
---|
180 | 180 | /* remove timeout return error and try to send command */ |
---|
| 181 | + break; |
---|
181 | 182 | } |
---|
182 | 183 | } |
---|
183 | 184 | time++; |
---|
.. | .. |
---|
313 | 314 | return -ECOMM; |
---|
314 | 315 | } |
---|
315 | 316 | |
---|
| 317 | +void sdhci_enable_clk(struct sdhci_host *host, u16 clk) |
---|
| 318 | +{ |
---|
| 319 | + unsigned int timeout; |
---|
| 320 | + |
---|
| 321 | + clk |= SDHCI_CLOCK_INT_EN; |
---|
| 322 | + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
---|
| 323 | + |
---|
| 324 | + /* Wait max 20 ms */ |
---|
| 325 | + timeout = 20; |
---|
| 326 | + while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) |
---|
| 327 | + & SDHCI_CLOCK_INT_STABLE)) { |
---|
| 328 | + if (timeout == 0) { |
---|
| 329 | + printf("%s: Internal clock never stabilised.\n", |
---|
| 330 | + __func__); |
---|
| 331 | + return; |
---|
| 332 | + } |
---|
| 333 | + timeout--; |
---|
| 334 | + udelay(1000); |
---|
| 335 | + } |
---|
| 336 | + clk |= SDHCI_CLOCK_CARD_EN; |
---|
| 337 | + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
---|
| 338 | +} |
---|
| 339 | + |
---|
316 | 340 | int sdhci_set_clock(struct sdhci_host *host, unsigned int clock) |
---|
317 | 341 | { |
---|
318 | 342 | unsigned int div, clk = 0, timeout; |
---|
.. | .. |
---|
379 | 403 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; |
---|
380 | 404 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) |
---|
381 | 405 | << SDHCI_DIVIDER_HI_SHIFT; |
---|
382 | | - clk |= SDHCI_CLOCK_INT_EN; |
---|
383 | | - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
---|
384 | 406 | |
---|
385 | | - /* Wait max 20 ms */ |
---|
386 | | - timeout = 20; |
---|
387 | | - while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) |
---|
388 | | - & SDHCI_CLOCK_INT_STABLE)) { |
---|
389 | | - if (timeout == 0) { |
---|
390 | | - printf("%s: Internal clock never stabilised.\n", |
---|
391 | | - __func__); |
---|
392 | | - return -EBUSY; |
---|
393 | | - } |
---|
394 | | - timeout--; |
---|
395 | | - udelay(1000); |
---|
396 | | - } |
---|
397 | | - clk |= SDHCI_CLOCK_CARD_EN; |
---|
398 | | - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
---|
| 407 | + sdhci_enable_clk(host, clk); |
---|
399 | 408 | |
---|
400 | 409 | host->clock = clock; |
---|
401 | 410 | return 0; |
---|
.. | .. |
---|
681 | 690 | return sdhci_init(mmc); |
---|
682 | 691 | } |
---|
683 | 692 | |
---|
| 693 | +static int sdhci_set_enhanced_strobe(struct udevice *dev) |
---|
| 694 | +{ |
---|
| 695 | + struct mmc *mmc = mmc_get_mmc_dev(dev); |
---|
| 696 | + struct sdhci_host *host = mmc->priv; |
---|
| 697 | + |
---|
| 698 | + if (host->ops && host->ops->set_enhanced_strobe) |
---|
| 699 | + return host->ops->set_enhanced_strobe(host); |
---|
| 700 | + |
---|
| 701 | + return -ENOTSUPP; |
---|
| 702 | +} |
---|
| 703 | + |
---|
684 | 704 | const struct dm_mmc_ops sdhci_ops = { |
---|
685 | 705 | .card_busy = sdhci_card_busy, |
---|
686 | 706 | .send_cmd = sdhci_send_command, |
---|
687 | 707 | .set_ios = sdhci_set_ios, |
---|
688 | 708 | .execute_tuning = sdhci_execute_tuning, |
---|
| 709 | + .set_enhanced_strobe = sdhci_set_enhanced_strobe, |
---|
689 | 710 | }; |
---|
690 | 711 | #else |
---|
691 | 712 | static const struct mmc_ops sdhci_ops = { |
---|