rtw89: 8852c: add read/write rf register function
authorChung-Hsuan Hung <hsuan8331@realtek.com>
Thu, 17 Mar 2022 05:55:35 +0000 (13:55 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 17 Mar 2022 14:20:27 +0000 (16:20 +0200)
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: Chung-Hsuan Hung <hsuan8331@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220317055543.40514-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/phy.h
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8852c.c

index b75d086..43d73ec 100644 (file)
@@ -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)
 {
index d6bc84a..e600e01 100644 (file)
@@ -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);
index 09bf3af..26efdfa 100644 (file)
 #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)
 #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)
index c74dede..173008b 100644 (file)
@@ -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,