33
33
#define O2_SD_ADMA2 0xE7
34
34
#define O2_SD_INF_MOD 0xF1
35
35
#define O2_SD_MISC_CTRL4 0xFC
36
+ #define O2_SD_MISC_CTRL 0x1C0
37
+ #define O2_SD_PWR_FORCE_L0 0x0002
36
38
#define O2_SD_TUNING_CTRL 0x300
37
39
#define O2_SD_PLL_SETTING 0x304
38
40
#define O2_SD_MISC_SETTING 0x308
@@ -300,6 +302,8 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
300
302
{
301
303
struct sdhci_host * host = mmc_priv (mmc );
302
304
int current_bus_width = 0 ;
305
+ u32 scratch32 = 0 ;
306
+ u16 scratch = 0 ;
303
307
304
308
/*
305
309
* 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)
312
316
if (WARN_ON ((opcode != MMC_SEND_TUNING_BLOCK_HS200 ) &&
313
317
(opcode != MMC_SEND_TUNING_BLOCK )))
314
318
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 ));
315
330
/*
316
331
* Judge the tuning reason, whether caused by dll shift
317
332
* 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)
344
359
sdhci_set_bus_width (host , current_bus_width );
345
360
}
346
361
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
+
347
367
sdhci_reset (host , SDHCI_RESET_CMD );
348
368
sdhci_reset (host , SDHCI_RESET_DATA );
349
369
0 commit comments