Commit 5f028a9c authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

rtw88: 8723d: Add set_channel

Set MAC/BB/RF register according to specified channel. The function
rtw_set_channel_mac() is used to set MAC registers, but 8723D only need
some of them.

For channel 14, we need to set different CCK DFIR values, so restore the
values when channel 1 to 13 is selected.

Spur calibration is needed in channel 13 and 14, and we do notch if spur
is over threshold.
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/20200504105010.10780-4-yhchuang@realtek.com
parent 158441a2
......@@ -40,6 +40,9 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
}
rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);
if (rtw_chip_wcpu_11n(rtwdev))
return;
value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
rtw_write32(rtwdev, REG_AFE_CTRL1, value32);
......
......@@ -287,6 +287,166 @@ static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}
static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
u8 channel, u32 thres)
{
u32 freq;
bool ret = false;
if (channel == 13)
freq = FREQ_CH13;
else if (channel == 14)
freq = FREQ_CH14;
else
return false;
rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE);
rtw_write32(rtwdev, REG_PSDFN, freq);
rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq);
msleep(30);
if (rtw_read32(rtwdev, REG_PSDRPT) >= thres)
ret = true;
rtw_write32(rtwdev, REG_PSDFN, freq);
rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE);
return ret;
}
static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch)
{
if (!notch) {
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f);
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
return;
}
switch (channel) {
case 13:
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb);
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000);
rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
break;
case 14:
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5);
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000);
rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
break;
default:
rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
break;
}
}
static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel)
{
bool notch;
if (channel < 13) {
rtw8723d_cfg_notch(rtwdev, channel, false);
return;
}
notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES);
rtw8723d_cfg_notch(rtwdev, channel, notch);
}
static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
{
u32 rf_cfgch_a, rf_cfgch_b;
rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK);
rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK;
rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK;
rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK);
rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK);
rf_cfgch_a &= ~RFCFGCH_BW_MASK;
switch (bw) {
case RTW_CHANNEL_WIDTH_20:
rf_cfgch_a |= RFCFGCH_BW_20M;
break;
case RTW_CHANNEL_WIDTH_40:
rf_cfgch_a |= RFCFGCH_BW_40M;
break;
default:
break;
}
rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a);
rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b);
rtw8723d_spur_cal(rtwdev, channel);
}
static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = {
[0] = {
{ .len = 4, .reg = 0xA24, .val = 0x64B80C1C },
{ .len = 4, .reg = 0xA28, .val = 0x00008810 },
{ .len = 4, .reg = 0xAAC, .val = 0x01235667 },
},
[1] = {
{ .len = 4, .reg = 0xA24, .val = 0x0000B81C },
{ .len = 4, .reg = 0xA28, .val = 0x00000000 },
{ .len = 4, .reg = 0xAAC, .val = 0x00003667 },
},
};
static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_ch_idx)
{
const struct rtw_backup_info *cck_dfir;
int i;
cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1];
for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++)
rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val);
switch (bw) {
case RTW_CHANNEL_WIDTH_20:
rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);
rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);
rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1);
rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa);
break;
case RTW_CHANNEL_WIDTH_40:
rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1);
rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1);
rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0);
rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND,
(primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0));
break;
default:
break;
}
}
static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_chan_idx)
{
rtw8723d_set_channel_rf(rtwdev, channel, bw);
rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
}
#define BIT_CFENDFORM BIT(9)
#define BIT_WMAC_TCR_ERR0 BIT(12)
#define BIT_WMAC_TCR_ERR1 BIT(13)
......@@ -383,6 +543,7 @@ static struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723d_read_efuse,
.query_rx_desc = rtw8723d_query_rx_desc,
.set_channel = rtw8723d_set_channel,
.mac_init = rtw8723d_mac_init,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
......
......@@ -66,7 +66,38 @@ struct rtw8723d_efuse {
#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \
le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))
#define SPUR_THRES 0x16
#define CCK_DFIR_NR 3
#define DIS_3WIRE 0xccf000c0
#define EN_3WIRE 0xccc000c0
#define START_PSD 0x400000
#define FREQ_CH13 0xfccd
#define FREQ_CH14 0xff9a
#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0)
#define RFCFGCH_BW_MASK (BIT(11) | BIT(10))
#define RFCFGCH_BW_20M (BIT(11) | BIT(10))
#define RFCFGCH_BW_40M BIT(10)
#define BIT_MASK_RFMOD BIT(0)
#define REG_PSDFN 0x0808
#define REG_ANALOG_P4 0x088c
#define REG_PSDRPT 0x08b4
#define REG_FPGA1_RFMOD 0x0900
#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_OFDM0_RXDSP 0x0c40
#define BIT_MASK_RXDSP GENMASK(28, 24)
#define BIT_EN_RXDSP BIT(9)
#define REG_OFDM0_XAAGC1 0x0c50
#define REG_OFDM0_XBAGC1 0x0c58
#define REG_OFDM1_CFOTRK 0x0d2c
#define BIT_EN_CFOTRK BIT(28)
#define REG_OFDM1_CSI1 0x0d40
#define REG_OFDM1_CSI2 0x0d44
#define REG_OFDM1_CSI3 0x0d48
#define REG_OFDM1_CSI4 0x0d4c
#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