Commit b1c5f308 authored by Ricky WU's avatar Ricky WU Committed by Greg Kroah-Hartman
Browse files

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: default avatarRicky Wu <Ricky_wu@realtek.com>
Link: https://lore.kernel.org/r/18101ecb0f0749ccb9f564eda171ba40@realtek.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 35a76096
Loading
Loading
Loading
Loading
+62 −53
Original line number Diff line number Diff line
@@ -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);
	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)((lval >> 16) & 0x03);
		pcr_dbg(pcr, "0x816: %d\n", valid);
	}
	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;
	}

	return retval;
	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,
+3 −0
Original line number Diff line number Diff line
@@ -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)