Skip to content

Commit

Permalink
misc: rtsx: Fix some platforms can not boot and move the l1ss judgmen…
Browse files Browse the repository at this point in the history
…t to probe

commit 101bd90 ("misc: rtsx: judge ASPM Mode to set PETXCFG Reg")
some readers no longer force #CLKREQ to low
when the system need to enter ASPM.
But some platform maybe not implement complete ASPM?
it causes some platforms can not boot

Like in the past only the platform support L1ss we release the #CLKREQ.
Move the judgment (L1ss) to probe,
we think read config space one time when the driver start is enough

Fixes: 101bd90 ("misc: rtsx: judge ASPM Mode to set PETXCFG Reg")
Cc: stable <stable@kernel.org>
Reported-by: Paul Grandperrin <paul.grandperrin@gmail.com>
Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
Tested-By: Jade Lovelace <lists@jade.fyi>
Link: https://lore.kernel.org/r/37b1afb997f14946a8784c73d1f9a4f5@realtek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ricky WU authored and Greg Kroah-Hartman committed Sep 25, 2023
1 parent 6465e26 commit 0e4cac5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 212 deletions.
55 changes: 6 additions & 49 deletions drivers/misc/cardreader/rts5227.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,63 +83,20 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)

static void rts5227_init_from_cfg(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
int l1ss;
u32 lval;
struct rtsx_cr_option *option = &pcr->option;

l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
if (!l1ss)
return;

pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

if (CHK_PCI_PID(pcr, 0x522A)) {
if (0 == (lval & 0x0F))
rtsx_pci_enable_oobs_polling(pcr);
else
if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
| PM_L1_1_EN | PM_L1_2_EN))
rtsx_pci_disable_oobs_polling(pcr);
else
rtsx_pci_enable_oobs_polling(pcr);
}

if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
rtsx_set_dev_flag(pcr, PM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
rtsx_set_dev_flag(pcr, PM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_2_EN);

if (option->ltr_en) {
u16 val;

pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
option->ltr_enabled = true;
option->ltr_active = true;
if (option->ltr_enabled)
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
} else {
option->ltr_enabled = false;
}
}

if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
| PM_L1_1_EN | PM_L1_2_EN))
option->force_clkreq_0 = false;
else
option->force_clkreq_0 = true;

}

static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
Expand Down Expand Up @@ -195,7 +152,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
}
}

if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG)
if (option->force_clkreq_0)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else
Expand Down
57 changes: 17 additions & 40 deletions drivers/misc/cardreader/rts5228.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,59 +386,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr)

static void rts5228_init_from_cfg(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
int l1ss;
u32 lval;
struct rtsx_cr_option *option = &pcr->option;

l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
if (!l1ss)
return;

pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

if (0 == (lval & 0x0F))
rtsx_pci_enable_oobs_polling(pcr);
else
if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
| PM_L1_1_EN | PM_L1_2_EN))
rtsx_pci_disable_oobs_polling(pcr);

if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
rtsx_set_dev_flag(pcr, PM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
rtsx_set_dev_flag(pcr, PM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_2_EN);
rtsx_pci_enable_oobs_polling(pcr);

rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
if (option->ltr_en) {
u16 val;

pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
option->ltr_enabled = true;
option->ltr_active = true;
if (option->ltr_en) {
if (option->ltr_enabled)
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
} else {
option->ltr_enabled = false;
}
}
}

static int rts5228_extra_init_hw(struct rtsx_pcr *pcr)
{
struct rtsx_cr_option *option = &pcr->option;

rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1,
CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);
Expand Down Expand Up @@ -469,6 +435,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr)
else
rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);

/*
* If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
* to drive low, and we forcibly request clock.
*/
if (option->force_clkreq_0)
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);

if (pcr->rtd3_en) {
Expand Down
56 changes: 7 additions & 49 deletions drivers/misc/cardreader/rts5249.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,64 +86,22 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)

static void rts5249_init_from_cfg(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
int l1ss;
struct rtsx_cr_option *option = &(pcr->option);
u32 lval;

l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
if (!l1ss)
return;

pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) {
if (0 == (lval & 0x0F))
rtsx_pci_enable_oobs_polling(pcr);
else
if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
| PM_L1_1_EN | PM_L1_2_EN))
rtsx_pci_disable_oobs_polling(pcr);
else
rtsx_pci_enable_oobs_polling(pcr);
}


if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
rtsx_set_dev_flag(pcr, PM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
rtsx_set_dev_flag(pcr, PM_L1_2_EN);

if (option->ltr_en) {
u16 val;

pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
option->ltr_enabled = true;
option->ltr_active = true;
if (option->ltr_enabled)
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
} else {
option->ltr_enabled = false;
}
}
}

static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
{
struct rtsx_cr_option *option = &(pcr->option);

if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
| PM_L1_1_EN | PM_L1_2_EN))
option->force_clkreq_0 = false;
else
option->force_clkreq_0 = true;

return 0;
}

static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
{
/* Set relink_time to 0 */
Expand Down Expand Up @@ -276,7 +234,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
struct rtsx_cr_option *option = &(pcr->option);

rts5249_init_from_cfg(pcr);
rts5249_init_from_hw(pcr);

rtsx_pci_init_cmd(pcr);

Expand Down Expand Up @@ -327,11 +284,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
}
}


/*
* If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
* to drive low, and we forcibly request clock.
*/
if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG)
if (option->force_clkreq_0)
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else
Expand Down
43 changes: 13 additions & 30 deletions drivers/misc/cardreader/rts5260.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)

static void rts5260_init_from_cfg(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
int l1ss;
struct rtsx_cr_option *option = &pcr->option;
u32 lval;

l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
if (!l1ss)
return;

pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
rtsx_set_dev_flag(pcr, PM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
rtsx_set_dev_flag(pcr, PM_L1_2_EN);

rts5260_pwr_saving_setting(pcr);

if (option->ltr_en) {
u16 val;

pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
option->ltr_enabled = true;
option->ltr_active = true;
if (option->ltr_enabled)
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
} else {
option->ltr_enabled = false;
}
}
}

static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)
{
struct rtsx_cr_option *option = &pcr->option;

/* Set mcu_cnt to 7 to ensure data can be sampled properly */
rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07);
Expand All @@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)

rts5260_init_hw(pcr);

/*
* If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
* to drive low, and we forcibly request clock.
*/
if (option->force_clkreq_0)
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00);

return 0;
Expand Down
52 changes: 13 additions & 39 deletions drivers/misc/cardreader/rts5261.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,54 +454,17 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr)

static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
int l1ss;
u32 lval;
struct rtsx_cr_option *option = &pcr->option;

l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
if (!l1ss)
return;

pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
rtsx_set_dev_flag(pcr, PM_L1_1_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
rtsx_set_dev_flag(pcr, PM_L1_2_EN);
else
rtsx_clear_dev_flag(pcr, PM_L1_2_EN);

rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
if (option->ltr_en) {
u16 val;

pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
option->ltr_enabled = true;
option->ltr_active = true;
if (option->ltr_enabled)
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
} else {
option->ltr_enabled = false;
}
}
}

static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
{
struct rtsx_cr_option *option = &pcr->option;
u32 val;

rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
Expand Down Expand Up @@ -547,6 +510,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
else
rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);

/*
* If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
* to drive low, and we forcibly request clock.
*/
if (option->force_clkreq_0)
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else
rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);

if (pcr->rtd3_en) {
Expand Down
Loading

0 comments on commit 0e4cac5

Please sign in to comment.