Commit 58aeb562 authored by Fred Ai's avatar Fred Ai Committed by Ulf Hansson
Browse files

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: default avatarFred Ai <fred.ai@bayhubtech.com>
Fixes:4be33cf1 ("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: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 41bccc98
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -693,6 +693,35 @@ static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *io
	return 0;
}

static void sdhci_pci_o2_set_power(struct sdhci_host *host, unsigned char mode,  unsigned short vdd)
{
	struct sdhci_pci_chip *chip;
	struct sdhci_pci_slot *slot = sdhci_priv(host);
	u32 scratch_32 = 0;
	u8 scratch_8 = 0;

	chip = slot->chip;

	if (mode == MMC_POWER_OFF) {
		/* UnLock WP */
		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
		scratch_8 &= 0x7f;
		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);

		/* Set PCR 0x354[16] to switch Clock Source back to OPE Clock */
		pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32);
		scratch_32 &= ~(O2_SD_SEL_DLL);
		pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32);

		/* Lock WP */
		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8);
		scratch_8 |= 0x80;
		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
	}

	sdhci_set_power(host, mode, vdd);
}

static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
{
	struct sdhci_pci_chip *chip;
@@ -1051,6 +1080,7 @@ static const struct sdhci_ops sdhci_pci_o2_ops = {
	.set_bus_width = sdhci_set_bus_width,
	.reset = sdhci_reset,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
	.set_power = sdhci_pci_o2_set_power,
};

const struct sdhci_pci_fixes sdhci_o2 = {