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