]> www.infradead.org Git - linux.git/commitdiff
wifi: rtw89: 8922a: add digital compensation to avoid TX EVM degrade
authorKuan-Chung Chen <damon.chen@realtek.com>
Fri, 9 Aug 2024 07:20:08 +0000 (15:20 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 16 Aug 2024 11:24:58 +0000 (19:24 +0800)
TX EVM will significantly decrease for long packets when
the TX idle time increases. Introduce digital compensation
based on TX idle time, to mitigate TX EVM degradation, and
TX throughput improved from 1871 to 1947 Mbps.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240809072012.84152-3-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/ps.c
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index b42a33b9868a08069958566772637c4e181d218f..3edb2f4372e441166ce08737f77027b67ebfabc9 100644 (file)
@@ -3566,6 +3566,8 @@ struct rtw89_chip_ops {
        void (*cfg_txrx_path)(struct rtw89_dev *rtwdev);
        void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev,
                                       s8 pw_ofst, enum rtw89_mac_idx mac_idx);
+       void (*digital_pwr_comp)(struct rtw89_dev *rtwdev,
+                                enum rtw89_phy_idx phy_idx);
        int (*pwr_on_func)(struct rtw89_dev *rtwdev);
        int (*pwr_off_func)(struct rtw89_dev *rtwdev);
        void (*query_rxdesc)(struct rtw89_dev *rtwdev,
@@ -6274,6 +6276,15 @@ void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
                chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx);
 }
 
+static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev,
+                                              enum rtw89_phy_idx phy_idx)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       if (chip->ops->digital_pwr_comp)
+               chip->ops->digital_pwr_comp(rtwdev, phy_idx);
+}
+
 static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev,
                                          const struct rtw89_txpwr_table *tbl)
 {
index 92074b73ebebdcb2e4f871ee26d8fcdd7d7e1ab1..aebd6404f802501df6299c96a29d71a87baaf37f 100644 (file)
@@ -98,10 +98,10 @@ static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
        rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
 }
 
-static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id)
+static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
        struct rtw89_lps_parm lps_param = {
-               .macid = mac_id,
+               .macid = rtwvif->mac_id,
                .psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
                .lastrpwm = RTW89_LAST_RPWM_ACTIVE,
        };
@@ -109,6 +109,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id)
        rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
        rtw89_fw_leave_lps_check(rtwdev, 0);
        rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
+       rtw89_chip_digital_pwr_comp(rtwdev, rtwvif->phy_idx);
 }
 
 void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
@@ -137,7 +138,7 @@ static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwv
            rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
                return;
 
-       __rtw89_leave_lps(rtwdev, rtwvif->mac_id);
+       __rtw89_leave_lps(rtwdev, rtwvif);
 }
 
 void rtw89_leave_lps(struct rtw89_dev *rtwdev)
index 7afec48c4056eecf780f79b3b36f4578351b8ee7..eacf9161db2cad61023596e128512a6786195cf2 100644 (file)
 #define R_BE_WP_PAGE_INFO1 0xB7AC
 #define B_BE_WP_AVAL_PG_MASK GENMASK(28, 16)
 
+#define R_BE_LTPC_T0_PATH0 0xBA28
+#define R_BE_LTPC_T0_PATH1 0xBB28
+
 #define R_BE_CMAC_SHARE_FUNC_EN 0x0E000
 #define B_BE_CMAC_SHARE_CRPRT BIT(31)
 #define B_BE_CMAC_SHARE_EN BIT(30)
index e6463035a7af04da1261f9d8fa5da37a16f074ad..d1358b9a73f913cbfe522c283ce6efeaf012ceda 100644 (file)
@@ -2388,6 +2388,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8851b_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = rtw8851b_bb_cfg_txrx_path,
        .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset,
+       .digital_pwr_comp       = NULL,
        .pwr_on_func            = rtw8851b_pwr_on_func,
        .pwr_off_func           = rtw8851b_pwr_off_func,
        .query_rxdesc           = rtw89_core_query_rxdesc,
index 7ea388fa06574f9591f02f7856bec1c51d849fdc..b073e041a16bf7b3c75c014b24030d61935fc1e7 100644 (file)
@@ -2111,6 +2111,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8852a_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = NULL,
        .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset,
+       .digital_pwr_comp       = NULL,
        .pwr_on_func            = NULL,
        .pwr_off_func           = NULL,
        .query_rxdesc           = rtw89_core_query_rxdesc,
index f26979b89cc9af8c42cf40816cf045c047f71561..36a81c3323f8d9d3871c28bccd9cf6593cdbe8dc 100644 (file)
@@ -742,6 +742,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8852bx_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = rtw8852bx_bb_cfg_txrx_path,
        .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset,
+       .digital_pwr_comp       = NULL,
        .pwr_on_func            = rtw8852b_pwr_on_func,
        .pwr_off_func           = rtw8852b_pwr_off_func,
        .query_rxdesc           = rtw89_core_query_rxdesc,
