OSDN Git Service

misc: rtsx: add rts5261 efuse function
authorRicky WU <ricky_wu@realtek.com>
Mon, 21 Mar 2022 11:18:30 +0000 (11:18 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 13:37:36 +0000 (15:37 +0200)
move rts5261_fetch_vendor_settings() to rts5261_init_from_hw()
make sure it be called from S3 or D3

add more register setting when efuse is set
read efuse setting to register on init flow

Signed-off-by: Ricky Wu <Ricky_wu@realtek.com>
Link: https://lore.kernel.org/r/18101ecb0f0749ccb9f564eda171ba40@realtek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/cardreader/rts5261.c
include/linux/rtsx_pci.h

index a77585a..749cc5a 100644 (file)
@@ -57,40 +57,6 @@ static void rts5261_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
                         0xFF, driving[drive_sel][2]);
 }
 
-static void rtsx5261_fetch_vendor_settings(struct rtsx_pcr *pcr)
-{
-       struct pci_dev *pdev = pcr->pci;
-       u32 reg;
-
-       /* 0x814~0x817 */
-       pci_read_config_dword(pdev, PCR_SETTING_REG2, &reg);
-       pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
-
-       if (!rts5261_vendor_setting_valid(reg)) {
-               /* Not support MMC default */
-               pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
-               pcr_dbg(pcr, "skip fetch vendor setting\n");
-               return;
-       }
-
-       if (!rts5261_reg_check_mmc_support(reg))
-               pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
-
-       /* TO do: need to add rtd3 function */
-       pcr->rtd3_en = rts5261_reg_to_rtd3(reg);
-
-       if (rts5261_reg_check_reverse_socket(reg))
-               pcr->flags |= PCR_REVERSE_SOCKET;
-
-       /* 0x724~0x727 */
-       pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg);
-       pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
-
-       pcr->aspm_en = rts5261_reg_to_aspm(reg);
-       pcr->sd30_drive_sel_1v8 = rts5261_reg_to_sd30_drive_sel_1v8(reg);
-       pcr->sd30_drive_sel_3v3 = rts5261_reg_to_sd30_drive_sel_3v3(reg);
-}
-
 static void rts5261_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
 {
        /* Set relink_time to 0 */
@@ -391,11 +357,11 @@ static void rts5261_process_ocp(struct rtsx_pcr *pcr)
 
 }
 
-static int rts5261_init_from_hw(struct rtsx_pcr *pcr)
+static void rts5261_init_from_hw(struct rtsx_pcr *pcr)
 {
        struct pci_dev *pdev = pcr->pci;
-       int retval;
-       u32 lval, i;
+       u32 lval1, lval2, i;
+       u16 setting_reg1, setting_reg2;
        u8 valid, efuse_valid, tmp;
 
        rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
@@ -418,26 +384,70 @@ static int rts5261_init_from_hw(struct rtsx_pcr *pcr)
        efuse_valid = ((tmp & 0x0C) >> 2);
        pcr_dbg(pcr, "Load efuse valid: 0x%x\n", efuse_valid);
 
-       if (efuse_valid == 0) {
-               retval = pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval);
-               if (retval != 0)
-                       pcr_dbg(pcr, "read 0x814 DW fail\n");
-               pcr_dbg(pcr, "DW from 0x814: 0x%x\n", lval);
-               /* 0x816 */
-               valid = (u8)((lval >> 16) & 0x03);
-               pcr_dbg(pcr, "0x816: %d\n", valid);
-       }
+       pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval2);
+       pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, lval2);
+       /* 0x816 */
+       valid = (u8)((lval2 >> 16) & 0x03);
+
        rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
                REG_EFUSE_POR, 0);
        pcr_dbg(pcr, "Disable efuse por!\n");
 
-       pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval);
-       lval = lval & 0x00FFFFFF;
-       retval = pci_write_config_dword(pdev, PCR_SETTING_REG2, lval);
-       if (retval != 0)
-               pcr_dbg(pcr, "write config fail\n");
+       if (efuse_valid == 2 || efuse_valid == 3) {
+               if (valid == 3) {
+                       /* Bypass efuse */
+                       setting_reg1 = PCR_SETTING_REG1;
+                       setting_reg2 = PCR_SETTING_REG2;
+               } else {
+                       /* Use efuse data */
+                       setting_reg1 = PCR_SETTING_REG4;
+                       setting_reg2 = PCR_SETTING_REG5;
+               }
+       } else if (efuse_valid == 0) {
+               // default
+               setting_reg1 = PCR_SETTING_REG1;
+               setting_reg2 = PCR_SETTING_REG2;
+       }
+
+       pci_read_config_dword(pdev, setting_reg2, &lval2);
+       pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg2, lval2);
+
+       if (!rts5261_vendor_setting_valid(lval2)) {
+               /* Not support MMC default */
+               pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
+               pcr_dbg(pcr, "skip fetch vendor setting\n");
+               return;
+       }
+
+       if (!rts5261_reg_check_mmc_support(lval2))
+               pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
 
-       return retval;
+       pcr->rtd3_en = rts5261_reg_to_rtd3(lval2);
+
+       if (rts5261_reg_check_reverse_socket(lval2))
+               pcr->flags |= PCR_REVERSE_SOCKET;
+
+       pci_read_config_dword(pdev, setting_reg1, &lval1);
+       pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg1, lval1);
+
+       pcr->aspm_en = rts5261_reg_to_aspm(lval1);
+       pcr->sd30_drive_sel_1v8 = rts5261_reg_to_sd30_drive_sel_1v8(lval1);
+       pcr->sd30_drive_sel_3v3 = rts5261_reg_to_sd30_drive_sel_3v3(lval1);
+
+       if (setting_reg1 == PCR_SETTING_REG1) {
+               /* store setting */
+               rtsx_pci_write_register(pcr, 0xFF0C, 0xFF, (u8)(lval1 & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF0D, 0xFF, (u8)((lval1 >> 8) & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF0E, 0xFF, (u8)((lval1 >> 16) & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF0F, 0xFF, (u8)((lval1 >> 24) & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF10, 0xFF, (u8)(lval2 & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF11, 0xFF, (u8)((lval2 >> 8) & 0xFF));
+               rtsx_pci_write_register(pcr, 0xFF12, 0xFF, (u8)((lval2 >> 16) & 0xFF));
+
+               pci_write_config_dword(pdev, PCR_SETTING_REG4, lval1);
+               lval2 = lval2 & 0x00FFFFFF;
+               pci_write_config_dword(pdev, PCR_SETTING_REG5, lval2);
+       }
 }
 
 static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
@@ -636,7 +646,6 @@ static void rts5261_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
 }
 
 static const struct pcr_ops rts5261_pcr_ops = {
-       .fetch_vendor_settings = rtsx5261_fetch_vendor_settings,
        .turn_on_led = rts5261_turn_on_led,
        .turn_off_led = rts5261_turn_off_led,
        .extra_init_hw = rts5261_extra_init_hw,
index 3d780b4..534038d 100644 (file)
 #define PCR_SETTING_REG1               0x724
 #define PCR_SETTING_REG2               0x814
 #define PCR_SETTING_REG3               0x747
+#define PCR_SETTING_REG4               0x818
+#define PCR_SETTING_REG5               0x81C
+
 
 #define rtsx_pci_init_cmd(pcr)         ((pcr)->ci = 0)