Commit 5227c2ee authored by Tzu-En Huang's avatar Tzu-En Huang Committed by Kalle Valo

rtw88: 8822c: add SW DPK support

Power amplifiers are not linear components, and require DPK to
reduce its nonlinearity. DPK is called Digital Pre-distortion
Calibration, can be used to compensate the output of power.

DPK tracking is in charge of tracking the thermal changes. And
it then shifts the power curve accordingly, which makes the
power output remains linear even if the PA works in different
temperature.

To perform DPK, the parameter table should also be updated.
And the table will be applied when device is powered on.
Then DPK will reference the values to calibrate.
Signed-off-by: default avatarTzu-En Huang <tehuang@realtek.com>
Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 1ac3294b
......@@ -721,7 +721,7 @@ static void rtw_coex_set_rf_para(struct rtw_dev *rtwdev,
rtw_coex_set_bt_rx_gain(rtwdev, para.bt_lna_lvl);
}
static u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
{
u32 val;
......
......@@ -346,6 +346,7 @@ void rtw_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
}
void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb);
u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr);
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
u32 mask, u32 val);
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);
......
......@@ -641,6 +641,8 @@ struct rtw_chip_ops {
void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
void (*false_alarm_statistics)(struct rtw_dev *rtwdev);
void (*do_iqk)(struct rtw_dev *rtwdev);
void (*dpk_track)(struct rtw_dev *rtwdev);
void (*do_dpk)(struct rtw_dev *rtwdev);
/* for coex */
void (*coex_set_init)(struct rtw_dev *rtwdev);
......@@ -864,6 +866,9 @@ struct rtw_chip_info {
const struct rtw_rfe_def *rfe_defs;
u32 rfe_defs_size;
bool en_dis_dpd;
u16 dpd_ratemask;
/* coex paras */
u32 coex_para_ver;
u8 bt_desired_ver;
......@@ -1075,6 +1080,37 @@ struct rtw_coex {
struct delayed_work defreeze_work;
};
#define DPK_RF_REG_NUM 7
#define DPK_RF_PATH_NUM 2
#define DPK_BB_REG_NUM 18
#define DPK_CHANNEL_WIDTH_80 1
DECLARE_EWMA(thermal, 10, 4);
struct rtw_dpk_info {
bool is_dpk_pwr_on;
bool is_reload;
DECLARE_BITMAP(dpk_path_ok, DPK_RF_PATH_NUM);
u8 thermal_dpk[DPK_RF_PATH_NUM];
struct ewma_thermal avg_thermal[DPK_RF_PATH_NUM];
u32 gnt_control;
u32 gnt_value;
u8 result[RTW_RF_PATH_MAX];
u8 dpk_txagc[RTW_RF_PATH_MAX];
u32 coef[RTW_RF_PATH_MAX][20];
u16 dpk_gs[RTW_RF_PATH_MAX];
u8 thermal_dpk_delta[RTW_RF_PATH_MAX];
u8 pre_pwsf[RTW_RF_PATH_MAX];
u8 dpk_band;
u8 dpk_ch;
u8 dpk_bw;
};
#define DACK_MSBK_BACKUP_NUM 0xf
#define DACK_DCK_BACKUP_NUM 0x2
......@@ -1108,6 +1144,8 @@ struct rtw_dm_info {
u32 dack_adck[RTW_RF_PATH_MAX];
u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM];
u8 dack_dck[RTW_RF_PATH_MAX][2][DACK_DCK_BACKUP_NUM];
struct rtw_dpk_info dpk_info;
};
struct rtw_efuse {
......
......@@ -439,12 +439,21 @@ static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)
rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
}
static void rtw_phy_dpk_track(struct rtw_dev *rtwdev)
{
struct rtw_chip_info *chip = rtwdev->chip;
if (chip->ops->dpk_track)
chip->ops->dpk_track(rtwdev);
}
void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
{
/* for further calculation */
rtw_phy_statistics(rtwdev);
rtw_phy_dig(rtwdev);
rtw_phy_ra_info_update(rtwdev);
rtw_phy_dpk_track(rtwdev);
}
#define FRAC_BITS 3
......@@ -1316,11 +1325,20 @@ void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
static void rtw_load_rfk_table(struct rtw_dev *rtwdev)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
if (!chip->rfk_init_tbl)
return;
rtw_write32_mask(rtwdev, 0x1e24, BIT(17), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(28), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(29), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(30), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(31), 0x0);
rtw_load_table(rtwdev, chip->rfk_init_tbl);
dpk_info->is_dpk_pwr_on = 1;
}
void rtw_phy_load_tables(struct rtw_dev *rtwdev)
......@@ -1430,6 +1448,37 @@ static u8 rtw_get_channel_group(u8 channel)
}
}
static s8 rtw_phy_get_dis_dpd_by_rate_diff(struct rtw_dev *rtwdev, u16 rate)
{
struct rtw_chip_info *chip = rtwdev->chip;
s8 dpd_diff = 0;
if (!chip->en_dis_dpd)
return 0;
#define RTW_DPD_RATE_CHECK(_rate) \
case DESC_RATE ## _rate: \
if (DIS_DPD_RATE ## _rate & chip->dpd_ratemask) \
dpd_diff = -6 * chip->txgi_factor; \
break
switch (rate) {
RTW_DPD_RATE_CHECK(6M);
RTW_DPD_RATE_CHECK(9M);
RTW_DPD_RATE_CHECK(MCS0);
RTW_DPD_RATE_CHECK(MCS1);
RTW_DPD_RATE_CHECK(MCS8);
RTW_DPD_RATE_CHECK(MCS9);
RTW_DPD_RATE_CHECK(VHT1SS_MCS0);
RTW_DPD_RATE_CHECK(VHT1SS_MCS1);
RTW_DPD_RATE_CHECK(VHT2SS_MCS0);
RTW_DPD_RATE_CHECK(VHT2SS_MCS1);
}
#undef RTW_DPD_RATE_CHECK
return dpd_diff;
}
static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
struct rtw_2g_txpwr_idx *pwr_idx_2g,
enum rtw_bandwidth bandwidth,
......@@ -1638,6 +1687,9 @@ rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate,
tx_power = pwr_param.pwr_base;
offset = min_t(s8, pwr_param.pwr_offset, pwr_param.pwr_limit);
if (rtwdev->chip->en_dis_dpd)
offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate);
tx_power += offset;
if (tx_power > rtwdev->chip->max_power_index)
......
......@@ -341,6 +341,20 @@
#define REG_RFE_CTRL_E 0x0974
#define REG_DIS_DPD 0x0a70
#define DIS_DPD_MASK GENMASK(9, 0)
#define DIS_DPD_RATE6M BIT(0)
#define DIS_DPD_RATE9M BIT(1)
#define DIS_DPD_RATEMCS0 BIT(2)
#define DIS_DPD_RATEMCS1 BIT(3)
#define DIS_DPD_RATEMCS8 BIT(4)
#define DIS_DPD_RATEMCS9 BIT(5)
#define DIS_DPD_RATEVHT1SS_MCS0 BIT(6)
#define DIS_DPD_RATEVHT1SS_MCS1 BIT(7)
#define DIS_DPD_RATEVHT2SS_MCS0 BIT(8)
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
#define DIS_DPD_RATEALL GENMASK(9, 0)
#define REG_RFE_CTRL8 0x0cb4
#define BIT_MASK_RFE_SEL89 GENMASK(7, 0)
#define REG_RFE_INV8 0x0cbd
......@@ -471,6 +485,7 @@
#define RF_LUTWA 0x33
#define RF_LUTWD1 0x3e
#define RF_LUTWD0 0x3f
#define RF_T_METER 0x42
#define RF_XTALX2 0xb8
#define RF_MALSEL 0xbe
#define RF_RCKD 0xde
......
......@@ -1001,6 +1001,10 @@ static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
counter, reload, ++do_iqk_cnt, iqk_fail_mask);
}
static void rtw8822b_do_dpk(struct rtw_dev *rtwdev)
{
}
static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev)
{
/* enable TBTT nterrupt */
......@@ -1795,6 +1799,7 @@ static struct rtw_chip_ops rtw8822b_ops = {
.cfg_ldo25 = rtw8822b_cfg_ldo25,
.false_alarm_statistics = rtw8822b_false_alarm_statistics,
.do_iqk = rtw8822b_do_iqk,
.do_dpk = rtw8822b_do_dpk,
.coex_set_init = rtw8822b_coex_cfg_init,
.coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,
......
......@@ -96,6 +96,35 @@ struct rtw8822c_efuse {
};
};
enum rtw8822c_dpk_agc_phase {
RTW_DPK_GAIN_CHECK,
RTW_DPK_GAIN_LARGE,
RTW_DPK_GAIN_LESS,
RTW_DPK_GL_LARGE,
RTW_DPK_GL_LESS,
RTW_DPK_LOSS_CHECK,
RTW_DPK_AGC_OUT,
};
enum rtw8822c_dpk_one_shot_action {
RTW_DPK_CAL_PWR,
RTW_DPK_GAIN_LOSS,
RTW_DPK_DO_DPK,
RTW_DPK_DPK_ON,
RTW_DPK_DAGC,
RTW_DPK_ACTION_MAX
};
void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,
const struct rtw_table *tbl);
#define RTW_DECL_TABLE_DPK(name) \
const struct rtw_table name ## _tbl = { \
.data = name, \
.size = ARRAY_SIZE(name), \
.parse = rtw8822c_parse_tbl_dpk, \
}
#define DACK_PATH_8822C 2
#define DACK_REG_8822C 16
#define DACK_RF_8822C 1
......@@ -208,4 +237,59 @@ struct rtw8822c_efuse {
#define REG_DCKB_Q_0 0x41d8
#define REG_DCKB_Q_1 0x41dc
#define RF_MODE_TRXAGC 0x00
#define RF_RXAGC_OFFSET 0x19
#define RF_BW_TRXBB 0x1a
#define RF_TX_GAIN_OFFSET 0x55
#define RF_TX_GAIN 0x56
#define RF_TXA_LB_SW 0x63
#define RF_RXG_GAIN 0x87
#define RF_RXA_MIX_GAIN 0x8a
#define RF_EXT_TIA_BW 0x8f
#define RF_DEBUG 0xde
#define REG_NCTL0 0x1b00
#define REG_DPD_CTL0_S0 0x1b04
#define REG_DPD_CTL1_S0 0x1b08
#define REG_IQK_CTL1 0x1b20
#define REG_DPD_LUT0 0x1b44
#define REG_DPD_CTL0_S1 0x1b5c
#define REG_DPD_LUT3 0x1b60
#define REG_DPD_CTL1_S1 0x1b60
#define REG_DPD_AGC 0x1b67
#define REG_DPD_CTL0 0x1bb4
#define REG_R_CONFIG 0x1bcc
#define REG_RXSRAM_CTL 0x1bd4
#define REG_DPD_CTL11 0x1be4
#define REG_DPD_CTL12 0x1be8
#define REG_DPD_CTL15 0x1bf4
#define REG_DPD_CTL16 0x1bf8
#define REG_STAT_RPT 0x1bfc
#define BIT_EXT_TIA_BW BIT(1)
#define BIT_DE_TRXBW BIT(2)
#define BIT_DE_TX_GAIN BIT(16)
#define BIT_RXG_GAIN BIT(18)
#define BIT_DE_PWR_TRIM BIT(19)
#define BIT_INNER_LB BIT(21)
#define BIT_BYPASS_DPD BIT(25)
#define BIT_DPD_EN BIT(31)
#define BIT_SUBPAGE GENMASK(3, 0)
#define BIT_TXAGC GENMASK(4, 0)
#define BIT_GAIN_TXBB GENMASK(4, 0)
#define BIT_LB_ATT GENMASK(4, 2)
#define BIT_RXA_MIX_GAIN GENMASK(4, 3)
#define BIT_IQ_SWITCH GENMASK(5, 0)
#define BIT_DPD_CLK GENMASK(7, 4)
#define BIT_RXAGC GENMASK(9, 5)
#define BIT_BW_RXBB GENMASK(11, 10)
#define BIT_LB_SW GENMASK(13, 12)
#define BIT_BW_TXBB GENMASK(14, 12)
#define BIT_GLOSS_DB GENMASK(14, 12)
#define BIT_TXA_LB_ATT GENMASK(15, 14)
#define BIT_TX_OFFSET_VAL GENMASK(18, 14)
#define BIT_RPT_SEL GENMASK(20, 16)
#define BIT_GS_PWSF GENMASK(27, 0)
#define BIT_RPT_DGAIN GENMASK(27, 16)
#define BIT_TX_CFIR GENMASK(31, 30)
#endif
......@@ -12,6 +12,9 @@ extern const struct rtw_table rtw8822c_bb_pg_type0_tbl;
extern const struct rtw_table rtw8822c_rf_a_tbl;
extern const struct rtw_table rtw8822c_rf_b_tbl;
extern const struct rtw_table rtw8822c_txpwr_lmt_type0_tbl;
extern const struct rtw_table rtw8822c_dpk_afe_no_dpk_tbl;
extern const struct rtw_table rtw8822c_dpk_afe_is_dpk_tbl;
extern const struct rtw_table rtw8822c_dpk_mac_bb_tbl;
extern const struct rtw_table rtw8822c_array_mp_cal_init_tbl;
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment