rtw89: 8852c: rfk: add DACK
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 2 May 2022 23:54:02 +0000 (07:54 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 3 May 2022 05:32:02 +0000 (08:32 +0300)
DACK (digital-to-analog converters calibration) is used to calibrate DAC
to output analog signals as expected.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220502235408.15052-3-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h

index 83cb509d2fbe983a576779b2fab23f53ad3df463..ce472d3b1a6657faf996e900f33e9169edc64af3 100644 (file)
 #define R_S0_HW_SI_DIS 0x1200
 #define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28)
 #define R_P0_RXCK 0x12A0
-#define B_P0_RXCK_VAL GENMASK(18, 16)
-#define B_P0_RXCK_ON BIT(19)
 #define B_P0_RXCK_BW3 BIT(30)
+#define B_P0_TXCK_ALL GENMASK(19, 12)
+#define B_P0_RXCK_ON BIT(19)
+#define B_P0_RXCK_VAL GENMASK(18, 16)
+#define B_P0_TXCK_ON BIT(15)
+#define B_P0_TXCK_VAL GENMASK(14, 12)
 #define R_P0_NRBW 0x12B8
 #define B_P0_NRBW_DBG BIT(30)
 #define R_S0_RXDC 0x12D4
 #define R_IQKINF2 0x9FE8
 #define B_IQKINF2_FCNT GENMASK(23, 16)
 #define B_IQKINF2_KCNT GENMASK(15, 8)
-#define B_IQKINF2_NCTLV GENMAKS(7, 0)
+#define B_IQKINF2_NCTLV GENMASK(7, 0)
+#define R_DCOF0 0xC000
+#define B_DCOF0_V GENMASK(4, 1)
+#define R_DCOF1 0xC004
+#define B_DCOF1_S BIT(0)
+#define R_DCOF8 0xC020
+#define B_DCOF8_V GENMASK(4, 1)
+#define R_DACK_S0P0 0xC040
+#define B_DACK_S0P0_OK BIT(31)
+#define R_DACK_BIAS00 0xc048
+#define B_DACK_BIAS00 GENMASK(11, 2)
+#define R_DACK_S0P2 0xC05C
+#define B_DACK_S0M0 GENMASK(31, 24)
+#define B_DACK_S0P2_OK BIT(2)
+#define R_DACK_DADCK00 0xC060
+#define B_DACK_DADCK00 GENMASK(31, 24)
+#define R_DACK_S0P1 0xC064
+#define B_DACK_S0P1_OK BIT(31)
+#define R_DACK_BIAS01 0xC06C
+#define B_DACK_BIAS01 GENMASK(11, 2)
+#define R_DACK_S0P3 0xC080
+#define B_DACK_S0M1 GENMASK(31, 24)
+#define B_DACK_S0P3_OK BIT(2)
+#define R_DACK_DADCK01 0xC084
+#define B_DACK_DADCK01 GENMASK(31, 24)
+#define R_DRCK 0xC0C4
+#define B_DRCK_IDLE BIT(9)
+#define B_DRCK_EN BIT(6)
+#define B_DRCK_VAL GENMASK(4, 0)
+#define R_DRCK_RES 0xC0C8
+#define B_DRCK_RES GENMASK(19, 15)
+#define B_DRCK_POL BIT(3)
 #define R_PATH0_SAMPL_DLY_T_V1 0xC0D4
 #define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26)
+#define R_P0_CFCH_BW0 0xC0D4
+#define B_P0_CFCH_BW0 GENMASK(27, 26)
+#define R_P0_CFCH_BW1 0xC0D8
+#define B_P0_CFCH_BW1 GENMASK(8, 5)
+#define R_ADDCK0 0xC0F4
+#define B_ADDCK0 GENMASK(9, 8)
+#define B_ADDCK0_EN BIT(4)
+#define B_ADDCK0_RST BIT(2)
+#define R_ADDCK0_RL 0xC0F8
+#define B_ADDCK0_RLS GENMASK(29, 28)
+#define B_ADDCK0_RL1 GENMASK(27, 18)
+#define B_ADDCK0_RL0 GENMASK(17, 8)
+#define R_ADDCKR0 0xC0FC
+#define B_ADDCKR0_A0 GENMASK(19, 10)
+#define B_ADDCKR0_A1 GENMASK(9, 0)
+#define R_DACK10 0xC100
+#define B_DACK10 GENMASK(4, 1)
+#define R_DACK1_K 0xc104
+#define B_DACK1_EN BIT(0)
+#define R_DACK11 0xC120
+#define B_DACK11 GENMASK(4, 1)
+#define R_DACK_S1P0 0xC140
+#define B_DACK_S1P0_OK BIT(31)
+#define R_DACK_BIAS10 0xC148
+#define B_DACK_BIAS10 GENMASK(11, 2)
+#define R_DACK10S 0xC15C
+#define B_DACK10S GENMASK(31, 24)
+#define R_DACK_S1P2 0xC15C
+#define B_DACK_S1P2_OK BIT(2)
+#define R_DACK_DADCK10 0xC160
+#define B_DACK_DADCK10 GENMASK(31, 24)
+#define R_DACK_S1P1 0xC164
+#define B_DACK_S1P1_OK BIT(31)
+#define R_DACK_BIAS11 0xC16C
+#define B_DACK_BIAS11 GENMASK(11, 2)
+#define R_DACK11S 0xC180
+#define B_DACK11S GENMASK(31, 24)
+#define R_DACK_S1P3 0xC180
+#define B_DACK_S1P3_OK BIT(2)
+#define R_DACK_DADCK11 0xC184
+#define B_DACK_DADCK11 GENMASK(31, 24)
 #define R_PATH1_SAMPL_DLY_T_V1 0xC1D4
 #define B_PATH1_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26)
 #define R_PATH0_BW_SEL_V1 0xC0D8
 #define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5)
 #define R_PATH1_BW_SEL_V1 0xC1D8
 #define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5)
-#define R_P0_CFCH_BW0 0xC0D4
-#define B_P0_CFCH_BW0 GENMASK(27, 26)
-#define R_P0_CFCH_BW1 0xC0D8
-#define B_P0_CFCH_BW1 GENMASK(8, 5)
+#define R_ADDCK1 0xC1F4
+#define B_ADDCK1 GENMASK(9, 8)
+#define B_ADDCK1_EN BIT(4)
+#define B_ADDCK1_RST BIT(2)
+#define R_ADDCK1_RL 0xC1F8
+#define B_ADDCK1_RLS GENMASK(29, 28)
+#define B_ADDCK1_RL1 GENMASK(27, 18)
+#define B_ADDCK1_RL0 GENMASK(17, 8)
+#define R_ADDCKR1 0xC1fC
+#define B_ADDCKR1_A0 GENMASK(19, 10)
+#define B_ADDCKR1_A1 GENMASK(9, 0)
 
 /* WiFi CPU local domain */
 #define R_AX_WDT_CTRL 0x0040
index 27556846821260bfd682711974278a3d18026cf3..502627d8141d42703ba213a9236e04ecc5d81f82 100644 (file)
@@ -1771,6 +1771,8 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
        struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
 
        memset(mcc_info, 0, sizeof(*mcc_info));
+
+       rtw8852c_dack(rtwdev);
 }
 
 static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
