| .. | .. |
|---|
| 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 = { |
|---|