@@ -3219,6 +3219,40 @@ static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev,
pci_free_irq_vectors(pdev);
}
+static int rtw89_write32_mio(struct rtw89_dev *rtwdev, u16 addr, u32 val)
+{
+ u8 page_sel, addr_lsb;
+ u32 val32;
+ int ret;
+
+ page_sel = FIELD_GET(MIO_ADDR_PAGE_MASK, addr);
+ addr_lsb = FIELD_GET(B_AX_PCIE_MIO_ADDR_MASK, addr);
+
+ val32 = FIELD_PREP(B_AX_PCIE_MIO_ADDR_PAGE_V1_MASK, page_sel) |
+ FIELD_PREP(B_AX_PCIE_MIO_ADDR_MASK, addr_lsb) |
+ FIELD_PREP(B_AX_PCIE_MIO_WE_MASK, MIO_WRITE_BYTE_ALL);
+
+ rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_AUXCLK_GATE);
+ rtw89_write32(rtwdev, R_AX_PCIE_MIO_INTF, val32);
+ rtw89_write32(rtwdev, R_AX_PCIE_MIO_INTD, val);
+ rtw89_write32(rtwdev, R_AX_PCIE_MIO_INTF, val32 | B_AX_PCIE_MIO_BYIOREG);
+
+ ret = read_poll_timeout_atomic(rtw89_read32, val32,
+ val32 & B_AX_PCIE_MIO_BYIOREG, true,
+ 1, 1000, rtwdev, R_AX_PCIE_MIO_INTF);
+ if (ret) {
+ rtw89_err(rtwdev, "MIO write timeout\n");
+ rtw89_write32_clr(rtwdev, R_AX_PCIE_MIO_INTF,
+ B_AX_PCIE_MIO_WE_MASK |
+ B_AX_PCIE_MIO_BYIOREG);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL,
+ B_AX_PCIE_AUXCLK_GATE);
+ return ret;
+ }
+
+ return 0;
+}
+
static int rtw89_read32_mio(struct rtw89_dev *rtwdev, u16 addr, u32 *val)
{
u8 page_sel, addr_lsb;
@@ -3322,6 +3356,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
if (rtw89_pci_disable_clkreq)
@@ -3332,19 +3367,33 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_err(rtwdev, "failed to set CLKREQ Delay\n");
- if (enable)
- ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL,
- RTW89_PCIE_BIT_CLK);
- else
- ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1_CTRL,
- RTW89_PCIE_BIT_CLK);
- if (ret)
- rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d",
- enable ? "set" : "unset", ret);
+ if (chip_id == RTL8852A) {
+ if (enable)
+ ret = rtw89_pci_config_byte_set(rtwdev,
+ RTW89_PCIE_L1_CTRL,
+ RTW89_PCIE_BIT_CLK);
+ else
+ ret = rtw89_pci_config_byte_clr(rtwdev,
+ RTW89_PCIE_L1_CTRL,
+ RTW89_PCIE_BIT_CLK);
+ if (ret)
+ rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d",
+ enable ? "set" : "unset", ret);
+ } else if (chip_id == RTL8852C) {
+ rtw89_write32_set(rtwdev, R_AX_PCIE_LAT_CTRL,
+ B_AX_CLK_REQ_SEL_OPT | B_AX_CLK_REQ_SEL);
+ if (enable)
+ rtw89_write32_set(rtwdev, R_AX_L1_CLK_CTRL,
+ B_AX_CLK_REQ_N);
+ else
+ rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL,
+ B_AX_CLK_REQ_N);
+ }
}
static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u8 value = 0;
int ret;
@@ -3363,12 +3412,23 @@ static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_err(rtwdev, "failed to read ASPM Delay\n");
- if (enable)
- ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL,
- RTW89_PCIE_BIT_L1);
- else
- ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1_CTRL,
- RTW89_PCIE_BIT_L1);
+ if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (enable)
+ ret = rtw89_pci_config_byte_set(rtwdev,
+ RTW89_PCIE_L1_CTRL,
+ RTW89_PCIE_BIT_L1);
+ else
+ ret = rtw89_pci_config_byte_clr(rtwdev,
+ RTW89_PCIE_L1_CTRL,
+ RTW89_PCIE_BIT_L1);
+ } else if (chip_id == RTL8852C) {
+ if (enable)
+ rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+ B_AX_ASPM_CTRL_L1);
+ else
+ rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+ B_AX_ASPM_CTRL_L1);
+ }
if (ret)
rtw89_err(rtwdev, "failed to %s ASPM L1, ret=%d",
enable ? "set" : "unset", ret);
@@ -3429,17 +3489,34 @@ static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev)
static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ u32 val32;
int ret;
- if (enable)
- ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_TIMER_CTRL,
- RTW89_PCIE_BIT_L1SUB);
- else
- ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_TIMER_CTRL,
- RTW89_PCIE_BIT_L1SUB);
- if (ret)
- rtw89_err(rtwdev, "failed to %s L1SS, ret=%d",
- enable ? "set" : "unset", ret);
+ if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (enable)
+ ret = rtw89_pci_config_byte_set(rtwdev,
+ RTW89_PCIE_TIMER_CTRL,
+ RTW89_PCIE_BIT_L1SUB);
+ else
+ ret = rtw89_pci_config_byte_clr(rtwdev,
+ RTW89_PCIE_TIMER_CTRL,
+ RTW89_PCIE_BIT_L1SUB);
+ if (ret)
+ rtw89_err(rtwdev, "failed to %s L1SS, ret=%d",
+ enable ? "set" : "unset", ret);
+ } else if (chip_id == RTL8852C) {
+ rtw89_read32_mio(rtwdev, RTW89_PCIE_L1SS_STS_V1, &val32);
+ val32 &= ~(RTW89_PCIE_BIT_ASPM_L11 | RTW89_PCIE_BIT_PCI_L11);
+ rtw89_write32_mio(rtwdev, RTW89_PCIE_L1SS_STS_V1, val32);
+
+ if (enable)
+ rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+ B_AX_L1SUB_DISABLE);
+ else
+ rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+ B_AX_L1SUB_DISABLE);
+ }
}
static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev)
@@ -62,9 +62,16 @@
#define B_AX_REQ_ENTR_L1 BIT(8)
#define B_AX_L1SUB_DISABLE BIT(0)
+#define R_AX_L1_CLK_CTRL 0x3010
+#define B_AX_CLK_REQ_N BIT(1)
+
#define R_AX_PCIE_BG_CLR 0x303C
#define B_AX_BG_CLR_ASYNC_M3 BIT(4)
+#define R_AX_PCIE_LAT_CTRL 0x3044
+#define B_AX_CLK_REQ_SEL_OPT BIT(1)
+#define B_AX_CLK_REQ_SEL BIT(0)
+
#define R_AX_PCIE_IO_RCY_M1 0x3100
#define B_AX_PCIE_IO_RCY_P_M1 BIT(5)
#define B_AX_PCIE_IO_RCY_WDT_P_M1 BIT(4)
@@ -545,6 +552,10 @@
#define RTW89_PCIE_L1SS_CAP_V1 0x2160
#define RTW89_PCIE_L1SS_SUP_V1 0x2164
#define RTW89_PCIE_L1SS_STS_V1 0x2168
+#define RTW89_PCIE_BIT_ASPM_L11 BIT(3)
+#define RTW89_PCIE_BIT_ASPM_L12 BIT(2)
+#define RTW89_PCIE_BIT_PCI_L11 BIT(1)
+#define RTW89_PCIE_BIT_PCI_L12 BIT(0)
#define RTW89_PCIE_ASPM_CTRL_V1 0x270C
#define INTF_INTGRA_MINREF_V1 90
#define INTF_INTGRA_HOSTREF_V1 100