Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <shirley.her@bayhubtech.com>
Link: https://lore.kernel.org/r/20210206014051.3418-1-shirley.her@bayhubtech.com
Fixes: 7b7d897e8898 ("mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Shirley Her and committed by
Ulf Hansson
1ad9f880 3f957dec

+20
+20
drivers/mmc/host/sdhci-pci-o2micro.c
··· 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 ··· 302 300 { 303 301 struct sdhci_host *host = mmc_priv(mmc); 304 302 int current_bus_width = 0; 303 + u32 scratch32 = 0; 304 + u16 scratch = 0; 305 305 306 306 /* 307 307 * This handler only implements the eMMC tuning that is specific to ··· 316 312 if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) && 317 313 (opcode != MMC_SEND_TUNING_BLOCK))) 318 314 return -EINVAL; 315 + 316 + /* Force power mode enter L0 */ 317 + scratch = sdhci_readw(host, O2_SD_MISC_CTRL); 318 + scratch |= O2_SD_PWR_FORCE_L0; 319 + sdhci_writew(host, scratch, O2_SD_MISC_CTRL); 320 + 321 + /* wait DLL lock, timeout value 5ms */ 322 + if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host, 323 + scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000)) 324 + pr_warn("%s: DLL can't lock in 5ms after force L0 during tuning.\n", 325 + mmc_hostname(host->mmc)); 319 326 /* 320 327 * Judge the tuning reason, whether caused by dll shift 321 328 * If cause by dll shift, should call sdhci_o2_dll_recovery ··· 358 343 mmc->ios.bus_width = MMC_BUS_WIDTH_8; 359 344 sdhci_set_bus_width(host, current_bus_width); 360 345 } 346 + 347 + /* Cancel force power mode enter L0 */ 348 + scratch = sdhci_readw(host, O2_SD_MISC_CTRL); 349 + scratch &= ~(O2_SD_PWR_FORCE_L0); 350 + sdhci_writew(host, scratch, O2_SD_MISC_CTRL); 361 351 362 352 sdhci_reset(host, SDHCI_RESET_CMD); 363 353 sdhci_reset(host, SDHCI_RESET_DATA);