Commit 84d0e33e authored by Chung-Hsuan Hung's avatar Chung-Hsuan Hung Committed by Kalle Valo
Browse files

rtw89: 8852c: add read/write rf register function



Using encoded address which BIT(16) is used to discriminate which region is
going to access. Illustrate the calling flow as below

rtw89_phy_write_rf_v1() -+-> rtw89_phy_write_rf()   // old interface
                         +-> rtw89_phy_write_rf_a() // new interface

Signed-off-by: default avatarChung-Hsuan Hung <hsuan8331@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220317055543.40514-5-pkshih@realtek.com
parent a9ffae8d
Loading
Loading
Loading
Loading
+110 −0
Original line number Diff line number Diff line
@@ -604,6 +604,12 @@ u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(rtw89_phy_get_txsc);

static bool rtw89_phy_check_swsi_busy(struct rtw89_dev *rtwdev)
{
	return !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_W_BUSY_V1) ||
	       !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_R_BUSY_V1);
}

u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
		      u32 addr, u32 mask)
{
@@ -626,6 +632,56 @@ u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_read_rf);

static u32 rtw89_phy_read_rf_a(struct rtw89_dev *rtwdev,
			       enum rtw89_rf_path rf_path, u32 addr, u32 mask)
{
	bool busy;
	bool done;
	u32 val;
	int ret;

	ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy,
				       1, 30, false, rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "read rf busy swsi\n");
		return INV_RF_DATA;
	}

	mask &= RFREG_MASK;

	val = FIELD_PREP(B_SWSI_READ_ADDR_PATH_V1, rf_path) |
	      FIELD_PREP(B_SWSI_READ_ADDR_ADDR_V1, addr);
	rtw89_phy_write32_mask(rtwdev, R_SWSI_READ_ADDR_V1, B_SWSI_READ_ADDR_V1, val);
	udelay(2);

	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, 1,
				       30, false, rtwdev, R_SWSI_V1,
				       B_SWSI_R_DATA_DONE_V1);
	if (ret) {
		rtw89_err(rtwdev, "read swsi busy\n");
		return INV_RF_DATA;
	}

	return rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, mask);
}

u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
			 u32 addr, u32 mask)
{
	bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr);

	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_a(rtwdev, rf_path, addr, mask);
}
EXPORT_SYMBOL(rtw89_phy_read_rf_v1);

bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
			u32 addr, u32 mask, u32 data)
{
@@ -651,6 +707,60 @@ bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
}
EXPORT_SYMBOL(rtw89_phy_write_rf);

static bool rtw89_phy_write_rf_a(struct rtw89_dev *rtwdev,
				 enum rtw89_rf_path rf_path, u32 addr, u32 mask,
				 u32 data)
{
	u8 bit_shift;
	u32 val;
	bool busy, b_msk_en = false;
	int ret;

	ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy,
				       1, 30, false, rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "write rf busy swsi\n");
		return false;
	}

	data &= RFREG_MASK;
	mask &= RFREG_MASK;

	if (mask != RFREG_MASK) {
		b_msk_en = true;
		rtw89_phy_write32_mask(rtwdev, R_SWSI_BIT_MASK_V1, RFREG_MASK,
				       mask);
		bit_shift = __ffs(mask);
		data = (data << bit_shift) & RFREG_MASK;
	}

	val = FIELD_PREP(B_SWSI_DATA_BIT_MASK_EN_V1, b_msk_en) |
	      FIELD_PREP(B_SWSI_DATA_PATH_V1, rf_path) |
	      FIELD_PREP(B_SWSI_DATA_ADDR_V1, addr) |
	      FIELD_PREP(B_SWSI_DATA_VAL_V1, data);

	rtw89_phy_write32_mask(rtwdev, R_SWSI_DATA_V1, MASKDWORD, val);

	return true;
}

bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
			   u32 addr, u32 mask, u32 data)
{
	bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr);

	if (rf_path >= rtwdev->chip->rf_path_num) {
		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
		return false;
	}

	if (ad_sel)
		return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data);
	else
		return rtw89_phy_write_rf_a(rtwdev, rf_path, addr, mask, data);
}
EXPORT_SYMBOL(rtw89_phy_write_rf_v1);

static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
			       enum rtw89_phy_idx phy_idx)
{
+5 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "core.h"

#define RTW89_PHY_ADDR_OFFSET	0x10000
#define RTW89_RF_ADDR_ADSEL_MASK  BIT(16)

#define get_phy_headline(addr)		FIELD_GET(GENMASK(31, 28), addr)
#define PHY_HEADLINE_VALID	0xf
@@ -395,8 +396,12 @@ u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
		      enum rtw89_bandwidth dbw);
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);
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);
void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev);
void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev);
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
+15 −0
Original line number Diff line number Diff line
@@ -1805,6 +1805,17 @@
#define B_ANAPAR_FLTRST BIT(22)
#define B_ANAPAR_CRXBB GENMASK(18, 16)
#define B_ANAPAR_14 GENMASK(15, 0)
#define R_SWSI_DATA_V1 0x0370
#define B_SWSI_DATA_VAL_V1 GENMASK(19, 0)
#define B_SWSI_DATA_ADDR_V1 GENMASK(27, 20)
#define B_SWSI_DATA_PATH_V1 GENMASK(30, 28)
#define B_SWSI_DATA_BIT_MASK_EN_V1 BIT(31)
#define R_SWSI_BIT_MASK_V1 0x0374
#define B_SWSI_BIT_MASK_V1 GENMASK(19, 0)
#define R_SWSI_READ_ADDR_V1 0x0378
#define B_SWSI_READ_ADDR_ADDR_V1 GENMASK(7, 0)
#define B_SWSI_READ_ADDR_PATH_V1 GENMASK(10, 8)
#define B_SWSI_READ_ADDR_V1 GENMASK(10, 0)
#define R_UPD_CLK_ADC 0x0700
#define B_UPD_CLK_ADC_ON BIT(24)
#define B_UPD_CLK_ADC_VAL GENMASK(26, 25)
@@ -1912,6 +1923,10 @@
#define R_CFO_COMP_SEG0_H 0x1388
#define R_CFO_COMP_SEG0_CTRL 0x138C
#define R_DBG32_D 0x1730
#define R_SWSI_V1 0x174C
#define B_SWSI_W_BUSY_V1 BIT(24)
#define B_SWSI_R_BUSY_V1 BIT(25)
#define B_SWSI_R_DATA_DONE_V1 BIT(26)
#define R_TX_COUNTER 0x1A40
#define R_IFS_CLM_TX_CNT 0x1ACC
#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16)
+4 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "phy.h"
#include "reg.h"
#include "rtw8852c.h"

@@ -484,6 +485,8 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
	.read_efuse		= rtw8852c_read_efuse,
	.read_phycap		= rtw8852c_read_phycap,
	.power_trim		= rtw8852c_power_trim,
	.read_rf		= rtw89_phy_read_rf_v1,
	.write_rf		= rtw89_phy_write_rf_v1,
	.set_txpwr_ul_tb_offset	= rtw8852c_set_txpwr_ul_tb_offset,
	.pwr_on_func		= rtw8852c_pwr_on_func,
	.pwr_off_func		= rtw8852c_pwr_off_func,
@@ -494,6 +497,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
	.ops			= &rtw8852c_chip_ops,
	.fw_name		= "rtw89/rtw8852c_fw.bin",
	.dle_mem		= rtw8852c_dle_mem_pcie,
	.rf_base_addr		= {0xe000, 0xf000},
	.pwr_on_seq		= NULL,
	.pwr_off_seq		= NULL,
	.sec_ctrl_efuse_size	= 4,