rtw89: 8852c: process efuse of phycap
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 7 Mar 2022 06:04:56 +0000 (14:04 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 10 Mar 2022 16:43:51 +0000 (18:43 +0200)
Read phycap data programmed in efuse, and store them into array.

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

index 6013f73..483cf45 100644 (file)
@@ -2666,18 +2666,22 @@ struct rtw89_cfo_tracking_info {
 
 /* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */
 #define TSSI_TRIM_CH_GROUP_NUM 8
+#define TSSI_TRIM_CH_GROUP_NUM_6G 16
 
 #define TSSI_CCK_CH_GROUP_NUM 6
 #define TSSI_MCS_2G_CH_GROUP_NUM 5
 #define TSSI_MCS_5G_CH_GROUP_NUM 14
+#define TSSI_MCS_6G_CH_GROUP_NUM 32
 #define TSSI_MCS_CH_GROUP_NUM \
        (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM)
 
 struct rtw89_tssi_info {
        u8 thermal[RF_PATH_MAX];
        s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM];
+       s8 tssi_trim_6g[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM_6G];
        s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM];
        s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM];
+       s8 tssi_6g_mcs[RF_PATH_MAX][TSSI_MCS_6G_CH_GROUP_NUM];
        s8 extra_ofst[RF_PATH_MAX];
        bool tssi_tracking_check[RF_PATH_MAX];
        u8 default_txagc_offset[RF_PATH_MAX];
index e17e0ab..df6e9bf 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright(c) 2019-2022  Realtek Corporation
  */
 
+#include "debug.h"
 #include "fw.h"
 #include "mac.h"
 #include "reg.h"
@@ -220,7 +221,163 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
        return 0;
 }
 
+static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+       struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+       static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
+       static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
+       u32 addr = rtwdev->chip->phycap_addr;
+       bool pg = false;
+       u32 ofst;
+       u8 i, j;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
+                       /* addrs are in decreasing order */
+                       ofst = tssi_trim_addr[i] - addr - j;
+                       tssi->tssi_trim[i][j] = phycap_map[ofst];
+
+                       if (phycap_map[ofst] != 0xff)
+                               pg = true;
+               }
+
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
+                       /* addrs are in decreasing order */
+                       ofst = tssi_trim_addr_6g[i] - addr - j;
+                       tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
+
+                       if (phycap_map[ofst] != 0xff)
+                               pg = true;
+               }
+       }
+
+       if (!pg) {
+               memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
+               memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
+               rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                           "[TSSI][TRIM] no PG, set all trim info to 0\n");
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++)
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
+                       rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                                   "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
+                                   i, j, tssi->tssi_trim[i][j],
+                                   tssi_trim_addr[i] - j);
+}
+
+static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
+                                                u8 *phycap_map)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
+       u32 addr = rtwdev->chip->phycap_addr;
+       u8 i;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
+                           i, info->thermal_trim[i]);
+
+               if (info->thermal_trim[i] != 0xff)
+                       info->pg_thermal_trim = true;
+       }
+}
+
+static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
+{
+#define __thm_setting(raw)                             \
+({                                                     \
+       u8 __v = (raw);                                 \
+       ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1);       \
+})
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       u8 i, val;
+
+       if (!info->pg_thermal_trim) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] no PG, do nothing\n");
+
+               return;
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               val = __thm_setting(info->thermal_trim[i]);
+               rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
+                           i, val);
+       }
+#undef __thm_setting
+}
+
+static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
+                                                u8 *phycap_map)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
+       u32 addr = rtwdev->chip->phycap_addr;
+       u8 i;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
+                           i, info->pa_bias_trim[i]);
+
+               if (info->pa_bias_trim[i] != 0xff)
+                       info->pg_pa_bias_trim = true;
+       }
+}
+
+static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       u8 pabias_2g, pabias_5g;
+       u8 i;
+
+       if (!info->pg_pa_bias_trim) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] no PG, do nothing\n");
+
+               return;
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
+               pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
+                           i, pabias_2g, pabias_5g);
+
+               rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
+               rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
+       }
+}
+
+static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+       rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
+       rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
+       rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
+
+       return 0;
+}
+
+static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
+{
+       rtw8852c_thermal_trim(rtwdev);
+       rtw8852c_pa_bias_trim(rtwdev);
+}
+
 static const struct rtw89_chip_ops rtw8852c_chip_ops = {
+       .read_phycap            = rtw8852c_read_phycap,
+       .power_trim             = rtw8852c_power_trim,
        .pwr_on_func            = rtw8852c_pwr_on_func,
        .pwr_off_func           = rtw8852c_pwr_off_func,
 };
@@ -238,6 +395,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .limit_efuse_size       = 1280,
        .dav_phy_efuse_size     = 96,
        .dav_log_efuse_size     = 16,
+       .phycap_addr            = 0x590,
+       .phycap_size            = 0x60,
        .hci_func_en_addr       = R_AX_HCI_FUNC_EN_V1,
        .h2c_ctrl_reg           = R_AX_H2CREG_CTRL_V1,
        .h2c_regs               = rtw8852c_h2c_regs,
index 68a3972..8abca49 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "core.h"
 
+#define RF_PATH_NUM_8852C 2
+
 extern const struct rtw89_chip_info rtw8852c_chip_info;
 
 #endif