Skip to content

Commit

Permalink
mmc: sdhci-pci-o2micro: Bug fix for SDR104 HW tuning failure
Browse files Browse the repository at this point in the history
commit 1ad9f88 upstream.

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: 7b7d897 ("mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
shirleyher3118 authored and gregkh committed Mar 4, 2021
1 parent a8997b9 commit e793c06
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions drivers/mmc/host/sdhci-pci-o2micro.c
Expand Up @@ -33,6 +33,8 @@
#define O2_SD_ADMA2 0xE7
#define O2_SD_INF_MOD 0xF1
#define O2_SD_MISC_CTRL4 0xFC
#define O2_SD_MISC_CTRL 0x1C0
#define O2_SD_PWR_FORCE_L0 0x0002
#define O2_SD_TUNING_CTRL 0x300
#define O2_SD_PLL_SETTING 0x304
#define O2_SD_MISC_SETTING 0x308
Expand Down Expand Up @@ -300,6 +302,8 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host = mmc_priv(mmc);
int current_bus_width = 0;
u32 scratch32 = 0;
u16 scratch = 0;

/*
* This handler only implements the eMMC tuning that is specific to
Expand All @@ -312,6 +316,17 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
(opcode != MMC_SEND_TUNING_BLOCK)))
return -EINVAL;

/* Force power mode enter L0 */
scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
scratch |= O2_SD_PWR_FORCE_L0;
sdhci_writew(host, scratch, O2_SD_MISC_CTRL);

/* wait DLL lock, timeout value 5ms */
if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,
scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000))
pr_warn("%s: DLL can't lock in 5ms after force L0 during tuning.\n",
mmc_hostname(host->mmc));
/*
* Judge the tuning reason, whether caused by dll shift
* If cause by dll shift, should call sdhci_o2_dll_recovery
Expand Down Expand Up @@ -344,6 +359,11 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
sdhci_set_bus_width(host, current_bus_width);
}

/* Cancel force power mode enter L0 */
scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
scratch &= ~(O2_SD_PWR_FORCE_L0);
sdhci_writew(host, scratch, O2_SD_MISC_CTRL);

sdhci_reset(host, SDHCI_RESET_CMD);
sdhci_reset(host, SDHCI_RESET_DATA);

Expand Down

0 comments on commit e793c06

Please sign in to comment.