wifi: rtw89: 8852b: rfk: add RX DCK
authorPing-Ke Shih <pkshih@realtek.com>
Wed, 12 Oct 2022 08:32:32 +0000 (16:32 +0800)
committerKalle Valo <kvalo@kernel.org>
Wed, 19 Oct 2022 05:56:12 +0000 (08:56 +0300)
RX DCK is receiver DC calibration. With this calibration, we have proper
DC offset to reflect correct received signal strength indicator. Do this
calibration when bringing up interface and going to run on AP channel.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221012083234.20224-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h

index 1dcb900..306f6a2 100644 (file)
@@ -12,6 +12,7 @@
 #include "rtw8852b_rfk_table.h"
 #include "rtw8852b_table.h"
 
+#define RTW8852B_RXDCK_VER 0x1
 #define ADDC_T_AVG 100
 
 static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
@@ -32,6 +33,47 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
        return val;
 }
 
+static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+                       enum rtw89_rf_path path)
+{
+       rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0);
+       rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0);
+       rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1);
+       mdelay(1);
+}
+
+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+       u8 path, dck_tune;
+       u32 rf_reg5;
+
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n",
+                   RTW8852B_RXDCK_VER, rtwdev->hal.cv);
+
+       for (path = 0; path < RF_PATH_NUM_8852B; path++) {
+               rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
+               dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE);
+
+               if (rtwdev->is_tssi_mode[path])
+                       rtw89_phy_write32_mask(rtwdev,
+                                              R_P0_TSSI_TRK + (path << 13),
+                                              B_P0_TSSI_TRK_EN, 0x1);
+
+               rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
+               rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
+               rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
+               _set_rx_dck(rtwdev, phy, path);
+               rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune);
+               rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
+
+               if (rtwdev->is_tssi_mode[path])
+                       rtw89_phy_write32_mask(rtwdev,
+                                              R_P0_TSSI_TRK + (path << 13),
+                                              B_P0_TSSI_TRK_EN, 0x0);
+       }
+}
+
 static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
 {
        u32 rf_reg5;
@@ -488,6 +530,24 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
        rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n");
 }
 
+static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
+{
+       u32 rf_mode;
+       u8 path;
+       int ret;
+
+       for (path = 0; path < RF_PATH_MAX; path++) {
+               if (!(kpath & BIT(path)))
+                       continue;
+
+               ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode,
+                                              rf_mode != 2, 2, 5000, false,
+                                              rtwdev, path, RR_MOD, RR_MOD_MASK);
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret);
+       }
+}
+
 void rtw8852b_rck(struct rtw89_dev *rtwdev)
 {
        u8 path;
@@ -505,6 +565,21 @@ void rtw8852b_dack(struct rtw89_dev *rtwdev)
        rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
 }
 
+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+       u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+       u32 tx_en;
+
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
+       rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
+       _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
+
+       _rx_dck(rtwdev, phy_idx);
+
+       rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
+}
+
 static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
                        enum rtw89_bandwidth bw, bool dav)
 {
index 84325ab..24e4924 100644 (file)
@@ -9,6 +9,7 @@
 
 void rtw8852b_rck(struct rtw89_dev *rtwdev);
 void rtw8852b_dack(struct rtw89_dev *rtwdev);
+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
                             const struct rtw89_chan *chan,
                             enum rtw89_phy_idx phy_idx);