diff options
| -rw-r--r-- | drivers/mmc/core/sdio.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4eab79e09cc..fb99ccff908 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
| @@ -165,6 +165,36 @@ static int sdio_enable_wide(struct mmc_card *card) | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | /* | 167 | /* |
| 168 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
| 169 | */ | ||
| 170 | static int sdio_enable_hs(struct mmc_card *card) | ||
| 171 | { | ||
| 172 | int ret; | ||
| 173 | u8 speed; | ||
| 174 | |||
| 175 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
| 176 | return 0; | ||
| 177 | |||
| 178 | if (!card->cccr.high_speed) | ||
| 179 | return 0; | ||
| 180 | |||
| 181 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); | ||
| 182 | if (ret) | ||
| 183 | return ret; | ||
| 184 | |||
| 185 | speed |= SDIO_SPEED_EHS; | ||
| 186 | |||
| 187 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); | ||
| 188 | if (ret) | ||
| 189 | return ret; | ||
| 190 | |||
| 191 | mmc_card_set_highspeed(card); | ||
| 192 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | /* | ||
| 168 | * Host is being removed. Free up the current card. | 198 | * Host is being removed. Free up the current card. |
| 169 | */ | 199 | */ |
| 170 | static void mmc_sdio_remove(struct mmc_host *host) | 200 | static void mmc_sdio_remove(struct mmc_host *host) |
| @@ -333,10 +363,26 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
| 333 | goto remove; | 363 | goto remove; |
| 334 | 364 | ||
| 335 | /* | 365 | /* |
| 336 | * No support for high-speed yet, so just set | 366 | * Switch to high-speed (if supported). |
| 337 | * the card's maximum speed. | ||
| 338 | */ | 367 | */ |
| 339 | mmc_set_clock(host, card->cis.max_dtr); | 368 | err = sdio_enable_hs(card); |
| 369 | if (err) | ||
| 370 | goto remove; | ||
| 371 | |||
| 372 | /* | ||
| 373 | * Change to the card's maximum speed. | ||
| 374 | */ | ||
| 375 | if (mmc_card_highspeed(card)) { | ||
| 376 | /* | ||
| 377 | * The SDIO specification doesn't mention how | ||
| 378 | * the CIS transfer speed register relates to | ||
| 379 | * high-speed, but it seems that 50 MHz is | ||
| 380 | * mandatory. | ||
| 381 | */ | ||
| 382 | mmc_set_clock(host, 50000000); | ||
| 383 | } else { | ||
| 384 | mmc_set_clock(host, card->cis.max_dtr); | ||
| 385 | } | ||
| 340 | 386 | ||
| 341 | /* | 387 | /* |
| 342 | * Switch to wider bus (if supported). | 388 | * Switch to wider bus (if supported). |
