]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
misc: rtsx: Add support for RTS5264 Version B and optimize init flow
authorRicky Wu <ricky_wu@realtek.com>
Fri, 20 Jun 2025 07:13:25 +0000 (15:13 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Jun 2025 15:45:55 +0000 (16:45 +0100)
This patch adds support for the Realtek RTS5264 Version B
card reader controller.
To support this chip revision, the driver introduces specific
initialization logic to handle the hardware requirements of
Version B. The probe flow is updated to detect this version
and apply the necessary register configurations.
Additionally, the initialization sequence for Version B has
been optimized to improve robustness and ensure proper device
setup during power-on.
These changes ensure correct operation and compatibility with
systems using RTS5264 Version B.

Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
Link: https://lore.kernel.org/r/20250620071325.1887017-1-ricky_wu@realtek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/cardreader/rts5264.c
drivers/misc/cardreader/rts5264.h
drivers/misc/cardreader/rtsx_pcr.c

index 06d7a8a95fd6edf3ff8425d05dc5312ade8e8b27..d050c9fff7ac487a60bc0543636802828e03c4be 100644 (file)
@@ -413,8 +413,8 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
 {
        struct pci_dev *pdev = pcr->pci;
        u32 lval1, lval2, i;
-       u16 setting_reg1, setting_reg2;
-       u8 valid, efuse_valid, tmp;
+       u16 setting_reg1, setting_reg2, phy_val;
+       u8 valid, efuse_valid, tmp, efuse_len;
 
        rtsx_pci_write_register(pcr, RTS5264_REG_PME_FORCE_CTL,
                REG_EFUSE_POR | REG_EFUSE_POWER_MASK,
@@ -433,6 +433,8 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
                        break;
        }
        rtsx_pci_read_register(pcr, RTS5264_EFUSE_READ_DATA, &tmp);
+       efuse_len = ((tmp & 0x70) >> 4);
+       pcr_dbg(pcr, "Load efuse len: 0x%x\n", efuse_len);
        efuse_valid = ((tmp & 0x0C) >> 2);
        pcr_dbg(pcr, "Load efuse valid: 0x%x\n", efuse_valid);
 
@@ -445,6 +447,58 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
                REG_EFUSE_POR, 0);
        pcr_dbg(pcr, "Disable efuse por!\n");
 
+       if (is_version(pcr, PID_5264, RTS5264_IC_VER_B)) {
+               pci_write_config_dword(pdev, 0x718, 0x0007C000);
+               rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE, 0xFF, 0x88);
+               rtsx_pci_read_phy_register(pcr, _PHY_REV0, &phy_val);
+               phy_val &= 0xFFFD;
+
+               if (efuse_len == 0) {
+                       rtsx_pci_write_register(pcr, RTS5264_FW_CFG_INFO2, 0x0F, 0x0F);
+                       rtsx_pci_write_register(pcr, 0xFF14, 0xFF, 0x79);
+                       rtsx_pci_write_register(pcr, 0xFF15, 0xFF, 0xFF);
+                       rtsx_pci_write_register(pcr, 0xFF16, 0xFF, 0x3D);
+                       rtsx_pci_write_register(pcr, 0xFF17, 0xFF, 0xFE);
+
+                       rtsx_pci_write_register(pcr, 0xFF18, 0xFF, 0x5B);
+                       rtsx_pci_write_register(pcr, 0xFF19, 0xFF, 0xFF);
+                       rtsx_pci_write_register(pcr, 0xFF1A, 0xFF, 0x3E);
+                       rtsx_pci_write_register(pcr, 0xFF1B, 0xFF, 0xFE);
+
+                       rtsx_pci_write_register(pcr, 0xFF1C, 0xFF, 0x00);
+                       rtsx_pci_write_register(pcr, 0xFF1D, 0xFF, 0xFF);
+                       rtsx_pci_write_register(pcr, 0xFF1E, 0xFF, 0x3F);
+                       rtsx_pci_write_register(pcr, 0xFF1F, 0xFF, 0xFE);
+
+                       rtsx_pci_write_register(pcr, 0xFF20, 0xFF, 0x81);
+                       rtsx_pci_write_register(pcr, 0xFF21, 0xFF, 0xFF);
+                       rtsx_pci_write_register(pcr, 0xFF22, 0xFF, 0x3C);
+                       rtsx_pci_write_register(pcr, 0xFF23, 0xFF, 0xFE);
+               }
+
+               rtsx_pci_write_register(pcr, 0xFF24, 0xFF, 0x79);
+               rtsx_pci_write_register(pcr, 0xFF25, 0xFF, 0x5B);
+               rtsx_pci_write_register(pcr, 0xFF26, 0xFF, 0x00);
+               rtsx_pci_write_register(pcr, 0xFF27, 0xFF, 0x40);
+
+               rtsx_pci_write_register(pcr, 0xFF28, 0xFF, (u8)phy_val);
+               rtsx_pci_write_register(pcr, 0xFF29, 0xFF, (u8)(phy_val >> 8));
+               rtsx_pci_write_register(pcr, 0xFF2A, 0xFF, 0x19);
+               rtsx_pci_write_register(pcr, 0xFF2B, 0xFF, 0x40);
+
+               rtsx_pci_write_register(pcr, 0xFF2C, 0xFF, 0x20);
+               rtsx_pci_write_register(pcr, 0xFF2D, 0xFF, 0xDA);
+               rtsx_pci_write_register(pcr, 0xFF2E, 0xFF, 0x0A);
+               rtsx_pci_write_register(pcr, 0xFF2F, 0xFF, 0x40);
+
+               rtsx_pci_write_register(pcr, 0xFF30, 0xFF, 0x20);
+               rtsx_pci_write_register(pcr, 0xFF31, 0xFF, 0xD2);
+               rtsx_pci_write_register(pcr, 0xFF32, 0xFF, 0x0A);
+               rtsx_pci_write_register(pcr, 0xFF33, 0xFF, 0x40);
+       } else {
+               rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE, 0x80, 0x80);
+       }
+
        if (efuse_valid == 2 || efuse_valid == 3) {
                if (valid == 3) {
                        /* Bypass efuse */
@@ -618,6 +672,9 @@ static int rts5264_optimize_phy(struct rtsx_pcr *pcr)
                        rtsx_pci_update_phy(pcr, _PHY_REV0, 0x1FF, 0x3800);
        }
 
+       if (is_version(pcr, PID_5264, RTS5264_IC_VER_B))
+               rtsx_pci_write_phy_register(pcr, 0x00, 0x5B79);
+
        return 0;
 }
 
