]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: pci: consider RTL8922D in PCI common flow
authorPing-Ke Shih <pkshih@realtek.com>
Sat, 10 Jan 2026 02:20:19 +0000 (10:20 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Thu, 15 Jan 2026 01:20:28 +0000 (09:20 +0800)
Clear TX/RX ring index, PCI operating mode, SER setting, PCI LTR and
preinit settings.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260110022019.2254969-9-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/pci_be.c
drivers/net/wireless/realtek/rtw89/reg.h

index 64c080053fd1d1ea9310d87013b3239def16b352..b0081b6940468500bc3fa11940b490539ea6e089 100644 (file)
@@ -55,6 +55,8 @@
 #define B_AX_CALIB_EN                  BIT(13)
 #define B_AX_DIV                       GENMASK(15, 14)
 #define RAC_SET_PPR_V1                 0x31
+#define RAC_ANA41                      0x41
+#define PHY_ERR_FLAG_EN                        BIT(6)
 
 #define R_AX_DBI_FLAG                  0x1090
 #define B_AX_DBI_RFLAG                 BIT(17)
 #define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900
 #define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980
 
+#define RAC_DIRECT_OFFESET_L0_G1 0x3800
+#define RAC_DIRECT_OFFESET_L1_G1 0x3900
+#define RAC_DIRECT_OFFESET_L0_G2 0x3A00
+#define RAC_DIRECT_OFFESET_L1_G2 0x3B00
+
 #define RTW89_PCI_WR_RETRY_CNT         20
 
 /* Interrupts */
 #define B_BE_PCIE_EN_AUX_CLK BIT(0)
 
 #define R_BE_PCIE_PS_CTRL 0x3008
+#define B_BE_ASPM_L11_EN BIT(19)
+#define B_BE_ASPM_L12_EN BIT(18)
+#define B_BE_PCIPM_L11_EN BIT(17)
+#define B_BE_PCIPM_L12_EN BIT(16)
 #define B_BE_RSM_L0S_EN BIT(8)
 #define B_BE_CMAC_EXIT_L1_EN BIT(7)
 #define B_BE_DMAC0_EXIT_L1_EN BIT(6)
 #define R_BE_PCIE_CRPWM 0x30C4
 
 #define R_BE_L1_2_CTRL_HCILDO 0x3110
+#define B_BE_PM_CLKREQ_EXT_RB BIT(11)
+#define B_BE_PCIE_DIS_RTK_PRST_N_L1_2 BIT(10)
+#define B_BE_PCIE_PRST_IN_L1_2_RB BIT(9)
+#define B_BE_PCIE_PRST_SEL_RB_V1 BIT(8)
+#define B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB BIT(7)
+#define B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB BIT(6)
 #define B_BE_PCIE_DIS_L1_2_CTRL_HCILDO BIT(0)
 
 #define R_BE_PL1_DBG_INFO 0x3120
 #define B_BE_PL1_SER_PL1_EN BIT(31)
 #define B_BE_PL1_IGNORE_HOT_RST BIT(30)
 #define B_BE_PL1_TIMER_UNIT_MASK GENMASK(19, 17)
+#define PCIE_SER_TIMER_UNIT 0x2
 #define B_BE_PL1_TIMER_CLEAR BIT(0)
 
 #define R_BE_REG_PL1_MASK 0x34B0
+#define B_BE_SER_LTSSM_UNSTABLE_MASK BIT(6)
 #define B_BE_SER_PCLKREQ_ACK_MASK BIT(5)
 #define B_BE_SER_PM_CLK_MASK BIT(4)
 #define B_BE_SER_LTSSM_IMR BIT(3)
 #define B_BE_CLR_CH2_IDX BIT(2)
 #define B_BE_CLR_CH1_IDX BIT(1)
 #define B_BE_CLR_CH0_IDX BIT(0)
+#define B_BE_CLR_ALL_IDX_MASK (B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | \
+                              B_BE_CLR_CH2_IDX | B_BE_CLR_CH3_IDX | \
+                              B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX | \
+                              B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | \
+                              B_BE_CLR_CH8_IDX | B_BE_CLR_CH9_IDX | \
+                              B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX | \
+                              B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | \
+                              B_BE_CLR_CH14_IDX)
+#define B_BE_CLR_ALL_IDX_MASK_V1 (B_BE_CLR_CH0_IDX | B_BE_CLR_CH2_IDX | \
+                                 B_BE_CLR_CH4_IDX | B_BE_CLR_CH6_IDX | \
+                                 B_BE_CLR_CH8_IDX | B_BE_CLR_CH10_IDX | \
+                                 B_BE_CLR_CH12_IDX)
 
 #define R_BE_RXBD_RWPTR_CLR1_V1 0xB018
 #define B_BE_CLR_ROQ1_IDX_V1 BIT(5)
