Commit 1d229e88 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo
Browse files

rtw88: 8723d: add IQ calibration



IQ calibration is used to calibrate RF characteristic to yield expected
performance. Basically, we do calibration twice and compare the similarity
to determine calibration is good or not, if not we do the third
calibration, and then compare with the results of first and second
calibration. If it still not similar, IQK is failed.

Before doing calibration, we need to backup registers that will be
modified in calibration procedure, and restore these registers after
calibration is done.

A calibration procedure can divided into four sub-procedures that are
S1-TX, S1-RX, S0-TX and S0-RX. Where, S1 and S0 represent to path A and B
respectively. Each sub-procedure configure proper registers, and then
rigger one-shot calibration and poll until completion. For RX calibration,
it needs to do twice one-shot calibration, first one is to yield parameter
used by second one.

The result of TX part is stored for TX power tracking that adjusts TX AGC
to output expected power.

Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200512102621.5148-3-yhchuang@realtek.com
parent f71eb7f6
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1400,6 +1400,16 @@ struct rtw_pkt_count {
DECLARE_EWMA(evm, 10, 4);
DECLARE_EWMA(snr, 10, 4);

struct rtw_iqk_info {
	bool done;
	struct {
		u32 s1_x;
		u32 s1_y;
		u32 s0_x;
		u32 s0_y;
	} result;
};

struct rtw_dm_info {
	u32 cck_fa_cnt;
	u32 ofdm_fa_cnt;
@@ -1459,6 +1469,8 @@ struct rtw_dm_info {
	struct rtw_pkt_count last_pkt_count;
	struct ewma_evm ewma_evm[RTW_EVM_NUM];
	struct ewma_snr ewma_snr[RTW_SNR_NUM];

	struct rtw_iqk_info iqk;
};

struct rtw_efuse {
+2 −0
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@ void rtw_phy_init(struct rtw_dev *rtwdev)
	mask = chip->dig[0].mask;
	dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
	rtw_phy_cck_pd_init(rtwdev);

	dm_info->iqk.done = false;
}

void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
+10 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@
#define BIT_DPDT_SEL_EN		BIT(23)
#define REG_LEDCFG2		0x004E
#define REG_PAD_CTRL1		0x0064
#define BIT_BT_BTG_SEL		BIT(31)
#define BIT_PAPE_WLBT_SEL	BIT(29)
#define BIT_LNAON_WLBT_SEL	BIT(28)
#define BIT_BTGP_JTAG_EN	BIT(24)
@@ -611,7 +612,10 @@

#define REG_IGN_GNTBT4	0x4160

#define RF_MODE		0x00
#define RF_MODOPT	0x01
#define RF_WLINT	0x01
#define RF_WLSEL	0x02
#define RF_DTXLOK	0x08
#define RF_CFGCH	0x18
#define RF_RCK		0x1d
@@ -619,9 +623,15 @@
#define RF_LUTWD1	0x3e
#define RF_LUTWD0	0x3f
#define RF_T_METER	0x42
#define RF_BSPAD	0x54
#define RF_GAINTX	0x56
#define RF_TXATANK	0x64
#define RF_TRXIQ	0x66
#define RF_RXIQGEN	0x8d
#define RF_XTALX2	0xb8
#define RF_MALSEL	0xbe
#define RF_RCKD		0xde
#define RF_TXADBG	0xde
#define RF_LUTDBG	0xdf
#define RF_LUTWE2	0xee
#define RF_LUTWE	0xef
+817 −0

File changed.

Preview size limit exceeded, changes collapsed.

+122 −0
Original line number Diff line number Diff line
@@ -5,6 +5,34 @@
#ifndef __RTW8723D_H__
#define __RTW8723D_H__

enum rtw8723d_path {
	PATH_S1,
	PATH_S0,
	PATH_NR,
};

enum rtw8723d_iqk_round {
	IQK_ROUND_0,
	IQK_ROUND_1,
	IQK_ROUND_2,
	IQK_ROUND_HYBRID,
	IQK_ROUND_SIZE,
	IQK_ROUND_INVALID = 0xff,
};

enum rtw8723d_iqk_result {
	IQK_S1_TX_X,
	IQK_S1_TX_Y,
	IQK_S1_RX_X,
	IQK_S1_RX_Y,
	IQK_S0_TX_X,
	IQK_S0_TX_Y,
	IQK_S0_RX_X,
	IQK_S0_RX_Y,
	IQK_NR,
	IQK_SX_NR = IQK_NR / PATH_NR,
};

struct rtw8723de_efuse {
	u8 mac_addr[ETH_ALEN];		/* 0xd0 */
	u8 vender_id[2];
@@ -66,6 +94,34 @@ struct rtw8723d_efuse {
#define GET_PHY_STAT_P1_RXSNR_A(phy_stat)                                      \
	le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))

static inline s32 iqkxy_to_s32(s32 val)
{
	/* val is Q10.8 */
	return sign_extend32(val, 9);
}

static inline s32 iqk_mult(s32 x, s32 y, s32 *ext)
{
	/* x, y and return value are Q10.8 */
	s32 t;

	t = x * y;
	if (ext)
		*ext = (t >> 7) & 0x1;	/* Q.16 --> Q.9; get LSB of Q.9 */

	return (t >> 8);	/* Q.16 --> Q.8 */
}

#define MAX_TOLERANCE	5
#define IQK_TX_X_ERR	0x142
#define IQK_TX_Y_ERR	0x42
#define IQK_RX_X_UPPER	0x11a
#define IQK_RX_X_LOWER	0xe6
#define IQK_RX_Y_LMT	0x1a
#define IQK_TX_OK	BIT(0)
#define IQK_RX_OK	BIT(1)
#define PATH_IQK_RETRY	2

#define SPUR_THRES		0x16
#define CCK_DFIR_NR		3
#define DIS_3WIRE		0xccf000c0
@@ -80,15 +136,20 @@ struct rtw8723d_efuse {
#define BIT_MASK_RFMOD		BIT(0)
#define BIT_LCK			BIT(15)

#define REG_BTG_SEL		0x0067
#define REG_LTECOEX_PATH_CONTROL	0x0070
#define REG_PSDFN		0x0808
#define REG_BB_PWR_SAV1_11N	0x0874
#define REG_ANALOG_P4		0x088c
#define REG_PSDRPT		0x08b4
#define REG_FPGA1_RFMOD		0x0900
#define REG_BB_SEL_BTG		0x0948
#define REG_BBRX_DFIR		0x0954
#define BIT_MASK_RXBB_DFIR	GENMASK(27, 24)
#define BIT_RXBB_DFIR_EN	BIT(19)
#define REG_CCK0_SYS		0x0a00
#define BIT_CCK_SIDE_BAND	BIT(4)
#define REG_CCK_ANT_SEL_11N	0x0a04
#define REG_CCK_FA_RST_11N	0x0a2c
#define BIT_MASK_CCK_CNT_KEEP	BIT(12)
#define BIT_MASK_CCK_CNT_EN	BIT(13)
@@ -103,13 +164,48 @@ struct rtw8723d_efuse {
#define BIT_MASK_CCK_FA_LSB	GENMASK(15, 8)
#define REG_OFDM_FA_HOLDC_11N	0x0c00
#define BIT_MASK_OFDM_FA_KEEP	BIT(31)
#define REG_BB_RX_PATH_11N	0x0c04
#define REG_TRMUX_11N		0x0c08
#define REG_OFDM_FA_RSTC_11N	0x0c0c
#define BIT_MASK_OFDM_FA_RST	BIT(31)
#define REG_A_RXIQI		0x0c14
#define BIT_MASK_RXIQ_S1_X	0x000003FF
#define BIT_MASK_RXIQ_S1_Y1	0x0000FC00
#define BIT_SET_RXIQ_S1_Y1(y)	((y) & 0x3F)
#define REG_OFDM0_RXDSP		0x0c40
#define BIT_MASK_RXDSP		GENMASK(28, 24)
#define BIT_EN_RXDSP		BIT(9)
#define REG_OFDM_0_ECCA_THRESHOLD	0x0c4c
#define BIT_MASK_OFDM0_EXT_A	BIT(31)
#define BIT_MASK_OFDM0_EXT_C	BIT(29)
#define BIT_MASK_OFDM0_EXTS	(BIT(31) | BIT(29) | BIT(28))
#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28))
#define REG_OFDM0_XAAGC1	0x0c50
#define REG_OFDM0_XBAGC1	0x0c58
#define REG_OFDM_0_XA_TX_IQ_IMBALANCE	0x0c80
#define BIT_MASK_TXIQ_ELM_A	0x03ff
#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) |    \
				       ((a) & 0x03ff))
#define BIT_MASK_TXIQ_ELM_C	GENMASK(21, 16)
#define BIT_SET_TXIQ_ELM_C2(c)	((c) & 0x3F)
#define BIT_MASK_TXIQ_ELM_D	GENMASK(31, 22)
#define REG_TXIQK_MATRIXA_LSB2_11N	0x0c94
#define BIT_SET_TXIQ_ELM_C1(c)	(((c) & 0x000003C0) >> 6)
#define REG_RXIQK_MATRIX_LSB_11N	0x0ca0
#define BIT_MASK_RXIQ_S1_Y2	0xF0000000
#define BIT_SET_RXIQ_S1_Y2(y)	(((y) >> 6) & 0xF)
#define REG_TXIQ_AB_S0		0x0cd0
#define BIT_MASK_TXIQ_A_S0	0x000007FE
#define BIT_MASK_TXIQ_A_EXT_S0	BIT(0)
#define BIT_MASK_TXIQ_B_S0	0x0007E000
#define REG_TXIQ_CD_S0		0x0cd4
#define BIT_MASK_TXIQ_C_S0	0x000007FE
#define BIT_MASK_TXIQ_C_EXT_S0	BIT(0)
#define BIT_MASK_TXIQ_D_S0	GENMASK(22, 13)
#define BIT_MASK_TXIQ_D_EXT_S0	BIT(12)
#define REG_RXIQ_AB_S0		0x0cd8
#define BIT_MASK_RXIQ_X_S0	0x000003FF
#define BIT_MASK_RXIQ_Y_S0	0x003FF000
#define REG_OFDM_FA_TYPE1_11N	0x0cf0
#define BIT_MASK_OFDM_FF_CNT	GENMASK(15, 0)
#define BIT_MASK_OFDM_SF_CNT	GENMASK(31, 16)
@@ -132,6 +228,32 @@ struct rtw8723d_efuse {
#define BIT_MASK_OFDM_CRC_CNT	GENMASK(31, 16)
#define REG_OFDM_FA_TYPE4_11N	0x0da8
#define BIT_MASK_OFDM_MNS_CNT	GENMASK(15, 0)
#define REG_FPGA0_IQK_11N	0x0e28
#define BIT_MASK_IQK_MOD	0xffffff00
#define EN_IQK			0x808000
#define RST_IQK			0x000000
#define REG_TXIQK_TONE_A_11N	0x0e30
#define REG_RXIQK_TONE_A_11N	0x0e34
#define REG_TXIQK_PI_A_11N	0x0e38
#define REG_RXIQK_PI_A_11N	0x0e3c
#define REG_TXIQK_11N		0x0e40
#define BIT_SET_TXIQK_11N(x, y)	(0x80007C00 | ((x) << 16) | (y))
#define REG_RXIQK_11N		0x0e44
#define REG_IQK_AGC_PTS_11N	0x0e48
#define REG_IQK_AGC_RSP_11N	0x0e4c
#define REG_TX_IQK_TONE_B	0x0e50
#define REG_RX_IQK_TONE_B	0x0e54
#define REG_IQK_RES_TX		0x0e94
#define BIT_MASK_RES_TX		GENMASK(25, 16)
#define REG_IQK_RES_TY		0x0e9c
#define BIT_MASK_RES_TY		GENMASK(25, 16)
#define REG_IQK_RES_RX		0x0ea4
#define BIT_MASK_RES_RX		GENMASK(25, 16)
#define REG_IQK_RES_RY		0x0eac
#define BIT_IQK_TX_FAIL		BIT(28)
#define BIT_IQK_RX_FAIL		BIT(27)
#define BIT_IQK_DONE		BIT(26)
#define BIT_MASK_RES_RY		GENMASK(25, 16)
#define REG_PAGE_F_RST_11N		0x0f14
#define BIT_MASK_F_RST_ALL		BIT(16)
#define REG_IGI_C_11N			0x0f84