Skip to content

Commit 0e92aec

Browse files
Victor Shihstorulf
authored andcommitted
mmc: sdhci-pci-gli: Add support SD Express card for GL9767
Add support SD Express card for GL9767. The workflow of the SD Express card in GL9767 is as below. 1. GL9767 operates in SD mode and set MMC_CAP2_SD_EXP flag. 2. If card is inserted, Host send CMD8 to ask the capabilities of the card. 3. If the card has PCIe capability, then init_sd_express() will be invoked. 4. If the card has been put in write protect state then the SD features supported by SD mode but not supported by PCIe mode, therefore GL9767 switch to SD mode. 5. If the card has not been put in write protect state then GL9767 switch from SD mode to PCIe/NVMe mode and mmc driver handover control to NVMe driver. 6. If card is removed, GL9767 will return to SD mode. Signed-off-by: Ben Chuang <[email protected]> Signed-off-by: Victor Shih <[email protected]> Acked-by: Adrian Hunter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 17b4921 commit 0e92aec

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

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

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@
164164
#define PCIE_GLI_9767_CFG 0x8A0
165165
#define PCIE_GLI_9767_CFG_LOW_PWR_OFF BIT(12)
166166

167+
#define PCIE_GLI_9767_COMBO_MUX_CTL 0x8C8
168+
#define PCIE_GLI_9767_COMBO_MUX_CTL_RST_EN BIT(6)
169+
#define PCIE_GLI_9767_COMBO_MUX_CTL_WAIT_PERST_EN BIT(10)
170+
167171
#define PCIE_GLI_9767_PWR_MACRO_CTL 0x8D0
168172
#define PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE GENMASK(3, 0)
169173
#define PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE GENMASK(15, 12)
@@ -181,6 +185,9 @@
181185
#define PCIE_GLI_9767_SCR_CORE_PWR_D3_OFF BIT(21)
182186
#define PCIE_GLI_9767_SCR_CFG_RST_DATA_LINK_DOWN BIT(30)
183187

188+
#define PCIE_GLI_9767_SDHC_CAP 0x91C
189+
#define PCIE_GLI_9767_SDHC_CAP_SDEI_RESULT BIT(5)
190+
184191
#define PCIE_GLI_9767_SD_PLL_CTL 0x938
185192
#define PCIE_GLI_9767_SD_PLL_CTL_PLL_LDIV GENMASK(9, 0)
186193
#define PCIE_GLI_9767_SD_PLL_CTL_PLL_PDIV GENMASK(15, 12)
@@ -191,6 +198,23 @@
191198
#define PCIE_GLI_9767_SD_PLL_CTL2 0x93C
192199
#define PCIE_GLI_9767_SD_PLL_CTL2_PLLSSC_PPM GENMASK(31, 16)
193200

201+
#define PCIE_GLI_9767_SD_EXPRESS_CTL 0x940
202+
#define PCIE_GLI_9767_SD_EXPRESS_CTL_SDEI_EXE BIT(0)
203+
#define PCIE_GLI_9767_SD_EXPRESS_CTL_SD_EXPRESS_MODE BIT(1)
204+
205+
#define PCIE_GLI_9767_SD_DATA_MULTI_CTL 0x944
206+
#define PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME GENMASK(23, 16)
207+
#define PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME_VALUE 0x64
208+
209+
#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2 0x950
210+
#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE BIT(0)
211+
212+
#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2 0x954
213+
#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2_SDEI_COMPLETE_STATUS_EN BIT(0)
214+
215+
#define PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2 0x958
216+
#define PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2_SDEI_COMPLETE_SIGNAL_EN BIT(0)
217+
194218
#define GLI_MAX_TUNING_LOOP 40
195219

196220
/* Genesys Logic chipset */
@@ -935,6 +959,93 @@ static void sdhci_gl9767_reset(struct sdhci_host *host, u8 mask)
935959
gli_set_9767(host);
936960
}
937961