index 56f0876c03fbd7b192348ebc0cb160b2ac34b37c..4245a2c5f9d67dcdc1dd448b998c0c8effed381a 100644 (file)
@@ -2,11 +2,13 @@
 /* Copyright(c) 2019-2022  Realtek Corporation
  */
 
+#include "coex.h"
 #include "debug.h"
 #include "phy.h"
 #include "reg.h"
 #include "rtw8852c.h"
 #include "rtw8852c_rfk.h"
+#include "rtw8852c_rfk_table.h"
 
 static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
@@ -22,6 +24,441 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
                return RF_B;
 }
 
+static void _dack_dump(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u8 i;
+       u8 t;
+
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n",
+                   dack->addck_d[0][0], dack->addck_d[0][1]);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n",
+                   dack->addck_d[1][0], dack->addck_d[1][1]);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+                   dack->dadck_d[0][0], dack->dadck_d[0][1]);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+                   dack->dadck_d[1][0], dack->dadck_d[1][1]);
+
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n",
+                   dack->biask_d[0][0], dack->biask_d[0][1]);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                   "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n",
+                   dack->biask_d[1][0], dack->biask_d[1][1]);
+
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               t = dack->msbk_d[0][0][i];
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+       }
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               t = dack->msbk_d[0][1][i];
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+       }
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               t = dack->msbk_d[1][0][i];
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+       }
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               t = dack->msbk_d[1][1][i];
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+       }
+}
+
+static void _addck_backup(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0);
+       dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0,
+                                                   B_ADDCKR0_A0);
+       dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0,
+                                                   B_ADDCKR0_A1);
+
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0);
+       dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1,
+                                                   B_ADDCKR1_A0);
+       dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1,
+                                                   B_ADDCKR1_A1);
+}
+
+static void _addck_reload(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1,
+                              dack->addck_d[0][0]);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0,
+                              dack->addck_d[0][1]);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1,
+                              dack->addck_d[1][0]);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0,
+                              dack->addck_d[1][1]);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x3);
+}
+
+static void _dack_backup_s0(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u8 i;
+
+       rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i);
+               dack->msbk_d[0][0][i] = rtw89_phy_read32_mask(rtwdev,
+                                                             R_DACK_S0P2,
+                                                             B_DACK_S0M0);
+               rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i);
+               dack->msbk_d[0][1][i] = rtw89_phy_read32_mask(rtwdev,
+                                                             R_DACK_S0P3,
+                                                             B_DACK_S0M1);
+       }
+       dack->biask_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00,
+                                                   B_DACK_BIAS00);
+       dack->biask_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01,
+                                                   B_DACK_BIAS01);
+       dack->dadck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00,
+                                                   B_DACK_DADCK00);
+       dack->dadck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01,
+                                                   B_DACK_DADCK01);
+}
+
+static void _dack_backup_s1(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u8 i;
+
+       rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+       for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+               rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i);
+               dack->msbk_d[1][0][i] = rtw89_phy_read32_mask(rtwdev,
+                                                             R_DACK10S,
+                                                             B_DACK10S);
+               rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i);
+               dack->msbk_d[1][1][i] = rtw89_phy_read32_mask(rtwdev,
+                                                             R_DACK11S,
+                                                             B_DACK11S);
+       }
+       dack->biask_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10,
+                                                   B_DACK_BIAS10);
+       dack->biask_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11,
+                                                   B_DACK_BIAS11);
+       dack->dadck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10,
+                                                   B_DACK_DADCK10);
+       dack->dadck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11,
+                                                   B_DACK_DADCK11);
+}
+
+static void _dack_reload_by_path(struct rtw89_dev *rtwdev,
+                                enum rtw89_rf_path path, u8 index)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u32 idx_offset, path_offset;
+       u32 val32, offset, addr;
+       u8 i;
+
+       idx_offset = (index == 0 ? 0 : 0x14);
+       path_offset = (path == RF_PATH_A ? 0 : 0x28);
+       offset = idx_offset + path_offset;
+
+       rtw89_rfk_parser(rtwdev, &rtw8852c_dack_reload_defs_tbl);
+
+       /* msbk_d: 15/14/13/12 */
+       val32 = 0x0;
+       for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++)
+               val32 |= dack->msbk_d[path][index][i + 12] << (i * 8);
+       addr = 0xc200 + offset;
+       rtw89_phy_write32(rtwdev, addr, val32);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr,
+                   rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD));
+
+       /* msbk_d: 11/10/9/8 */
+       val32 = 0x0;
+       for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++)
+               val32 |= dack->msbk_d[path][index][i + 8] << (i * 8);
+       addr = 0xc204 + offset;
+       rtw89_phy_write32(rtwdev, addr, val32);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr,
+                   rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD));
+
+       /* msbk_d: 7/6/5/4 */
+       val32 = 0x0;
+       for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++)
+               val32 |= dack->msbk_d[path][index][i + 4] << (i * 8);
+       addr = 0xc208 + offset;
+       rtw89_phy_write32(rtwdev, addr, val32);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr,
+                   rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD));
+
+       /* msbk_d: 3/2/1/0 */
+       val32 = 0x0;
+       for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++)
+               val32 |= dack->msbk_d[path][index][i] << (i * 8);
+       addr = 0xc20c + offset;
+       rtw89_phy_write32(rtwdev, addr, val32);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", addr,
+                   rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD));
+
+       /* dadak_d/biask_d */
+       val32 = (dack->biask_d[path][index] << 22) |
+               (dack->dadck_d[path][index] << 14);
+       addr = 0xc210 + offset;
+       rtw89_phy_write32(rtwdev, addr, val32);
+       rtw89_phy_write32_set(rtwdev, addr, BIT(1));
+}
+
+static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
+{
+       u8 i;
+
+       for (i = 0; i < 2; i++)
+               _dack_reload_by_path(rtwdev, path, i);
+}
+
+static void _addck(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u32 val;
+       int ret;
+
+       /* S0 */
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0);
+       fsleep(1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1);
+
+       ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+                                      1, 10000, false, rtwdev, 0xc0fc, BIT(0));
+       if (ret) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n");
+               dack->addck_timeout[0] = true;
+       }
+
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0);
+
+       /* S1 */
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, 0x0);
+       udelay(1);
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1);
+
+       ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+                                      1, 10000, false, rtwdev, 0xc1fc, BIT(0));
+       if (ret) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n");
+               dack->addck_timeout[0] = true;
+       }
+       rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, 0x0);
+}
+
+static void _dack_reset(struct rtw89_dev *rtwdev, u8 path)
+{
+       rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+                                &rtw8852c_dack_reset_defs_a_tbl,
+                                &rtw8852c_dack_reset_defs_b_tbl);
+}
+
+enum adc_ck {
+       ADC_NA = 0,
+       ADC_480M = 1,
+       ADC_960M = 2,
+       ADC_1920M = 3,
+};
+
+enum dac_ck {
+       DAC_40M = 0,
+       DAC_80M = 1,
+       DAC_120M = 2,
+       DAC_160M = 3,
+       DAC_240M = 4,
+       DAC_320M = 5,
+       DAC_480M = 6,
+       DAC_960M = 7,
+};
+
+enum rf_mode {
+       RF_SHUT_DOWN = 0x0,
+       RF_STANDBY = 0x1,
+       RF_TX = 0x2,
+       RF_RX = 0x3,
+       RF_TXIQK = 0x4,
+       RF_DPK = 0x5,
+       RF_RXK1 = 0x6,
+       RF_RXK2 = 0x7,
+};
+
+static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
+                               enum dac_ck ck)
+{
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0);
+
+       if (!force)
+               return;
+
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck);
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1);
+}
+
+static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
+                               enum adc_ck ck)
+{
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0);
+
+       if (!force)
+               return;
+
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck);
+       rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1);
+}
+
+static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0)
+{
+       if (s0) {
+               if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0)
+                       return false;
+       } else {
+               if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 ||
+                   rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0)
+                       return false;
+       }
+
+       return true;
+}
+
+static void _dack_s0(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       bool done;
+       int ret;
+
+       rtw8852c_txck_force(rtwdev, RF_PATH_A, true, DAC_160M);
+       rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s0_tbl);
+
+       _dack_reset(rtwdev, RF_PATH_A);
+
+       rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1);
+       ret = read_poll_timeout_atomic(_check_dack_done, done, done,
+                                      1, 10000, false, rtwdev, true);
+       if (ret) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n");
+               dack->msbk_timeout[0] = true;
+       }
+       rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x0);
+       rtw8852c_txck_force(rtwdev, RF_PATH_A, false, DAC_960M);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n");
+
+       _dack_backup_s0(rtwdev);
+       _dack_reload(rtwdev, RF_PATH_A);
+       rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
+}
+
+static void _dack_s1(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       bool done;
+       int ret;
+
+       rtw8852c_txck_force(rtwdev, RF_PATH_B, true, DAC_160M);
+       rtw89_rfk_parser(rtwdev, &rtw8852c_dack_defs_s1_tbl);
+
+       _dack_reset(rtwdev, RF_PATH_B);
+
+       rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x1);
+       ret = read_poll_timeout_atomic(_check_dack_done, done, done,
+                                      1, 10000, false, rtwdev, false);
+       if (ret) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DACK timeout\n");
+               dack->msbk_timeout[0] = true;
+       }
+       rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x0);
+       rtw8852c_txck_force(rtwdev, RF_PATH_B, false, DAC_960M);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n");
+
+       _dack_backup_s1(rtwdev);
+       _dack_reload(rtwdev, RF_PATH_B);
+       rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
+}
+
+static void _dack(struct rtw89_dev *rtwdev)
+{
+       _dack_s0(rtwdev);
+       _dack_s1(rtwdev);
+}
+
+static void _drck(struct rtw89_dev *rtwdev)
+{
+       u32 val;
+       int ret;
+
+       rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1);
+       ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+                                      1, 10000, false, rtwdev, 0xc0c8, BIT(3));
+       if (ret)
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,  "[DACK]DRCK timeout\n");
+
+       rtw89_rfk_parser(rtwdev, &rtw8852c_drck_defs_tbl);
+
+       val = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, B_DRCK_RES);
+       rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0);
+       rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, val);
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n",
+                   rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD));
+}
+
+static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
+{
+       struct rtw89_dack_info *dack = &rtwdev->dack;
+       u32 rf0_0, rf1_0;
+       u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB);
+
+       dack->dack_done = false;
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n");
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n");
+       rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK);
+       rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK);
+       _drck(rtwdev);
+
+       rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0);
+       rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0);
+       rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1);
+       rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START);
+       _addck(rtwdev);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP);
+
+       _addck_backup(rtwdev);
+       _addck_reload(rtwdev);
+       rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0);
+       rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START);
+       _dack(rtwdev);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP);
+
+       _dack_dump(rtwdev);
+       dack->dack_done = true;
+       rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0);
+       rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0);
+       rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1);
+       rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1);
+       dack->dack_cnt++;
+       rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n");
+}
+
 static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
                        enum rtw89_bandwidth bw, bool is_dav)
 {
@@ -212,3 +649,12 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
        rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, param->center_chan, param->band_type,
                            param->bandwidth);
 }
+
+void rtw8852c_dack(struct rtw89_dev *rtwdev)
+{
+       u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0);
+
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
+       _dac_cal(rtwdev, false);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
+}
index 0e75555c1612d0c5f8383af42996f0c0cbfd0a2e..7323183e74d419365419401efe17bc1e69d20820 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "core.h"
 
+void rtw8852c_dack(struct rtw89_dev *rtwdev);
 void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
                             struct rtw89_channel_params *param,
                             enum rtw89_phy_idx phy_idx);