index fb98ef9dbc54910ac1a19eeedcb3ce50e0199e25..647bc98bcc5d4905105452312450106c8bb564ab 100644 (file)
@@ -676,6 +676,7 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8852bx_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = rtw8852bx_bb_cfg_txrx_path,
        .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset,
+       .digital_pwr_comp       = NULL,
        .pwr_on_func            = rtw8852bt_pwr_on_func,
        .pwr_off_func           = rtw8852bt_pwr_off_func,
        .query_rxdesc           = rtw89_core_query_rxdesc,
index dc1da9ff055c4082a7c781e6b0442deda9075eac..65e61a2ede27fb4e20621c6487227b5676be858d 100644 (file)
@@ -2891,6 +2891,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8852c_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = rtw8852c_bb_cfg_txrx_path,
        .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
+       .digital_pwr_comp       = NULL,
        .pwr_on_func            = rtw8852c_pwr_on_func,
        .pwr_off_func           = rtw8852c_pwr_off_func,
        .query_rxdesc           = rtw89_core_query_rxdesc,
index 6004a622d2448e52eeeca67204408ecca59df669..7f4ac8b63e4872ed812ae02ed0de8617b67c4d6a 100644 (file)
@@ -1689,6 +1689,60 @@ static int rtw8922a_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev,
        return 0;
 }
 
+#define DIGITAL_PWR_COMP_REG_NUM 22
+static const u32 rtw8922a_digital_pwr_comp_val[][DIGITAL_PWR_COMP_REG_NUM] = {
+       {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
+        0x0BB80708, 0x17701194, 0x02020100, 0x03030303, 0x01000303,
+        0x05030302, 0x06060605, 0x06050300, 0x0A090807, 0x02000B0B,
+        0x09080604, 0x0D0D0C0B, 0x08060400, 0x110F0C0B, 0x05001111,
+        0x0D0C0907, 0x12121210},
+       {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
+        0x0BB80708, 0x17701194, 0x04030201, 0x05050505, 0x01000505,
+        0x07060504, 0x09090908, 0x09070400, 0x0E0D0C0B, 0x03000E0E,
+        0x0D0B0907, 0x1010100F, 0x0B080500, 0x1512100D, 0x05001515,
+        0x100D0B08, 0x15151512},
+};
+
+static void rtw8922a_set_digital_pwr_comp(struct rtw89_dev *rtwdev,
+                                         bool enable, u8 nss,
+                                         enum rtw89_rf_path path)
+{
+       static const u32 ltpc_t0[2] = {R_BE_LTPC_T0_PATH0, R_BE_LTPC_T0_PATH1};
+       const u32 *digital_pwr_comp;
+       u32 addr, val;
+       u32 i;
+
+       if (nss == 1)
+               digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0];
+       else
+               digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1];
+
+       addr = ltpc_t0[path];
+       for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) {
+               val = enable ? digital_pwr_comp[i] : 0;
+               rtw89_phy_write32(rtwdev, addr, val);
+       }
+}
+
+static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev,
+                                     enum rtw89_phy_idx phy_idx)
+{
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+       bool enable = chan->band_type != RTW89_BAND_2G;
+       u8 path;
+
+       if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
+               if (phy_idx == RTW89_PHY_0)
+                       path = RF_PATH_A;
+               else
+                       path = RF_PATH_B;
+               rtw8922a_set_digital_pwr_comp(rtwdev, enable, 1, path);
+       } else {
+               rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_A);
+               rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_B);
+       }
+}
+
 static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode)
 {
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
@@ -1810,11 +1864,13 @@ static void rtw8922a_pre_set_channel_bb(struct rtw89_dev *rtwdev,
 }
 
 static void rtw8922a_post_set_channel_bb(struct rtw89_dev *rtwdev,
-                                        enum rtw89_mlo_dbcc_mode mode)
+                                        enum rtw89_mlo_dbcc_mode mode,
+                                        enum rtw89_phy_idx phy_idx)
 {
        if (!rtwdev->dbcc_en)
                return;
 
+       rtw8922a_digital_pwr_comp(rtwdev, phy_idx);
        rtw8922a_ctrl_mlo(rtwdev, mode);
 }
 
@@ -1921,7 +1977,7 @@ static void rtw8922a_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
        rtw8922a_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter);
 
        if (!enter) {
-               rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode);
+               rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx);
                rtw8922a_post_set_channel_rf(rtwdev, phy_idx);
        }
 }
@@ -2494,6 +2550,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
        .ctrl_nbtg_bt_tx        = rtw8922a_ctrl_nbtg_bt_tx,
        .cfg_txrx_path          = rtw8922a_bb_cfg_txrx_path,
        .set_txpwr_ul_tb_offset = NULL,
+       .digital_pwr_comp       = rtw8922a_digital_pwr_comp,
        .pwr_on_func            = rtw8922a_pwr_on_func,
        .pwr_off_func           = rtw8922a_pwr_off_func,
        .query_rxdesc           = rtw89_core_query_rxdesc_v2,