962+
static int gl9767_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios)
963+
{
964+
struct sdhci_host *host = mmc_priv(mmc);
965+
struct sdhci_pci_slot *slot = sdhci_priv(host);
966+
struct pci_dev *pdev;
967+
u32 value;
968+
int i;
969+
970+
pdev = slot->chip->pdev;
971+
972+
if (mmc->ops->get_ro(mmc)) {
973+
mmc->ios.timing &= ~(MMC_TIMING_SD_EXP | MMC_TIMING_SD_EXP_1_2V);
974+
return 0;
975+
}
976+
977+
gl9767_vhs_write(pdev);
978+
979+
pci_read_config_dword(pdev, PCIE_GLI_9767_COMBO_MUX_CTL, &value);
980+
value &= ~(PCIE_GLI_9767_COMBO_MUX_CTL_RST_EN | PCIE_GLI_9767_COMBO_MUX_CTL_WAIT_PERST_EN);
981+
pci_write_config_dword(pdev, PCIE_GLI_9767_COMBO_MUX_CTL, value);
982+
983+
pci_read_config_dword(pdev, PCIE_GLI_9767_SD_DATA_MULTI_CTL, &value);
984+
value &= ~PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME;
985+
value |= FIELD_PREP(PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME,
986+
PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME_VALUE);
987+
pci_write_config_dword(pdev, PCIE_GLI_9767_SD_DATA_MULTI_CTL, value);
988+
989+
pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, &value);
990+
value |= PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE;
991+
pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, value);
992+
993+
pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2, &value);
994+
value |= PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2_SDEI_COMPLETE_STATUS_EN;
995+
pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2, value);
996+
997+
pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2, &value);
998+
value |= PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2_SDEI_COMPLETE_SIGNAL_EN;
999+
pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2, value);
1000+
1001+
pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
1002+
value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
1003+
pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
1004+
1005+
value = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1006+
value &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_PLL_EN);
1007+
sdhci_writew(host, value, SDHCI_CLOCK_CONTROL);
1008+
1009+
value = sdhci_readb(host, SDHCI_POWER_CONTROL);
1010+
value |= (SDHCI_VDD2_POWER_180 | SDHCI_VDD2_POWER_ON);
1011+
sdhci_writeb(host, value, SDHCI_POWER_CONTROL);
1012+
1013+
pci_read_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, &value);
1014+
value |= PCIE_GLI_9767_SD_EXPRESS_CTL_SDEI_EXE;
1015+
pci_write_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, value);
1016+
1017+
for (i = 0; i < 2; i++) {
1018+
usleep_range(10000, 10100);
1019+
pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, &value);
1020+
if (value & PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE) {
1021+
pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2,
1022+
value);
1023+
break;
1024+
}
1025+
}
1026+
1027+
pci_read_config_dword(pdev, PCIE_GLI_9767_SDHC_CAP, &value);
1028+
if (value & PCIE_GLI_9767_SDHC_CAP_SDEI_RESULT) {
1029+
pci_read_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, &value);
1030+
value |= PCIE_GLI_9767_SD_EXPRESS_CTL_SD_EXPRESS_MODE;
1031+
pci_write_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, value);
1032+
} else {
1033+
mmc->ios.timing &= ~(MMC_TIMING_SD_EXP | MMC_TIMING_SD_EXP_1_2V);
1034+
1035+
value = sdhci_readb(host, SDHCI_POWER_CONTROL);
1036+
value &= ~(SDHCI_VDD2_POWER_180 | SDHCI_VDD2_POWER_ON);
1037+
sdhci_writeb(host, value, SDHCI_POWER_CONTROL);
1038+
1039+
value = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1040+
value |= (SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_PLL_EN);
1041+
sdhci_writew(host, value, SDHCI_CLOCK_CONTROL);
1042+
}
1043+
1044+
gl9767_vhs_read(pdev);
1045+
1046+
return 0;
1047+
}
1048+
9381049
static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot)
9391050
{
9401051
struct sdhci_host *host = slot->host;
@@ -967,6 +1078,8 @@ static int gli_probe_slot_gl9767(struct sdhci_pci_slot *slot)
9671078
gl9767_hw_setting(slot);
9681079
gli_pcie_enable_msi(slot);
9691080
slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
1081+
host->mmc->caps2 |= MMC_CAP2_SD_EXP;
1082+
host->mmc_host_ops.init_sd_express = gl9767_init_sd_express;
9701083
sdhci_enable_v4_mode(host);
9711084

9721085
return 0;

0 commit comments

Comments
 (0)