@@ -820,7 +877,7 @@ int rts5264_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
                        SSC_DEPTH_MASK, ssc_depth);
        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
 
-       if (is_version(pcr, 0x5264, IC_VER_A)) {
+       if (is_version(pcr, PID_5264, RTS5264_IC_VER_A)) {
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RTS5264_CARD_CLK_SRC2,
                        RTS5264_REG_BIG_KVCO_A, 0);
index e3cbbf2fe1a4312a932dfdd32a132a718de73e3d..f3e81daa708d7c9c5b025de39a1e06b9a279fac7 100644 (file)
@@ -61,6 +61,8 @@
 /* DMACTL 0xFE2C */
 #define RTS5264_DMA_PACK_SIZE_MASK     0x70
 
+#define RTS5264_FW_CFG_INFO2   0xFF52
+
 #define RTS5264_FW_CFG1                        0xFF55
 #define RTS5264_SYS_CLK_SEL_MCU_CLK    (0x01<<7)
 #define RTS5264_CRC_CLK_SEL_MCU_CLK    (0x01<<6)
 #define SD_LUN                 1
 #define SD_EXPRESS_LUN         2
 
+#define RTS5264_IC_VER_A               0
+#define RTS5264_IC_VER_B               2
+#define RTS5264_IC_VER_C               3
+
 int rts5264_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
                u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
 
index a7b066c487400fc7f7d44c5225522edfee1a95e3..f9952d76d6ed73ca52f0c6ea9ab43bbb0aef28df 100644 (file)
@@ -1236,7 +1236,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
        else if (PCI_PID(pcr) == PID_5228)
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF,
                        RTS5228_SSC_DEPTH_2M);
-       else if (is_version(pcr, 0x5264, IC_VER_A))
+       else if (is_version(pcr, PID_5264, RTS5264_IC_VER_A))
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
        else if (PCI_PID(pcr) == PID_5264)
                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF,