Skip to content

Commit

Permalink
misc: rtsx: add rts5261 efuse function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ricky WU authored and Greg Kroah-Hartman committed May 9, 2022
1 parent 35a7609 commit b1c5f30
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 53 deletions.
115 changes: 62 additions & 53 deletions drivers/misc/cardreader/rts5261.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions include/linux/rtsx_pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,9 @@
#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)

Expand Down

0 comments on commit b1c5f30

Please sign in to comment.