|
63 | 63 | #define SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY GENMASK(2, 0)
|
64 | 64 | #define GLI_9750_TUNING_PARAMETERS_RX_DLY_VALUE 0x1
|
65 | 65 |
|
| 66 | +#define SDHCI_GLI_9763E_CTRL_HS400 0x7 |
| 67 | + |
| 68 | +#define SDHCI_GLI_9763E_HS400_ES_REG 0x52C |
| 69 | +#define SDHCI_GLI_9763E_HS400_ES_BIT BIT(8) |
| 70 | + |
| 71 | +#define PCIE_GLI_9763E_VHS 0x884 |
| 72 | +#define GLI_9763E_VHS_REV GENMASK(19, 16) |
| 73 | +#define GLI_9763E_VHS_REV_R 0x0 |
| 74 | +#define GLI_9763E_VHS_REV_M 0x1 |
| 75 | +#define GLI_9763E_VHS_REV_W 0x2 |
| 76 | +#define PCIE_GLI_9763E_SCR 0x8E0 |
| 77 | +#define GLI_9763E_SCR_AXI_REQ BIT(9) |
| 78 | + |
66 | 79 | #define GLI_MAX_TUNING_LOOP 40
|
67 | 80 |
|
68 | 81 | /* Genesys Logic chipset */
|
@@ -351,6 +364,81 @@ static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip)
|
351 | 364 | }
|
352 | 365 | #endif
|
353 | 366 |
|
| 367 | +static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, |
| 368 | + struct mmc_ios *ios) |
| 369 | +{ |
| 370 | + struct sdhci_host *host = mmc_priv(mmc); |
| 371 | + u32 val; |
| 372 | + |
| 373 | + val = sdhci_readl(host, SDHCI_GLI_9763E_HS400_ES_REG); |
| 374 | + if (ios->enhanced_strobe) |
| 375 | + val |= SDHCI_GLI_9763E_HS400_ES_BIT; |
| 376 | + else |
| 377 | + val &= ~SDHCI_GLI_9763E_HS400_ES_BIT; |
| 378 | + |
| 379 | + sdhci_writel(host, val, SDHCI_GLI_9763E_HS400_ES_REG); |
| 380 | +} |
| 381 | + |
| 382 | +static void sdhci_set_gl9763e_signaling(struct sdhci_host *host, |
| 383 | + unsigned int timing) |
| 384 | +{ |
| 385 | + u16 ctrl_2; |
| 386 | + |
| 387 | + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 388 | + ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; |
| 389 | + if (timing == MMC_TIMING_MMC_HS200) |
| 390 | + ctrl_2 |= SDHCI_CTRL_UHS_SDR104; |
| 391 | + else if (timing == MMC_TIMING_MMC_HS) |
| 392 | + ctrl_2 |= SDHCI_CTRL_UHS_SDR25; |
| 393 | + else if (timing == MMC_TIMING_MMC_DDR52) |
| 394 | + ctrl_2 |= SDHCI_CTRL_UHS_DDR50; |
| 395 | + else if (timing == MMC_TIMING_MMC_HS400) |
| 396 | + ctrl_2 |= SDHCI_GLI_9763E_CTRL_HS400; |
| 397 | + |
| 398 | + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
| 399 | +} |
| 400 | + |
| 401 | +static void gli_set_gl9763e(struct sdhci_pci_slot *slot) |
| 402 | +{ |
| 403 | + struct pci_dev *pdev = slot->chip->pdev; |
| 404 | + u32 value; |
| 405 | + |
| 406 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); |
| 407 | + value &= ~GLI_9763E_VHS_REV; |
| 408 | + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); |
| 409 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); |
| 410 | + |
| 411 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_SCR, &value); |
| 412 | + value |= GLI_9763E_SCR_AXI_REQ; |
| 413 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_SCR, value); |
| 414 | + |
| 415 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); |
| 416 | + value &= ~GLI_9763E_VHS_REV; |
| 417 | + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); |
| 418 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); |
| 419 | +} |
| 420 | + |
| 421 | +static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) |
| 422 | +{ |
| 423 | + struct sdhci_host *host = slot->host; |
| 424 | + |
| 425 | + host->mmc->caps |= MMC_CAP_8_BIT_DATA | |
| 426 | + MMC_CAP_1_8V_DDR | |
| 427 | + MMC_CAP_NONREMOVABLE; |
| 428 | + host->mmc->caps2 |= MMC_CAP2_HS200_1_8V_SDR | |
| 429 | + MMC_CAP2_HS400_1_8V | |
| 430 | + MMC_CAP2_HS400_ES | |
| 431 | + MMC_CAP2_NO_SDIO | |
| 432 | + MMC_CAP2_NO_SD; |
| 433 | + gli_pcie_enable_msi(slot); |
| 434 | + host->mmc_host_ops.hs400_enhanced_strobe = |
| 435 | + gl9763e_hs400_enhanced_strobe; |
| 436 | + gli_set_gl9763e(slot); |
| 437 | + sdhci_enable_v4_mode(host); |
| 438 | + |
| 439 | + return 0; |
| 440 | +} |
| 441 | + |
354 | 442 | static const struct sdhci_ops sdhci_gl9755_ops = {
|
355 | 443 | .set_clock = sdhci_set_clock,
|
356 | 444 | .enable_dma = sdhci_pci_enable_dma,
|
@@ -390,3 +478,21 @@ const struct sdhci_pci_fixes sdhci_gl9750 = {
|
390 | 478 | .resume = sdhci_pci_gli_resume,
|
391 | 479 | #endif
|
392 | 480 | };
|
| 481 | + |
| 482 | +static const struct sdhci_ops sdhci_gl9763e_ops = { |
| 483 | + .set_clock = sdhci_set_clock, |
| 484 | + .enable_dma = sdhci_pci_enable_dma, |
| 485 | + .set_bus_width = sdhci_set_bus_width, |
| 486 | + .reset = sdhci_reset, |
| 487 | + .set_uhs_signaling = sdhci_set_gl9763e_signaling, |
| 488 | + .voltage_switch = sdhci_gli_voltage_switch, |
| 489 | +}; |
| 490 | + |
| 491 | +const struct sdhci_pci_fixes sdhci_gl9763e = { |
| 492 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
| 493 | + .probe_slot = gli_probe_slot_gl9763e, |
| 494 | + .ops = &sdhci_gl9763e_ops, |
| 495 | +#ifdef CONFIG_PM_SLEEP |
| 496 | + .resume = sdhci_pci_gli_resume, |
| 497 | +#endif |
| 498 | +}; |
0 commit comments