index 148cce0df058e6f10998b160fd2c10351242c6d2..33bdd3e66bf6e3aac6b5e48fb45d1ad53f371ddd 100644 (file)
@@ -46,6 +46,14 @@ static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable)
 
 static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable)
 {
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       struct rtw89_hal *hal = &rtwdev->hal;
+
+       if (enable && chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)
+               rtw89_write32_set(rtwdev, R_BE_PCIE_PS_CTRL,
+                                 B_BE_ASPM_L11_EN | B_BE_ASPM_L12_EN |
+                                 B_BE_PCIPM_L11_EN | B_BE_PCIPM_L12_EN);
+
        if (enable)
                rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG,
                                  B_BE_L1SUB_ENABLE);
@@ -154,7 +162,7 @@ static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev,
 
        rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);
 
-       if (io_en == MAC_AX_PCIE_ENABLE)
+       if (io_en == MAC_AX_PCIE_ENABLE && rtwdev->chip->chip_id == RTL8922A)
                rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1,
                                   B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4);
 }
@@ -162,14 +170,15 @@ static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev,
 static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev)
 {
        struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        struct rtw89_pci_rx_ring *rx_ring;
        u32 val;
 
-       val = B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | B_BE_CLR_CH2_IDX |
-             B_BE_CLR_CH3_IDX | B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX |
-             B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | B_BE_CLR_CH8_IDX |
-             B_BE_CLR_CH9_IDX | B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX |
-             B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | B_BE_CLR_CH14_IDX;
+       if (chip->chip_id == RTL8922A)
+               val = B_BE_CLR_ALL_IDX_MASK;
+       else
+               val = B_BE_CLR_ALL_IDX_MASK_V1;
+
        rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val);
 
        rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1,
@@ -226,20 +235,24 @@ static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev)
 static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_pci_info *info = rtwdev->pci_info;
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        u32 val32_init1, val32_rxapp, val32_exp;
 
        val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
-       val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE);
+       if (chip->chip_id == RTL8922A)
+               val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE);
        val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1);
 
-       if (info->rxbd_mode == MAC_AX_RXBD_PKT) {
-               val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM,
-                                              B_BE_RXQ_RXBD_MODE_MASK);
-       } else if (info->rxbd_mode == MAC_AX_RXBD_SEP) {
-               val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP,
-                                              B_BE_RXQ_RXBD_MODE_MASK);
-               val32_rxapp = u32_replace_bits(val32_rxapp, 0,
-                                              B_BE_APPEND_LEN_MASK);
+       if (chip->chip_id == RTL8922A) {
+               if (info->rxbd_mode == MAC_AX_RXBD_PKT) {
+                       val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM,
+                                                      B_BE_RXQ_RXBD_MODE_MASK);
+               } else if (info->rxbd_mode == MAC_AX_RXBD_SEP) {
+                       val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP,
+                                                      B_BE_RXQ_RXBD_MODE_MASK);
+                       val32_rxapp = u32_replace_bits(val32_rxapp, 0,
+                                                      B_BE_APPEND_LEN_MASK);
+               }
        }
 
        val32_init1 = u32_replace_bits(val32_init1, info->tx_burst,
@@ -254,7 +267,8 @@ static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev)
                                       B_BE_CFG_WD_PERIOD_ACTIVE_MASK);
 
        rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1);
-       rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp);
+       if (chip->chip_id == RTL8922A)
+               rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp);
        rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp);
 }
 
@@ -280,6 +294,10 @@ static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev)
 
 static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev)
 {
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       struct rtw89_hal *hal = &rtwdev->hal;
+       u32 clr;
+
        rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN);
        rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED,
                          B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP |
@@ -287,7 +305,16 @@ static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev)
        rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN |
                                                      B_BE_PCIE_DIS_L2_RTK_PERST |
                                                      B_BE_PCIE_DIS_L2__CTRL_LDO_HCI);
-       rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, B_BE_PCIE_DIS_L1_2_CTRL_HCILDO);
+
+       if (chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)
+               clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO |
+                     B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB |
+                     B_BE_PCIE_DIS_RTK_PRST_N_L1_2 |
+                     B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB;
+       else
+               clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO;
+
+       rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, clr);
 }
 
 static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev)
@@ -303,11 +330,25 @@ static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev)
 
        rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL);
        rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL);
+
+       if (chip->chip_id != RTL8922D)
+               return;
+
+       rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_SYM_PRST_CPHY_RST);
+       rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_USUS_OFFCAPC_EN);
 }
 
 static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
 {
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       struct rtw89_hal *hal = &rtwdev->hal;
        u32 val32;
+       int ret;
+
+       if (chip_id == RTL8922D)
+               goto be2_chips;
+       else if (chip_id != RTL8922A)
+               return;
 
        rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0);
        rtw89_write32_set(rtwdev, R_BE_FWS1IMR, B_BE_PCIE_SER_TIMEOUT_INDIC_EN);
