wifi: rtw89: phy: add {read,write}_rf_v3 for RTL8922D

Implement to access RF registers for RTL8922D.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260114013950.19704-3-pkshih@realtek.com
This commit is contained in:
Ping-Ke Shih 2026-01-14 09:39:40 +08:00
parent e497fc05e9
commit 1e3c50e0b4
3 changed files with 139 additions and 0 deletions

View File

@ -1036,6 +1036,68 @@ u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_read_rf_v2);
static u32 rtw89_phy_read_full_rf_v3_a(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path, u32 addr)
{
bool done;
u32 busy;
int ret;
u32 val;
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1, 30, false,
rtwdev, R_SW_SI_DATA_BE4,
B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4);
if (ret) {
rtw89_warn(rtwdev, "poll HWSI is busy\n");
return INV_RF_DATA;
}
val = u32_encode_bits(rf_path, GENMASK(10, 8)) |
u32_encode_bits(addr, GENMASK(7, 0));
rtw89_phy_write32_mask(rtwdev, R_SW_SI_READ_ADDR_BE4, B_SW_SI_READ_ADDR_BE4, val);
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done,
1, 30, false,
rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_DONE_BE4);
if (ret) {
rtw89_warn(rtwdev, "read HWSI is busy\n");
return INV_RF_DATA;
}
val = rtw89_phy_read32_mask(rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_BE4);
return val;
}
static u32 rtw89_phy_read_rf_v3_a(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path, u32 addr, u32 mask)
{
u32 val;
val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr);
return (val & mask) >> __ffs(mask);
}
u32 rtw89_phy_read_rf_v3(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_v3_a(rtwdev, rf_path, addr, mask);
}
EXPORT_SYMBOL(rtw89_phy_read_rf_v3);
bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data)
{
@ -1175,6 +1237,66 @@ bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_write_rf_v2);
static
bool rtw89_phy_write_full_rf_v3_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 data)
{
u32 busy;
u32 val;
int ret;
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1, 30, false,
rtwdev, R_SW_SI_DATA_BE4,
B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4);
if (ret) {
rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__);
return false;
}
val = u32_encode_bits(rf_path, B_SW_SI_DATA_PATH_BE4) |
u32_encode_bits(addr, B_SW_SI_DATA_ADR_BE4) |
u32_encode_bits(data, B_SW_SI_DATA_DAT_BE4);
rtw89_phy_write32(rtwdev, R_SW_SI_WDATA_BE4, val);
return true;
}
static
bool rtw89_phy_write_rf_a_v3(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_v3_a(rtwdev, rf_path, addr);
val &= ~mask;
val |= (data << __ffs(mask)) & mask;
}
return rtw89_phy_write_full_rf_v3_a(rtwdev, rf_path, addr, val);
}
bool rtw89_phy_write_rf_v3(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_v3(rtwdev, rf_path, addr, mask, data);
}
EXPORT_SYMBOL(rtw89_phy_write_rf_v3);
static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev)
{
return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1;

View File

@ -823,12 +823,16 @@ 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);
u32 rtw89_phy_read_rf_v3(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);
bool rtw89_phy_write_rf_v3(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_bb_afe(struct rtw89_dev *rtwdev);
void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio);

View File

@ -10124,6 +10124,19 @@
#define R_TSSI_K_P1 0xE7A0
#define B_TSSI_K_OFDM_P1 GENMASK(29, 20)
#define R_SW_SI_WDATA_BE4 0x20370
#define B_SW_SI_DATA_PATH_BE4 GENMASK(31, 28)
#define B_SW_SI_DATA_ADR_BE4 GENMASK(27, 20)
#define B_SW_SI_DATA_DAT_BE4 GENMASK(19, 0)
#define R_SW_SI_READ_ADDR_BE4 0x20378
#define B_SW_SI_READ_ADDR_BE4 GENMASK(10, 0)
#define R_SW_SI_DATA_BE4 0x2CF4C
#define B_SW_SI_READ_DATA_BE4 GENMASK(19, 0)
#define B_SW_SI_W_BUSY_BE4 BIT(24)
#define B_SW_SI_R_BUSY_BE4 BIT(25)
#define B_SW_SI_READ_DATA_DONE_BE4 BIT(26)
/* WiFi CPU local domain */
#define R_AX_WDT_CTRL 0x0040
#define B_AX_WDT_EN BIT(31)