misc: rtsx: add rts5261 efuse function

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>
This commit is contained in:
Ricky WU 2022-03-21 11:18:30 +00:00 committed by Greg Kroah-Hartman
parent 35a7609639
commit b1c5f30851
2 changed files with 65 additions and 53 deletions

View 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;
}
return retval;
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;
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,

View file

@ -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)