@@ -318,6 +359,43 @@ static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
        val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
                 B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK;
        rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
+
+       return;
+
+be2_chips:
+       rtw89_write32_clr(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
+       rtw89_write32_set(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
+
+       rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
+                                 RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
+       rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
+                                 RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
+       rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
+                                 RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
+       rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
+                                 RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
+
+       val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
+       val32 &= ~B_BE_PL1_SER_PL1_EN;
+       rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32);
+
+       ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32,
+                                      1, 1000, false, rtwdev, R_BE_REG_PL1_ISR);
+       if (ret)
+               rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n");
+
+       val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
+       val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
+                B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK |
+                B_BE_SER_LTSSM_UNSTABLE_MASK;
+       rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
+
+       rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK,
+                          PCIE_SER_TIMER_UNIT);
+       rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
+
+       if (hal->cid == RTL8922D_CID7090)
+               rtw89_write32_set(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_SER_DETECT_EN);
 }
 
 static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable)
@@ -416,6 +494,7 @@ static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev)
 int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en)
 {
        u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy;
+       u32 ltr_idle_lat_ctrl, ltr_act_lat_ctrl;
 
        ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0);
        if (rtw89_pci_ltr_is_err_reg_val(ctrl0))
@@ -458,8 +537,16 @@ int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en)
        cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK);
        dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK);
 
-       rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, 0x90039003);
-       rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, 0x880b880b);
+       if (rtwdev->chip->chip_id == RTL8922A) {
+               ltr_idle_lat_ctrl = 0x90039003;
+               ltr_act_lat_ctrl = 0x880b880b;
+       } else {
+               ltr_idle_lat_ctrl = 0x90019001;
+               ltr_act_lat_ctrl = 0x88018801;
+       }
+
+       rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, ltr_idle_lat_ctrl);
+       rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, ltr_act_lat_ctrl);
        rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0);
        rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl);
        rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0);
index 66794ecbaaa9bc01bcdf2531c2e37b4cfee1e972..efeb4507b1a9f5baca20f5af2c710ef0b275ef61 100644 (file)
 #define B_BE_EN_WLON BIT(16)
 #define B_BE_APDM_HPDN BIT(15)
 #define B_BE_PSUS_OFF_CAPC_EN BIT(14)
+#define B_BE_USUS_OFFCAPC_EN BIT(13)
 #define B_BE_AFSM_PCIE_SUS_EN BIT(12)
 #define B_BE_AFSM_WLSUS_EN BIT(11)
 #define B_BE_APFM_SWLPS BIT(10)
 #define B_BE_SYM_PADPDN_WL_RFC0_1P3 BIT(5)
 
 #define R_BE_RSV_CTRL 0x001C
+#define B_BE_R_SYM_PRST_CPHY_RST BIT(25)
+#define B_BE_R_SYM_PRST_PDN_EN BIT(24)
 #define B_BE_HR_BE_DBG GENMASK(23, 12)
 #define B_BE_R_SYM_DIS_PCIE_FLR BIT(9)
 #define B_BE_R_EN_HRST_PWRON BIT(8)
 
 #define R_BE_SYS_SDIO_CTRL 0x0070
 #define B_BE_MCM_FLASH_EN BIT(28)
+#define B_BE_SER_DETECT_EN BIT(26)
 #define B_BE_PCIE_SEC_LOAD BIT(26)
 #define B_BE_PCIE_SER_RSTB BIT(25)
 #define B_BE_PCIE_SEC_LOAD_CLR BIT(24)
 #define B_BE_WL_XTAL_SI_DATA_MASK GENMASK(15, 8)
 #define B_BE_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0)
 
+#define R_BE_PCIE_SER_DBG 0x02FC
+#define B_BE_PCIE_SER_DBG_MASK GENMASK(31, 10)
+#define B_BE_PCIE_SER_PHY_PROTECT BIT(9)
+#define B_BE_PCIE_SER_MAC_PROTECT BIT(8)
+#define B_BE_PCIE_SER_FLUSH_RSTB BIT(4)
+#define B_BE_PCIE_AXI_BRG_FLUSH_EN BIT(3)
+#define B_BE_PCIE_SER_AUXCLK_RDY BIT(2)
+#define B_BE_PCIE_SER_FRZ_REG_RST BIT(1)
+#define B_BE_PCIE_SER_FRZ_CFG_SPC_RST BIT(0)
+
 #define R_BE_IC_PWR_STATE 0x03F0
 #define B_BE_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16)
 #define MAC_AX_SYS_ACT 0x220