Skip to content

Commit 1ad9f88

Browse files
shirleyher3118storulf
authored andcommitted
mmc: sdhci-pci-o2micro: Bug fix for SDR104 HW tuning failure
Force chip enter L0 power state during SDR104 HW tuning to avoid tuning failure Signed-off-by: Shirley Her <[email protected]> Link: https://lore.kernel.org/r/[email protected] Fixes: 7b7d897 ("mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode") Cc: [email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 3f957de commit 1ad9f88

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

drivers/mmc/host/sdhci-pci-o2micro.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#define O2_SD_ADMA2 0xE7
3434
#define O2_SD_INF_MOD 0xF1
3535
#define O2_SD_MISC_CTRL4 0xFC
36+
#define O2_SD_MISC_CTRL 0x1C0
37+
#define O2_SD_PWR_FORCE_L0 0x0002
3638
#define O2_SD_TUNING_CTRL 0x300
3739
#define O2_SD_PLL_SETTING 0x304
3840
#define O2_SD_MISC_SETTING 0x308
@@ -300,6 +302,8 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
300302
{
301303
struct sdhci_host *host = mmc_priv(mmc);
302304
int current_bus_width = 0;
305+
u32 scratch32 = 0;
306+
u16 scratch = 0;
303307

304308
/*
305309
* This handler only implements the eMMC tuning that is specific to
@@ -312,6 +316,17 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
312316
if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
313317
(opcode != MMC_SEND_TUNING_BLOCK)))
314318
return -EINVAL;
319+
320+
/* Force power mode enter L0 */
321+
scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
322+
scratch |= O2_SD_PWR_FORCE_L0;
323+
sdhci_writew(host, scratch, O2_SD_MISC_CTRL);
324+
325+
/* wait DLL lock, timeout value 5ms */
326+
if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,
327+
scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000))
328+
pr_warn("%s: DLL can't lock in 5ms after force L0 during tuning.\n",
329+
mmc_hostname(host->mmc));
315330
/*
316331
* Judge the tuning reason, whether caused by dll shift
317332
* If cause by dll shift, should call sdhci_o2_dll_recovery
@@ -344,6 +359,11 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
344359
sdhci_set_bus_width(host, current_bus_width);
345360
}
346361

362+
/* Cancel force power mode enter L0 */
363+
scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
364+
scratch &= ~(O2_SD_PWR_FORCE_L0);
365+
sdhci_writew(host, scratch, O2_SD_MISC_CTRL);
366+
347367
sdhci_reset(host, SDHCI_RESET_CMD);
348368
sdhci_reset(host, SDHCI_RESET_DATA);
349369

0 commit comments

Comments
 (0)