Commit 88d1f9b2 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: 8922a: add RF read/write v2

Implement indirect interface v2 to read/write RF registers via PHY
registers for 8922A.
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240124033637.12330-5-pkshih@realtek.com
parent 1ba63a8a
......@@ -796,6 +796,71 @@ u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_read_rf_v1);
static u32 rtw89_phy_read_full_rf_v2_a(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path, u32 addr)
{
static const u16 r_addr_ofst[2] = {0x2C24, 0x2D24};
static const u16 addr_ofst[2] = {0x2ADC, 0x2BDC};
bool busy, done;
int ret;
u32 val;
rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_CTL_MASK, 0x1);
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1, 3800, false,
rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_BUSY);
if (ret) {
rtw89_warn(rtwdev, "poll HWSI is busy\n");
return INV_RF_DATA;
}
rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_MASK, addr);
rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_RD, 0x1);
udelay(2);
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done,
1, 3800, false,
rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_RDONE);
if (ret) {
rtw89_warn(rtwdev, "read HWSI is busy\n");
val = INV_RF_DATA;
goto out;
}
val = rtw89_phy_read32_mask(rtwdev, r_addr_ofst[rf_path], RFREG_MASK);
out:
rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_POLL_MASK, 0);
return val;
}
static u32 rtw89_phy_read_rf_v2_a(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path, u32 addr, u32 mask)
{
u32 val;
val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr);
return (val & mask) >> __ffs(mask);
}
u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask)
{
bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
if (rf_path >= rtwdev->chip->rf_path_num) {
rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
return INV_RF_DATA;
}
if (ad_sel)
return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask);
else
return rtw89_phy_read_rf_v2_a(rtwdev, rf_path, addr, mask);
}
EXPORT_SYMBOL(rtw89_phy_read_rf_v2);
bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data)
{
......@@ -875,6 +940,66 @@ bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_write_rf_v1);
static
bool rtw89_phy_write_full_rf_v2_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 data)
{
static const u32 addr_is_idle[2] = {0x2C24, 0x2D24};
static const u32 addr_ofst[2] = {0x2AE0, 0x2BE0};
bool busy;
u32 val;
int ret;
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1, 3800, false,
rtwdev, addr_is_idle[rf_path], BIT(29));
if (ret) {
rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__);
return false;
}
val = u32_encode_bits(addr, B_HWSI_DATA_ADDR) |
u32_encode_bits(data, B_HWSI_DATA_VAL);
rtw89_phy_write32(rtwdev, addr_ofst[rf_path], val);
return true;
}
static
bool rtw89_phy_write_rf_a_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data)
{
u32 val;
if (mask == RFREG_MASK) {
val = data;
} else {
val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr);
val &= ~mask;
val |= (data << __ffs(mask)) & mask;
}
return rtw89_phy_write_full_rf_v2_a(rtwdev, rf_path, addr, val);
}
bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data)
{
bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
if (rf_path >= rtwdev->chip->rf_path_num) {
rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
return INV_RF_DATA;
}
if (ad_sel)
return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data);
else
return rtw89_phy_write_rf_a_v2(rtwdev, rf_path, addr, mask, data);
}
EXPORT_SYMBOL(rtw89_phy_write_rf_v2);
static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev)
{
return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1;
......
......@@ -781,10 +781,14 @@ u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask);
u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask);
u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask);
bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data);
bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data);
bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data);
void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev);
void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio);
void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
......
......@@ -7997,6 +7997,21 @@
#define B_AFEDAC1 GENMASK(2, 0)
#define R_IQKDPK_HC 0x2AB8
#define B_IQKDPK_HC BIT(28)
#define R_HWSI_ADD0 0x2ADC
#define R_HWSI_ADD1 0x2BDC
#define B_HWSI_ADD_MASK GENMASK(11, 4)
#define B_HWSI_ADD_CTL_MASK GENMASK(2, 0)
#define B_HWSI_ADD_RD BIT(2)
#define B_HWSI_ADD_POLL_MASK GENMASK(1, 0)
#define B_HWSI_ADD_RUN BIT(1)
#define B_HWSI_ADD_BUSY BIT(0)
#define R_HWSI_DATA 0x2AE0
#define B_HWSI_DATA_VAL GENMASK(27, 8)
#define B_HWSI_DATA_ADDR GENMASK(7, 0)
#define R_HWSI_VAL0 0x2C24
#define R_HWSI_VAL1 0x2D24
#define B_HWSI_VAL_RDONE BIT(31)
#define B_HWSI_VAL_BUSY BIT(29)
#define R_P1_EN_SOUND_WO_NDP 0x2D7C
#define B_P1_EN_SOUND_WO_NDP BIT(1)
#define R_EDCCA_RPT_A_BE 0x2E38
......
......@@ -1594,6 +1594,8 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.bb_postinit = rtw8922a_bb_postinit,
.bb_reset = rtw8922a_bb_reset,
.bb_sethw = rtw8922a_bb_sethw,
.read_rf = rtw89_phy_read_rf_v2,
.write_rf = rtw89_phy_write_rf_v2,
.set_channel = rtw8922a_set_channel,
.read_efuse = rtw8922a_read_efuse,
.read_phycap = rtw8922a_read_phycap,
......
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