Skip to content

Commit 58aeb56

Browse files
FredAiBayHubTechstorulf
authored andcommitted
mmc: sdhci-pci-o2micro: Fix a warm reboot issue that disk can't be detected by BIOS
Driver shall switch clock source from DLL clock to OPE clock when power off card to ensure that card can be identified with OPE clock by BIOS. Signed-off-by: Fred Ai <fred.ai@bayhubtech.com> Fixes:4be33cf18703 ("mmc: sdhci-pci-o2micro: Improve card input timing at SDR104/HS200 mode") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240203102908.4683-1-fredaibayhubtech@126.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 41bccc9 commit 58aeb56

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,35 @@ static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *io
693693
return 0;
694694
}
695695

696+
static void sdhci_pci_o2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd)
697+
{
698+
struct sdhci_pci_chip *chip;
699+
struct sdhci_pci_slot *slot = sdhci_priv(host);
700+
u32 scratch_32 = 0;
701+
u8 scratch_8 = 0;
702+
703+
chip = slot->chip;
704+
705+
if (mode == MMC_POWER_OFF) {
706+
/* UnLock WP */
707+
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
708+
scratch_8 &= 0x7f;
709+
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
710+
711+
/* Set PCR 0x354[16] to switch Clock Source back to OPE Clock */
712+
pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32);
713+
scratch_32 &= ~(O2_SD_SEL_DLL);
714+
pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32);
715+
716+
/* Lock WP */
717+
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
718+
scratch_8 |= 0x80;
719+
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
720+
}
721+
722+
sdhci_set_power(host, mode, vdd);
723+
}
724+
696725
static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
697726
{
698727
struct sdhci_pci_chip *chip;
@@ -1051,6 +1080,7 @@ static const struct sdhci_ops sdhci_pci_o2_ops = {
10511080
.set_bus_width = sdhci_set_bus_width,
10521081
.reset = sdhci_reset,
10531082
.set_uhs_signaling = sdhci_set_uhs_signaling,
1083+
.set_power = sdhci_pci_o2_set_power,
10541084
};
10551085

10561086
const struct sdhci_pci_fixes sdhci_o2 = {

0 commit comments

Comments
 (0)