Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: rtsx_pci: Add SD Express mode support for RTS5261

RTS5261 support SD mode and PCIe/NVMe mode. The workflow is as follows.
1.RTS5261 work in SD mode and set MMC_CAPS2_SD_EXP flag.
2.If card is plugged in, Host send CMD8 to ask card's PCIe availability.
3.If the card has PCIe availability and WP is not set, init_sd_express() will be invoked,
RTS5261 switch to PCIe/NVMe mode.
4.Mmc driver handover it to NVMe driver.
5.If card is unplugged, RTS5261 will switch to SD mode.

Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
Link: https://lore.kernel.org/r/1603936703-3403-1-git-send-email-rui_feng@realsil.com.cn
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Rui Feng and committed by
Ulf Hansson
9ff43c7b 5afe8021

+58
+58
drivers/mmc/host/rtsx_pci_sdmmc.c
··· 895 895 static int sd_power_on(struct realtek_pci_sdmmc *host) 896 896 { 897 897 struct rtsx_pcr *pcr = host->pcr; 898 + struct mmc_host *mmc = host->mmc; 898 899 int err; 900 + u32 val; 899 901 900 902 if (host->power_state == SDMMC_POWER_ON) 901 903 return 0; ··· 923 921 err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); 924 922 if (err < 0) 925 923 return err; 924 + 925 + if (PCI_PID(pcr) == PID_5261) { 926 + if (pcr->extra_caps & EXTRA_CAPS_SD_EXPRESS) 927 + mmc->caps2 |= MMC_CAP2_SD_EXP | MMC_CAP2_SD_EXP_1_2V; 928 + /* 929 + * HW read wp status when resuming from S3/S4, 930 + * and then picks SD legacy interface if it's set 931 + * in read-only mode. 932 + */ 933 + val = rtsx_pci_readl(pcr, RTSX_BIPR); 934 + if (val & SD_WRITE_PROTECT) { 935 + pcr->extra_caps &= ~EXTRA_CAPS_SD_EXPRESS; 936 + mmc->caps2 &= ~(MMC_CAP2_SD_EXP | MMC_CAP2_SD_EXP_1_2V); 937 + } 938 + } 926 939 927 940 host->power_state = SDMMC_POWER_ON; 928 941 return 0; ··· 1325 1308 return err; 1326 1309 } 1327 1310 1311 + static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios) 1312 + { 1313 + u32 relink_time; 1314 + struct realtek_pci_sdmmc *host = mmc_priv(mmc); 1315 + struct rtsx_pcr *pcr = host->pcr; 1316 + 1317 + /* Set relink_time for changing to PCIe card */ 1318 + relink_time = 0x8FFF; 1319 + 1320 + rtsx_pci_write_register(pcr, 0xFF01, 0xFF, relink_time); 1321 + rtsx_pci_write_register(pcr, 0xFF02, 0xFF, relink_time >> 8); 1322 + rtsx_pci_write_register(pcr, 0xFF03, 0x01, relink_time >> 16); 1323 + 1324 + rtsx_pci_write_register(pcr, PETXCFG, 0x80, 0x80); 1325 + rtsx_pci_write_register(pcr, LDO_VCC_CFG0, 1326 + RTS5261_LDO1_OCP_THD_MASK, 1327 + pcr->option.sd_800mA_ocp_thd); 1328 + 1329 + if (pcr->ops->disable_auto_blink) 1330 + pcr->ops->disable_auto_blink(pcr); 1331 + 1332 + /* For PCIe/NVMe mode can't enter delink issue */ 1333 + pcr->hw_param.interrupt_en &= ~(SD_INT_EN); 1334 + rtsx_pci_writel(pcr, RTSX_BIER, pcr->hw_param.interrupt_en); 1335 + 1336 + rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4, 1337 + RTS5261_AUX_CLK_16M_EN, RTS5261_AUX_CLK_16M_EN); 1338 + rtsx_pci_write_register(pcr, RTS5261_FW_CFG0, 1339 + RTS5261_FW_ENTER_EXPRESS, RTS5261_FW_ENTER_EXPRESS); 1340 + rtsx_pci_write_register(pcr, RTS5261_FW_CFG1, 1341 + RTS5261_MCU_BUS_SEL_MASK | RTS5261_MCU_CLOCK_SEL_MASK 1342 + | RTS5261_MCU_CLOCK_GATING | RTS5261_DRIVER_ENABLE_FW, 1343 + RTS5261_MCU_CLOCK_SEL_16M | RTS5261_MCU_CLOCK_GATING 1344 + | RTS5261_DRIVER_ENABLE_FW); 1345 + host->eject = true; 1346 + return 0; 1347 + } 1348 + 1328 1349 static const struct mmc_host_ops realtek_pci_sdmmc_ops = { 1329 1350 .pre_req = sdmmc_pre_req, 1330 1351 .post_req = sdmmc_post_req, ··· 1372 1317 .get_cd = sdmmc_get_cd, 1373 1318 .start_signal_voltage_switch = sdmmc_switch_voltage, 1374 1319 .execute_tuning = sdmmc_execute_tuning, 1320 + .init_sd_express = sdmmc_init_sd_express, 1375 1321 }; 1376 1322 1377 1323 static void init_extra_caps(struct realtek_pci_sdmmc *host) ··· 1394 1338 mmc->caps |= MMC_CAP_8_BIT_DATA; 1395 1339 if (pcr->extra_caps & EXTRA_CAPS_NO_MMC) 1396 1340 mmc->caps2 |= MMC_CAP2_NO_MMC; 1341 + if (pcr->extra_caps & EXTRA_CAPS_SD_EXPRESS) 1342 + mmc->caps2 |= MMC_CAP2_SD_EXP | MMC_CAP2_SD_EXP_1_2V; 1397 1343 } 1398 1344 1399 1345 static void realtek_init_host(struct realtek_pci_sdmmc *host)