Skip to content

Commit 7b7d897

Browse files
shirleyher3118storulf
authored andcommitted
mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode
Add HW tuning support for SD host controller in SDR104 mode Signed-off-by: Shirley Her <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent cdd2b76 commit 7b7d897

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

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

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ static void __sdhci_o2_execute_tuning(struct sdhci_host *host, u32 opcode)
196196
{
197197
int i;
198198

199-
sdhci_send_tuning(host, MMC_SEND_TUNING_BLOCK_HS200);
199+
sdhci_send_tuning(host, opcode);
200200

201201
for (i = 0; i < 150; i++) {
202202
u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -305,10 +305,12 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
305305
* This handler only implements the eMMC tuning that is specific to
306306
* this controller. Fall back to the standard method for other TIMING.
307307
*/
308-
if (host->timing != MMC_TIMING_MMC_HS200)
308+
if ((host->timing != MMC_TIMING_MMC_HS200) &&
309+
(host->timing != MMC_TIMING_UHS_SDR104))
309310
return sdhci_execute_tuning(mmc, opcode);
310311

311-
if (WARN_ON(opcode != MMC_SEND_TUNING_BLOCK_HS200))
312+
if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
313+
(opcode != MMC_SEND_TUNING_BLOCK)))
312314
return -EINVAL;
313315
/*
314316
* Judge the tuning reason, whether caused by dll shift
@@ -342,6 +344,9 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
342344
sdhci_set_bus_width(host, current_bus_width);
343345
}
344346

347+
sdhci_reset(host, SDHCI_RESET_CMD);
348+
sdhci_reset(host, SDHCI_RESET_DATA);
349+
345350
host->flags &= ~SDHCI_HS400_TUNING;
346351
return 0;
347352
}
@@ -369,7 +374,6 @@ static void o2_pci_led_enable(struct sdhci_pci_chip *chip)
369374
scratch_32 |= O2_SD_LED_ENABLE;
370375
pci_write_config_dword(chip->pdev,
371376
O2_SD_TEST_REG, scratch_32);
372-
373377
}
374378

375379
static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip)
@@ -497,6 +501,10 @@ static void sdhci_o2_enable_clk(struct sdhci_host *host, u16 clk)
497501
static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
498502
{
499503
u16 clk;
504+
u8 scratch;
505+
u32 scratch_32;
506+
struct sdhci_pci_slot *slot = sdhci_priv(host);
507+
struct sdhci_pci_chip *chip = slot->chip;
500508

501509
host->mmc->actual_clock = 0;
502510

@@ -505,6 +513,23 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
505513
if (clock == 0)
506514
return;
507515

516+
if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) {
517+
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
518+
519+
scratch &= 0x7f;
520+
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
521+
522+
pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);
523+
524+
if ((scratch_32 & 0xFFFF0000) != 0x2c280000)
525+
o2_pci_set_baseclk(chip, 0x2c280000);
526+
527+
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
528+
529+
scratch |= 0x80;
530+
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
531+
}
532+
508533
clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
509534
sdhci_o2_enable_clk(host, clk);
510535
}

0 commit comments

Comments
 (0)