12774f206SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 22774f206SBjoern A. Zeeb /* Copyright(c) 2018-2019 Realtek Corporation 32774f206SBjoern A. Zeeb */ 42774f206SBjoern A. Zeeb 52774f206SBjoern A. Zeeb #include <linux/module.h> 62774f206SBjoern A. Zeeb #include "main.h" 72774f206SBjoern A. Zeeb #include "coex.h" 82774f206SBjoern A. Zeeb #include "fw.h" 92774f206SBjoern A. Zeeb #include "tx.h" 102774f206SBjoern A. Zeeb #include "rx.h" 112774f206SBjoern A. Zeeb #include "phy.h" 122774f206SBjoern A. Zeeb #include "rtw8822c.h" 132774f206SBjoern A. Zeeb #include "rtw8822c_table.h" 142774f206SBjoern A. Zeeb #include "mac.h" 152774f206SBjoern A. Zeeb #include "reg.h" 162774f206SBjoern A. Zeeb #include "debug.h" 172774f206SBjoern A. Zeeb #include "util.h" 182774f206SBjoern A. Zeeb #include "bf.h" 192774f206SBjoern A. Zeeb #include "efuse.h" 202774f206SBjoern A. Zeeb 212774f206SBjoern A. Zeeb #define IQK_DONE_8822C 0xaa 222774f206SBjoern A. Zeeb 232774f206SBjoern A. Zeeb static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, 242774f206SBjoern A. Zeeb u8 rx_path, bool is_tx2_path); 252774f206SBjoern A. Zeeb 262774f206SBjoern A. Zeeb static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse, 272774f206SBjoern A. Zeeb struct rtw8822c_efuse *map) 282774f206SBjoern A. Zeeb { 292774f206SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->e.mac_addr); 302774f206SBjoern A. Zeeb } 312774f206SBjoern A. Zeeb 3290aac0d8SBjoern A. Zeeb static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse, 3390aac0d8SBjoern A. Zeeb struct rtw8822c_efuse *map) 3490aac0d8SBjoern A. Zeeb { 3590aac0d8SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->u.mac_addr); 3690aac0d8SBjoern A. Zeeb } 3790aac0d8SBjoern A. Zeeb 3890aac0d8SBjoern A. Zeeb static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse, 3990aac0d8SBjoern A. Zeeb struct rtw8822c_efuse *map) 4090aac0d8SBjoern A. Zeeb { 4190aac0d8SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->s.mac_addr); 4290aac0d8SBjoern A. Zeeb } 4390aac0d8SBjoern A. Zeeb 442774f206SBjoern A. Zeeb static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 452774f206SBjoern A. Zeeb { 462774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 472774f206SBjoern A. Zeeb struct rtw8822c_efuse *map; 482774f206SBjoern A. Zeeb int i; 492774f206SBjoern A. Zeeb 502774f206SBjoern A. Zeeb map = (struct rtw8822c_efuse *)log_map; 512774f206SBjoern A. Zeeb 52*a0ccc12fSBjoern A. Zeeb efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); 532774f206SBjoern A. Zeeb efuse->rfe_option = map->rfe_option; 542774f206SBjoern A. Zeeb efuse->rf_board_option = map->rf_board_option; 552774f206SBjoern A. Zeeb efuse->crystal_cap = map->xtal_k & XCAP_MASK; 562774f206SBjoern A. Zeeb efuse->channel_plan = map->channel_plan; 572774f206SBjoern A. Zeeb efuse->country_code[0] = map->country_code[0]; 582774f206SBjoern A. Zeeb efuse->country_code[1] = map->country_code[1]; 592774f206SBjoern A. Zeeb efuse->bt_setting = map->rf_bt_setting; 602774f206SBjoern A. Zeeb efuse->regd = map->rf_board_option & 0x7; 612774f206SBjoern A. Zeeb efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal; 622774f206SBjoern A. Zeeb efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal; 632774f206SBjoern A. Zeeb efuse->thermal_meter_k = 642774f206SBjoern A. Zeeb (map->path_a_thermal + map->path_b_thermal) >> 1; 652774f206SBjoern A. Zeeb efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf; 662774f206SBjoern A. Zeeb 672774f206SBjoern A. Zeeb for (i = 0; i < 4; i++) 682774f206SBjoern A. Zeeb efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 692774f206SBjoern A. Zeeb 702774f206SBjoern A. Zeeb switch (rtw_hci_type(rtwdev)) { 712774f206SBjoern A. Zeeb case RTW_HCI_TYPE_PCIE: 722774f206SBjoern A. Zeeb rtw8822ce_efuse_parsing(efuse, map); 732774f206SBjoern A. Zeeb break; 7490aac0d8SBjoern A. Zeeb case RTW_HCI_TYPE_USB: 7590aac0d8SBjoern A. Zeeb rtw8822cu_efuse_parsing(efuse, map); 7690aac0d8SBjoern A. Zeeb break; 7790aac0d8SBjoern A. Zeeb case RTW_HCI_TYPE_SDIO: 7890aac0d8SBjoern A. Zeeb rtw8822cs_efuse_parsing(efuse, map); 7990aac0d8SBjoern A. Zeeb break; 802774f206SBjoern A. Zeeb default: 812774f206SBjoern A. Zeeb /* unsupported now */ 822774f206SBjoern A. Zeeb return -ENOTSUPP; 832774f206SBjoern A. Zeeb } 842774f206SBjoern A. Zeeb 852774f206SBjoern A. Zeeb return 0; 862774f206SBjoern A. Zeeb } 872774f206SBjoern A. Zeeb 882774f206SBjoern A. Zeeb static void rtw8822c_header_file_init(struct rtw_dev *rtwdev, bool pre) 892774f206SBjoern A. Zeeb { 902774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); 912774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_PI_ON); 922774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); 932774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_PI_ON); 942774f206SBjoern A. Zeeb 952774f206SBjoern A. Zeeb if (pre) 962774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); 972774f206SBjoern A. Zeeb else 982774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); 992774f206SBjoern A. Zeeb } 1002774f206SBjoern A. Zeeb 1012774f206SBjoern A. Zeeb static void rtw8822c_bb_reset(struct rtw_dev *rtwdev) 1022774f206SBjoern A. Zeeb { 1032774f206SBjoern A. Zeeb rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 1042774f206SBjoern A. Zeeb rtw_write16_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 1052774f206SBjoern A. Zeeb rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 1062774f206SBjoern A. Zeeb } 1072774f206SBjoern A. Zeeb 1082774f206SBjoern A. Zeeb static void rtw8822c_dac_backup_reg(struct rtw_dev *rtwdev, 1092774f206SBjoern A. Zeeb struct rtw_backup_info *backup, 1102774f206SBjoern A. Zeeb struct rtw_backup_info *backup_rf) 1112774f206SBjoern A. Zeeb { 1122774f206SBjoern A. Zeeb u32 path, i; 1132774f206SBjoern A. Zeeb u32 val; 1142774f206SBjoern A. Zeeb u32 reg; 1152774f206SBjoern A. Zeeb u32 rf_addr[DACK_RF_8822C] = {0x8f}; 1162774f206SBjoern A. Zeeb u32 addrs[DACK_REG_8822C] = {0x180c, 0x1810, 0x410c, 0x4110, 1172774f206SBjoern A. Zeeb 0x1c3c, 0x1c24, 0x1d70, 0x9b4, 1182774f206SBjoern A. Zeeb 0x1a00, 0x1a14, 0x1d58, 0x1c38, 1192774f206SBjoern A. Zeeb 0x1e24, 0x1e28, 0x1860, 0x4160}; 1202774f206SBjoern A. Zeeb 1212774f206SBjoern A. Zeeb for (i = 0; i < DACK_REG_8822C; i++) { 1222774f206SBjoern A. Zeeb backup[i].len = 4; 1232774f206SBjoern A. Zeeb backup[i].reg = addrs[i]; 1242774f206SBjoern A. Zeeb backup[i].val = rtw_read32(rtwdev, addrs[i]); 1252774f206SBjoern A. Zeeb } 1262774f206SBjoern A. Zeeb 1272774f206SBjoern A. Zeeb for (path = 0; path < DACK_PATH_8822C; path++) { 1282774f206SBjoern A. Zeeb for (i = 0; i < DACK_RF_8822C; i++) { 1292774f206SBjoern A. Zeeb reg = rf_addr[i]; 1302774f206SBjoern A. Zeeb val = rtw_read_rf(rtwdev, path, reg, RFREG_MASK); 1312774f206SBjoern A. Zeeb backup_rf[path * i + i].reg = reg; 1322774f206SBjoern A. Zeeb backup_rf[path * i + i].val = val; 1332774f206SBjoern A. Zeeb } 1342774f206SBjoern A. Zeeb } 1352774f206SBjoern A. Zeeb } 1362774f206SBjoern A. Zeeb 1372774f206SBjoern A. Zeeb static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev, 1382774f206SBjoern A. Zeeb struct rtw_backup_info *backup, 1392774f206SBjoern A. Zeeb struct rtw_backup_info *backup_rf) 1402774f206SBjoern A. Zeeb { 1412774f206SBjoern A. Zeeb u32 path, i; 1422774f206SBjoern A. Zeeb u32 val; 1432774f206SBjoern A. Zeeb u32 reg; 1442774f206SBjoern A. Zeeb 1452774f206SBjoern A. Zeeb rtw_restore_reg(rtwdev, backup, DACK_REG_8822C); 1462774f206SBjoern A. Zeeb 1472774f206SBjoern A. Zeeb for (path = 0; path < DACK_PATH_8822C; path++) { 1482774f206SBjoern A. Zeeb for (i = 0; i < DACK_RF_8822C; i++) { 1492774f206SBjoern A. Zeeb val = backup_rf[path * i + i].val; 1502774f206SBjoern A. Zeeb reg = backup_rf[path * i + i].reg; 1512774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, reg, RFREG_MASK, val); 1522774f206SBjoern A. Zeeb } 1532774f206SBjoern A. Zeeb } 1542774f206SBjoern A. Zeeb } 1552774f206SBjoern A. Zeeb 1562774f206SBjoern A. Zeeb static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value, 1572774f206SBjoern A. Zeeb u32 *min, u32 *max) 1582774f206SBjoern A. Zeeb { 1592774f206SBjoern A. Zeeb if (value >= 0x200) { 1602774f206SBjoern A. Zeeb if (*min >= 0x200) { 1612774f206SBjoern A. Zeeb if (*min > value) 1622774f206SBjoern A. Zeeb *min = value; 1632774f206SBjoern A. Zeeb } else { 1642774f206SBjoern A. Zeeb *min = value; 1652774f206SBjoern A. Zeeb } 1662774f206SBjoern A. Zeeb if (*max >= 0x200) { 1672774f206SBjoern A. Zeeb if (*max < value) 1682774f206SBjoern A. Zeeb *max = value; 1692774f206SBjoern A. Zeeb } 1702774f206SBjoern A. Zeeb } else { 1712774f206SBjoern A. Zeeb if (*min < 0x200) { 1722774f206SBjoern A. Zeeb if (*min > value) 1732774f206SBjoern A. Zeeb *min = value; 1742774f206SBjoern A. Zeeb } 1752774f206SBjoern A. Zeeb 1762774f206SBjoern A. Zeeb if (*max >= 0x200) { 1772774f206SBjoern A. Zeeb *max = value; 1782774f206SBjoern A. Zeeb } else { 1792774f206SBjoern A. Zeeb if (*max < value) 1802774f206SBjoern A. Zeeb *max = value; 1812774f206SBjoern A. Zeeb } 1822774f206SBjoern A. Zeeb } 1832774f206SBjoern A. Zeeb } 1842774f206SBjoern A. Zeeb 1852774f206SBjoern A. Zeeb static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2) 1862774f206SBjoern A. Zeeb { 1872774f206SBjoern A. Zeeb if (*v1 >= 0x200 && *v2 >= 0x200) { 1882774f206SBjoern A. Zeeb if (*v1 > *v2) 1892774f206SBjoern A. Zeeb swap(*v1, *v2); 1902774f206SBjoern A. Zeeb } else if (*v1 < 0x200 && *v2 < 0x200) { 1912774f206SBjoern A. Zeeb if (*v1 > *v2) 1922774f206SBjoern A. Zeeb swap(*v1, *v2); 1932774f206SBjoern A. Zeeb } else if (*v1 < 0x200 && *v2 >= 0x200) { 1942774f206SBjoern A. Zeeb swap(*v1, *v2); 1952774f206SBjoern A. Zeeb } 1962774f206SBjoern A. Zeeb } 1972774f206SBjoern A. Zeeb 1982774f206SBjoern A. Zeeb static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) 1992774f206SBjoern A. Zeeb { 2002774f206SBjoern A. Zeeb u32 i, j; 2012774f206SBjoern A. Zeeb 2022774f206SBjoern A. Zeeb for (i = 0; i < DACK_SN_8822C - 1; i++) { 2032774f206SBjoern A. Zeeb for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) { 2042774f206SBjoern A. Zeeb __rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]); 2052774f206SBjoern A. Zeeb __rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]); 2062774f206SBjoern A. Zeeb } 2072774f206SBjoern A. Zeeb } 2082774f206SBjoern A. Zeeb } 2092774f206SBjoern A. Zeeb 2102774f206SBjoern A. Zeeb static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val) 2112774f206SBjoern A. Zeeb { 2122774f206SBjoern A. Zeeb u32 p, m, t, i; 2132774f206SBjoern A. Zeeb 2142774f206SBjoern A. Zeeb m = 0; 2152774f206SBjoern A. Zeeb p = 0; 2162774f206SBjoern A. Zeeb for (i = 10; i < DACK_SN_8822C - 10; i++) { 2172774f206SBjoern A. Zeeb if (vec[i] > 0x200) 2182774f206SBjoern A. Zeeb m = (0x400 - vec[i]) + m; 2192774f206SBjoern A. Zeeb else 2202774f206SBjoern A. Zeeb p = vec[i] + p; 2212774f206SBjoern A. Zeeb } 2222774f206SBjoern A. Zeeb 2232774f206SBjoern A. Zeeb if (p > m) { 2242774f206SBjoern A. Zeeb t = p - m; 2252774f206SBjoern A. Zeeb t = t / (DACK_SN_8822C - 20); 2262774f206SBjoern A. Zeeb } else { 2272774f206SBjoern A. Zeeb t = m - p; 2282774f206SBjoern A. Zeeb t = t / (DACK_SN_8822C - 20); 2292774f206SBjoern A. Zeeb if (t != 0x0) 2302774f206SBjoern A. Zeeb t = 0x400 - t; 2312774f206SBjoern A. Zeeb } 2322774f206SBjoern A. Zeeb 2332774f206SBjoern A. Zeeb *val = t; 2342774f206SBjoern A. Zeeb } 2352774f206SBjoern A. Zeeb 2362774f206SBjoern A. Zeeb static u32 rtw8822c_get_path_write_addr(u8 path) 2372774f206SBjoern A. Zeeb { 2382774f206SBjoern A. Zeeb u32 base_addr; 2392774f206SBjoern A. Zeeb 2402774f206SBjoern A. Zeeb switch (path) { 2412774f206SBjoern A. Zeeb case RF_PATH_A: 2422774f206SBjoern A. Zeeb base_addr = 0x1800; 2432774f206SBjoern A. Zeeb break; 2442774f206SBjoern A. Zeeb case RF_PATH_B: 2452774f206SBjoern A. Zeeb base_addr = 0x4100; 2462774f206SBjoern A. Zeeb break; 2472774f206SBjoern A. Zeeb default: 2482774f206SBjoern A. Zeeb WARN_ON(1); 2492774f206SBjoern A. Zeeb return -1; 2502774f206SBjoern A. Zeeb } 2512774f206SBjoern A. Zeeb 2522774f206SBjoern A. Zeeb return base_addr; 2532774f206SBjoern A. Zeeb } 2542774f206SBjoern A. Zeeb 2552774f206SBjoern A. Zeeb static u32 rtw8822c_get_path_read_addr(u8 path) 2562774f206SBjoern A. Zeeb { 2572774f206SBjoern A. Zeeb u32 base_addr; 2582774f206SBjoern A. Zeeb 2592774f206SBjoern A. Zeeb switch (path) { 2602774f206SBjoern A. Zeeb case RF_PATH_A: 2612774f206SBjoern A. Zeeb base_addr = 0x2800; 2622774f206SBjoern A. Zeeb break; 2632774f206SBjoern A. Zeeb case RF_PATH_B: 2642774f206SBjoern A. Zeeb base_addr = 0x4500; 2652774f206SBjoern A. Zeeb break; 2662774f206SBjoern A. Zeeb default: 2672774f206SBjoern A. Zeeb WARN_ON(1); 2682774f206SBjoern A. Zeeb return -1; 2692774f206SBjoern A. Zeeb } 2702774f206SBjoern A. Zeeb 2712774f206SBjoern A. Zeeb return base_addr; 2722774f206SBjoern A. Zeeb } 2732774f206SBjoern A. Zeeb 2742774f206SBjoern A. Zeeb static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value) 2752774f206SBjoern A. Zeeb { 2762774f206SBjoern A. Zeeb bool ret = true; 2772774f206SBjoern A. Zeeb 2782774f206SBjoern A. Zeeb if ((value >= 0x200 && (0x400 - value) > 0x64) || 2792774f206SBjoern A. Zeeb (value < 0x200 && value > 0x64)) { 2802774f206SBjoern A. Zeeb ret = false; 2812774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n"); 2822774f206SBjoern A. Zeeb } 2832774f206SBjoern A. Zeeb 2842774f206SBjoern A. Zeeb return ret; 2852774f206SBjoern A. Zeeb } 2862774f206SBjoern A. Zeeb 2872774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) 2882774f206SBjoern A. Zeeb { 2892774f206SBjoern A. Zeeb u32 temp; 2902774f206SBjoern A. Zeeb int i = 0, cnt = 0; 2912774f206SBjoern A. Zeeb 2922774f206SBjoern A. Zeeb while (i < DACK_SN_8822C && cnt < 10000) { 2932774f206SBjoern A. Zeeb cnt++; 2942774f206SBjoern A. Zeeb temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 2952774f206SBjoern A. Zeeb iv[i] = (temp & 0x3ff000) >> 12; 2962774f206SBjoern A. Zeeb qv[i] = temp & 0x3ff; 2972774f206SBjoern A. Zeeb 2982774f206SBjoern A. Zeeb if (rtw8822c_dac_iq_check(rtwdev, iv[i]) && 2992774f206SBjoern A. Zeeb rtw8822c_dac_iq_check(rtwdev, qv[i])) 3002774f206SBjoern A. Zeeb i++; 3012774f206SBjoern A. Zeeb } 3022774f206SBjoern A. Zeeb } 3032774f206SBjoern A. Zeeb 3042774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev, 3052774f206SBjoern A. Zeeb u32 *iv, u32 *qv, 3062774f206SBjoern A. Zeeb u32 *i_value, u32 *q_value) 3072774f206SBjoern A. Zeeb { 3082774f206SBjoern A. Zeeb u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0; 3092774f206SBjoern A. Zeeb u32 i_delta, q_delta; 3102774f206SBjoern A. Zeeb u32 temp; 3112774f206SBjoern A. Zeeb int i, cnt = 0; 3122774f206SBjoern A. Zeeb 3132774f206SBjoern A. Zeeb do { 3142774f206SBjoern A. Zeeb i_min = iv[0]; 3152774f206SBjoern A. Zeeb i_max = iv[0]; 3162774f206SBjoern A. Zeeb q_min = qv[0]; 3172774f206SBjoern A. Zeeb q_max = qv[0]; 3182774f206SBjoern A. Zeeb for (i = 0; i < DACK_SN_8822C; i++) { 3192774f206SBjoern A. Zeeb rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max); 3202774f206SBjoern A. Zeeb rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max); 3212774f206SBjoern A. Zeeb } 3222774f206SBjoern A. Zeeb 3232774f206SBjoern A. Zeeb if (i_max < 0x200 && i_min < 0x200) 3242774f206SBjoern A. Zeeb i_delta = i_max - i_min; 3252774f206SBjoern A. Zeeb else if (i_max >= 0x200 && i_min >= 0x200) 3262774f206SBjoern A. Zeeb i_delta = i_max - i_min; 3272774f206SBjoern A. Zeeb else 3282774f206SBjoern A. Zeeb i_delta = i_max + (0x400 - i_min); 3292774f206SBjoern A. Zeeb 3302774f206SBjoern A. Zeeb if (q_max < 0x200 && q_min < 0x200) 3312774f206SBjoern A. Zeeb q_delta = q_max - q_min; 3322774f206SBjoern A. Zeeb else if (q_max >= 0x200 && q_min >= 0x200) 3332774f206SBjoern A. Zeeb q_delta = q_max - q_min; 3342774f206SBjoern A. Zeeb else 3352774f206SBjoern A. Zeeb q_delta = q_max + (0x400 - q_min); 3362774f206SBjoern A. Zeeb 3372774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 3382774f206SBjoern A. Zeeb "[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n", 3392774f206SBjoern A. Zeeb i_min, i_max, i_delta); 3402774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 3412774f206SBjoern A. Zeeb "[DACK] q: min=0x%08x, max=0x%08x, delta=0x%08x\n", 3422774f206SBjoern A. Zeeb q_min, q_max, q_delta); 3432774f206SBjoern A. Zeeb 3442774f206SBjoern A. Zeeb rtw8822c_dac_iq_sort(rtwdev, iv, qv); 3452774f206SBjoern A. Zeeb 3462774f206SBjoern A. Zeeb if (i_delta > 5 || q_delta > 5) { 3472774f206SBjoern A. Zeeb temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 3482774f206SBjoern A. Zeeb iv[0] = (temp & 0x3ff000) >> 12; 3492774f206SBjoern A. Zeeb qv[0] = temp & 0x3ff; 3502774f206SBjoern A. Zeeb temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 3512774f206SBjoern A. Zeeb iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12; 3522774f206SBjoern A. Zeeb qv[DACK_SN_8822C - 1] = temp & 0x3ff; 3532774f206SBjoern A. Zeeb } else { 3542774f206SBjoern A. Zeeb break; 3552774f206SBjoern A. Zeeb } 3562774f206SBjoern A. Zeeb } while (cnt++ < 100); 3572774f206SBjoern A. Zeeb 3582774f206SBjoern A. Zeeb rtw8822c_dac_iq_offset(rtwdev, iv, i_value); 3592774f206SBjoern A. Zeeb rtw8822c_dac_iq_offset(rtwdev, qv, q_value); 3602774f206SBjoern A. Zeeb } 3612774f206SBjoern A. Zeeb 3622774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev, 3632774f206SBjoern A. Zeeb u32 *i_value, u32 *q_value) 3642774f206SBjoern A. Zeeb { 3652774f206SBjoern A. Zeeb u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C]; 3662774f206SBjoern A. Zeeb u32 rf_a, rf_b; 3672774f206SBjoern A. Zeeb 3682774f206SBjoern A. Zeeb rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK); 3692774f206SBjoern A. Zeeb rf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK); 3702774f206SBjoern A. Zeeb 3712774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-A=0x%05x\n", rf_a); 3722774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-B=0x%05x\n", rf_b); 3732774f206SBjoern A. Zeeb 3742774f206SBjoern A. Zeeb rtw8822c_dac_cal_iq_sample(rtwdev, iv, qv); 3752774f206SBjoern A. Zeeb rtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value); 3762774f206SBjoern A. Zeeb } 3772774f206SBjoern A. Zeeb 3782774f206SBjoern A. Zeeb static void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev) 3792774f206SBjoern A. Zeeb { 3802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1d58, 0xff8, 0x1ff); 3812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1a00, 0x3, 0x2); 3822774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1a14, 0x300, 0x3); 3832774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1d70, 0x7e7e7e7e); 3842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x180c, 0x3, 0x0); 3852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x410c, 0x3, 0x0); 3862774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b00, 0x00000008); 3872774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1bcc, 0x3f); 3882774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b00, 0x0000000a); 3892774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1bcc, 0x3f); 3902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1e24, BIT(31), 0x0); 3912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1e28, 0xf, 0x3); 3922774f206SBjoern A. Zeeb } 3932774f206SBjoern A. Zeeb 3942774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, 3952774f206SBjoern A. Zeeb u8 path, u32 *adc_ic, u32 *adc_qc) 3962774f206SBjoern A. Zeeb { 3972774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 3982774f206SBjoern A. Zeeb u32 ic = 0, qc = 0, temp = 0; 3992774f206SBjoern A. Zeeb u32 base_addr; 4002774f206SBjoern A. Zeeb u32 path_sel; 4012774f206SBjoern A. Zeeb int i; 4022774f206SBjoern A. Zeeb 4032774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK path(%d)\n", path); 4042774f206SBjoern A. Zeeb 4052774f206SBjoern A. Zeeb base_addr = rtw8822c_get_path_write_addr(path); 4062774f206SBjoern A. Zeeb switch (path) { 4072774f206SBjoern A. Zeeb case RF_PATH_A: 4082774f206SBjoern A. Zeeb path_sel = 0xa0000; 4092774f206SBjoern A. Zeeb break; 4102774f206SBjoern A. Zeeb case RF_PATH_B: 4112774f206SBjoern A. Zeeb path_sel = 0x80000; 4122774f206SBjoern A. Zeeb break; 4132774f206SBjoern A. Zeeb default: 4142774f206SBjoern A. Zeeb WARN_ON(1); 4152774f206SBjoern A. Zeeb return; 4162774f206SBjoern A. Zeeb } 4172774f206SBjoern A. Zeeb 4182774f206SBjoern A. Zeeb /* ADCK step1 */ 4192774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x0); 4202774f206SBjoern A. Zeeb if (path == RF_PATH_B) 4212774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x30, 0x30db8041); 4222774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); 4232774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 4242774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02dd08c4); 4252774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); 4262774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK, 0x10000); 4272774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK, 0x10000); 4282774f206SBjoern A. Zeeb for (i = 0; i < 10; i++) { 4292774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK count=%d\n", i); 4302774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8003); 4312774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c24, 0x00010002); 4322774f206SBjoern A. Zeeb rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 4332774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 4342774f206SBjoern A. Zeeb "[DACK] before: i=0x%x, q=0x%x\n", ic, qc); 4352774f206SBjoern A. Zeeb 4362774f206SBjoern A. Zeeb /* compensation value */ 4372774f206SBjoern A. Zeeb if (ic != 0x0) { 4382774f206SBjoern A. Zeeb ic = 0x400 - ic; 4392774f206SBjoern A. Zeeb *adc_ic = ic; 4402774f206SBjoern A. Zeeb } 4412774f206SBjoern A. Zeeb if (qc != 0x0) { 4422774f206SBjoern A. Zeeb qc = 0x400 - qc; 4432774f206SBjoern A. Zeeb *adc_qc = qc; 4442774f206SBjoern A. Zeeb } 4452774f206SBjoern A. Zeeb temp = (ic & 0x3ff) | ((qc & 0x3ff) << 10); 4462774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x68, temp); 4472774f206SBjoern A. Zeeb dm_info->dack_adck[path] = temp; 4482774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK 0x%08x=0x08%x\n", 4492774f206SBjoern A. Zeeb base_addr + 0x68, temp); 4502774f206SBjoern A. Zeeb /* check ADC DC offset */ 4512774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103); 4522774f206SBjoern A. Zeeb rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 4532774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 4542774f206SBjoern A. Zeeb "[DACK] after: i=0x%08x, q=0x%08x\n", ic, qc); 4552774f206SBjoern A. Zeeb if (ic >= 0x200) 4562774f206SBjoern A. Zeeb ic = 0x400 - ic; 4572774f206SBjoern A. Zeeb if (qc >= 0x200) 4582774f206SBjoern A. Zeeb qc = 0x400 - qc; 4592774f206SBjoern A. Zeeb if (ic < 5 && qc < 5) 4602774f206SBjoern A. Zeeb break; 4612774f206SBjoern A. Zeeb } 4622774f206SBjoern A. Zeeb 4632774f206SBjoern A. Zeeb /* ADCK step2 */ 4642774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c3c, 0x00000003); 4652774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); 4662774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); 4672774f206SBjoern A. Zeeb 4682774f206SBjoern A. Zeeb /* release pull low switch on IQ path */ 4692774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0x8f, BIT(13), 0x1); 4702774f206SBjoern A. Zeeb } 4712774f206SBjoern A. Zeeb 4722774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path) 4732774f206SBjoern A. Zeeb { 4742774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 4752774f206SBjoern A. Zeeb u32 base_addr; 4762774f206SBjoern A. Zeeb u32 read_addr; 4772774f206SBjoern A. Zeeb 4782774f206SBjoern A. Zeeb base_addr = rtw8822c_get_path_write_addr(path); 4792774f206SBjoern A. Zeeb read_addr = rtw8822c_get_path_read_addr(path); 4802774f206SBjoern A. Zeeb 4812774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x68, dm_info->dack_adck[path]); 4822774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 4832774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 4842774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); 4852774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c38, 0xffffffff); 4862774f206SBjoern A. Zeeb } 4872774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 4882774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 4892774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); 4902774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff81); 4912774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); 4922774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); 4932774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xd8, 0x0008ff81); 4942774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); 4952774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); 4962774f206SBjoern A. Zeeb mdelay(2); 4972774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xbc, 0x000aff8d); 4982774f206SBjoern A. Zeeb mdelay(2); 4992774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); 5002774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); 5012774f206SBjoern A. Zeeb mdelay(1); 5022774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); 5032774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); 5042774f206SBjoern A. Zeeb mdelay(20); 5052774f206SBjoern A. Zeeb if (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) || 5062774f206SBjoern A. Zeeb !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff)) 5072774f206SBjoern A. Zeeb rtw_err(rtwdev, "failed to wait for dack ready\n"); 5082774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); 5092774f206SBjoern A. Zeeb mdelay(1); 5102774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); 5112774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb6db600); 5122774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 5132774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); 5142774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); 5152774f206SBjoern A. Zeeb } 5162774f206SBjoern A. Zeeb 5172774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev, 5182774f206SBjoern A. Zeeb u8 path, u32 *ic_out, u32 *qc_out) 5192774f206SBjoern A. Zeeb { 5202774f206SBjoern A. Zeeb u32 base_addr; 5212774f206SBjoern A. Zeeb u32 ic, qc, ic_in, qc_in; 5222774f206SBjoern A. Zeeb 5232774f206SBjoern A. Zeeb base_addr = rtw8822c_get_path_write_addr(path); 5242774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0); 5252774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, 0x8); 5262774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, 0x0); 5272774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, 0x8); 5282774f206SBjoern A. Zeeb 5292774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b00, 0x00000008); 5302774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1bcc, 0x03f); 5312774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 5322774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 5332774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1c3c, 0x00088103); 5342774f206SBjoern A. Zeeb 5352774f206SBjoern A. Zeeb rtw8822c_dac_cal_rf_mode(rtwdev, &ic_in, &qc_in); 5362774f206SBjoern A. Zeeb ic = ic_in; 5372774f206SBjoern A. Zeeb qc = qc_in; 5382774f206SBjoern A. Zeeb 5392774f206SBjoern A. Zeeb /* compensation value */ 5402774f206SBjoern A. Zeeb if (ic != 0x0) 5412774f206SBjoern A. Zeeb ic = 0x400 - ic; 5422774f206SBjoern A. Zeeb if (qc != 0x0) 5432774f206SBjoern A. Zeeb qc = 0x400 - qc; 5442774f206SBjoern A. Zeeb if (ic < 0x300) { 5452774f206SBjoern A. Zeeb ic = ic * 2 * 6 / 5; 5462774f206SBjoern A. Zeeb ic = ic + 0x80; 5472774f206SBjoern A. Zeeb } else { 5482774f206SBjoern A. Zeeb ic = (0x400 - ic) * 2 * 6 / 5; 5492774f206SBjoern A. Zeeb ic = 0x7f - ic; 5502774f206SBjoern A. Zeeb } 5512774f206SBjoern A. Zeeb if (qc < 0x300) { 5522774f206SBjoern A. Zeeb qc = qc * 2 * 6 / 5; 5532774f206SBjoern A. Zeeb qc = qc + 0x80; 5542774f206SBjoern A. Zeeb } else { 5552774f206SBjoern A. Zeeb qc = (0x400 - qc) * 2 * 6 / 5; 5562774f206SBjoern A. Zeeb qc = 0x7f - qc; 5572774f206SBjoern A. Zeeb } 5582774f206SBjoern A. Zeeb 5592774f206SBjoern A. Zeeb *ic_out = ic; 5602774f206SBjoern A. Zeeb *qc_out = qc; 5612774f206SBjoern A. Zeeb 5622774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] before i=0x%x, q=0x%x\n", ic_in, qc_in); 5632774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] after i=0x%x, q=0x%x\n", ic, qc); 5642774f206SBjoern A. Zeeb } 5652774f206SBjoern A. Zeeb 5662774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, 5672774f206SBjoern A. Zeeb u32 adc_ic, u32 adc_qc, 5682774f206SBjoern A. Zeeb u32 *ic_in, u32 *qc_in, 5692774f206SBjoern A. Zeeb u32 *i_out, u32 *q_out) 5702774f206SBjoern A. Zeeb { 5712774f206SBjoern A. Zeeb u32 base_addr; 5722774f206SBjoern A. Zeeb u32 read_addr; 5732774f206SBjoern A. Zeeb u32 ic, qc; 5742774f206SBjoern A. Zeeb u32 temp; 5752774f206SBjoern A. Zeeb 5762774f206SBjoern A. Zeeb base_addr = rtw8822c_get_path_write_addr(path); 5772774f206SBjoern A. Zeeb read_addr = rtw8822c_get_path_read_addr(path); 5782774f206SBjoern A. Zeeb ic = *ic_in; 5792774f206SBjoern A. Zeeb qc = *qc_in; 5802774f206SBjoern A. Zeeb 5812774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 5822774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 5832774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 5842774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); 5852774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xbc, 0xc008ff81); 5862774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); 5872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, ic & 0xf); 5882774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, (ic & 0xf0) >> 4); 5892774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); 5902774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xd8, 0xe008ff81); 5912774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); 5922774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, qc & 0xf); 5932774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, (qc & 0xf0) >> 4); 5942774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); 5952774f206SBjoern A. Zeeb mdelay(2); 5962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x6); 5972774f206SBjoern A. Zeeb mdelay(2); 5982774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); 5992774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); 6002774f206SBjoern A. Zeeb mdelay(1); 6012774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); 6022774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); 6032774f206SBjoern A. Zeeb mdelay(20); 6042774f206SBjoern A. Zeeb if (!check_hw_ready(rtwdev, read_addr + 0x24, 0x07f80000, ic) || 6052774f206SBjoern A. Zeeb !check_hw_ready(rtwdev, read_addr + 0x50, 0x07f80000, qc)) 6062774f206SBjoern A. Zeeb rtw_err(rtwdev, "failed to write IQ vector to hardware\n"); 6072774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); 6082774f206SBjoern A. Zeeb mdelay(1); 6092774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x3); 6102774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb6db600); 6112774f206SBjoern A. Zeeb 6122774f206SBjoern A. Zeeb /* check DAC DC offset */ 6132774f206SBjoern A. Zeeb temp = ((adc_ic + 0x10) & 0x3ff) | (((adc_qc + 0x10) & 0x3ff) << 10); 6142774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x68, temp); 6152774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 6162774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); 6172774f206SBjoern A. Zeeb rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 6182774f206SBjoern A. Zeeb if (ic >= 0x10) 6192774f206SBjoern A. Zeeb ic = ic - 0x10; 6202774f206SBjoern A. Zeeb else 6212774f206SBjoern A. Zeeb ic = 0x400 - (0x10 - ic); 6222774f206SBjoern A. Zeeb 6232774f206SBjoern A. Zeeb if (qc >= 0x10) 6242774f206SBjoern A. Zeeb qc = qc - 0x10; 6252774f206SBjoern A. Zeeb else 6262774f206SBjoern A. Zeeb qc = 0x400 - (0x10 - qc); 6272774f206SBjoern A. Zeeb 6282774f206SBjoern A. Zeeb *i_out = ic; 6292774f206SBjoern A. Zeeb *q_out = qc; 6302774f206SBjoern A. Zeeb 6312774f206SBjoern A. Zeeb if (ic >= 0x200) 6322774f206SBjoern A. Zeeb ic = 0x400 - ic; 6332774f206SBjoern A. Zeeb if (qc >= 0x200) 6342774f206SBjoern A. Zeeb qc = 0x400 - qc; 6352774f206SBjoern A. Zeeb 6362774f206SBjoern A. Zeeb *ic_in = ic; 6372774f206SBjoern A. Zeeb *qc_in = qc; 6382774f206SBjoern A. Zeeb 6392774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 6402774f206SBjoern A. Zeeb "[DACK] after DACK i=0x%x, q=0x%x\n", *i_out, *q_out); 6412774f206SBjoern A. Zeeb } 6422774f206SBjoern A. Zeeb 6432774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path) 6442774f206SBjoern A. Zeeb { 6452774f206SBjoern A. Zeeb u32 base_addr = rtw8822c_get_path_write_addr(path); 6462774f206SBjoern A. Zeeb 6472774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x68, 0x0); 6482774f206SBjoern A. Zeeb rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); 6492774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0xbc, 0x1, 0x0); 6502774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x1); 6512774f206SBjoern A. Zeeb } 6522774f206SBjoern A. Zeeb 6532774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev, 6542774f206SBjoern A. Zeeb u8 path, u8 vec, u32 w_addr, u32 r_addr) 6552774f206SBjoern A. Zeeb { 6562774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6572774f206SBjoern A. Zeeb u16 val; 6582774f206SBjoern A. Zeeb u32 i; 6592774f206SBjoern A. Zeeb 6602774f206SBjoern A. Zeeb if (WARN_ON(vec >= 2)) 6612774f206SBjoern A. Zeeb return; 6622774f206SBjoern A. Zeeb 6632774f206SBjoern A. Zeeb for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 6642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_addr, 0xf0000000, i); 6652774f206SBjoern A. Zeeb val = (u16)rtw_read32_mask(rtwdev, r_addr, 0x7fc0000); 6662774f206SBjoern A. Zeeb dm_info->dack_msbk[path][vec][i] = val; 6672774f206SBjoern A. Zeeb } 6682774f206SBjoern A. Zeeb } 6692774f206SBjoern A. Zeeb 6702774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path) 6712774f206SBjoern A. Zeeb { 6722774f206SBjoern A. Zeeb u32 w_off = 0x1c; 6732774f206SBjoern A. Zeeb u32 r_off = 0x2c; 6742774f206SBjoern A. Zeeb u32 w_addr, r_addr; 6752774f206SBjoern A. Zeeb 6762774f206SBjoern A. Zeeb if (WARN_ON(path >= 2)) 6772774f206SBjoern A. Zeeb return; 6782774f206SBjoern A. Zeeb 6792774f206SBjoern A. Zeeb /* backup I vector */ 6802774f206SBjoern A. Zeeb w_addr = rtw8822c_get_path_write_addr(path) + 0xb0; 6812774f206SBjoern A. Zeeb r_addr = rtw8822c_get_path_read_addr(path) + 0x10; 6822774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr); 6832774f206SBjoern A. Zeeb 6842774f206SBjoern A. Zeeb /* backup Q vector */ 6852774f206SBjoern A. Zeeb w_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; 6862774f206SBjoern A. Zeeb r_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off; 6872774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr); 6882774f206SBjoern A. Zeeb } 6892774f206SBjoern A. Zeeb 6902774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev) 6912774f206SBjoern A. Zeeb { 6922774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6932774f206SBjoern A. Zeeb u8 val; 6942774f206SBjoern A. Zeeb 6952774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000); 6962774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_A][0][0] = val; 6972774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_1, 0xf); 6982774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_A][0][1] = val; 6992774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000); 7002774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_A][1][0] = val; 7012774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_1, 0xf); 7022774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_A][1][1] = val; 7032774f206SBjoern A. Zeeb 7042774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000); 7052774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_B][0][0] = val; 7062774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_1, 0xf); 7072774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_B][1][0] = val; 7082774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000); 7092774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_B][0][1] = val; 7102774f206SBjoern A. Zeeb val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_1, 0xf); 7112774f206SBjoern A. Zeeb dm_info->dack_dck[RF_PATH_B][1][1] = val; 7122774f206SBjoern A. Zeeb } 7132774f206SBjoern A. Zeeb 7142774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev) 7152774f206SBjoern A. Zeeb { 7162774f206SBjoern A. Zeeb u32 temp[3]; 7172774f206SBjoern A. Zeeb 7182774f206SBjoern A. Zeeb temp[0] = rtw_read32(rtwdev, 0x1860); 7192774f206SBjoern A. Zeeb temp[1] = rtw_read32(rtwdev, 0x4160); 7202774f206SBjoern A. Zeeb temp[2] = rtw_read32(rtwdev, 0x9b4); 7212774f206SBjoern A. Zeeb 7222774f206SBjoern A. Zeeb /* set clock */ 7232774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 7242774f206SBjoern A. Zeeb 7252774f206SBjoern A. Zeeb /* backup path-A I/Q */ 7262774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, 0x1830, BIT(30)); 7272774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); 7282774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A); 7292774f206SBjoern A. Zeeb 7302774f206SBjoern A. Zeeb /* backup path-B I/Q */ 7312774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, 0x4130, BIT(30)); 7322774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); 7332774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B); 7342774f206SBjoern A. Zeeb 7352774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup_dck(rtwdev); 7362774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, 0x1830, BIT(30)); 7372774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, 0x4130, BIT(30)); 7382774f206SBjoern A. Zeeb 7392774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1860, temp[0]); 7402774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x4160, temp[1]); 7412774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, temp[2]); 7422774f206SBjoern A. Zeeb } 7432774f206SBjoern A. Zeeb 7442774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev) 7452774f206SBjoern A. Zeeb { 7462774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 7472774f206SBjoern A. Zeeb u8 val; 7482774f206SBjoern A. Zeeb 7492774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_DCKA_I_0, BIT(19)); 7502774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_A][0][0]; 7512774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000, val); 7522774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_A][0][1]; 7532774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKA_I_1, 0xf, val); 7542774f206SBjoern A. Zeeb 7552774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_DCKA_Q_0, BIT(19)); 7562774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_A][1][0]; 7572774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000, val); 7582774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_A][1][1]; 7592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKA_Q_1, 0xf, val); 7602774f206SBjoern A. Zeeb 7612774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_DCKB_I_0, BIT(19)); 7622774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_B][0][0]; 7632774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000, val); 7642774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_B][0][1]; 7652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKB_I_1, 0xf, val); 7662774f206SBjoern A. Zeeb 7672774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_DCKB_Q_0, BIT(19)); 7682774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_B][1][0]; 7692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000, val); 7702774f206SBjoern A. Zeeb val = dm_info->dack_dck[RF_PATH_B][1][1]; 7712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DCKB_Q_1, 0xf, val); 7722774f206SBjoern A. Zeeb } 7732774f206SBjoern A. Zeeb 7742774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev) 7752774f206SBjoern A. Zeeb { 7762774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 7772774f206SBjoern A. Zeeb 7782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x0); 7792774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x0); 7802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x0); 7812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x0); 7822774f206SBjoern A. Zeeb 7832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x0); 7842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); 7852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b4, BIT(0), 0x1); 7862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18d0, BIT(0), 0x1); 7872774f206SBjoern A. Zeeb 7882774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x0); 7892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); 7902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b4, BIT(0), 0x1); 7912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41d0, BIT(0), 0x1); 7922774f206SBjoern A. Zeeb 7932774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b0, 0xf00, 0x0); 7942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18c0, BIT(14), 0x0); 7952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18cc, 0xf00, 0x0); 7962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18dc, BIT(14), 0x0); 7972774f206SBjoern A. Zeeb 7982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x0); 7992774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x0); 8002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x1); 8012774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x1); 8022774f206SBjoern A. Zeeb 8032774f206SBjoern A. Zeeb rtw8822c_dac_cal_restore_dck(rtwdev); 8042774f206SBjoern A. Zeeb 8052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18c0, 0x38000, 0x7); 8062774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18dc, 0x38000, 0x7); 8072774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41c0, 0x38000, 0x7); 8082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41dc, 0x38000, 0x7); 8092774f206SBjoern A. Zeeb 8102774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b8, BIT(26) | BIT(25), 0x1); 8112774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18d4, BIT(26) | BIT(25), 0x1); 8122774f206SBjoern A. Zeeb 8132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b0, 0xf00, 0x0); 8142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41c0, BIT(14), 0x0); 8152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41cc, 0xf00, 0x0); 8162774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41dc, BIT(14), 0x0); 8172774f206SBjoern A. Zeeb 8182774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x0); 8192774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x0); 8202774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x1); 8212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x1); 8222774f206SBjoern A. Zeeb 8232774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b8, BIT(26) | BIT(25), 0x1); 8242774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41d4, BIT(26) | BIT(25), 0x1); 8252774f206SBjoern A. Zeeb } 8262774f206SBjoern A. Zeeb 8272774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev, 8282774f206SBjoern A. Zeeb u32 target_addr, u32 toggle_addr) 8292774f206SBjoern A. Zeeb { 8302774f206SBjoern A. Zeeb u32 cnt = 0; 8312774f206SBjoern A. Zeeb 8322774f206SBjoern A. Zeeb do { 8332774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x0); 8342774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x2); 8352774f206SBjoern A. Zeeb 8362774f206SBjoern A. Zeeb if (rtw_read32_mask(rtwdev, target_addr, 0xf) == 0x6) 8372774f206SBjoern A. Zeeb return true; 8382774f206SBjoern A. Zeeb 8392774f206SBjoern A. Zeeb } while (cnt++ < 100); 8402774f206SBjoern A. Zeeb 8412774f206SBjoern A. Zeeb return false; 8422774f206SBjoern A. Zeeb } 8432774f206SBjoern A. Zeeb 8442774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path) 8452774f206SBjoern A. Zeeb { 8462774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 8472774f206SBjoern A. Zeeb u32 w_off = 0x1c; 8482774f206SBjoern A. Zeeb u32 r_off = 0x2c; 8492774f206SBjoern A. Zeeb u32 w_i, r_i, w_q, r_q; 8502774f206SBjoern A. Zeeb u32 value; 8512774f206SBjoern A. Zeeb u32 i; 8522774f206SBjoern A. Zeeb 8532774f206SBjoern A. Zeeb w_i = rtw8822c_get_path_write_addr(path) + 0xb0; 8542774f206SBjoern A. Zeeb r_i = rtw8822c_get_path_read_addr(path) + 0x08; 8552774f206SBjoern A. Zeeb w_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; 8562774f206SBjoern A. Zeeb r_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off; 8572774f206SBjoern A. Zeeb 8582774f206SBjoern A. Zeeb if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8)) 8592774f206SBjoern A. Zeeb return false; 8602774f206SBjoern A. Zeeb 8612774f206SBjoern A. Zeeb for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 8622774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); 8632774f206SBjoern A. Zeeb value = dm_info->dack_msbk[path][0][i]; 8642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x4, 0xff8, value); 8652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i, 0xf0000000, i); 8662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x1); 8672774f206SBjoern A. Zeeb } 8682774f206SBjoern A. Zeeb 8692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); 8702774f206SBjoern A. Zeeb 8712774f206SBjoern A. Zeeb if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8)) 8722774f206SBjoern A. Zeeb return false; 8732774f206SBjoern A. Zeeb 8742774f206SBjoern A. Zeeb for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 8752774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); 8762774f206SBjoern A. Zeeb value = dm_info->dack_msbk[path][1][i]; 8772774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x4, 0xff8, value); 8782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q, 0xf0000000, i); 8792774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x1); 8802774f206SBjoern A. Zeeb } 8812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); 8822774f206SBjoern A. Zeeb 8832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x8, BIT(26) | BIT(25), 0x0); 8842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x8, BIT(26) | BIT(25), 0x0); 8852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_i + 0x4, BIT(0), 0x0); 8862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, w_q + 0x4, BIT(0), 0x0); 8872774f206SBjoern A. Zeeb 8882774f206SBjoern A. Zeeb return true; 8892774f206SBjoern A. Zeeb } 8902774f206SBjoern A. Zeeb 8912774f206SBjoern A. Zeeb static bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) 8922774f206SBjoern A. Zeeb { 8932774f206SBjoern A. Zeeb if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A)) 8942774f206SBjoern A. Zeeb return false; 8952774f206SBjoern A. Zeeb 8962774f206SBjoern A. Zeeb if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B)) 8972774f206SBjoern A. Zeeb return false; 8982774f206SBjoern A. Zeeb 8992774f206SBjoern A. Zeeb return true; 9002774f206SBjoern A. Zeeb } 9012774f206SBjoern A. Zeeb 9022774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) 9032774f206SBjoern A. Zeeb { 9042774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 9052774f206SBjoern A. Zeeb u32 temp[3]; 9062774f206SBjoern A. Zeeb 9072774f206SBjoern A. Zeeb /* sample the first element for both path's IQ vector */ 9082774f206SBjoern A. Zeeb if (dm_info->dack_msbk[RF_PATH_A][0][0] == 0 && 9092774f206SBjoern A. Zeeb dm_info->dack_msbk[RF_PATH_A][1][0] == 0 && 9102774f206SBjoern A. Zeeb dm_info->dack_msbk[RF_PATH_B][0][0] == 0 && 9112774f206SBjoern A. Zeeb dm_info->dack_msbk[RF_PATH_B][1][0] == 0) 9122774f206SBjoern A. Zeeb return false; 9132774f206SBjoern A. Zeeb 9142774f206SBjoern A. Zeeb temp[0] = rtw_read32(rtwdev, 0x1860); 9152774f206SBjoern A. Zeeb temp[1] = rtw_read32(rtwdev, 0x4160); 9162774f206SBjoern A. Zeeb temp[2] = rtw_read32(rtwdev, 0x9b4); 9172774f206SBjoern A. Zeeb 9182774f206SBjoern A. Zeeb rtw8822c_dac_cal_restore_prepare(rtwdev); 9192774f206SBjoern A. Zeeb if (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) || 9202774f206SBjoern A. Zeeb !check_hw_ready(rtwdev, 0x2834, 0x7fff80, 0xffff) || 9212774f206SBjoern A. Zeeb !check_hw_ready(rtwdev, 0x4508, 0x7fff80, 0xffff) || 9222774f206SBjoern A. Zeeb !check_hw_ready(rtwdev, 0x4534, 0x7fff80, 0xffff)) 9232774f206SBjoern A. Zeeb return false; 9242774f206SBjoern A. Zeeb 9252774f206SBjoern A. Zeeb if (!__rtw8822c_dac_cal_restore(rtwdev)) { 9262774f206SBjoern A. Zeeb rtw_err(rtwdev, "failed to restore dack vectors\n"); 9272774f206SBjoern A. Zeeb return false; 9282774f206SBjoern A. Zeeb } 9292774f206SBjoern A. Zeeb 9302774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x1); 9312774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); 9322774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1860, temp[0]); 9332774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x4160, temp[1]); 9342774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x1); 9352774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x1); 9362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x1); 9372774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x1); 9382774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x9b4, temp[2]); 9392774f206SBjoern A. Zeeb 9402774f206SBjoern A. Zeeb return true; 9412774f206SBjoern A. Zeeb } 9422774f206SBjoern A. Zeeb 9432774f206SBjoern A. Zeeb static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) 9442774f206SBjoern A. Zeeb { 9452774f206SBjoern A. Zeeb struct rtw_backup_info backup_rf[DACK_RF_8822C * DACK_PATH_8822C]; 9462774f206SBjoern A. Zeeb struct rtw_backup_info backup[DACK_REG_8822C]; 9472774f206SBjoern A. Zeeb u32 ic = 0, qc = 0, i; 9482774f206SBjoern A. Zeeb u32 i_a = 0x0, q_a = 0x0, i_b = 0x0, q_b = 0x0; 9492774f206SBjoern A. Zeeb u32 ic_a = 0x0, qc_a = 0x0, ic_b = 0x0, qc_b = 0x0; 9502774f206SBjoern A. Zeeb u32 adc_ic_a = 0x0, adc_qc_a = 0x0, adc_ic_b = 0x0, adc_qc_b = 0x0; 9512774f206SBjoern A. Zeeb 9522774f206SBjoern A. Zeeb if (rtw8822c_dac_cal_restore(rtwdev)) 9532774f206SBjoern A. Zeeb return; 9542774f206SBjoern A. Zeeb 9552774f206SBjoern A. Zeeb /* not able to restore, do it */ 9562774f206SBjoern A. Zeeb 9572774f206SBjoern A. Zeeb rtw8822c_dac_backup_reg(rtwdev, backup, backup_rf); 9582774f206SBjoern A. Zeeb 9592774f206SBjoern A. Zeeb rtw8822c_dac_bb_setting(rtwdev); 9602774f206SBjoern A. Zeeb 9612774f206SBjoern A. Zeeb /* path-A */ 9622774f206SBjoern A. Zeeb rtw8822c_dac_cal_adc(rtwdev, RF_PATH_A, &adc_ic_a, &adc_qc_a); 9632774f206SBjoern A. Zeeb for (i = 0; i < 10; i++) { 9642774f206SBjoern A. Zeeb rtw8822c_dac_cal_step1(rtwdev, RF_PATH_A); 9652774f206SBjoern A. Zeeb rtw8822c_dac_cal_step2(rtwdev, RF_PATH_A, &ic, &qc); 9662774f206SBjoern A. Zeeb ic_a = ic; 9672774f206SBjoern A. Zeeb qc_a = qc; 9682774f206SBjoern A. Zeeb 9692774f206SBjoern A. Zeeb rtw8822c_dac_cal_step3(rtwdev, RF_PATH_A, adc_ic_a, adc_qc_a, 9702774f206SBjoern A. Zeeb &ic, &qc, &i_a, &q_a); 9712774f206SBjoern A. Zeeb 9722774f206SBjoern A. Zeeb if (ic < 5 && qc < 5) 9732774f206SBjoern A. Zeeb break; 9742774f206SBjoern A. Zeeb } 9752774f206SBjoern A. Zeeb rtw8822c_dac_cal_step4(rtwdev, RF_PATH_A); 9762774f206SBjoern A. Zeeb 9772774f206SBjoern A. Zeeb /* path-B */ 9782774f206SBjoern A. Zeeb rtw8822c_dac_cal_adc(rtwdev, RF_PATH_B, &adc_ic_b, &adc_qc_b); 9792774f206SBjoern A. Zeeb for (i = 0; i < 10; i++) { 9802774f206SBjoern A. Zeeb rtw8822c_dac_cal_step1(rtwdev, RF_PATH_B); 9812774f206SBjoern A. Zeeb rtw8822c_dac_cal_step2(rtwdev, RF_PATH_B, &ic, &qc); 9822774f206SBjoern A. Zeeb ic_b = ic; 9832774f206SBjoern A. Zeeb qc_b = qc; 9842774f206SBjoern A. Zeeb 9852774f206SBjoern A. Zeeb rtw8822c_dac_cal_step3(rtwdev, RF_PATH_B, adc_ic_b, adc_qc_b, 9862774f206SBjoern A. Zeeb &ic, &qc, &i_b, &q_b); 9872774f206SBjoern A. Zeeb 9882774f206SBjoern A. Zeeb if (ic < 5 && qc < 5) 9892774f206SBjoern A. Zeeb break; 9902774f206SBjoern A. Zeeb } 9912774f206SBjoern A. Zeeb rtw8822c_dac_cal_step4(rtwdev, RF_PATH_B); 9922774f206SBjoern A. Zeeb 9932774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b00, 0x00000008); 9942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); 9952774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1bcc, 0x0); 9962774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b00, 0x0000000a); 9972774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1bcc, 0x0); 9982774f206SBjoern A. Zeeb 9992774f206SBjoern A. Zeeb rtw8822c_dac_restore_reg(rtwdev, backup, backup_rf); 10002774f206SBjoern A. Zeeb 10012774f206SBjoern A. Zeeb /* backup results to restore, saving a lot of time */ 10022774f206SBjoern A. Zeeb rtw8822c_dac_cal_backup(rtwdev); 10032774f206SBjoern A. Zeeb 10042774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: ic=0x%x, qc=0x%x\n", ic_a, qc_a); 10052774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: ic=0x%x, qc=0x%x\n", ic_b, qc_b); 10062774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: i=0x%x, q=0x%x\n", i_a, q_a); 10072774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: i=0x%x, q=0x%x\n", i_b, q_b); 10082774f206SBjoern A. Zeeb } 10092774f206SBjoern A. Zeeb 10102774f206SBjoern A. Zeeb static void rtw8822c_rf_x2_check(struct rtw_dev *rtwdev) 10112774f206SBjoern A. Zeeb { 10122774f206SBjoern A. Zeeb u8 x2k_busy; 10132774f206SBjoern A. Zeeb 10142774f206SBjoern A. Zeeb mdelay(1); 10152774f206SBjoern A. Zeeb x2k_busy = rtw_read_rf(rtwdev, RF_PATH_A, 0xb8, BIT(15)); 10162774f206SBjoern A. Zeeb if (x2k_busy == 1) { 10172774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0xC4440); 10182774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0xba, RFREG_MASK, 0x6840D); 10192774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0x80440); 10202774f206SBjoern A. Zeeb mdelay(1); 10212774f206SBjoern A. Zeeb } 10222774f206SBjoern A. Zeeb } 10232774f206SBjoern A. Zeeb 10242774f206SBjoern A. Zeeb static void rtw8822c_set_power_trim(struct rtw_dev *rtwdev, s8 bb_gain[2][8]) 10252774f206SBjoern A. Zeeb { 10262774f206SBjoern A. Zeeb #define RF_SET_POWER_TRIM(_path, _seq, _idx) \ 10272774f206SBjoern A. Zeeb do { \ 10282774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, _path, 0x33, RFREG_MASK, _seq); \ 10292774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, _path, 0x3f, RFREG_MASK, \ 10302774f206SBjoern A. Zeeb bb_gain[_path][_idx]); \ 10312774f206SBjoern A. Zeeb } while (0) 10322774f206SBjoern A. Zeeb u8 path; 10332774f206SBjoern A. Zeeb 10342774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10352774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0xee, BIT(19), 1); 10362774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x0, 0); 10372774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x1, 1); 10382774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x2, 2); 10392774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x3, 2); 10402774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x4, 3); 10412774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x5, 4); 10422774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x6, 5); 10432774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x7, 6); 10442774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x8, 7); 10452774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0x9, 3); 10462774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0xa, 4); 10472774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0xb, 5); 10482774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0xc, 6); 10492774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0xd, 7); 10502774f206SBjoern A. Zeeb RF_SET_POWER_TRIM(path, 0xe, 7); 10512774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0xee, BIT(19), 0); 10522774f206SBjoern A. Zeeb } 10532774f206SBjoern A. Zeeb #undef RF_SET_POWER_TRIM 10542774f206SBjoern A. Zeeb } 10552774f206SBjoern A. Zeeb 10562774f206SBjoern A. Zeeb static void rtw8822c_power_trim(struct rtw_dev *rtwdev) 10572774f206SBjoern A. Zeeb { 10582774f206SBjoern A. Zeeb u8 pg_pwr = 0xff, i, path, idx; 10592774f206SBjoern A. Zeeb s8 bb_gain[2][8] = {}; 10602774f206SBjoern A. Zeeb u16 rf_efuse_2g[3] = {PPG_2GL_TXAB, PPG_2GM_TXAB, PPG_2GH_TXAB}; 10612774f206SBjoern A. Zeeb u16 rf_efuse_5g[2][5] = {{PPG_5GL1_TXA, PPG_5GL2_TXA, PPG_5GM1_TXA, 10622774f206SBjoern A. Zeeb PPG_5GM2_TXA, PPG_5GH1_TXA}, 10632774f206SBjoern A. Zeeb {PPG_5GL1_TXB, PPG_5GL2_TXB, PPG_5GM1_TXB, 10642774f206SBjoern A. Zeeb PPG_5GM2_TXB, PPG_5GH1_TXB} }; 10652774f206SBjoern A. Zeeb bool set = false; 10662774f206SBjoern A. Zeeb 10672774f206SBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(rf_efuse_2g); i++) { 10682774f206SBjoern A. Zeeb rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[i], &pg_pwr); 10692774f206SBjoern A. Zeeb if (pg_pwr == EFUSE_READ_FAIL) 10702774f206SBjoern A. Zeeb continue; 10712774f206SBjoern A. Zeeb set = true; 10722774f206SBjoern A. Zeeb bb_gain[RF_PATH_A][i] = FIELD_GET(PPG_2G_A_MASK, pg_pwr); 10732774f206SBjoern A. Zeeb bb_gain[RF_PATH_B][i] = FIELD_GET(PPG_2G_B_MASK, pg_pwr); 10742774f206SBjoern A. Zeeb } 10752774f206SBjoern A. Zeeb 10762774f206SBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(rf_efuse_5g[0]); i++) { 10772774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10782774f206SBjoern A. Zeeb rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path][i], 10792774f206SBjoern A. Zeeb &pg_pwr); 10802774f206SBjoern A. Zeeb if (pg_pwr == EFUSE_READ_FAIL) 10812774f206SBjoern A. Zeeb continue; 10822774f206SBjoern A. Zeeb set = true; 10832774f206SBjoern A. Zeeb idx = i + ARRAY_SIZE(rf_efuse_2g); 10842774f206SBjoern A. Zeeb bb_gain[path][idx] = FIELD_GET(PPG_5G_MASK, pg_pwr); 10852774f206SBjoern A. Zeeb } 10862774f206SBjoern A. Zeeb } 10872774f206SBjoern A. Zeeb if (set) 10882774f206SBjoern A. Zeeb rtw8822c_set_power_trim(rtwdev, bb_gain); 10892774f206SBjoern A. Zeeb 10902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); 10912774f206SBjoern A. Zeeb } 10922774f206SBjoern A. Zeeb 10932774f206SBjoern A. Zeeb static void rtw8822c_thermal_trim(struct rtw_dev *rtwdev) 10942774f206SBjoern A. Zeeb { 10952774f206SBjoern A. Zeeb u16 rf_efuse[2] = {PPG_THERMAL_A, PPG_THERMAL_B}; 10962774f206SBjoern A. Zeeb u8 pg_therm = 0xff, thermal[2] = {0}, path; 10972774f206SBjoern A. Zeeb 10982774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 10992774f206SBjoern A. Zeeb rtw_read8_physical_efuse(rtwdev, rf_efuse[path], &pg_therm); 11002774f206SBjoern A. Zeeb if (pg_therm == EFUSE_READ_FAIL) 11012774f206SBjoern A. Zeeb return; 11022774f206SBjoern A. Zeeb /* Efuse value of BIT(0) shall be move to BIT(3), and the value 11032774f206SBjoern A. Zeeb * of BIT(1) to BIT(3) should be right shifted 1 bit. 11042774f206SBjoern A. Zeeb */ 11052774f206SBjoern A. Zeeb thermal[path] = FIELD_GET(GENMASK(3, 1), pg_therm); 11062774f206SBjoern A. Zeeb thermal[path] |= FIELD_PREP(BIT(3), pg_therm & BIT(0)); 11072774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0x43, RF_THEMAL_MASK, thermal[path]); 11082774f206SBjoern A. Zeeb } 11092774f206SBjoern A. Zeeb } 11102774f206SBjoern A. Zeeb 11112774f206SBjoern A. Zeeb static void rtw8822c_pa_bias(struct rtw_dev *rtwdev) 11122774f206SBjoern A. Zeeb { 11132774f206SBjoern A. Zeeb u16 rf_efuse_2g[2] = {PPG_PABIAS_2GA, PPG_PABIAS_2GB}; 11142774f206SBjoern A. Zeeb u16 rf_efuse_5g[2] = {PPG_PABIAS_5GA, PPG_PABIAS_5GB}; 11152774f206SBjoern A. Zeeb u8 pg_pa_bias = 0xff, path; 11162774f206SBjoern A. Zeeb 11172774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 11182774f206SBjoern A. Zeeb rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[path], 11192774f206SBjoern A. Zeeb &pg_pa_bias); 11202774f206SBjoern A. Zeeb if (pg_pa_bias == EFUSE_READ_FAIL) 11212774f206SBjoern A. Zeeb return; 11222774f206SBjoern A. Zeeb pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); 11232774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_2G_MASK, pg_pa_bias); 11242774f206SBjoern A. Zeeb } 11252774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 11262774f206SBjoern A. Zeeb rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path], 11272774f206SBjoern A. Zeeb &pg_pa_bias); 11282774f206SBjoern A. Zeeb pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); 11292774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_5G_MASK, pg_pa_bias); 11302774f206SBjoern A. Zeeb } 11312774f206SBjoern A. Zeeb } 11322774f206SBjoern A. Zeeb 11332774f206SBjoern A. Zeeb static void rtw8822c_rfk_handshake(struct rtw_dev *rtwdev, bool is_before_k) 11342774f206SBjoern A. Zeeb { 11352774f206SBjoern A. Zeeb struct rtw_dm_info *dm = &rtwdev->dm_info; 11362774f206SBjoern A. Zeeb u8 u1b_tmp; 11372774f206SBjoern A. Zeeb u8 u4b_tmp; 11382774f206SBjoern A. Zeeb int ret; 11392774f206SBjoern A. Zeeb 11402774f206SBjoern A. Zeeb if (is_before_k) { 11412774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 11422774f206SBjoern A. Zeeb "[RFK] WiFi / BT RFK handshake start!!\n"); 11432774f206SBjoern A. Zeeb 11442774f206SBjoern A. Zeeb if (!dm->is_bt_iqk_timeout) { 11452774f206SBjoern A. Zeeb ret = read_poll_timeout(rtw_read32_mask, u4b_tmp, 11462774f206SBjoern A. Zeeb u4b_tmp == 0, 20, 600000, false, 11472774f206SBjoern A. Zeeb rtwdev, REG_PMC_DBG_CTRL1, 11482774f206SBjoern A. Zeeb BITS_PMC_BT_IQK_STS); 11492774f206SBjoern A. Zeeb if (ret) { 11502774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 11512774f206SBjoern A. Zeeb "[RFK] Wait BT IQK finish timeout!!\n"); 11522774f206SBjoern A. Zeeb dm->is_bt_iqk_timeout = true; 11532774f206SBjoern A. Zeeb } 11542774f206SBjoern A. Zeeb } 11552774f206SBjoern A. Zeeb 11562774f206SBjoern A. Zeeb rtw_fw_inform_rfk_status(rtwdev, true); 11572774f206SBjoern A. Zeeb 11582774f206SBjoern A. Zeeb ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, 11592774f206SBjoern A. Zeeb u1b_tmp == 1, 20, 100000, false, 11602774f206SBjoern A. Zeeb rtwdev, REG_ARFR4, BIT_WL_RFK); 11612774f206SBjoern A. Zeeb if (ret) 11622774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 11632774f206SBjoern A. Zeeb "[RFK] Send WiFi RFK start H2C cmd FAIL!!\n"); 11642774f206SBjoern A. Zeeb } else { 11652774f206SBjoern A. Zeeb rtw_fw_inform_rfk_status(rtwdev, false); 11662774f206SBjoern A. Zeeb ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, 11672774f206SBjoern A. Zeeb u1b_tmp == 1, 20, 100000, false, 11682774f206SBjoern A. Zeeb rtwdev, REG_ARFR4, 11692774f206SBjoern A. Zeeb BIT_WL_RFK); 11702774f206SBjoern A. Zeeb if (ret) 11712774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 11722774f206SBjoern A. Zeeb "[RFK] Send WiFi RFK finish H2C cmd FAIL!!\n"); 11732774f206SBjoern A. Zeeb 11742774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 11752774f206SBjoern A. Zeeb "[RFK] WiFi / BT RFK handshake finish!!\n"); 11762774f206SBjoern A. Zeeb } 11772774f206SBjoern A. Zeeb } 11782774f206SBjoern A. Zeeb 11792774f206SBjoern A. Zeeb static void rtw8822c_rfk_power_save(struct rtw_dev *rtwdev, 11802774f206SBjoern A. Zeeb bool is_power_save) 11812774f206SBjoern A. Zeeb { 11822774f206SBjoern A. Zeeb u8 path; 11832774f206SBjoern A. Zeeb 11842774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 11852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 11862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_PS_EN, 11872774f206SBjoern A. Zeeb is_power_save ? 0 : 1); 11882774f206SBjoern A. Zeeb } 11892774f206SBjoern A. Zeeb } 11902774f206SBjoern A. Zeeb 11912774f206SBjoern A. Zeeb static void rtw8822c_txgapk_backup_bb_reg(struct rtw_dev *rtwdev, const u32 reg[], 11922774f206SBjoern A. Zeeb u32 reg_backup[], u32 reg_num) 11932774f206SBjoern A. Zeeb { 11942774f206SBjoern A. Zeeb u32 i; 11952774f206SBjoern A. Zeeb 11962774f206SBjoern A. Zeeb for (i = 0; i < reg_num; i++) { 11972774f206SBjoern A. Zeeb reg_backup[i] = rtw_read32(rtwdev, reg[i]); 11982774f206SBjoern A. Zeeb 11992774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Backup BB 0x%x = 0x%x\n", 12002774f206SBjoern A. Zeeb reg[i], reg_backup[i]); 12012774f206SBjoern A. Zeeb } 12022774f206SBjoern A. Zeeb } 12032774f206SBjoern A. Zeeb 12042774f206SBjoern A. Zeeb static void rtw8822c_txgapk_reload_bb_reg(struct rtw_dev *rtwdev, 12052774f206SBjoern A. Zeeb const u32 reg[], u32 reg_backup[], 12062774f206SBjoern A. Zeeb u32 reg_num) 12072774f206SBjoern A. Zeeb { 12082774f206SBjoern A. Zeeb u32 i; 12092774f206SBjoern A. Zeeb 12102774f206SBjoern A. Zeeb for (i = 0; i < reg_num; i++) { 12112774f206SBjoern A. Zeeb rtw_write32(rtwdev, reg[i], reg_backup[i]); 12122774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Reload BB 0x%x = 0x%x\n", 12132774f206SBjoern A. Zeeb reg[i], reg_backup[i]); 12142774f206SBjoern A. Zeeb } 12152774f206SBjoern A. Zeeb } 12162774f206SBjoern A. Zeeb 12172774f206SBjoern A. Zeeb static bool check_rf_status(struct rtw_dev *rtwdev, u8 status) 12182774f206SBjoern A. Zeeb { 12192774f206SBjoern A. Zeeb u8 reg_rf0_a, reg_rf0_b; 12202774f206SBjoern A. Zeeb 12212774f206SBjoern A. Zeeb reg_rf0_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 12222774f206SBjoern A. Zeeb RF_MODE_TRXAGC, BIT_RF_MODE); 12232774f206SBjoern A. Zeeb reg_rf0_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 12242774f206SBjoern A. Zeeb RF_MODE_TRXAGC, BIT_RF_MODE); 12252774f206SBjoern A. Zeeb 12262774f206SBjoern A. Zeeb if (reg_rf0_a == status || reg_rf0_b == status) 12272774f206SBjoern A. Zeeb return false; 12282774f206SBjoern A. Zeeb 12292774f206SBjoern A. Zeeb return true; 12302774f206SBjoern A. Zeeb } 12312774f206SBjoern A. Zeeb 12322774f206SBjoern A. Zeeb static void rtw8822c_txgapk_tx_pause(struct rtw_dev *rtwdev) 12332774f206SBjoern A. Zeeb { 12342774f206SBjoern A. Zeeb bool status; 12352774f206SBjoern A. Zeeb int ret; 12362774f206SBjoern A. Zeeb 12372774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_TXPAUSE, BIT_AC_QUEUE); 12382774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TX_FIFO, BIT_STOP_TX, 0x2); 12392774f206SBjoern A. Zeeb 12402774f206SBjoern A. Zeeb ret = read_poll_timeout_atomic(check_rf_status, status, status, 12412774f206SBjoern A. Zeeb 2, 5000, false, rtwdev, 2); 12422774f206SBjoern A. Zeeb if (ret) 12432774f206SBjoern A. Zeeb rtw_warn(rtwdev, "failed to pause TX\n"); 12442774f206SBjoern A. Zeeb 12452774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Tx pause!!\n"); 12462774f206SBjoern A. Zeeb } 12472774f206SBjoern A. Zeeb 12482774f206SBjoern A. Zeeb static void rtw8822c_txgapk_bb_dpk(struct rtw_dev *rtwdev, u8 path) 12492774f206SBjoern A. Zeeb { 12502774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 12512774f206SBjoern A. Zeeb 12522774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENFN, BIT_IQK_DPK_EN, 0x1); 12532774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, 12542774f206SBjoern A. Zeeb BIT_IQK_DPK_CLOCK_SRC, 0x1); 12552774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, 12562774f206SBjoern A. Zeeb BIT_IQK_DPK_RESET_SRC, 0x1); 12572774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_EN_IOQ_IQK_DPK, 0x1); 12582774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_TST_IQK2SET_SRC, 0x0); 12592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x1ff); 12602774f206SBjoern A. Zeeb 12612774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 12622774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, 12632774f206SBjoern A. Zeeb BIT_RFTXEN_GCK_FORCE_ON, 0x1); 12642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x1); 12652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, 12662774f206SBjoern A. Zeeb BIT_TX_SCALE_0DB, 0x1); 12672774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x0); 12682774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 12692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, 12702774f206SBjoern A. Zeeb BIT_RFTXEN_GCK_FORCE_ON, 0x1); 12712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE2, 12722774f206SBjoern A. Zeeb BIT_DIS_SHARERX_TXGAT, 0x1); 12732774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, 12742774f206SBjoern A. Zeeb BIT_TX_SCALE_0DB, 0x1); 12752774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x0); 12762774f206SBjoern A. Zeeb } 12772774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x2); 12782774f206SBjoern A. Zeeb } 12792774f206SBjoern A. Zeeb 12802774f206SBjoern A. Zeeb static void rtw8822c_txgapk_afe_dpk(struct rtw_dev *rtwdev, u8 path) 12812774f206SBjoern A. Zeeb { 12822774f206SBjoern A. Zeeb u32 reg; 12832774f206SBjoern A. Zeeb 12842774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 12852774f206SBjoern A. Zeeb 12862774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 12872774f206SBjoern A. Zeeb reg = REG_ANAPAR_A; 12882774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 12892774f206SBjoern A. Zeeb reg = REG_ANAPAR_B; 12902774f206SBjoern A. Zeeb } else { 12912774f206SBjoern A. Zeeb rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); 12922774f206SBjoern A. Zeeb return; 12932774f206SBjoern A. Zeeb } 12942774f206SBjoern A. Zeeb 12952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, MASKDWORD); 12962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); 12972774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); 12982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x701f0001); 12992774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x702f0001); 13002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x703f0001); 13012774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x704f0001); 13022774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705f0001); 13032774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x706f0001); 13042774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707f0001); 13052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708f0001); 13062774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709f0001); 13072774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70af0001); 13082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bf0001); 13092774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cf0001); 13102774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70df0001); 13112774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ef0001); 13122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); 13132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); 13142774f206SBjoern A. Zeeb } 13152774f206SBjoern A. Zeeb 13162774f206SBjoern A. Zeeb static void rtw8822c_txgapk_afe_dpk_restore(struct rtw_dev *rtwdev, u8 path) 13172774f206SBjoern A. Zeeb { 13182774f206SBjoern A. Zeeb u32 reg; 13192774f206SBjoern A. Zeeb 13202774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 13212774f206SBjoern A. Zeeb 13222774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 13232774f206SBjoern A. Zeeb reg = REG_ANAPAR_A; 13242774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 13252774f206SBjoern A. Zeeb reg = REG_ANAPAR_B; 13262774f206SBjoern A. Zeeb } else { 13272774f206SBjoern A. Zeeb rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); 13282774f206SBjoern A. Zeeb return; 13292774f206SBjoern A. Zeeb } 13302774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, 0xffa1005e); 13312774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700b8041); 13322774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70144041); 13332774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70244041); 13342774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70344041); 13352774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70444041); 13362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705b8041); 13372774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70644041); 13382774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707b8041); 13392774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708b8041); 13402774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709b8041); 13412774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ab8041); 13422774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bb8041); 13432774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cb8041); 13442774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70db8041); 13452774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70eb8041); 13462774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70fb8041); 13472774f206SBjoern A. Zeeb } 13482774f206SBjoern A. Zeeb 13492774f206SBjoern A. Zeeb static void rtw8822c_txgapk_bb_dpk_restore(struct rtw_dev *rtwdev, u8 path) 13502774f206SBjoern A. Zeeb { 13512774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 13522774f206SBjoern A. Zeeb 13532774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x0); 13542774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TIA_BYPASS, 0x0); 13552774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TXBB, 0x0); 13562774f206SBjoern A. Zeeb 13572774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); 13582774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 13592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 13602774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); 13612774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x1); 13622774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 13632774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 13642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); 13652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); 13662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x0); 13672774f206SBjoern A. Zeeb 13682774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 13692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, 13702774f206SBjoern A. Zeeb BIT_RFTXEN_GCK_FORCE_ON, 0x0); 13712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x0); 13722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, 13732774f206SBjoern A. Zeeb BIT_TX_SCALE_0DB, 0x0); 13742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x3); 13752774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 13762774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, 13772774f206SBjoern A. Zeeb BIT_RFTXEN_GCK_FORCE_ON, 0x0); 13782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE2, 13792774f206SBjoern A. Zeeb BIT_DIS_SHARERX_TXGAT, 0x0); 13802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, 13812774f206SBjoern A. Zeeb BIT_TX_SCALE_0DB, 0x0); 13822774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x3); 13832774f206SBjoern A. Zeeb } 13842774f206SBjoern A. Zeeb 13852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x0); 13862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_CFIR_EN, 0x5); 13872774f206SBjoern A. Zeeb } 13882774f206SBjoern A. Zeeb 13892774f206SBjoern A. Zeeb static bool _rtw8822c_txgapk_gain_valid(struct rtw_dev *rtwdev, u32 gain) 13902774f206SBjoern A. Zeeb { 13912774f206SBjoern A. Zeeb if ((FIELD_GET(BIT_GAIN_TX_PAD_H, gain) >= 0xc) && 13922774f206SBjoern A. Zeeb (FIELD_GET(BIT_GAIN_TX_PAD_L, gain) >= 0xe)) 13932774f206SBjoern A. Zeeb return true; 13942774f206SBjoern A. Zeeb 13952774f206SBjoern A. Zeeb return false; 13962774f206SBjoern A. Zeeb } 13972774f206SBjoern A. Zeeb 13982774f206SBjoern A. Zeeb static void _rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev, 13992774f206SBjoern A. Zeeb u8 band, u8 path) 14002774f206SBjoern A. Zeeb { 14012774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 14022774f206SBjoern A. Zeeb u32 v, tmp_3f = 0; 14032774f206SBjoern A. Zeeb u8 gain, check_txgain; 14042774f206SBjoern A. Zeeb 14052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 14062774f206SBjoern A. Zeeb 14072774f206SBjoern A. Zeeb switch (band) { 14082774f206SBjoern A. Zeeb case RF_BAND_2G_OFDM: 14092774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); 14102774f206SBjoern A. Zeeb break; 14112774f206SBjoern A. Zeeb case RF_BAND_5G_L: 14122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); 14132774f206SBjoern A. Zeeb break; 14142774f206SBjoern A. Zeeb case RF_BAND_5G_M: 14152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); 14162774f206SBjoern A. Zeeb break; 14172774f206SBjoern A. Zeeb case RF_BAND_5G_H: 14182774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); 14192774f206SBjoern A. Zeeb break; 14202774f206SBjoern A. Zeeb default: 14212774f206SBjoern A. Zeeb break; 14222774f206SBjoern A. Zeeb } 14232774f206SBjoern A. Zeeb 14242774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, MASKBYTE0, 0x88); 14252774f206SBjoern A. Zeeb 14262774f206SBjoern A. Zeeb check_txgain = 0; 14272774f206SBjoern A. Zeeb for (gain = 0; gain < RF_GAIN_NUM; gain++) { 14282774f206SBjoern A. Zeeb v = txgapk->rf3f_bp[band][gain][path]; 14292774f206SBjoern A. Zeeb if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { 14302774f206SBjoern A. Zeeb if (!check_txgain) { 14312774f206SBjoern A. Zeeb tmp_3f = txgapk->rf3f_bp[band][gain][path]; 14322774f206SBjoern A. Zeeb check_txgain = 1; 14332774f206SBjoern A. Zeeb } 14342774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 14352774f206SBjoern A. Zeeb "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", 14362774f206SBjoern A. Zeeb txgapk->rf3f_bp[band][gain][path]); 14372774f206SBjoern A. Zeeb } else { 14382774f206SBjoern A. Zeeb tmp_3f = txgapk->rf3f_bp[band][gain][path]; 14392774f206SBjoern A. Zeeb } 14402774f206SBjoern A. Zeeb 14412774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN, tmp_3f); 14422774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_I_GAIN, gain); 14432774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x1); 14442774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x0); 14452774f206SBjoern A. Zeeb 14462774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 14472774f206SBjoern A. Zeeb "[TXGAPK] Band=%d 0x1b98[11:0]=0x%03X path=%d\n", 14482774f206SBjoern A. Zeeb band, tmp_3f, path); 14492774f206SBjoern A. Zeeb } 14502774f206SBjoern A. Zeeb } 14512774f206SBjoern A. Zeeb 14522774f206SBjoern A. Zeeb static void rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev) 14532774f206SBjoern A. Zeeb { 14542774f206SBjoern A. Zeeb u8 path, band; 14552774f206SBjoern A. Zeeb 14562774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", 14572774f206SBjoern A. Zeeb __func__, rtwdev->dm_info.gapk.channel); 14582774f206SBjoern A. Zeeb 14592774f206SBjoern A. Zeeb for (band = 0; band < RF_BAND_MAX; band++) { 14602774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 14612774f206SBjoern A. Zeeb _rtw8822c_txgapk_write_gain_bb_table(rtwdev, 14622774f206SBjoern A. Zeeb band, path); 14632774f206SBjoern A. Zeeb } 14642774f206SBjoern A. Zeeb } 14652774f206SBjoern A. Zeeb } 14662774f206SBjoern A. Zeeb 14672774f206SBjoern A. Zeeb static void rtw8822c_txgapk_read_offset(struct rtw_dev *rtwdev, u8 path) 14682774f206SBjoern A. Zeeb { 14692774f206SBjoern A. Zeeb static const u32 cfg1_1b00[2] = {0x00000d18, 0x00000d2a}; 14702774f206SBjoern A. Zeeb static const u32 cfg2_1b00[2] = {0x00000d19, 0x00000d2b}; 14712774f206SBjoern A. Zeeb static const u32 set_pi[2] = {REG_RSV_CTRL, REG_WLRF1}; 14722774f206SBjoern A. Zeeb static const u32 path_setting[2] = {REG_ORITXCODE, REG_ORITXCODE2}; 14732774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 14742774f206SBjoern A. Zeeb u8 channel = txgapk->channel; 14752774f206SBjoern A. Zeeb u32 val; 14762774f206SBjoern A. Zeeb int i; 14772774f206SBjoern A. Zeeb 14782774f206SBjoern A. Zeeb if (path >= ARRAY_SIZE(cfg1_1b00) || 14792774f206SBjoern A. Zeeb path >= ARRAY_SIZE(cfg2_1b00) || 14802774f206SBjoern A. Zeeb path >= ARRAY_SIZE(set_pi) || 14812774f206SBjoern A. Zeeb path >= ARRAY_SIZE(path_setting)) { 14822774f206SBjoern A. Zeeb rtw_warn(rtwdev, "[TXGAPK] wrong path %d\n", path); 14832774f206SBjoern A. Zeeb return; 14842774f206SBjoern A. Zeeb } 14852774f206SBjoern A. Zeeb 14862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, BIT_ANT_PATH, path + 1); 14872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, MASKDWORD, 0xe4e40000); 14882774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXANTSEG, BIT_ANTSEG, 0x3); 14892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, path_setting[path], MASK20BITS, 0x33312); 14902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, path_setting[path], BIT_PATH_EN, 0x1); 14912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x0); 14922774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT_TXA_TANK, 0x1); 14932774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_IDAC, BIT_TX_MODE, 0x820); 14942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 14952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); 14962774f206SBjoern A. Zeeb 14972774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TX_TONE_IDX, MASKBYTE0, 0x018); 14982774f206SBjoern A. Zeeb fsleep(1000); 14992774f206SBjoern A. Zeeb if (channel >= 1 && channel <= 14) 15002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_2G_SWING); 15012774f206SBjoern A. Zeeb else 15022774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_5G_SWING); 15032774f206SBjoern A. Zeeb fsleep(1000); 15042774f206SBjoern A. Zeeb 15052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg1_1b00[path]); 15062774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg2_1b00[path]); 15072774f206SBjoern A. Zeeb 15082774f206SBjoern A. Zeeb read_poll_timeout(rtw_read32_mask, val, 15092774f206SBjoern A. Zeeb val == 0x55, 1000, 100000, false, 15102774f206SBjoern A. Zeeb rtwdev, REG_RPT_CIP, BIT_RPT_CIP_STATUS); 15112774f206SBjoern A. Zeeb 15122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x2); 15132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 15142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_EN, 0x1); 15152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x12); 15162774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x3); 15172774f206SBjoern A. Zeeb val = rtw_read32(rtwdev, REG_STAT_RPT); 15182774f206SBjoern A. Zeeb 15192774f206SBjoern A. Zeeb txgapk->offset[0][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); 15202774f206SBjoern A. Zeeb txgapk->offset[1][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); 15212774f206SBjoern A. Zeeb txgapk->offset[2][path] = (s8)FIELD_GET(BIT_GAPK_RPT2, val); 15222774f206SBjoern A. Zeeb txgapk->offset[3][path] = (s8)FIELD_GET(BIT_GAPK_RPT3, val); 15232774f206SBjoern A. Zeeb txgapk->offset[4][path] = (s8)FIELD_GET(BIT_GAPK_RPT4, val); 15242774f206SBjoern A. Zeeb txgapk->offset[5][path] = (s8)FIELD_GET(BIT_GAPK_RPT5, val); 15252774f206SBjoern A. Zeeb txgapk->offset[6][path] = (s8)FIELD_GET(BIT_GAPK_RPT6, val); 15262774f206SBjoern A. Zeeb txgapk->offset[7][path] = (s8)FIELD_GET(BIT_GAPK_RPT7, val); 15272774f206SBjoern A. Zeeb 15282774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x4); 15292774f206SBjoern A. Zeeb val = rtw_read32(rtwdev, REG_STAT_RPT); 15302774f206SBjoern A. Zeeb 15312774f206SBjoern A. Zeeb txgapk->offset[8][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); 15322774f206SBjoern A. Zeeb txgapk->offset[9][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); 15332774f206SBjoern A. Zeeb 15342774f206SBjoern A. Zeeb for (i = 0; i < RF_HW_OFFSET_NUM; i++) 15352774f206SBjoern A. Zeeb if (txgapk->offset[i][path] & BIT(3)) 15362774f206SBjoern A. Zeeb txgapk->offset[i][path] = txgapk->offset[i][path] | 15372774f206SBjoern A. Zeeb 0xf0; 15382774f206SBjoern A. Zeeb for (i = 0; i < RF_HW_OFFSET_NUM; i++) 15392774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 15402774f206SBjoern A. Zeeb "[TXGAPK] offset %d %d path=%d\n", 15412774f206SBjoern A. Zeeb txgapk->offset[i][path], i, path); 15422774f206SBjoern A. Zeeb } 15432774f206SBjoern A. Zeeb 15442774f206SBjoern A. Zeeb static void rtw8822c_txgapk_calculate_offset(struct rtw_dev *rtwdev, u8 path) 15452774f206SBjoern A. Zeeb { 15462774f206SBjoern A. Zeeb static const u32 bb_reg[] = {REG_ANTMAP0, REG_TXLGMAP, REG_TXANTSEG, 15472774f206SBjoern A. Zeeb REG_ORITXCODE, REG_ORITXCODE2}; 15482774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 15492774f206SBjoern A. Zeeb u8 channel = txgapk->channel; 15502774f206SBjoern A. Zeeb u32 reg_backup[ARRAY_SIZE(bb_reg)] = {0}; 15512774f206SBjoern A. Zeeb 15522774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", 15532774f206SBjoern A. Zeeb __func__, channel); 15542774f206SBjoern A. Zeeb 15552774f206SBjoern A. Zeeb rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, 15562774f206SBjoern A. Zeeb reg_backup, ARRAY_SIZE(bb_reg)); 15572774f206SBjoern A. Zeeb 15582774f206SBjoern A. Zeeb if (channel >= 1 && channel <= 14) { 15592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 15602774f206SBjoern A. Zeeb REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 15612774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 15622774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); 15632774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 15642774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 15652774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x5000f); 15662774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x0); 15672774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x1); 15682774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0f); 15692774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 15702774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); 15712774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 15722774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); 15732774f206SBjoern A. Zeeb 15742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x00); 15752774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); 15762774f206SBjoern A. Zeeb 15772774f206SBjoern A. Zeeb rtw8822c_txgapk_read_offset(rtwdev, path); 15782774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); 15792774f206SBjoern A. Zeeb 15802774f206SBjoern A. Zeeb } else { 15812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 15822774f206SBjoern A. Zeeb REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 15832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 15842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); 15852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 15862774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 15872774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50011); 15882774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x3); 15892774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x3); 15902774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); 15912774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 15922774f206SBjoern A. Zeeb RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0x2); 15932774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x12); 15942774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 15952774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 15962774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); 15972774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x5); 15982774f206SBjoern A. Zeeb 15992774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); 16002774f206SBjoern A. Zeeb 16012774f206SBjoern A. Zeeb if (channel >= 36 && channel <= 64) 16022774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 16032774f206SBjoern A. Zeeb REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); 16042774f206SBjoern A. Zeeb else if (channel >= 100 && channel <= 144) 16052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 16062774f206SBjoern A. Zeeb REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); 16072774f206SBjoern A. Zeeb else if (channel >= 149 && channel <= 177) 16082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 16092774f206SBjoern A. Zeeb REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); 16102774f206SBjoern A. Zeeb 16112774f206SBjoern A. Zeeb rtw8822c_txgapk_read_offset(rtwdev, path); 16122774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); 16132774f206SBjoern A. Zeeb } 16142774f206SBjoern A. Zeeb rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, 16152774f206SBjoern A. Zeeb reg_backup, ARRAY_SIZE(bb_reg)); 16162774f206SBjoern A. Zeeb } 16172774f206SBjoern A. Zeeb 16182774f206SBjoern A. Zeeb static void rtw8822c_txgapk_rf_restore(struct rtw_dev *rtwdev, u8 path) 16192774f206SBjoern A. Zeeb { 16202774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 16212774f206SBjoern A. Zeeb 16222774f206SBjoern A. Zeeb if (path >= rtwdev->hal.rf_path_num) 16232774f206SBjoern A. Zeeb return; 16242774f206SBjoern A. Zeeb 16252774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x3); 16262774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x0); 16272774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x0); 16282774f206SBjoern A. Zeeb } 16292774f206SBjoern A. Zeeb 16302774f206SBjoern A. Zeeb static u32 rtw8822c_txgapk_cal_gain(struct rtw_dev *rtwdev, u32 gain, s8 offset) 16312774f206SBjoern A. Zeeb { 16322774f206SBjoern A. Zeeb u32 gain_x2, new_gain; 16332774f206SBjoern A. Zeeb 16342774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 16352774f206SBjoern A. Zeeb 16362774f206SBjoern A. Zeeb if (_rtw8822c_txgapk_gain_valid(rtwdev, gain)) { 16372774f206SBjoern A. Zeeb new_gain = gain; 16382774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 16392774f206SBjoern A. Zeeb "[TXGAPK] gain=0x%03X(>=0xCEX) offset=%d new_gain=0x%03X\n", 16402774f206SBjoern A. Zeeb gain, offset, new_gain); 16412774f206SBjoern A. Zeeb return new_gain; 16422774f206SBjoern A. Zeeb } 16432774f206SBjoern A. Zeeb 16442774f206SBjoern A. Zeeb gain_x2 = (gain << 1) + offset; 16452774f206SBjoern A. Zeeb new_gain = (gain_x2 >> 1) | (gain_x2 & BIT(0) ? BIT_GAIN_EXT : 0); 16462774f206SBjoern A. Zeeb 16472774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 16482774f206SBjoern A. Zeeb "[TXGAPK] gain=0x%X offset=%d new_gain=0x%X\n", 16492774f206SBjoern A. Zeeb gain, offset, new_gain); 16502774f206SBjoern A. Zeeb 16512774f206SBjoern A. Zeeb return new_gain; 16522774f206SBjoern A. Zeeb } 16532774f206SBjoern A. Zeeb 16542774f206SBjoern A. Zeeb static void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev) 16552774f206SBjoern A. Zeeb { 16562774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 16572774f206SBjoern A. Zeeb u32 i, j, tmp = 0x20, tmp_3f, v; 16582774f206SBjoern A. Zeeb s8 offset_tmp[RF_GAIN_NUM] = {0}; 16592774f206SBjoern A. Zeeb u8 path, band = RF_BAND_2G_OFDM, channel = txgapk->channel; 16602774f206SBjoern A. Zeeb 16612774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 16622774f206SBjoern A. Zeeb 16632774f206SBjoern A. Zeeb if (channel >= 1 && channel <= 14) { 16642774f206SBjoern A. Zeeb tmp = 0x20; 16652774f206SBjoern A. Zeeb band = RF_BAND_2G_OFDM; 16662774f206SBjoern A. Zeeb } else if (channel >= 36 && channel <= 64) { 16672774f206SBjoern A. Zeeb tmp = 0x200; 16682774f206SBjoern A. Zeeb band = RF_BAND_5G_L; 16692774f206SBjoern A. Zeeb } else if (channel >= 100 && channel <= 144) { 16702774f206SBjoern A. Zeeb tmp = 0x280; 16712774f206SBjoern A. Zeeb band = RF_BAND_5G_M; 16722774f206SBjoern A. Zeeb } else if (channel >= 149 && channel <= 177) { 16732774f206SBjoern A. Zeeb tmp = 0x300; 16742774f206SBjoern A. Zeeb band = RF_BAND_5G_H; 16752774f206SBjoern A. Zeeb } else { 16762774f206SBjoern A. Zeeb rtw_err(rtwdev, "[TXGAPK] unknown channel %d!!\n", channel); 16772774f206SBjoern A. Zeeb return; 16782774f206SBjoern A. Zeeb } 16792774f206SBjoern A. Zeeb 16802774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 16812774f206SBjoern A. Zeeb for (i = 0; i < RF_GAIN_NUM; i++) { 16822774f206SBjoern A. Zeeb offset_tmp[i] = 0; 16832774f206SBjoern A. Zeeb for (j = i; j < RF_GAIN_NUM; j++) { 16842774f206SBjoern A. Zeeb v = txgapk->rf3f_bp[band][j][path]; 16852774f206SBjoern A. Zeeb if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) 16862774f206SBjoern A. Zeeb continue; 16872774f206SBjoern A. Zeeb 16882774f206SBjoern A. Zeeb offset_tmp[i] += txgapk->offset[j][path]; 16892774f206SBjoern A. Zeeb txgapk->fianl_offset[i][path] = offset_tmp[i]; 16902774f206SBjoern A. Zeeb } 16912774f206SBjoern A. Zeeb 16922774f206SBjoern A. Zeeb v = txgapk->rf3f_bp[band][i][path]; 16932774f206SBjoern A. Zeeb if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { 16942774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 16952774f206SBjoern A. Zeeb "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", 16962774f206SBjoern A. Zeeb txgapk->rf3f_bp[band][i][path]); 16972774f206SBjoern A. Zeeb } else { 16982774f206SBjoern A. Zeeb txgapk->rf3f_fs[path][i] = offset_tmp[i]; 16992774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 17002774f206SBjoern A. Zeeb "[TXGAPK] offset %d %d\n", 17012774f206SBjoern A. Zeeb offset_tmp[i], i); 17022774f206SBjoern A. Zeeb } 17032774f206SBjoern A. Zeeb } 17042774f206SBjoern A. Zeeb 17052774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x10000); 17062774f206SBjoern A. Zeeb for (i = 0; i < RF_GAIN_NUM; i++) { 17072774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 17082774f206SBjoern A. Zeeb RF_LUTWA, RFREG_MASK, tmp + i); 17092774f206SBjoern A. Zeeb 17102774f206SBjoern A. Zeeb tmp_3f = rtw8822c_txgapk_cal_gain(rtwdev, 17112774f206SBjoern A. Zeeb txgapk->rf3f_bp[band][i][path], 17122774f206SBjoern A. Zeeb offset_tmp[i]); 17132774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_LUTWD0, 17142774f206SBjoern A. Zeeb BIT_GAIN_EXT | BIT_DATA_L, tmp_3f); 17152774f206SBjoern A. Zeeb 17162774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 17172774f206SBjoern A. Zeeb "[TXGAPK] 0x33=0x%05X 0x3f=0x%04X\n", 17182774f206SBjoern A. Zeeb tmp + i, tmp_3f); 17192774f206SBjoern A. Zeeb } 17202774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x0); 17212774f206SBjoern A. Zeeb } 17222774f206SBjoern A. Zeeb } 17232774f206SBjoern A. Zeeb 17242774f206SBjoern A. Zeeb static void rtw8822c_txgapk_save_all_tx_gain_table(struct rtw_dev *rtwdev) 17252774f206SBjoern A. Zeeb { 17262774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 17272774f206SBjoern A. Zeeb static const u32 three_wire[2] = {REG_3WIRE, REG_3WIRE2}; 17282774f206SBjoern A. Zeeb static const u8 ch_num[RF_BAND_MAX] = {1, 1, 36, 100, 149}; 17292774f206SBjoern A. Zeeb static const u8 band_num[RF_BAND_MAX] = {0x0, 0x0, 0x1, 0x3, 0x5}; 17302774f206SBjoern A. Zeeb static const u8 cck[RF_BAND_MAX] = {0x1, 0x0, 0x0, 0x0, 0x0}; 17312774f206SBjoern A. Zeeb u8 path, band, gain, rf0_idx; 17322774f206SBjoern A. Zeeb u32 rf18, v; 17332774f206SBjoern A. Zeeb 17342774f206SBjoern A. Zeeb if (rtwdev->dm_info.dm_flags & BIT(RTW_DM_CAP_TXGAPK)) 17352774f206SBjoern A. Zeeb return; 17362774f206SBjoern A. Zeeb 17372774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 17382774f206SBjoern A. Zeeb 17392774f206SBjoern A. Zeeb if (txgapk->read_txgain == 1) { 17402774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 17412774f206SBjoern A. Zeeb "[TXGAPK] Already Read txgapk->read_txgain return!!!\n"); 17422774f206SBjoern A. Zeeb rtw8822c_txgapk_write_gain_bb_table(rtwdev); 17432774f206SBjoern A. Zeeb return; 17442774f206SBjoern A. Zeeb } 17452774f206SBjoern A. Zeeb 17462774f206SBjoern A. Zeeb for (band = 0; band < RF_BAND_MAX; band++) { 17472774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 17482774f206SBjoern A. Zeeb rf18 = rtw_read_rf(rtwdev, path, RF_CFGCH, RFREG_MASK); 17492774f206SBjoern A. Zeeb 17502774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 17512774f206SBjoern A. Zeeb three_wire[path], BIT_3WIRE_EN, 0x0); 17522774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 17532774f206SBjoern A. Zeeb RF_CFGCH, MASKBYTE0, ch_num[band]); 17542774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 17552774f206SBjoern A. Zeeb RF_CFGCH, BIT_BAND, band_num[band]); 17562774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 17572774f206SBjoern A. Zeeb RF_BW_TRXBB, BIT_DBG_CCK_CCA, cck[band]); 17582774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 17592774f206SBjoern A. Zeeb RF_BW_TRXBB, BIT_TX_CCK_IND, cck[band]); 17602774f206SBjoern A. Zeeb gain = 0; 17612774f206SBjoern A. Zeeb for (rf0_idx = 1; rf0_idx < 32; rf0_idx += 3) { 17622774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, 17632774f206SBjoern A. Zeeb MASKBYTE0, rf0_idx); 17642774f206SBjoern A. Zeeb v = rtw_read_rf(rtwdev, path, 17652774f206SBjoern A. Zeeb RF_TX_RESULT, RFREG_MASK); 17662774f206SBjoern A. Zeeb txgapk->rf3f_bp[band][gain][path] = v & BIT_DATA_L; 17672774f206SBjoern A. Zeeb 17682774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 17692774f206SBjoern A. Zeeb "[TXGAPK] 0x5f=0x%03X band=%d path=%d\n", 17702774f206SBjoern A. Zeeb txgapk->rf3f_bp[band][gain][path], 17712774f206SBjoern A. Zeeb band, path); 17722774f206SBjoern A. Zeeb gain++; 17732774f206SBjoern A. Zeeb } 17742774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_CFGCH, RFREG_MASK, rf18); 17752774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 17762774f206SBjoern A. Zeeb three_wire[path], BIT_3WIRE_EN, 0x3); 17772774f206SBjoern A. Zeeb } 17782774f206SBjoern A. Zeeb } 17792774f206SBjoern A. Zeeb rtw8822c_txgapk_write_gain_bb_table(rtwdev); 17802774f206SBjoern A. Zeeb txgapk->read_txgain = 1; 17812774f206SBjoern A. Zeeb } 17822774f206SBjoern A. Zeeb 17832774f206SBjoern A. Zeeb static void rtw8822c_txgapk(struct rtw_dev *rtwdev) 17842774f206SBjoern A. Zeeb { 17852774f206SBjoern A. Zeeb static const u32 bb_reg[2] = {REG_TX_PTCL_CTRL, REG_TX_FIFO}; 17862774f206SBjoern A. Zeeb struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 17872774f206SBjoern A. Zeeb u32 bb_reg_backup[2]; 17882774f206SBjoern A. Zeeb u8 path; 17892774f206SBjoern A. Zeeb 17902774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 17912774f206SBjoern A. Zeeb 17922774f206SBjoern A. Zeeb rtw8822c_txgapk_save_all_tx_gain_table(rtwdev); 17932774f206SBjoern A. Zeeb 17942774f206SBjoern A. Zeeb if (txgapk->read_txgain == 0) { 17952774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 17962774f206SBjoern A. Zeeb "[TXGAPK] txgapk->read_txgain == 0 return!!!\n"); 17972774f206SBjoern A. Zeeb return; 17982774f206SBjoern A. Zeeb } 17992774f206SBjoern A. Zeeb 18002774f206SBjoern A. Zeeb if (rtwdev->efuse.power_track_type >= 4 && 18012774f206SBjoern A. Zeeb rtwdev->efuse.power_track_type <= 7) { 18022774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 18032774f206SBjoern A. Zeeb "[TXGAPK] Normal Mode in TSSI mode. return!!!\n"); 18042774f206SBjoern A. Zeeb return; 18052774f206SBjoern A. Zeeb } 18062774f206SBjoern A. Zeeb 18072774f206SBjoern A. Zeeb rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, 18082774f206SBjoern A. Zeeb bb_reg_backup, ARRAY_SIZE(bb_reg)); 18092774f206SBjoern A. Zeeb rtw8822c_txgapk_tx_pause(rtwdev); 18102774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 18112774f206SBjoern A. Zeeb txgapk->channel = rtw_read_rf(rtwdev, path, 18122774f206SBjoern A. Zeeb RF_CFGCH, RFREG_MASK) & MASKBYTE0; 18132774f206SBjoern A. Zeeb rtw8822c_txgapk_bb_dpk(rtwdev, path); 18142774f206SBjoern A. Zeeb rtw8822c_txgapk_afe_dpk(rtwdev, path); 18152774f206SBjoern A. Zeeb rtw8822c_txgapk_calculate_offset(rtwdev, path); 18162774f206SBjoern A. Zeeb rtw8822c_txgapk_rf_restore(rtwdev, path); 18172774f206SBjoern A. Zeeb rtw8822c_txgapk_afe_dpk_restore(rtwdev, path); 18182774f206SBjoern A. Zeeb rtw8822c_txgapk_bb_dpk_restore(rtwdev, path); 18192774f206SBjoern A. Zeeb } 18202774f206SBjoern A. Zeeb rtw8822c_txgapk_write_tx_gain(rtwdev); 18212774f206SBjoern A. Zeeb rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, 18222774f206SBjoern A. Zeeb bb_reg_backup, ARRAY_SIZE(bb_reg)); 18232774f206SBjoern A. Zeeb } 18242774f206SBjoern A. Zeeb 18252774f206SBjoern A. Zeeb static void rtw8822c_do_gapk(struct rtw_dev *rtwdev) 18262774f206SBjoern A. Zeeb { 18272774f206SBjoern A. Zeeb struct rtw_dm_info *dm = &rtwdev->dm_info; 18282774f206SBjoern A. Zeeb 18292774f206SBjoern A. Zeeb if (dm->dm_flags & BIT(RTW_DM_CAP_TXGAPK)) { 18302774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] feature disable!!!\n"); 18312774f206SBjoern A. Zeeb return; 18322774f206SBjoern A. Zeeb } 18332774f206SBjoern A. Zeeb rtw8822c_rfk_handshake(rtwdev, true); 18342774f206SBjoern A. Zeeb rtw8822c_txgapk(rtwdev); 18352774f206SBjoern A. Zeeb rtw8822c_rfk_handshake(rtwdev, false); 18362774f206SBjoern A. Zeeb } 18372774f206SBjoern A. Zeeb 18382774f206SBjoern A. Zeeb static void rtw8822c_rf_init(struct rtw_dev *rtwdev) 18392774f206SBjoern A. Zeeb { 18402774f206SBjoern A. Zeeb rtw8822c_rf_dac_cal(rtwdev); 18412774f206SBjoern A. Zeeb rtw8822c_rf_x2_check(rtwdev); 18422774f206SBjoern A. Zeeb rtw8822c_thermal_trim(rtwdev); 18432774f206SBjoern A. Zeeb rtw8822c_power_trim(rtwdev); 18442774f206SBjoern A. Zeeb rtw8822c_pa_bias(rtwdev); 18452774f206SBjoern A. Zeeb } 18462774f206SBjoern A. Zeeb 18472774f206SBjoern A. Zeeb static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev) 18482774f206SBjoern A. Zeeb { 18492774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 18502774f206SBjoern A. Zeeb u8 path; 18512774f206SBjoern A. Zeeb 18522774f206SBjoern A. Zeeb for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) { 18532774f206SBjoern A. Zeeb dm_info->delta_power_index[path] = 0; 18542774f206SBjoern A. Zeeb ewma_thermal_init(&dm_info->avg_thermal[path]); 18552774f206SBjoern A. Zeeb dm_info->thermal_avg[path] = 0xff; 18562774f206SBjoern A. Zeeb } 18572774f206SBjoern A. Zeeb 18582774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 18592774f206SBjoern A. Zeeb dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 18602774f206SBjoern A. Zeeb dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k; 18612774f206SBjoern A. Zeeb } 18622774f206SBjoern A. Zeeb 18632774f206SBjoern A. Zeeb static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) 18642774f206SBjoern A. Zeeb { 18652774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 18662774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 18672774f206SBjoern A. Zeeb u8 crystal_cap; 18682774f206SBjoern A. Zeeb u8 cck_gi_u_bnd_msb = 0; 18692774f206SBjoern A. Zeeb u8 cck_gi_u_bnd_lsb = 0; 18702774f206SBjoern A. Zeeb u8 cck_gi_l_bnd_msb = 0; 18712774f206SBjoern A. Zeeb u8 cck_gi_l_bnd_lsb = 0; 18722774f206SBjoern A. Zeeb bool is_tx2_path; 18732774f206SBjoern A. Zeeb 18742774f206SBjoern A. Zeeb /* power on BB/RF domain */ 18752774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, 18762774f206SBjoern A. Zeeb BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); 18772774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_RF_CTRL, 18782774f206SBjoern A. Zeeb BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 18792774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN); 18802774f206SBjoern A. Zeeb 18812774f206SBjoern A. Zeeb /* disable low rate DPD */ 18822774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); 18832774f206SBjoern A. Zeeb 18842774f206SBjoern A. Zeeb /* pre init before header files config */ 18852774f206SBjoern A. Zeeb rtw8822c_header_file_init(rtwdev, true); 18862774f206SBjoern A. Zeeb 18872774f206SBjoern A. Zeeb rtw_phy_load_tables(rtwdev); 18882774f206SBjoern A. Zeeb 18892774f206SBjoern A. Zeeb crystal_cap = rtwdev->efuse.crystal_cap & 0x7f; 18902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, 0xfffc00, 18912774f206SBjoern A. Zeeb crystal_cap | (crystal_cap << 7)); 18922774f206SBjoern A. Zeeb 18932774f206SBjoern A. Zeeb /* post init after header files config */ 18942774f206SBjoern A. Zeeb rtw8822c_header_file_init(rtwdev, false); 18952774f206SBjoern A. Zeeb 18962774f206SBjoern A. Zeeb is_tx2_path = false; 18972774f206SBjoern A. Zeeb rtw8822c_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx, 18982774f206SBjoern A. Zeeb is_tx2_path); 18992774f206SBjoern A. Zeeb rtw_phy_init(rtwdev); 19002774f206SBjoern A. Zeeb 19012774f206SBjoern A. Zeeb cck_gi_u_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc000); 19022774f206SBjoern A. Zeeb cck_gi_u_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1aa8, 0xf0000); 19032774f206SBjoern A. Zeeb cck_gi_l_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc0); 19042774f206SBjoern A. Zeeb cck_gi_l_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1a70, 0x0f000000); 19052774f206SBjoern A. Zeeb 19062774f206SBjoern A. Zeeb dm_info->cck_gi_u_bnd = ((cck_gi_u_bnd_msb << 4) | (cck_gi_u_bnd_lsb)); 19072774f206SBjoern A. Zeeb dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb)); 19082774f206SBjoern A. Zeeb 19092774f206SBjoern A. Zeeb rtw8822c_rf_init(rtwdev); 19102774f206SBjoern A. Zeeb rtw8822c_pwrtrack_init(rtwdev); 19112774f206SBjoern A. Zeeb 19122774f206SBjoern A. Zeeb rtw_bf_phy_init(rtwdev); 19132774f206SBjoern A. Zeeb } 19142774f206SBjoern A. Zeeb 19152774f206SBjoern A. Zeeb #define WLAN_TXQ_RPT_EN 0x1F 19162774f206SBjoern A. Zeeb #define WLAN_SLOT_TIME 0x09 19172774f206SBjoern A. Zeeb #define WLAN_PIFS_TIME 0x1C 19182774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_CONT_TX 0x0A 19192774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_CONT_TX 0x0E 19202774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_TRX 0x0A 19212774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_TRX 0x10 19222774f206SBjoern A. Zeeb #define WLAN_NAV_MAX 0xC8 19232774f206SBjoern A. Zeeb #define WLAN_RDG_NAV 0x05 19242774f206SBjoern A. Zeeb #define WLAN_TXOP_NAV 0x1B 19252774f206SBjoern A. Zeeb #define WLAN_CCK_RX_TSF 0x30 19262774f206SBjoern A. Zeeb #define WLAN_OFDM_RX_TSF 0x30 19272774f206SBjoern A. Zeeb #define WLAN_TBTT_PROHIBIT 0x04 /* unit : 32us */ 19282774f206SBjoern A. Zeeb #define WLAN_TBTT_HOLD_TIME 0x064 /* unit : 32us */ 19292774f206SBjoern A. Zeeb #define WLAN_DRV_EARLY_INT 0x04 19302774f206SBjoern A. Zeeb #define WLAN_BCN_CTRL_CLT0 0x10 19312774f206SBjoern A. Zeeb #define WLAN_BCN_DMA_TIME 0x02 19322774f206SBjoern A. Zeeb #define WLAN_BCN_MAX_ERR 0xFF 19332774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_DUR_TUNE 0x0A 19342774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_DUR_TUNE 0x10 19352774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_CTX 0x0A 19362774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_IRX 0x0A 19372774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_CTX 0x0E 19382774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_IRX 0x0E 19392774f206SBjoern A. Zeeb #define WLAN_EIFS_DUR_TUNE 0x40 19402774f206SBjoern A. Zeeb #define WLAN_EDCA_VO_PARAM 0x002FA226 19412774f206SBjoern A. Zeeb #define WLAN_EDCA_VI_PARAM 0x005EA328 19422774f206SBjoern A. Zeeb #define WLAN_EDCA_BE_PARAM 0x005EA42B 19432774f206SBjoern A. Zeeb #define WLAN_EDCA_BK_PARAM 0x0000A44F 19442774f206SBjoern A. Zeeb 19452774f206SBjoern A. Zeeb #define WLAN_RX_FILTER0 0xFFFFFFFF 19462774f206SBjoern A. Zeeb #define WLAN_RX_FILTER2 0xFFFF 19472774f206SBjoern A. Zeeb #define WLAN_RCR_CFG 0xE400220E 19482774f206SBjoern A. Zeeb #define WLAN_RXPKT_MAX_SZ 12288 19492774f206SBjoern A. Zeeb #define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) 19502774f206SBjoern A. Zeeb 19512774f206SBjoern A. Zeeb #define WLAN_AMPDU_MAX_TIME 0x70 19522774f206SBjoern A. Zeeb #define WLAN_RTS_LEN_TH 0xFF 19532774f206SBjoern A. Zeeb #define WLAN_RTS_TX_TIME_TH 0x08 19542774f206SBjoern A. Zeeb #define WLAN_MAX_AGG_PKT_LIMIT 0x3f 19552774f206SBjoern A. Zeeb #define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x3f 19562774f206SBjoern A. Zeeb #define WLAN_PRE_TXCNT_TIME_TH 0x1E0 19572774f206SBjoern A. Zeeb #define FAST_EDCA_VO_TH 0x06 19582774f206SBjoern A. Zeeb #define FAST_EDCA_VI_TH 0x06 19592774f206SBjoern A. Zeeb #define FAST_EDCA_BE_TH 0x06 19602774f206SBjoern A. Zeeb #define FAST_EDCA_BK_TH 0x06 19612774f206SBjoern A. Zeeb #define WLAN_BAR_RETRY_LIMIT 0x01 19622774f206SBjoern A. Zeeb #define WLAN_BAR_ACK_TYPE 0x05 19632774f206SBjoern A. Zeeb #define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 19642774f206SBjoern A. Zeeb #define WLAN_RESP_TXRATE 0x84 19652774f206SBjoern A. Zeeb #define WLAN_ACK_TO 0x21 19662774f206SBjoern A. Zeeb #define WLAN_ACK_TO_CCK 0x6A 19672774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_CNT_1_4 0x01000000 19682774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_CNT_5_8 0x08070504 19692774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_CNT_5_8 0x08070504 19702774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_RATE0 0xFE01F010 19712774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_RATE0_H 0x40000000 19722774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE1 0x003FF010 19732774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE1_H 0x40000000 19742774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE4 0x0600F010 19752774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE4_H 0x400003E0 19762774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE5 0x0600F015 19772774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE5_H 0x000000E0 19782774f206SBjoern A. Zeeb #define WLAN_MULTI_ADDR 0xFFFFFFFF 19792774f206SBjoern A. Zeeb 19802774f206SBjoern A. Zeeb #define WLAN_TX_FUNC_CFG1 0x30 19812774f206SBjoern A. Zeeb #define WLAN_TX_FUNC_CFG2 0x30 19822774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_NORM_FUNC1 0x98 19832774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_LB_FUNC1 0x80 19842774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_FUNC2 0xb0810041 19852774f206SBjoern A. Zeeb #define WLAN_MAC_INT_MIG_CFG 0x33330000 19862774f206SBjoern A. Zeeb 19872774f206SBjoern A. Zeeb #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ 19882774f206SBjoern A. Zeeb (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ 19892774f206SBjoern A. Zeeb (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ 19902774f206SBjoern A. Zeeb (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) 19912774f206SBjoern A. Zeeb 19922774f206SBjoern A. Zeeb #define WLAN_SIFS_DUR_TUNE (WLAN_SIFS_CCK_DUR_TUNE | \ 19932774f206SBjoern A. Zeeb (WLAN_SIFS_OFDM_DUR_TUNE << 8)) 19942774f206SBjoern A. Zeeb 19952774f206SBjoern A. Zeeb #define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ 19962774f206SBjoern A. Zeeb (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) 19972774f206SBjoern A. Zeeb 19982774f206SBjoern A. Zeeb #define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) 19992774f206SBjoern A. Zeeb #define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) 20002774f206SBjoern A. Zeeb 20012774f206SBjoern A. Zeeb #define MAC_CLK_SPEED 80 /* 80M */ 20022774f206SBjoern A. Zeeb #define EFUSE_PCB_INFO_OFFSET 0xCA 20032774f206SBjoern A. Zeeb 20042774f206SBjoern A. Zeeb static int rtw8822c_mac_init(struct rtw_dev *rtwdev) 20052774f206SBjoern A. Zeeb { 20062774f206SBjoern A. Zeeb u8 value8; 20072774f206SBjoern A. Zeeb u16 value16; 20082774f206SBjoern A. Zeeb u32 value32; 20092774f206SBjoern A. Zeeb u16 pre_txcnt; 20102774f206SBjoern A. Zeeb 20112774f206SBjoern A. Zeeb /* txq control */ 20122774f206SBjoern A. Zeeb value8 = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL); 20132774f206SBjoern A. Zeeb value8 |= (BIT(7) & ~BIT(1) & ~BIT(2)); 20142774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, value8); 20152774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 20162774f206SBjoern A. Zeeb /* sifs control */ 20172774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SIFS_DUR_TUNE); 20182774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); 20192774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RESP_SIFS_CCK, 20202774f206SBjoern A. Zeeb WLAN_SIFS_CCK_CTX | WLAN_SIFS_CCK_IRX << 8); 20212774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RESP_SIFS_OFDM, 20222774f206SBjoern A. Zeeb WLAN_SIFS_OFDM_CTX | WLAN_SIFS_OFDM_IRX << 8); 20232774f206SBjoern A. Zeeb /* rate fallback control */ 20242774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DARFRC, WLAN_DATA_RATE_FB_CNT_1_4); 20252774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DARFRCH, WLAN_DATA_RATE_FB_CNT_5_8); 20262774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RARFRCH, WLAN_RTS_RATE_FB_CNT_5_8); 20272774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFR0, WLAN_DATA_RATE_FB_RATE0); 20282774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFRH0, WLAN_DATA_RATE_FB_RATE0_H); 20292774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFR1_V1, WLAN_RTS_RATE_FB_RATE1); 20302774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFRH1_V1, WLAN_RTS_RATE_FB_RATE1_H); 20312774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFR4, WLAN_RTS_RATE_FB_RATE4); 20322774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFRH4, WLAN_RTS_RATE_FB_RATE4_H); 20332774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFR5, WLAN_RTS_RATE_FB_RATE5); 20342774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_ARFRH5, WLAN_RTS_RATE_FB_RATE5_H); 20352774f206SBjoern A. Zeeb /* protocol configuration */ 20362774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); 20372774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); 20382774f206SBjoern A. Zeeb pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; 20392774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); 20402774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); 20412774f206SBjoern A. Zeeb value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | 20422774f206SBjoern A. Zeeb (WLAN_MAX_AGG_PKT_LIMIT << 16) | 20432774f206SBjoern A. Zeeb (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); 20442774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); 20452774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, 20462774f206SBjoern A. Zeeb WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); 20472774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); 20482774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); 20492774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); 20502774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); 20512774f206SBjoern A. Zeeb /* close BA parser */ 20522774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_LIFETIME_EN, BIT_BA_PARSER_EN); 20532774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_RRSR, BITS_RRSR_RSC); 20542774f206SBjoern A. Zeeb 20552774f206SBjoern A. Zeeb /* EDCA configuration */ 20562774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_EDCA_VO_PARAM, WLAN_EDCA_VO_PARAM); 20572774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_EDCA_VI_PARAM, WLAN_EDCA_VI_PARAM); 20582774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_EDCA_BE_PARAM, WLAN_EDCA_BE_PARAM); 20592774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_EDCA_BK_PARAM, WLAN_EDCA_BK_PARAM); 20602774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); 20612774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); 20622774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_RD_CTRL + 1, 20632774f206SBjoern A. Zeeb (BIT_DIS_TXOP_CFE | BIT_DIS_LSIG_CFE | 20642774f206SBjoern A. Zeeb BIT_DIS_STBC_CFE) >> 8); 20652774f206SBjoern A. Zeeb 20662774f206SBjoern A. Zeeb /* MAC clock configuration */ 20672774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BIT_MAC_CLK_SEL); 20682774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED); 20692774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED); 20702774f206SBjoern A. Zeeb 20712774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_MISC_CTRL, 20722774f206SBjoern A. Zeeb BIT_EN_FREE_CNT | BIT_DIS_SECOND_CCA); 20732774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); 20742774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_TXPAUSE, 0x0000); 20752774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); 20762774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); 20772774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); 20782774f206SBjoern A. Zeeb /* Set beacon cotnrol - enable TSF and other related functions */ 20792774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 20802774f206SBjoern A. Zeeb /* Set send beacon related registers */ 20812774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); 20822774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); 20832774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BCN_CTRL_CLINT0, WLAN_BCN_CTRL_CLT0); 20842774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); 20852774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BCN_MAX_ERR, WLAN_BCN_MAX_ERR); 20862774f206SBjoern A. Zeeb 20872774f206SBjoern A. Zeeb /* WMAC configuration */ 20882774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_MAR, WLAN_MULTI_ADDR); 20892774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_MAR + 4, WLAN_MULTI_ADDR); 20902774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BBPSF_CTRL + 2, WLAN_RESP_TXRATE); 20912774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_ACKTO, WLAN_ACK_TO); 20922774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_ACKTO_CCK, WLAN_ACK_TO_CCK); 20932774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_EIFS, WLAN_EIFS_DUR_TUNE); 20942774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_NAV_CTRL + 2, WLAN_NAV_MAX); 20952774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H + 2, WLAN_BAR_ACK_TYPE); 20962774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 20972774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 20982774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 20992774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); 21002774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); 21012774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); 21022774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GENERAL_OPTION, BIT_DUMMY_FCS_READY_MASK_EN); 21032774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); 21042774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION_1, WLAN_MAC_OPT_NORM_FUNC1); 21052774f206SBjoern A. Zeeb 21062774f206SBjoern A. Zeeb /* init low power */ 21072774f206SBjoern A. Zeeb value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL + 2) & 0xF00F; 21082774f206SBjoern A. Zeeb value16 |= (BIT_RXGCK_VHT_FIFOTHR(1) | BIT_RXGCK_HT_FIFOTHR(1) | 21092774f206SBjoern A. Zeeb BIT_RXGCK_OFDM_FIFOTHR(1) | BIT_RXGCK_CCK_FIFOTHR(1)) >> 16; 21102774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXPSF_CTRL + 2, value16); 21112774f206SBjoern A. Zeeb value16 = 0; 21122774f206SBjoern A. Zeeb value16 = BIT_SET_RXPSF_PKTLENTHR(value16, 1); 21132774f206SBjoern A. Zeeb value16 |= BIT_RXPSF_CTRLEN | BIT_RXPSF_VHTCHKEN | BIT_RXPSF_HTCHKEN 21142774f206SBjoern A. Zeeb | BIT_RXPSF_OFDMCHKEN | BIT_RXPSF_CCKCHKEN 21152774f206SBjoern A. Zeeb | BIT_RXPSF_OFDMRST; 21162774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); 21172774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPSF_TYPE_CTRL, 0xFFFFFFFF); 21182774f206SBjoern A. Zeeb /* rx ignore configuration */ 21192774f206SBjoern A. Zeeb value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL); 21202774f206SBjoern A. Zeeb value16 &= ~(BIT_RXPSF_MHCHKEN | BIT_RXPSF_CCKRST | 21212774f206SBjoern A. Zeeb BIT_RXPSF_CONT_ERRCHKEN); 21222774f206SBjoern A. Zeeb value16 = BIT_SET_RXPSF_ERRTHR(value16, 0x07); 21232774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); 21242774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, 21252774f206SBjoern A. Zeeb BIT_DIS_CHK_VHTSIGB_CRC); 21262774f206SBjoern A. Zeeb 21272774f206SBjoern A. Zeeb /* Interrupt migration configuration */ 21282774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG); 21292774f206SBjoern A. Zeeb 21302774f206SBjoern A. Zeeb return 0; 21312774f206SBjoern A. Zeeb } 21322774f206SBjoern A. Zeeb 21332774f206SBjoern A. Zeeb #define FWCD_SIZE_REG_8822C 0x2000 21342774f206SBjoern A. Zeeb #define FWCD_SIZE_DMEM_8822C 0x10000 21352774f206SBjoern A. Zeeb #define FWCD_SIZE_IMEM_8822C 0x10000 21362774f206SBjoern A. Zeeb #define FWCD_SIZE_EMEM_8822C 0x20000 21372774f206SBjoern A. Zeeb #define FWCD_SIZE_ROM_8822C 0x10000 21382774f206SBjoern A. Zeeb 21392774f206SBjoern A. Zeeb static const u32 __fwcd_segs_8822c[] = { 21402774f206SBjoern A. Zeeb FWCD_SIZE_REG_8822C, 21412774f206SBjoern A. Zeeb FWCD_SIZE_DMEM_8822C, 21422774f206SBjoern A. Zeeb FWCD_SIZE_IMEM_8822C, 21432774f206SBjoern A. Zeeb FWCD_SIZE_EMEM_8822C, 21442774f206SBjoern A. Zeeb FWCD_SIZE_ROM_8822C, 21452774f206SBjoern A. Zeeb }; 21462774f206SBjoern A. Zeeb 21472774f206SBjoern A. Zeeb static const struct rtw_fwcd_segs rtw8822c_fwcd_segs = { 21482774f206SBjoern A. Zeeb .segs = __fwcd_segs_8822c, 21492774f206SBjoern A. Zeeb .num = ARRAY_SIZE(__fwcd_segs_8822c), 21502774f206SBjoern A. Zeeb }; 21512774f206SBjoern A. Zeeb 21522774f206SBjoern A. Zeeb static int rtw8822c_dump_fw_crash(struct rtw_dev *rtwdev) 21532774f206SBjoern A. Zeeb { 21542774f206SBjoern A. Zeeb #define __dump_fw_8822c(_dev, _mem) \ 21552774f206SBjoern A. Zeeb rtw_dump_fw(_dev, OCPBASE_ ## _mem ## _88XX, \ 21562774f206SBjoern A. Zeeb FWCD_SIZE_ ## _mem ## _8822C, RTW_FWCD_ ## _mem) 21572774f206SBjoern A. Zeeb int ret; 21582774f206SBjoern A. Zeeb 21592774f206SBjoern A. Zeeb ret = rtw_dump_reg(rtwdev, 0x0, FWCD_SIZE_REG_8822C); 21602774f206SBjoern A. Zeeb if (ret) 21612774f206SBjoern A. Zeeb return ret; 21622774f206SBjoern A. Zeeb ret = __dump_fw_8822c(rtwdev, DMEM); 21632774f206SBjoern A. Zeeb if (ret) 21642774f206SBjoern A. Zeeb return ret; 21652774f206SBjoern A. Zeeb ret = __dump_fw_8822c(rtwdev, IMEM); 21662774f206SBjoern A. Zeeb if (ret) 21672774f206SBjoern A. Zeeb return ret; 21682774f206SBjoern A. Zeeb ret = __dump_fw_8822c(rtwdev, EMEM); 21692774f206SBjoern A. Zeeb if (ret) 21702774f206SBjoern A. Zeeb return ret; 21712774f206SBjoern A. Zeeb ret = __dump_fw_8822c(rtwdev, ROM); 21722774f206SBjoern A. Zeeb if (ret) 21732774f206SBjoern A. Zeeb return ret; 21742774f206SBjoern A. Zeeb 21752774f206SBjoern A. Zeeb return 0; 21762774f206SBjoern A. Zeeb 21772774f206SBjoern A. Zeeb #undef __dump_fw_8822c 21782774f206SBjoern A. Zeeb } 21792774f206SBjoern A. Zeeb 21802774f206SBjoern A. Zeeb static void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable) 21812774f206SBjoern A. Zeeb { 21822774f206SBjoern A. Zeeb if (enable) { 21832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x1); 21842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANAPAR_A, BIT_ANAPAR_UPDATE, 0x1); 21852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANAPAR_B, BIT_ANAPAR_UPDATE, 0x1); 21862774f206SBjoern A. Zeeb } else { 21872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x0); 21882774f206SBjoern A. Zeeb } 21892774f206SBjoern A. Zeeb } 21902774f206SBjoern A. Zeeb 21912774f206SBjoern A. Zeeb static void rtw8822c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 21922774f206SBjoern A. Zeeb { 21932774f206SBjoern A. Zeeb #define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) 21942774f206SBjoern A. Zeeb #define RF18_BAND_2G (0) 21952774f206SBjoern A. Zeeb #define RF18_BAND_5G (BIT(16) | BIT(8)) 21962774f206SBjoern A. Zeeb #define RF18_CHANNEL_MASK (MASKBYTE0) 21972774f206SBjoern A. Zeeb #define RF18_RFSI_MASK (BIT(18) | BIT(17)) 21982774f206SBjoern A. Zeeb #define RF18_RFSI_GE_CH80 (BIT(17)) 21992774f206SBjoern A. Zeeb #define RF18_RFSI_GT_CH140 (BIT(18)) 22002774f206SBjoern A. Zeeb #define RF18_BW_MASK (BIT(13) | BIT(12)) 22012774f206SBjoern A. Zeeb #define RF18_BW_20M (BIT(13) | BIT(12)) 22022774f206SBjoern A. Zeeb #define RF18_BW_40M (BIT(13)) 22032774f206SBjoern A. Zeeb #define RF18_BW_80M (BIT(12)) 22042774f206SBjoern A. Zeeb 22052774f206SBjoern A. Zeeb u32 rf_reg18 = 0; 22062774f206SBjoern A. Zeeb u32 rf_rxbb = 0; 22072774f206SBjoern A. Zeeb 22084f3b2bbaSBjoern A. Zeeb #if defined(__linux__) 22092774f206SBjoern A. Zeeb rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); 22104f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__) 22114f3b2bbaSBjoern A. Zeeb rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 22124f3b2bbaSBjoern A. Zeeb #endif 22132774f206SBjoern A. Zeeb 22142774f206SBjoern A. Zeeb rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | 22152774f206SBjoern A. Zeeb RF18_BW_MASK); 22162774f206SBjoern A. Zeeb 22172774f206SBjoern A. Zeeb rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); 22182774f206SBjoern A. Zeeb rf_reg18 |= (channel & RF18_CHANNEL_MASK); 22192774f206SBjoern A. Zeeb if (IS_CH_5G_BAND_4(channel)) 22202774f206SBjoern A. Zeeb rf_reg18 |= RF18_RFSI_GT_CH140; 22212774f206SBjoern A. Zeeb else if (IS_CH_5G_BAND_3(channel)) 22222774f206SBjoern A. Zeeb rf_reg18 |= RF18_RFSI_GE_CH80; 22232774f206SBjoern A. Zeeb 22242774f206SBjoern A. Zeeb switch (bw) { 22252774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_5: 22262774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_10: 22272774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_20: 22282774f206SBjoern A. Zeeb default: 22292774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_20M; 22302774f206SBjoern A. Zeeb rf_rxbb = 0x18; 22312774f206SBjoern A. Zeeb break; 22322774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_40: 22332774f206SBjoern A. Zeeb /* RF bandwidth */ 22342774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_40M; 22352774f206SBjoern A. Zeeb rf_rxbb = 0x10; 22362774f206SBjoern A. Zeeb break; 22372774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_80: 22382774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_80M; 22392774f206SBjoern A. Zeeb rf_rxbb = 0x8; 22402774f206SBjoern A. Zeeb break; 22412774f206SBjoern A. Zeeb } 22422774f206SBjoern A. Zeeb 22432774f206SBjoern A. Zeeb rtw8822c_rstb_3wire(rtwdev, false); 22442774f206SBjoern A. Zeeb 22452774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x01); 22462774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, 0x1f, 0x12); 22472774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, 0xfffff, rf_rxbb); 22482774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x00); 22492774f206SBjoern A. Zeeb 22502774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x01); 22512774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWA, 0x1f, 0x12); 22522774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWD0, 0xfffff, rf_rxbb); 22532774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x00); 22542774f206SBjoern A. Zeeb 22552774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_reg18); 22562774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_reg18); 22572774f206SBjoern A. Zeeb 22582774f206SBjoern A. Zeeb rtw8822c_rstb_3wire(rtwdev, true); 22592774f206SBjoern A. Zeeb } 22602774f206SBjoern A. Zeeb 22612774f206SBjoern A. Zeeb static void rtw8822c_toggle_igi(struct rtw_dev *rtwdev) 22622774f206SBjoern A. Zeeb { 22632774f206SBjoern A. Zeeb u32 igi; 22642774f206SBjoern A. Zeeb 22652774f206SBjoern A. Zeeb igi = rtw_read32_mask(rtwdev, REG_RXIGI, 0x7f); 22662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi - 2); 22672774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi - 2); 22682774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi); 22692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi); 22702774f206SBjoern A. Zeeb } 22712774f206SBjoern A. Zeeb 22722774f206SBjoern A. Zeeb static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, 22732774f206SBjoern A. Zeeb u8 primary_ch_idx) 22742774f206SBjoern A. Zeeb { 22752774f206SBjoern A. Zeeb if (IS_CH_2G_BAND(channel)) { 22762774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); 22772774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_TXF4, BIT(20)); 22782774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 22792774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); 22802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0xF); 22812774f206SBjoern A. Zeeb 22822774f206SBjoern A. Zeeb switch (bw) { 22832774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_20: 22842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, 22852774f206SBjoern A. Zeeb 0x5); 22862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, 22872774f206SBjoern A. Zeeb 0x5); 22882774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 22892774f206SBjoern A. Zeeb 0x6); 22902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 22912774f206SBjoern A. Zeeb 0x6); 22922774f206SBjoern A. Zeeb break; 22932774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_40: 22942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, 22952774f206SBjoern A. Zeeb 0x4); 22962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, 22972774f206SBjoern A. Zeeb 0x4); 22982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 22992774f206SBjoern A. Zeeb 0x0); 23002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 23012774f206SBjoern A. Zeeb 0x0); 23022774f206SBjoern A. Zeeb break; 23032774f206SBjoern A. Zeeb } 23042774f206SBjoern A. Zeeb if (channel == 13 || channel == 14) 23052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x969); 23062774f206SBjoern A. Zeeb else if (channel == 11 || channel == 12) 23072774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x96a); 23082774f206SBjoern A. Zeeb else 23092774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x9aa); 23102774f206SBjoern A. Zeeb if (channel == 14) { 23112774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x3da0); 23122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, 23132774f206SBjoern A. Zeeb 0x4962c931); 23142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x6aa3); 23152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xaa7b); 23162774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xf3d7); 23172774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 0x0); 23182774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, 23192774f206SBjoern A. Zeeb 0xff012455); 23202774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 0xffff); 23212774f206SBjoern A. Zeeb } else { 23222774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x5284); 23232774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, 23242774f206SBjoern A. Zeeb 0x3e18fec8); 23252774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x0a88); 23262774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xacc4); 23272774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xc8b2); 23282774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 23292774f206SBjoern A. Zeeb 0x00faf0de); 23302774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, 23312774f206SBjoern A. Zeeb 0x00122344); 23322774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 23332774f206SBjoern A. Zeeb 0x0fffffff); 23342774f206SBjoern A. Zeeb } 23352774f206SBjoern A. Zeeb if (channel == 13) 23362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); 23372774f206SBjoern A. Zeeb else 23382774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x1); 23392774f206SBjoern A. Zeeb } else if (IS_CH_5G_BAND(channel)) { 23402774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); 23412774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 23422774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); 23432774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_TXF4, BIT(20)); 23442774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22); 23452774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); 23462774f206SBjoern A. Zeeb if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { 23472774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 23482774f206SBjoern A. Zeeb 0x1); 23492774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 23502774f206SBjoern A. Zeeb 0x1); 23512774f206SBjoern A. Zeeb } else if (IS_CH_5G_BAND_3(channel)) { 23522774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 23532774f206SBjoern A. Zeeb 0x2); 23542774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 23552774f206SBjoern A. Zeeb 0x2); 23562774f206SBjoern A. Zeeb } else if (IS_CH_5G_BAND_4(channel)) { 23572774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 23582774f206SBjoern A. Zeeb 0x3); 23592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 23602774f206SBjoern A. Zeeb 0x3); 23612774f206SBjoern A. Zeeb } 23622774f206SBjoern A. Zeeb 23632774f206SBjoern A. Zeeb if (channel >= 36 && channel <= 51) 23642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x494); 23652774f206SBjoern A. Zeeb else if (channel >= 52 && channel <= 55) 23662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x493); 23672774f206SBjoern A. Zeeb else if (channel >= 56 && channel <= 111) 23682774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x453); 23692774f206SBjoern A. Zeeb else if (channel >= 112 && channel <= 119) 23702774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x452); 23712774f206SBjoern A. Zeeb else if (channel >= 120 && channel <= 172) 23722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x412); 23732774f206SBjoern A. Zeeb else if (channel >= 173 && channel <= 177) 23742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x411); 23752774f206SBjoern A. Zeeb } 23762774f206SBjoern A. Zeeb 23772774f206SBjoern A. Zeeb switch (bw) { 23782774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_20: 23792774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x19B); 23802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 23812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x0); 23822774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x7); 23832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x6); 23842774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 23852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 23862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 23872774f206SBjoern A. Zeeb break; 23882774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_40: 23892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4), 23902774f206SBjoern A. Zeeb (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); 23912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x5); 23922774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); 23932774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, 23942774f206SBjoern A. Zeeb (primary_ch_idx | (primary_ch_idx << 4))); 23952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x1); 23962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 23972774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); 23982774f206SBjoern A. Zeeb break; 23992774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_80: 24002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0xa); 24012774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); 24022774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, 24032774f206SBjoern A. Zeeb (primary_ch_idx | (primary_ch_idx << 4))); 24042774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x6); 24052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); 24062774f206SBjoern A. Zeeb break; 24072774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_5: 24082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); 24092774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 24102774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x1); 24112774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x4); 24122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x4); 24132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 24142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 24152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 24162774f206SBjoern A. Zeeb break; 24172774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_10: 24182774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); 24192774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 24202774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x2); 24212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x6); 24222774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x5); 24232774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 24242774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 24252774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 24262774f206SBjoern A. Zeeb break; 24272774f206SBjoern A. Zeeb } 24282774f206SBjoern A. Zeeb } 24292774f206SBjoern A. Zeeb 24302774f206SBjoern A. Zeeb static void rtw8822c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, 24312774f206SBjoern A. Zeeb u8 primary_chan_idx) 24322774f206SBjoern A. Zeeb { 24332774f206SBjoern A. Zeeb rtw8822c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 24342774f206SBjoern A. Zeeb rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); 24352774f206SBjoern A. Zeeb rtw8822c_set_channel_rf(rtwdev, channel, bw); 24362774f206SBjoern A. Zeeb rtw8822c_toggle_igi(rtwdev); 24372774f206SBjoern A. Zeeb } 24382774f206SBjoern A. Zeeb 24392774f206SBjoern A. Zeeb static void rtw8822c_config_cck_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 24402774f206SBjoern A. Zeeb { 24412774f206SBjoern A. Zeeb if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { 24422774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x0); 24432774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x0); 24442774f206SBjoern A. Zeeb } else if (rx_path == BB_PATH_AB) { 24452774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x1); 24462774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x1); 24472774f206SBjoern A. Zeeb } 24482774f206SBjoern A. Zeeb 24492774f206SBjoern A. Zeeb if (rx_path == BB_PATH_A) 24502774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x0); 24512774f206SBjoern A. Zeeb else if (rx_path == BB_PATH_B) 24522774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x5); 24532774f206SBjoern A. Zeeb else if (rx_path == BB_PATH_AB) 24542774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x1); 24552774f206SBjoern A. Zeeb } 24562774f206SBjoern A. Zeeb 24572774f206SBjoern A. Zeeb static void rtw8822c_config_ofdm_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 24582774f206SBjoern A. Zeeb { 24592774f206SBjoern A. Zeeb if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { 24602774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x0); 24612774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x0); 24622774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x0); 24632774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x0); 24642774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x0); 24652774f206SBjoern A. Zeeb } else if (rx_path == BB_PATH_AB) { 24662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x1); 24672774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x1); 24682774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x1); 24692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x1); 24702774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x1); 24712774f206SBjoern A. Zeeb } 24722774f206SBjoern A. Zeeb 24732774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x824, 0x0f000000, rx_path); 24742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x824, 0x000f0000, rx_path); 24752774f206SBjoern A. Zeeb } 24762774f206SBjoern A. Zeeb 24772774f206SBjoern A. Zeeb static void rtw8822c_config_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 24782774f206SBjoern A. Zeeb { 24792774f206SBjoern A. Zeeb rtw8822c_config_cck_rx_path(rtwdev, rx_path); 24802774f206SBjoern A. Zeeb rtw8822c_config_ofdm_rx_path(rtwdev, rx_path); 24812774f206SBjoern A. Zeeb } 24822774f206SBjoern A. Zeeb 24832774f206SBjoern A. Zeeb static void rtw8822c_config_cck_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 24842774f206SBjoern A. Zeeb bool is_tx2_path) 24852774f206SBjoern A. Zeeb { 24862774f206SBjoern A. Zeeb if (tx_path == BB_PATH_A) { 24872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); 24882774f206SBjoern A. Zeeb } else if (tx_path == BB_PATH_B) { 24892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x4); 24902774f206SBjoern A. Zeeb } else { 24912774f206SBjoern A. Zeeb if (is_tx2_path) 24922774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0xc); 24932774f206SBjoern A. Zeeb else 24942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); 24952774f206SBjoern A. Zeeb } 24962774f206SBjoern A. Zeeb rtw8822c_bb_reset(rtwdev); 24972774f206SBjoern A. Zeeb } 24982774f206SBjoern A. Zeeb 24992774f206SBjoern A. Zeeb static void rtw8822c_config_ofdm_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 25002774f206SBjoern A. Zeeb enum rtw_bb_path tx_path_sel_1ss) 25012774f206SBjoern A. Zeeb { 25022774f206SBjoern A. Zeeb if (tx_path == BB_PATH_A) { 25032774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x11); 25042774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); 25052774f206SBjoern A. Zeeb } else if (tx_path == BB_PATH_B) { 25062774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x12); 25072774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); 25082774f206SBjoern A. Zeeb } else { 25092774f206SBjoern A. Zeeb if (tx_path_sel_1ss == BB_PATH_AB) { 25102774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x33); 25112774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0404); 25122774f206SBjoern A. Zeeb } else if (tx_path_sel_1ss == BB_PATH_B) { 25132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x32); 25142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); 25152774f206SBjoern A. Zeeb } else if (tx_path_sel_1ss == BB_PATH_A) { 25162774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x31); 25172774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); 25182774f206SBjoern A. Zeeb } 25192774f206SBjoern A. Zeeb } 25202774f206SBjoern A. Zeeb rtw8822c_bb_reset(rtwdev); 25212774f206SBjoern A. Zeeb } 25222774f206SBjoern A. Zeeb 25232774f206SBjoern A. Zeeb static void rtw8822c_config_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 25242774f206SBjoern A. Zeeb enum rtw_bb_path tx_path_sel_1ss, 25252774f206SBjoern A. Zeeb enum rtw_bb_path tx_path_cck, 25262774f206SBjoern A. Zeeb bool is_tx2_path) 25272774f206SBjoern A. Zeeb { 25282774f206SBjoern A. Zeeb rtw8822c_config_cck_tx_path(rtwdev, tx_path_cck, is_tx2_path); 25292774f206SBjoern A. Zeeb rtw8822c_config_ofdm_tx_path(rtwdev, tx_path, tx_path_sel_1ss); 25302774f206SBjoern A. Zeeb rtw8822c_bb_reset(rtwdev); 25312774f206SBjoern A. Zeeb } 25322774f206SBjoern A. Zeeb 25332774f206SBjoern A. Zeeb static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, 25342774f206SBjoern A. Zeeb u8 rx_path, bool is_tx2_path) 25352774f206SBjoern A. Zeeb { 25362774f206SBjoern A. Zeeb if ((tx_path | rx_path) & BB_PATH_A) 25372774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x33312); 25382774f206SBjoern A. Zeeb else 25392774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x11111); 25402774f206SBjoern A. Zeeb if ((tx_path | rx_path) & BB_PATH_B) 25412774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x33312); 25422774f206SBjoern A. Zeeb else 25432774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x11111); 25442774f206SBjoern A. Zeeb 25452774f206SBjoern A. Zeeb rtw8822c_config_rx_path(rtwdev, rx_path); 25462774f206SBjoern A. Zeeb rtw8822c_config_tx_path(rtwdev, tx_path, BB_PATH_A, BB_PATH_A, 25472774f206SBjoern A. Zeeb is_tx2_path); 25482774f206SBjoern A. Zeeb 25492774f206SBjoern A. Zeeb rtw8822c_toggle_igi(rtwdev); 25502774f206SBjoern A. Zeeb } 25512774f206SBjoern A. Zeeb 25522774f206SBjoern A. Zeeb static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, 25532774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 25542774f206SBjoern A. Zeeb { 25552774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 25562774f206SBjoern A. Zeeb u8 l_bnd, u_bnd; 25572774f206SBjoern A. Zeeb u8 gain_a, gain_b; 25582774f206SBjoern A. Zeeb s8 rx_power[RTW_RF_PATH_MAX]; 25592774f206SBjoern A. Zeeb s8 min_rx_power = -120; 25602774f206SBjoern A. Zeeb u8 rssi; 25612774f206SBjoern A. Zeeb u8 channel; 25622774f206SBjoern A. Zeeb int path; 25632774f206SBjoern A. Zeeb 25642774f206SBjoern A. Zeeb rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status); 25652774f206SBjoern A. Zeeb rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status); 25662774f206SBjoern A. Zeeb l_bnd = dm_info->cck_gi_l_bnd; 25672774f206SBjoern A. Zeeb u_bnd = dm_info->cck_gi_u_bnd; 25682774f206SBjoern A. Zeeb gain_a = GET_PHY_STAT_P0_GAIN_A(phy_status); 25692774f206SBjoern A. Zeeb gain_b = GET_PHY_STAT_P0_GAIN_B(phy_status); 25702774f206SBjoern A. Zeeb if (gain_a < l_bnd) 25712774f206SBjoern A. Zeeb rx_power[RF_PATH_A] += (l_bnd - gain_a) << 1; 25722774f206SBjoern A. Zeeb else if (gain_a > u_bnd) 25732774f206SBjoern A. Zeeb rx_power[RF_PATH_A] -= (gain_a - u_bnd) << 1; 25742774f206SBjoern A. Zeeb if (gain_b < l_bnd) 25752774f206SBjoern A. Zeeb rx_power[RF_PATH_B] += (l_bnd - gain_b) << 1; 25762774f206SBjoern A. Zeeb else if (gain_b > u_bnd) 25772774f206SBjoern A. Zeeb rx_power[RF_PATH_B] -= (gain_b - u_bnd) << 1; 25782774f206SBjoern A. Zeeb 25792774f206SBjoern A. Zeeb rx_power[RF_PATH_A] -= 110; 25802774f206SBjoern A. Zeeb rx_power[RF_PATH_B] -= 110; 25812774f206SBjoern A. Zeeb 25822774f206SBjoern A. Zeeb channel = GET_PHY_STAT_P0_CHANNEL(phy_status); 2583*a0ccc12fSBjoern A. Zeeb if (channel != 0) 25842774f206SBjoern A. Zeeb rtw_set_rx_freq_band(pkt_stat, channel); 2585*a0ccc12fSBjoern A. Zeeb else 2586*a0ccc12fSBjoern A. Zeeb pkt_stat->channel_invalid = true; 25872774f206SBjoern A. Zeeb 25882774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; 25892774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; 25902774f206SBjoern A. Zeeb 25912774f206SBjoern A. Zeeb for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 25922774f206SBjoern A. Zeeb rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 25932774f206SBjoern A. Zeeb dm_info->rssi[path] = rssi; 25942774f206SBjoern A. Zeeb } 25952774f206SBjoern A. Zeeb 25962774f206SBjoern A. Zeeb pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 25972774f206SBjoern A. Zeeb pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 25982774f206SBjoern A. Zeeb pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 25992774f206SBjoern A. Zeeb min_rx_power); 26002774f206SBjoern A. Zeeb } 26012774f206SBjoern A. Zeeb 26022774f206SBjoern A. Zeeb static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 26032774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 26042774f206SBjoern A. Zeeb { 26052774f206SBjoern A. Zeeb struct rtw_path_div *p_div = &rtwdev->dm_path_div; 26062774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 26072774f206SBjoern A. Zeeb u8 rxsc, bw; 26082774f206SBjoern A. Zeeb s8 min_rx_power = -120; 26092774f206SBjoern A. Zeeb s8 rx_evm; 26102774f206SBjoern A. Zeeb u8 evm_dbm = 0; 26112774f206SBjoern A. Zeeb u8 rssi; 26122774f206SBjoern A. Zeeb int path; 26132774f206SBjoern A. Zeeb u8 channel; 26142774f206SBjoern A. Zeeb 26152774f206SBjoern A. Zeeb if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 26162774f206SBjoern A. Zeeb rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); 26172774f206SBjoern A. Zeeb else 26182774f206SBjoern A. Zeeb rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); 26192774f206SBjoern A. Zeeb 2620*a0ccc12fSBjoern A. Zeeb if (rxsc == 0) 2621*a0ccc12fSBjoern A. Zeeb bw = rtwdev->hal.current_band_width; 2622*a0ccc12fSBjoern A. Zeeb else if (rxsc >= 1 && rxsc <= 8) 26232774f206SBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_20; 2624*a0ccc12fSBjoern A. Zeeb else if (rxsc >= 9 && rxsc <= 12) 2625*a0ccc12fSBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_40; 2626*a0ccc12fSBjoern A. Zeeb else 2627*a0ccc12fSBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_80; 26282774f206SBjoern A. Zeeb 26292774f206SBjoern A. Zeeb channel = GET_PHY_STAT_P1_CHANNEL(phy_status); 26302774f206SBjoern A. Zeeb rtw_set_rx_freq_band(pkt_stat, channel); 26312774f206SBjoern A. Zeeb 26322774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; 26332774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110; 26342774f206SBjoern A. Zeeb pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2); 26352774f206SBjoern A. Zeeb pkt_stat->bw = bw; 26362774f206SBjoern A. Zeeb pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], 26372774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_B], 26382774f206SBjoern A. Zeeb min_rx_power); 26392774f206SBjoern A. Zeeb 26402774f206SBjoern A. Zeeb dm_info->curr_rx_rate = pkt_stat->rate; 26412774f206SBjoern A. Zeeb 26422774f206SBjoern A. Zeeb pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); 26432774f206SBjoern A. Zeeb pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); 26442774f206SBjoern A. Zeeb 26452774f206SBjoern A. Zeeb pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); 26462774f206SBjoern A. Zeeb pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); 26472774f206SBjoern A. Zeeb 26482774f206SBjoern A. Zeeb pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); 26492774f206SBjoern A. Zeeb pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); 26502774f206SBjoern A. Zeeb 26512774f206SBjoern A. Zeeb for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 26522774f206SBjoern A. Zeeb rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 26532774f206SBjoern A. Zeeb dm_info->rssi[path] = rssi; 26542774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 26552774f206SBjoern A. Zeeb p_div->path_a_sum += rssi; 26562774f206SBjoern A. Zeeb p_div->path_a_cnt++; 26572774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 26582774f206SBjoern A. Zeeb p_div->path_b_sum += rssi; 26592774f206SBjoern A. Zeeb p_div->path_b_cnt++; 26602774f206SBjoern A. Zeeb } 26612774f206SBjoern A. Zeeb dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; 26622774f206SBjoern A. Zeeb dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; 26632774f206SBjoern A. Zeeb 26642774f206SBjoern A. Zeeb rx_evm = pkt_stat->rx_evm[path]; 26652774f206SBjoern A. Zeeb 26662774f206SBjoern A. Zeeb if (rx_evm < 0) { 26672774f206SBjoern A. Zeeb if (rx_evm == S8_MIN) 26682774f206SBjoern A. Zeeb evm_dbm = 0; 26692774f206SBjoern A. Zeeb else 26702774f206SBjoern A. Zeeb evm_dbm = ((u8)-rx_evm >> 1); 26712774f206SBjoern A. Zeeb } 26722774f206SBjoern A. Zeeb dm_info->rx_evm_dbm[path] = evm_dbm; 26732774f206SBjoern A. Zeeb } 26742774f206SBjoern A. Zeeb rtw_phy_parsing_cfo(rtwdev, pkt_stat); 26752774f206SBjoern A. Zeeb } 26762774f206SBjoern A. Zeeb 26772774f206SBjoern A. Zeeb static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 26782774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 26792774f206SBjoern A. Zeeb { 26802774f206SBjoern A. Zeeb u8 page; 26812774f206SBjoern A. Zeeb 26822774f206SBjoern A. Zeeb page = *phy_status & 0xf; 26832774f206SBjoern A. Zeeb 26842774f206SBjoern A. Zeeb switch (page) { 26852774f206SBjoern A. Zeeb case 0: 26862774f206SBjoern A. Zeeb query_phy_status_page0(rtwdev, phy_status, pkt_stat); 26872774f206SBjoern A. Zeeb break; 26882774f206SBjoern A. Zeeb case 1: 26892774f206SBjoern A. Zeeb query_phy_status_page1(rtwdev, phy_status, pkt_stat); 26902774f206SBjoern A. Zeeb break; 26912774f206SBjoern A. Zeeb default: 26922774f206SBjoern A. Zeeb rtw_warn(rtwdev, "unused phy status page (%d)\n", page); 26932774f206SBjoern A. Zeeb return; 26942774f206SBjoern A. Zeeb } 26952774f206SBjoern A. Zeeb } 26962774f206SBjoern A. Zeeb 26972774f206SBjoern A. Zeeb static void 26982774f206SBjoern A. Zeeb rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, 26992774f206SBjoern A. Zeeb u8 *tx_pwr_ref_ofdm) 27002774f206SBjoern A. Zeeb { 27012774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 27022774f206SBjoern A. Zeeb u32 txref_cck[2] = {0x18a0, 0x41a0}; 27032774f206SBjoern A. Zeeb u32 txref_ofdm[2] = {0x18e8, 0x41e8}; 27042774f206SBjoern A. Zeeb u8 path; 27052774f206SBjoern A. Zeeb 27062774f206SBjoern A. Zeeb for (path = 0; path < hal->rf_path_num; path++) { 27072774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); 27082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, txref_cck[path], 0x7f0000, 27092774f206SBjoern A. Zeeb tx_pwr_ref_cck[path]); 27102774f206SBjoern A. Zeeb } 27112774f206SBjoern A. Zeeb for (path = 0; path < hal->rf_path_num; path++) { 27122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); 27132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, txref_ofdm[path], 0x1fc00, 27142774f206SBjoern A. Zeeb tx_pwr_ref_ofdm[path]); 27152774f206SBjoern A. Zeeb } 27162774f206SBjoern A. Zeeb } 27172774f206SBjoern A. Zeeb 27182774f206SBjoern A. Zeeb static void rtw8822c_set_tx_power_diff(struct rtw_dev *rtwdev, u8 rate, 27192774f206SBjoern A. Zeeb s8 *diff_idx) 27202774f206SBjoern A. Zeeb { 27212774f206SBjoern A. Zeeb u32 offset_txagc = 0x3a00; 27222774f206SBjoern A. Zeeb u8 rate_idx = rate & 0xfc; 27232774f206SBjoern A. Zeeb u8 pwr_idx[4]; 27242774f206SBjoern A. Zeeb u32 phy_pwr_idx; 27252774f206SBjoern A. Zeeb int i; 27262774f206SBjoern A. Zeeb 27272774f206SBjoern A. Zeeb for (i = 0; i < 4; i++) 27282774f206SBjoern A. Zeeb pwr_idx[i] = diff_idx[i] & 0x7f; 27292774f206SBjoern A. Zeeb 27302774f206SBjoern A. Zeeb phy_pwr_idx = pwr_idx[0] | 27312774f206SBjoern A. Zeeb (pwr_idx[1] << 8) | 27322774f206SBjoern A. Zeeb (pwr_idx[2] << 16) | 27332774f206SBjoern A. Zeeb (pwr_idx[3] << 24); 27342774f206SBjoern A. Zeeb 27352774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0x0); 27362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, offset_txagc + rate_idx, MASKDWORD, 27372774f206SBjoern A. Zeeb phy_pwr_idx); 27382774f206SBjoern A. Zeeb } 27392774f206SBjoern A. Zeeb 27402774f206SBjoern A. Zeeb static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) 27412774f206SBjoern A. Zeeb { 27422774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 27432774f206SBjoern A. Zeeb u8 rs, rate, j; 27442774f206SBjoern A. Zeeb u8 pwr_ref_cck[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATE11M], 27452774f206SBjoern A. Zeeb hal->tx_pwr_tbl[RF_PATH_B][DESC_RATE11M]}; 27462774f206SBjoern A. Zeeb u8 pwr_ref_ofdm[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATEMCS7], 27472774f206SBjoern A. Zeeb hal->tx_pwr_tbl[RF_PATH_B][DESC_RATEMCS7]}; 27482774f206SBjoern A. Zeeb s8 diff_a, diff_b; 27492774f206SBjoern A. Zeeb u8 pwr_a, pwr_b; 27502774f206SBjoern A. Zeeb s8 diff_idx[4]; 27512774f206SBjoern A. Zeeb 27522774f206SBjoern A. Zeeb rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); 27532774f206SBjoern A. Zeeb for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { 27542774f206SBjoern A. Zeeb for (j = 0; j < rtw_rate_size[rs]; j++) { 27552774f206SBjoern A. Zeeb rate = rtw_rate_section[rs][j]; 27562774f206SBjoern A. Zeeb pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; 27572774f206SBjoern A. Zeeb pwr_b = hal->tx_pwr_tbl[RF_PATH_B][rate]; 27582774f206SBjoern A. Zeeb if (rs == 0) { 27592774f206SBjoern A. Zeeb diff_a = (s8)pwr_a - (s8)pwr_ref_cck[0]; 27602774f206SBjoern A. Zeeb diff_b = (s8)pwr_b - (s8)pwr_ref_cck[1]; 27612774f206SBjoern A. Zeeb } else { 27622774f206SBjoern A. Zeeb diff_a = (s8)pwr_a - (s8)pwr_ref_ofdm[0]; 27632774f206SBjoern A. Zeeb diff_b = (s8)pwr_b - (s8)pwr_ref_ofdm[1]; 27642774f206SBjoern A. Zeeb } 27652774f206SBjoern A. Zeeb diff_idx[rate % 4] = min(diff_a, diff_b); 27662774f206SBjoern A. Zeeb if (rate % 4 == 3) 27672774f206SBjoern A. Zeeb rtw8822c_set_tx_power_diff(rtwdev, rate - 3, 27682774f206SBjoern A. Zeeb diff_idx); 27692774f206SBjoern A. Zeeb } 27702774f206SBjoern A. Zeeb } 27712774f206SBjoern A. Zeeb } 27722774f206SBjoern A. Zeeb 27732774f206SBjoern A. Zeeb static int rtw8822c_set_antenna(struct rtw_dev *rtwdev, 27742774f206SBjoern A. Zeeb u32 antenna_tx, 27752774f206SBjoern A. Zeeb u32 antenna_rx) 27762774f206SBjoern A. Zeeb { 27772774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 27782774f206SBjoern A. Zeeb 27792774f206SBjoern A. Zeeb switch (antenna_tx) { 27802774f206SBjoern A. Zeeb case BB_PATH_A: 27812774f206SBjoern A. Zeeb case BB_PATH_B: 27822774f206SBjoern A. Zeeb case BB_PATH_AB: 27832774f206SBjoern A. Zeeb break; 27842774f206SBjoern A. Zeeb default: 27859c951734SBjoern A. Zeeb rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); 27862774f206SBjoern A. Zeeb return -EINVAL; 27872774f206SBjoern A. Zeeb } 27882774f206SBjoern A. Zeeb 27892774f206SBjoern A. Zeeb /* path B only is not available for RX */ 27902774f206SBjoern A. Zeeb switch (antenna_rx) { 27912774f206SBjoern A. Zeeb case BB_PATH_A: 27922774f206SBjoern A. Zeeb case BB_PATH_AB: 27932774f206SBjoern A. Zeeb break; 27942774f206SBjoern A. Zeeb default: 27959c951734SBjoern A. Zeeb rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); 27962774f206SBjoern A. Zeeb return -EINVAL; 27972774f206SBjoern A. Zeeb } 27982774f206SBjoern A. Zeeb 27992774f206SBjoern A. Zeeb hal->antenna_tx = antenna_tx; 28002774f206SBjoern A. Zeeb hal->antenna_rx = antenna_rx; 28012774f206SBjoern A. Zeeb 28022774f206SBjoern A. Zeeb rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); 28032774f206SBjoern A. Zeeb 28042774f206SBjoern A. Zeeb return 0; 28052774f206SBjoern A. Zeeb } 28062774f206SBjoern A. Zeeb 28072774f206SBjoern A. Zeeb static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 28082774f206SBjoern A. Zeeb { 28092774f206SBjoern A. Zeeb u8 ldo_pwr; 28102774f206SBjoern A. Zeeb 28112774f206SBjoern A. Zeeb ldo_pwr = rtw_read8(rtwdev, REG_ANAPARLDO_POW_MAC); 28122774f206SBjoern A. Zeeb ldo_pwr = enable ? ldo_pwr | BIT_LDOE25_PON : ldo_pwr & ~BIT_LDOE25_PON; 28132774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr); 28142774f206SBjoern A. Zeeb } 28152774f206SBjoern A. Zeeb 28162774f206SBjoern A. Zeeb static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) 28172774f206SBjoern A. Zeeb { 28182774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 28192774f206SBjoern A. Zeeb u32 cck_enable; 28202774f206SBjoern A. Zeeb u32 cck_fa_cnt; 28212774f206SBjoern A. Zeeb u32 crc32_cnt; 28222774f206SBjoern A. Zeeb u32 cca32_cnt; 28232774f206SBjoern A. Zeeb u32 ofdm_fa_cnt; 28242774f206SBjoern A. Zeeb u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; 28252774f206SBjoern A. Zeeb u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, 28262774f206SBjoern A. Zeeb fast_fsync, crc8_fail_vhta, mcs_fail_vht; 28272774f206SBjoern A. Zeeb 28282774f206SBjoern A. Zeeb cck_enable = rtw_read32(rtwdev, REG_ENCCK) & BIT_CCK_BLK_EN; 28292774f206SBjoern A. Zeeb cck_fa_cnt = rtw_read16(rtwdev, REG_CCK_FACNT); 28302774f206SBjoern A. Zeeb 28312774f206SBjoern A. Zeeb ofdm_fa_cnt1 = rtw_read32(rtwdev, REG_OFDM_FACNT1); 28322774f206SBjoern A. Zeeb ofdm_fa_cnt2 = rtw_read32(rtwdev, REG_OFDM_FACNT2); 28332774f206SBjoern A. Zeeb ofdm_fa_cnt3 = rtw_read32(rtwdev, REG_OFDM_FACNT3); 28342774f206SBjoern A. Zeeb ofdm_fa_cnt4 = rtw_read32(rtwdev, REG_OFDM_FACNT4); 28352774f206SBjoern A. Zeeb ofdm_fa_cnt5 = rtw_read32(rtwdev, REG_OFDM_FACNT5); 28362774f206SBjoern A. Zeeb 28372774f206SBjoern A. Zeeb parity_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt1); 28382774f206SBjoern A. Zeeb rate_illegal = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt2); 28392774f206SBjoern A. Zeeb crc8_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt2); 28402774f206SBjoern A. Zeeb crc8_fail_vhta = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt3); 28412774f206SBjoern A. Zeeb mcs_fail = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt4); 28422774f206SBjoern A. Zeeb mcs_fail_vht = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt4); 28432774f206SBjoern A. Zeeb fast_fsync = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt5); 28442774f206SBjoern A. Zeeb sb_search_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt5); 28452774f206SBjoern A. Zeeb 28462774f206SBjoern A. Zeeb ofdm_fa_cnt = parity_fail + rate_illegal + crc8_fail + crc8_fail_vhta + 28472774f206SBjoern A. Zeeb mcs_fail + mcs_fail_vht + fast_fsync + sb_search_fail; 28482774f206SBjoern A. Zeeb 28492774f206SBjoern A. Zeeb dm_info->cck_fa_cnt = cck_fa_cnt; 28502774f206SBjoern A. Zeeb dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 28512774f206SBjoern A. Zeeb dm_info->total_fa_cnt = ofdm_fa_cnt; 28522774f206SBjoern A. Zeeb dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0; 28532774f206SBjoern A. Zeeb 28542774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, 0x2c04); 28552774f206SBjoern A. Zeeb dm_info->cck_ok_cnt = crc32_cnt & 0xffff; 28562774f206SBjoern A. Zeeb dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 28572774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, 0x2c14); 28582774f206SBjoern A. Zeeb dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff; 28592774f206SBjoern A. Zeeb dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 28602774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, 0x2c10); 28612774f206SBjoern A. Zeeb dm_info->ht_ok_cnt = crc32_cnt & 0xffff; 28622774f206SBjoern A. Zeeb dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 28632774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, 0x2c0c); 28642774f206SBjoern A. Zeeb dm_info->vht_ok_cnt = crc32_cnt & 0xffff; 28652774f206SBjoern A. Zeeb dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 28662774f206SBjoern A. Zeeb 28672774f206SBjoern A. Zeeb cca32_cnt = rtw_read32(rtwdev, 0x2c08); 28682774f206SBjoern A. Zeeb dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); 28692774f206SBjoern A. Zeeb dm_info->cck_cca_cnt = cca32_cnt & 0xffff; 28702774f206SBjoern A. Zeeb dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 28712774f206SBjoern A. Zeeb if (cck_enable) 28722774f206SBjoern A. Zeeb dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 28732774f206SBjoern A. Zeeb 28742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0); 28752774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2); 28762774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0); 28772774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 2); 28782774f206SBjoern A. Zeeb 28792774f206SBjoern A. Zeeb /* disable rx clk gating to reset counters */ 28802774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); 28812774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); 28822774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); 28832774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); 28842774f206SBjoern A. Zeeb } 28852774f206SBjoern A. Zeeb 28862774f206SBjoern A. Zeeb static void rtw8822c_do_lck(struct rtw_dev *rtwdev) 28872774f206SBjoern A. Zeeb { 28882774f206SBjoern A. Zeeb u32 val; 28892774f206SBjoern A. Zeeb 28902774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010); 28912774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA); 28922774f206SBjoern A. Zeeb fsleep(1); 28932774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000); 28942774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001); 28952774f206SBjoern A. Zeeb read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000, 28962774f206SBjoern A. Zeeb true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000); 28972774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8); 28982774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010); 28992774f206SBjoern A. Zeeb 29002774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); 29012774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000); 29022774f206SBjoern A. Zeeb fsleep(1); 29032774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); 29042774f206SBjoern A. Zeeb } 29052774f206SBjoern A. Zeeb 29062774f206SBjoern A. Zeeb static void rtw8822c_do_iqk(struct rtw_dev *rtwdev) 29072774f206SBjoern A. Zeeb { 29082774f206SBjoern A. Zeeb struct rtw_iqk_para para = {0}; 29092774f206SBjoern A. Zeeb u8 iqk_chk; 29102774f206SBjoern A. Zeeb int ret; 29112774f206SBjoern A. Zeeb 29122774f206SBjoern A. Zeeb para.clear = 1; 29132774f206SBjoern A. Zeeb rtw_fw_do_iqk(rtwdev, ¶); 29142774f206SBjoern A. Zeeb 29152774f206SBjoern A. Zeeb ret = read_poll_timeout(rtw_read8, iqk_chk, iqk_chk == IQK_DONE_8822C, 29162774f206SBjoern A. Zeeb 20000, 300000, false, rtwdev, REG_RPT_CIP); 29172774f206SBjoern A. Zeeb if (ret) 29182774f206SBjoern A. Zeeb rtw_warn(rtwdev, "failed to poll iqk status bit\n"); 29192774f206SBjoern A. Zeeb 29202774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_IQKSTAT, 0x0); 29212774f206SBjoern A. Zeeb } 29222774f206SBjoern A. Zeeb 29232774f206SBjoern A. Zeeb /* for coex */ 29242774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_init(struct rtw_dev *rtwdev) 29252774f206SBjoern A. Zeeb { 29262774f206SBjoern A. Zeeb /* enable TBTT nterrupt */ 29272774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 29282774f206SBjoern A. Zeeb 29292774f206SBjoern A. Zeeb /* BT report packet sample rate */ 29302774f206SBjoern A. Zeeb /* 0x790[5:0]=0x5 */ 29312774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 29322774f206SBjoern A. Zeeb 29332774f206SBjoern A. Zeeb /* enable BT counter statistics */ 29342774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); 29352774f206SBjoern A. Zeeb 29362774f206SBjoern A. Zeeb /* enable PTA (3-wire function form BT side) */ 29372774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 29382774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); 29392774f206SBjoern A. Zeeb 29402774f206SBjoern A. Zeeb /* enable PTA (tx/rx signal form WiFi side) */ 29412774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 29422774f206SBjoern A. Zeeb /* wl tx signal to PTA not case EDCCA */ 29432774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); 29442774f206SBjoern A. Zeeb /* GNT_BT=1 while select both */ 29452774f206SBjoern A. Zeeb rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); 29462774f206SBjoern A. Zeeb /* BT_CCA = ~GNT_WL_BB, not or GNT_BT_BB, LTE_Rx */ 29472774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_DUMMY_PAGE4_V1, BIT_BTCCA_CTRL); 29482774f206SBjoern A. Zeeb 29492774f206SBjoern A. Zeeb /* to avoid RF parameter error */ 29502774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODOPT, 0xfffff, 0x40000); 29512774f206SBjoern A. Zeeb } 29522774f206SBjoern A. Zeeb 29532774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 29542774f206SBjoern A. Zeeb { 29552774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 29562774f206SBjoern A. Zeeb struct rtw_coex_stat *coex_stat = &coex->stat; 29572774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 29582774f206SBjoern A. Zeeb u32 rf_0x1; 29592774f206SBjoern A. Zeeb 29602774f206SBjoern A. Zeeb if (coex_stat->gnt_workaround_state == coex_stat->wl_coex_mode) 29612774f206SBjoern A. Zeeb return; 29622774f206SBjoern A. Zeeb 29632774f206SBjoern A. Zeeb coex_stat->gnt_workaround_state = coex_stat->wl_coex_mode; 29642774f206SBjoern A. Zeeb 29652774f206SBjoern A. Zeeb if ((coex_stat->kt_ver == 0 && coex->under_5g) || coex->freerun) 29662774f206SBjoern A. Zeeb rf_0x1 = 0x40021; 29672774f206SBjoern A. Zeeb else 29682774f206SBjoern A. Zeeb rf_0x1 = 0x40000; 29692774f206SBjoern A. Zeeb 29702774f206SBjoern A. Zeeb /* BT at S1 for Shared-Ant */ 29712774f206SBjoern A. Zeeb if (efuse->share_ant) 29722774f206SBjoern A. Zeeb rf_0x1 |= BIT(13); 29732774f206SBjoern A. Zeeb 29742774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, 0x1, 0xfffff, rf_0x1); 29752774f206SBjoern A. Zeeb 29762774f206SBjoern A. Zeeb /* WL-S0 2G RF TRX cannot be masked by GNT_BT 29772774f206SBjoern A. Zeeb * enable "WLS0 BB chage RF mode if GNT_BT = 1" for shared-antenna type 29782774f206SBjoern A. Zeeb * disable:0x1860[3] = 1, enable:0x1860[3] = 0 29792774f206SBjoern A. Zeeb * 29802774f206SBjoern A. Zeeb * enable "DAC off if GNT_WL = 0" for non-shared-antenna 29812774f206SBjoern A. Zeeb * disable 0x1c30[22] = 0, 29822774f206SBjoern A. Zeeb * enable: 0x1c30[22] = 1, 0x1c38[12] = 0, 0x1c38[28] = 1 29839c951734SBjoern A. Zeeb */ 29849c951734SBjoern A. Zeeb if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { 29859c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_ANAPAR + 2, 29869c951734SBjoern A. Zeeb BIT_ANAPAR_BTPS >> 16, 0); 29879c951734SBjoern A. Zeeb } else { 29889c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_ANAPAR + 2, 29899c951734SBjoern A. Zeeb BIT_ANAPAR_BTPS >> 16, 1); 29909c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1, 29919c951734SBjoern A. Zeeb BIT_DAC_OFF_ENABLE, 0); 29929c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3, 29939c951734SBjoern A. Zeeb BIT_DAC_OFF_ENABLE, 1); 29949c951734SBjoern A. Zeeb } 29959c951734SBjoern A. Zeeb 29969c951734SBjoern A. Zeeb /* disable WL-S1 BB chage RF mode if GNT_BT 29972774f206SBjoern A. Zeeb * since RF TRx mask can do it 29982774f206SBjoern A. Zeeb */ 29999c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_IGN_GNTBT4, 30009c951734SBjoern A. Zeeb BIT_PI_IGNORE_GNT_BT, 1); 30012774f206SBjoern A. Zeeb 30022774f206SBjoern A. Zeeb /* disable WL-S0 BB chage RF mode if wifi is at 5G, 30032774f206SBjoern A. Zeeb * or antenna path is separated 30042774f206SBjoern A. Zeeb */ 30059c951734SBjoern A. Zeeb if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { 30069c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 30079c951734SBjoern A. Zeeb BIT_PI_IGNORE_GNT_BT, 1); 30089c951734SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 30099c951734SBjoern A. Zeeb BIT_NOMASK_TXBT_ENABLE, 1); 30109c951734SBjoern A. Zeeb } else if (coex_stat->wl_coex_mode == COEX_WLINK_5G || 30112774f206SBjoern A. Zeeb coex->under_5g || !efuse->share_ant) { 30122774f206SBjoern A. Zeeb if (coex_stat->kt_ver >= 3) { 30132774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 30142774f206SBjoern A. Zeeb BIT_PI_IGNORE_GNT_BT, 0); 30152774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 30162774f206SBjoern A. Zeeb BIT_NOMASK_TXBT_ENABLE, 1); 30172774f206SBjoern A. Zeeb } else { 30182774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 30192774f206SBjoern A. Zeeb BIT_PI_IGNORE_GNT_BT, 1); 30202774f206SBjoern A. Zeeb } 30212774f206SBjoern A. Zeeb } else { 30222774f206SBjoern A. Zeeb /* shared-antenna */ 30232774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 30242774f206SBjoern A. Zeeb BIT_PI_IGNORE_GNT_BT, 0); 30252774f206SBjoern A. Zeeb if (coex_stat->kt_ver >= 3) { 30262774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 30272774f206SBjoern A. Zeeb BIT_NOMASK_TXBT_ENABLE, 0); 30282774f206SBjoern A. Zeeb } 30292774f206SBjoern A. Zeeb } 30302774f206SBjoern A. Zeeb } 30312774f206SBjoern A. Zeeb 30322774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) 30332774f206SBjoern A. Zeeb { 30342774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0); 30352774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0); 30362774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0); 30372774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0); 30382774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0); 30392774f206SBjoern A. Zeeb } 30402774f206SBjoern A. Zeeb 30412774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 30422774f206SBjoern A. Zeeb { 30432774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 30442774f206SBjoern A. Zeeb struct rtw_coex_rfe *coex_rfe = &coex->rfe; 30452774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 30462774f206SBjoern A. Zeeb 30472774f206SBjoern A. Zeeb coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; 30482774f206SBjoern A. Zeeb coex_rfe->ant_switch_polarity = 0; 30492774f206SBjoern A. Zeeb coex_rfe->ant_switch_exist = false; 30502774f206SBjoern A. Zeeb coex_rfe->ant_switch_with_bt = false; 30512774f206SBjoern A. Zeeb coex_rfe->ant_switch_diversity = false; 30522774f206SBjoern A. Zeeb 30532774f206SBjoern A. Zeeb if (efuse->share_ant) 30542774f206SBjoern A. Zeeb coex_rfe->wlg_at_btg = true; 30552774f206SBjoern A. Zeeb else 30562774f206SBjoern A. Zeeb coex_rfe->wlg_at_btg = false; 30572774f206SBjoern A. Zeeb 30582774f206SBjoern A. Zeeb /* disable LTE coex in wifi side */ 30592774f206SBjoern A. Zeeb rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); 30602774f206SBjoern A. Zeeb rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); 30612774f206SBjoern A. Zeeb rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); 30622774f206SBjoern A. Zeeb } 30632774f206SBjoern A. Zeeb 30642774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 30652774f206SBjoern A. Zeeb { 30662774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 30672774f206SBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 30682774f206SBjoern A. Zeeb 30692774f206SBjoern A. Zeeb if (wl_pwr == coex_dm->cur_wl_pwr_lvl) 30702774f206SBjoern A. Zeeb return; 30712774f206SBjoern A. Zeeb 30722774f206SBjoern A. Zeeb coex_dm->cur_wl_pwr_lvl = wl_pwr; 30732774f206SBjoern A. Zeeb } 30742774f206SBjoern A. Zeeb 30752774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 30762774f206SBjoern A. Zeeb { 30772774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 30782774f206SBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 30792774f206SBjoern A. Zeeb 30802774f206SBjoern A. Zeeb if (low_gain == coex_dm->cur_wl_rx_low_gain_en) 30812774f206SBjoern A. Zeeb return; 30822774f206SBjoern A. Zeeb 30832774f206SBjoern A. Zeeb coex_dm->cur_wl_rx_low_gain_en = low_gain; 30842774f206SBjoern A. Zeeb 30852774f206SBjoern A. Zeeb if (coex_dm->cur_wl_rx_low_gain_en) { 30862774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n"); 30872774f206SBjoern A. Zeeb 30882774f206SBjoern A. Zeeb /* set Rx filter corner RCK offset */ 30892774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x22); 30902774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x36); 30912774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x22); 30922774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x36); 30932774f206SBjoern A. Zeeb 30942774f206SBjoern A. Zeeb } else { 30952774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n"); 30962774f206SBjoern A. Zeeb 30972774f206SBjoern A. Zeeb /* set Rx filter corner RCK offset */ 30982774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x20); 30992774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x0); 31002774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x20); 31012774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x0); 31022774f206SBjoern A. Zeeb } 31032774f206SBjoern A. Zeeb } 31042774f206SBjoern A. Zeeb 31052774f206SBjoern A. Zeeb static void rtw8822c_bf_enable_bfee_su(struct rtw_dev *rtwdev, 31062774f206SBjoern A. Zeeb struct rtw_vif *vif, 31072774f206SBjoern A. Zeeb struct rtw_bfee *bfee) 31082774f206SBjoern A. Zeeb { 31092774f206SBjoern A. Zeeb u8 csi_rsc = 0; 31102774f206SBjoern A. Zeeb u32 tmp6dc; 31112774f206SBjoern A. Zeeb 31122774f206SBjoern A. Zeeb rtw_bf_enable_bfee_su(rtwdev, vif, bfee); 31132774f206SBjoern A. Zeeb 31142774f206SBjoern A. Zeeb tmp6dc = rtw_read32(rtwdev, REG_BBPSF_CTRL) | 31152774f206SBjoern A. Zeeb BIT_WMAC_USE_NDPARATE | 31162774f206SBjoern A. Zeeb (csi_rsc << 13); 31172774f206SBjoern A. Zeeb if (vif->net_type == RTW_NET_AP_MODE) 31182774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc | BIT(12)); 31192774f206SBjoern A. Zeeb else 31202774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc & ~BIT(12)); 31212774f206SBjoern A. Zeeb 31222774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_CSI_RRSR, 0x550); 31232774f206SBjoern A. Zeeb } 31242774f206SBjoern A. Zeeb 31252774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee_su(struct rtw_dev *rtwdev, 31262774f206SBjoern A. Zeeb struct rtw_vif *vif, 31272774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 31282774f206SBjoern A. Zeeb { 31292774f206SBjoern A. Zeeb if (enable) 31302774f206SBjoern A. Zeeb rtw8822c_bf_enable_bfee_su(rtwdev, vif, bfee); 31312774f206SBjoern A. Zeeb else 31322774f206SBjoern A. Zeeb rtw_bf_remove_bfee_su(rtwdev, bfee); 31332774f206SBjoern A. Zeeb } 31342774f206SBjoern A. Zeeb 31352774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee_mu(struct rtw_dev *rtwdev, 31362774f206SBjoern A. Zeeb struct rtw_vif *vif, 31372774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 31382774f206SBjoern A. Zeeb { 31392774f206SBjoern A. Zeeb if (enable) 31402774f206SBjoern A. Zeeb rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); 31412774f206SBjoern A. Zeeb else 31422774f206SBjoern A. Zeeb rtw_bf_remove_bfee_mu(rtwdev, bfee); 31432774f206SBjoern A. Zeeb } 31442774f206SBjoern A. Zeeb 31452774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, 31462774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 31472774f206SBjoern A. Zeeb { 31482774f206SBjoern A. Zeeb if (bfee->role == RTW_BFEE_SU) 31492774f206SBjoern A. Zeeb rtw8822c_bf_config_bfee_su(rtwdev, vif, bfee, enable); 31502774f206SBjoern A. Zeeb else if (bfee->role == RTW_BFEE_MU) 31512774f206SBjoern A. Zeeb rtw8822c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); 31522774f206SBjoern A. Zeeb else 31532774f206SBjoern A. Zeeb rtw_warn(rtwdev, "wrong bfee role\n"); 31542774f206SBjoern A. Zeeb } 31552774f206SBjoern A. Zeeb 31562774f206SBjoern A. Zeeb struct dpk_cfg_pair { 31572774f206SBjoern A. Zeeb u32 addr; 31582774f206SBjoern A. Zeeb u32 bitmask; 31592774f206SBjoern A. Zeeb u32 data; 31602774f206SBjoern A. Zeeb }; 31612774f206SBjoern A. Zeeb 31622774f206SBjoern A. Zeeb void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev, 31632774f206SBjoern A. Zeeb const struct rtw_table *tbl) 31642774f206SBjoern A. Zeeb { 31652774f206SBjoern A. Zeeb const struct dpk_cfg_pair *p = tbl->data; 31662774f206SBjoern A. Zeeb const struct dpk_cfg_pair *end = p + tbl->size / 3; 31672774f206SBjoern A. Zeeb 31682774f206SBjoern A. Zeeb BUILD_BUG_ON(sizeof(struct dpk_cfg_pair) != sizeof(u32) * 3); 31692774f206SBjoern A. Zeeb 31702774f206SBjoern A. Zeeb for (; p < end; p++) 31712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, p->addr, p->bitmask, p->data); 31722774f206SBjoern A. Zeeb } 31732774f206SBjoern A. Zeeb 31742774f206SBjoern A. Zeeb static void rtw8822c_dpk_set_gnt_wl(struct rtw_dev *rtwdev, bool is_before_k) 31752774f206SBjoern A. Zeeb { 31762774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 31772774f206SBjoern A. Zeeb 31782774f206SBjoern A. Zeeb if (is_before_k) { 31792774f206SBjoern A. Zeeb dpk_info->gnt_control = rtw_read32(rtwdev, 0x70); 31802774f206SBjoern A. Zeeb dpk_info->gnt_value = rtw_coex_read_indirect_reg(rtwdev, 0x38); 31812774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x70, BIT(26), 0x1); 31822774f206SBjoern A. Zeeb rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKBYTE1, 0x77); 31832774f206SBjoern A. Zeeb } else { 31842774f206SBjoern A. Zeeb rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKDWORD, 31852774f206SBjoern A. Zeeb dpk_info->gnt_value); 31862774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x70, dpk_info->gnt_control); 31872774f206SBjoern A. Zeeb } 31882774f206SBjoern A. Zeeb } 31892774f206SBjoern A. Zeeb 31902774f206SBjoern A. Zeeb static void 31912774f206SBjoern A. Zeeb rtw8822c_dpk_restore_registers(struct rtw_dev *rtwdev, u32 reg_num, 31922774f206SBjoern A. Zeeb struct rtw_backup_info *bckp) 31932774f206SBjoern A. Zeeb { 31942774f206SBjoern A. Zeeb rtw_restore_reg(rtwdev, bckp, reg_num); 31952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 31962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0x4); 31972774f206SBjoern A. Zeeb } 31982774f206SBjoern A. Zeeb 31992774f206SBjoern A. Zeeb static void 32002774f206SBjoern A. Zeeb rtw8822c_dpk_backup_registers(struct rtw_dev *rtwdev, u32 *reg, 32012774f206SBjoern A. Zeeb u32 reg_num, struct rtw_backup_info *bckp) 32022774f206SBjoern A. Zeeb { 32032774f206SBjoern A. Zeeb u32 i; 32042774f206SBjoern A. Zeeb 32052774f206SBjoern A. Zeeb for (i = 0; i < reg_num; i++) { 32062774f206SBjoern A. Zeeb bckp[i].len = 4; 32072774f206SBjoern A. Zeeb bckp[i].reg = reg[i]; 32082774f206SBjoern A. Zeeb bckp[i].val = rtw_read32(rtwdev, reg[i]); 32092774f206SBjoern A. Zeeb } 32102774f206SBjoern A. Zeeb } 32112774f206SBjoern A. Zeeb 32122774f206SBjoern A. Zeeb static void rtw8822c_dpk_backup_rf_registers(struct rtw_dev *rtwdev, 32132774f206SBjoern A. Zeeb u32 *rf_reg, 32142774f206SBjoern A. Zeeb u32 rf_reg_bak[][2]) 32152774f206SBjoern A. Zeeb { 32162774f206SBjoern A. Zeeb u32 i; 32172774f206SBjoern A. Zeeb 32182774f206SBjoern A. Zeeb for (i = 0; i < DPK_RF_REG_NUM; i++) { 32192774f206SBjoern A. Zeeb rf_reg_bak[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A, 32202774f206SBjoern A. Zeeb rf_reg[i], RFREG_MASK); 32212774f206SBjoern A. Zeeb rf_reg_bak[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B, 32222774f206SBjoern A. Zeeb rf_reg[i], RFREG_MASK); 32232774f206SBjoern A. Zeeb } 32242774f206SBjoern A. Zeeb } 32252774f206SBjoern A. Zeeb 32262774f206SBjoern A. Zeeb static void rtw8822c_dpk_reload_rf_registers(struct rtw_dev *rtwdev, 32272774f206SBjoern A. Zeeb u32 *rf_reg, 32282774f206SBjoern A. Zeeb u32 rf_reg_bak[][2]) 32292774f206SBjoern A. Zeeb { 32302774f206SBjoern A. Zeeb u32 i; 32312774f206SBjoern A. Zeeb 32322774f206SBjoern A. Zeeb for (i = 0; i < DPK_RF_REG_NUM; i++) { 32332774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, rf_reg[i], RFREG_MASK, 32342774f206SBjoern A. Zeeb rf_reg_bak[i][RF_PATH_A]); 32352774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, rf_reg[i], RFREG_MASK, 32362774f206SBjoern A. Zeeb rf_reg_bak[i][RF_PATH_B]); 32372774f206SBjoern A. Zeeb } 32382774f206SBjoern A. Zeeb } 32392774f206SBjoern A. Zeeb 32402774f206SBjoern A. Zeeb static void rtw8822c_dpk_information(struct rtw_dev *rtwdev) 32412774f206SBjoern A. Zeeb { 32422774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 32432774f206SBjoern A. Zeeb u32 reg; 32442774f206SBjoern A. Zeeb u8 band_shift; 32452774f206SBjoern A. Zeeb 32464f3b2bbaSBjoern A. Zeeb #if defined(__linux__) 32472774f206SBjoern A. Zeeb reg = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); 32484f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__) 32494f3b2bbaSBjoern A. Zeeb reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 32504f3b2bbaSBjoern A. Zeeb #endif 32512774f206SBjoern A. Zeeb 32522774f206SBjoern A. Zeeb band_shift = FIELD_GET(BIT(16), reg); 32532774f206SBjoern A. Zeeb dpk_info->dpk_band = 1 << band_shift; 32542774f206SBjoern A. Zeeb dpk_info->dpk_ch = FIELD_GET(0xff, reg); 32552774f206SBjoern A. Zeeb dpk_info->dpk_bw = FIELD_GET(0x3000, reg); 32562774f206SBjoern A. Zeeb } 32572774f206SBjoern A. Zeeb 32582774f206SBjoern A. Zeeb static void rtw8822c_dpk_rxbb_dc_cal(struct rtw_dev *rtwdev, u8 path) 32592774f206SBjoern A. Zeeb { 32602774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); 32612774f206SBjoern A. Zeeb udelay(5); 32622774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84801); 32632774f206SBjoern A. Zeeb usleep_range(600, 610); 32642774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); 32652774f206SBjoern A. Zeeb } 32662774f206SBjoern A. Zeeb 32672774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_dc_corr_check(struct rtw_dev *rtwdev, u8 path) 32682774f206SBjoern A. Zeeb { 32692774f206SBjoern A. Zeeb u16 dc_i, dc_q; 32702774f206SBjoern A. Zeeb u8 corr_idx; 32712774f206SBjoern A. Zeeb 32722774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000900f0); 32732774f206SBjoern A. Zeeb dc_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); 32742774f206SBjoern A. Zeeb dc_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(11, 0)); 32752774f206SBjoern A. Zeeb 32762774f206SBjoern A. Zeeb if (dc_i & BIT(11)) 32772774f206SBjoern A. Zeeb dc_i = 0x1000 - dc_i; 32782774f206SBjoern A. Zeeb if (dc_q & BIT(11)) 32792774f206SBjoern A. Zeeb dc_q = 0x1000 - dc_q; 32802774f206SBjoern A. Zeeb 32812774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 32822774f206SBjoern A. Zeeb corr_idx = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(7, 0)); 32832774f206SBjoern A. Zeeb rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(15, 8)); 32842774f206SBjoern A. Zeeb 32852774f206SBjoern A. Zeeb if (dc_i > 200 || dc_q > 200 || corr_idx < 40 || corr_idx > 65) 32862774f206SBjoern A. Zeeb return 1; 32872774f206SBjoern A. Zeeb else 32882774f206SBjoern A. Zeeb return 0; 32892774f206SBjoern A. Zeeb 32902774f206SBjoern A. Zeeb } 32912774f206SBjoern A. Zeeb 32922774f206SBjoern A. Zeeb static void rtw8822c_dpk_tx_pause(struct rtw_dev *rtwdev) 32932774f206SBjoern A. Zeeb { 32942774f206SBjoern A. Zeeb u8 reg_a, reg_b; 32952774f206SBjoern A. Zeeb u16 count = 0; 32962774f206SBjoern A. Zeeb 32972774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x522, 0xff); 32982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1e70, 0xf, 0x2); 32992774f206SBjoern A. Zeeb 33002774f206SBjoern A. Zeeb do { 33012774f206SBjoern A. Zeeb reg_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 0x00, 0xf0000); 33022774f206SBjoern A. Zeeb reg_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 0x00, 0xf0000); 33032774f206SBjoern A. Zeeb udelay(2); 33042774f206SBjoern A. Zeeb count++; 33052774f206SBjoern A. Zeeb } while ((reg_a == 2 || reg_b == 2) && count < 2500); 33062774f206SBjoern A. Zeeb } 33072774f206SBjoern A. Zeeb 33082774f206SBjoern A. Zeeb static void rtw8822c_dpk_mac_bb_setting(struct rtw_dev *rtwdev) 33092774f206SBjoern A. Zeeb { 33102774f206SBjoern A. Zeeb rtw8822c_dpk_tx_pause(rtwdev); 33112774f206SBjoern A. Zeeb rtw_load_table(rtwdev, &rtw8822c_dpk_mac_bb_tbl); 33122774f206SBjoern A. Zeeb } 33132774f206SBjoern A. Zeeb 33142774f206SBjoern A. Zeeb static void rtw8822c_dpk_afe_setting(struct rtw_dev *rtwdev, bool is_do_dpk) 33152774f206SBjoern A. Zeeb { 33162774f206SBjoern A. Zeeb if (is_do_dpk) 33172774f206SBjoern A. Zeeb rtw_load_table(rtwdev, &rtw8822c_dpk_afe_is_dpk_tbl); 33182774f206SBjoern A. Zeeb else 33192774f206SBjoern A. Zeeb rtw_load_table(rtwdev, &rtw8822c_dpk_afe_no_dpk_tbl); 33202774f206SBjoern A. Zeeb } 33212774f206SBjoern A. Zeeb 33222774f206SBjoern A. Zeeb static void rtw8822c_dpk_pre_setting(struct rtw_dev *rtwdev) 33232774f206SBjoern A. Zeeb { 33242774f206SBjoern A. Zeeb u8 path; 33252774f206SBjoern A. Zeeb 33262774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 33272774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_RXAGC_OFFSET, RFREG_MASK, 0x0); 33282774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); 33292774f206SBjoern A. Zeeb if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) 33302774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); 33312774f206SBjoern A. Zeeb else 33322774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); 33332774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_LUT0, BIT_GLOSS_DB, 0x4); 33342774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x3); 33352774f206SBjoern A. Zeeb } 33362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 33372774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL11, 0x3b23170b); 33382774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL12, 0x775f5347); 33392774f206SBjoern A. Zeeb } 33402774f206SBjoern A. Zeeb 33412774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_rf_setting(struct rtw_dev *rtwdev, u8 path) 33422774f206SBjoern A. Zeeb { 33432774f206SBjoern A. Zeeb u32 ori_txbb; 33442774f206SBjoern A. Zeeb 33452774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50017); 33462774f206SBjoern A. Zeeb ori_txbb = rtw_read_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK); 33472774f206SBjoern A. Zeeb 33482774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 33492774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_PWR_TRIM, 0x1); 33502774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_BB_GAIN, 0x0); 33512774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK, ori_txbb); 33522774f206SBjoern A. Zeeb 33532774f206SBjoern A. Zeeb if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) { 33542774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x1); 33552774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x0); 33562774f206SBjoern A. Zeeb } else { 33572774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x0); 33582774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x6); 33592774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); 33602774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0); 33612774f206SBjoern A. Zeeb } 33622774f206SBjoern A. Zeeb 33632774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); 33642774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 33652774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 33662774f206SBjoern A. Zeeb 33672774f206SBjoern A. Zeeb if (rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80) 33682774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x2); 33692774f206SBjoern A. Zeeb else 33702774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); 33712774f206SBjoern A. Zeeb 33722774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT(1), 0x1); 33732774f206SBjoern A. Zeeb 33742774f206SBjoern A. Zeeb usleep_range(100, 110); 33752774f206SBjoern A. Zeeb 33762774f206SBjoern A. Zeeb return ori_txbb & 0x1f; 33772774f206SBjoern A. Zeeb } 33782774f206SBjoern A. Zeeb 33792774f206SBjoern A. Zeeb static u16 rtw8822c_dpk_get_cmd(struct rtw_dev *rtwdev, u8 action, u8 path) 33802774f206SBjoern A. Zeeb { 33812774f206SBjoern A. Zeeb u16 cmd; 33822774f206SBjoern A. Zeeb u8 bw = rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80 ? 2 : 0; 33832774f206SBjoern A. Zeeb 33842774f206SBjoern A. Zeeb switch (action) { 33852774f206SBjoern A. Zeeb case RTW_DPK_GAIN_LOSS: 33862774f206SBjoern A. Zeeb cmd = 0x14 + path; 33872774f206SBjoern A. Zeeb break; 33882774f206SBjoern A. Zeeb case RTW_DPK_DO_DPK: 33892774f206SBjoern A. Zeeb cmd = 0x16 + path + bw; 33902774f206SBjoern A. Zeeb break; 33912774f206SBjoern A. Zeeb case RTW_DPK_DPK_ON: 33922774f206SBjoern A. Zeeb cmd = 0x1a + path; 33932774f206SBjoern A. Zeeb break; 33942774f206SBjoern A. Zeeb case RTW_DPK_DAGC: 33952774f206SBjoern A. Zeeb cmd = 0x1c + path + bw; 33962774f206SBjoern A. Zeeb break; 33972774f206SBjoern A. Zeeb default: 33982774f206SBjoern A. Zeeb return 0; 33992774f206SBjoern A. Zeeb } 34002774f206SBjoern A. Zeeb 34012774f206SBjoern A. Zeeb return (cmd << 8) | 0x48; 34022774f206SBjoern A. Zeeb } 34032774f206SBjoern A. Zeeb 34042774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_one_shot(struct rtw_dev *rtwdev, u8 path, u8 action) 34052774f206SBjoern A. Zeeb { 34062774f206SBjoern A. Zeeb u16 dpk_cmd; 34072774f206SBjoern A. Zeeb u8 result = 0; 34082774f206SBjoern A. Zeeb 34092774f206SBjoern A. Zeeb rtw8822c_dpk_set_gnt_wl(rtwdev, true); 34102774f206SBjoern A. Zeeb 34112774f206SBjoern A. Zeeb if (action == RTW_DPK_CAL_PWR) { 34122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x1); 34132774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x0); 34142774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); 34152774f206SBjoern A. Zeeb msleep(10); 34162774f206SBjoern A. Zeeb if (!check_hw_ready(rtwdev, REG_STAT_RPT, BIT(31), 0x1)) { 34172774f206SBjoern A. Zeeb result = 1; 34182774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); 34192774f206SBjoern A. Zeeb } 34202774f206SBjoern A. Zeeb } else { 34212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 34222774f206SBjoern A. Zeeb 0x8 | (path << 1)); 34232774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); 34242774f206SBjoern A. Zeeb 34252774f206SBjoern A. Zeeb dpk_cmd = rtw8822c_dpk_get_cmd(rtwdev, action, path); 34262774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, dpk_cmd); 34272774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, dpk_cmd + 1); 34282774f206SBjoern A. Zeeb msleep(10); 34292774f206SBjoern A. Zeeb if (!check_hw_ready(rtwdev, 0x2d9c, 0xff, 0x55)) { 34302774f206SBjoern A. Zeeb result = 1; 34312774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); 34322774f206SBjoern A. Zeeb } 34332774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 34342774f206SBjoern A. Zeeb 0x8 | (path << 1)); 34352774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); 34362774f206SBjoern A. Zeeb } 34372774f206SBjoern A. Zeeb 34382774f206SBjoern A. Zeeb rtw8822c_dpk_set_gnt_wl(rtwdev, false); 34392774f206SBjoern A. Zeeb 34402774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1b10, 0x0); 34412774f206SBjoern A. Zeeb 34422774f206SBjoern A. Zeeb return result; 34432774f206SBjoern A. Zeeb } 34442774f206SBjoern A. Zeeb 34452774f206SBjoern A. Zeeb static u16 rtw8822c_dpk_dgain_read(struct rtw_dev *rtwdev, u8 path) 34462774f206SBjoern A. Zeeb { 34472774f206SBjoern A. Zeeb u16 dgain; 34482774f206SBjoern A. Zeeb 34492774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 34502774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, 0x00ff0000, 0x0); 34512774f206SBjoern A. Zeeb 34522774f206SBjoern A. Zeeb dgain = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); 34532774f206SBjoern A. Zeeb 34542774f206SBjoern A. Zeeb return dgain; 34552774f206SBjoern A. Zeeb } 34562774f206SBjoern A. Zeeb 34572774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_thermal_read(struct rtw_dev *rtwdev, u8 path) 34582774f206SBjoern A. Zeeb { 34592774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); 34602774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x0); 34612774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); 34622774f206SBjoern A. Zeeb udelay(15); 34632774f206SBjoern A. Zeeb 34642774f206SBjoern A. Zeeb return (u8)rtw_read_rf(rtwdev, path, RF_T_METER, 0x0007e); 34652774f206SBjoern A. Zeeb } 34662774f206SBjoern A. Zeeb 34672774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_pas_read(struct rtw_dev *rtwdev, u8 path) 34682774f206SBjoern A. Zeeb { 34692774f206SBjoern A. Zeeb u32 i_val, q_val; 34702774f206SBjoern A. Zeeb 34712774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); 34722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); 34732774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060001); 34742774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b4c, 0x00000000); 34752774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b4c, 0x00080000); 34762774f206SBjoern A. Zeeb 34772774f206SBjoern A. Zeeb q_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD); 34782774f206SBjoern A. Zeeb i_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD); 34792774f206SBjoern A. Zeeb 34802774f206SBjoern A. Zeeb if (i_val & BIT(15)) 34812774f206SBjoern A. Zeeb i_val = 0x10000 - i_val; 34822774f206SBjoern A. Zeeb if (q_val & BIT(15)) 34832774f206SBjoern A. Zeeb q_val = 0x10000 - q_val; 34842774f206SBjoern A. Zeeb 34852774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1b4c, 0x00000000); 34862774f206SBjoern A. Zeeb 34872774f206SBjoern A. Zeeb return i_val * i_val + q_val * q_val; 34882774f206SBjoern A. Zeeb } 34892774f206SBjoern A. Zeeb 34902774f206SBjoern A. Zeeb static u32 rtw8822c_psd_log2base(u32 val) 34912774f206SBjoern A. Zeeb { 34922774f206SBjoern A. Zeeb u32 tmp, val_integerd_b, tindex; 34932774f206SBjoern A. Zeeb u32 result, val_fractiond_b; 34942774f206SBjoern A. Zeeb u32 table_fraction[21] = {0, 432, 332, 274, 232, 200, 174, 34952774f206SBjoern A. Zeeb 151, 132, 115, 100, 86, 74, 62, 51, 34962774f206SBjoern A. Zeeb 42, 32, 23, 15, 7, 0}; 34972774f206SBjoern A. Zeeb 34982774f206SBjoern A. Zeeb if (val == 0) 34992774f206SBjoern A. Zeeb return 0; 35002774f206SBjoern A. Zeeb 35012774f206SBjoern A. Zeeb val_integerd_b = __fls(val) + 1; 35022774f206SBjoern A. Zeeb 35032774f206SBjoern A. Zeeb tmp = (val * 100) / (1 << val_integerd_b); 35042774f206SBjoern A. Zeeb tindex = tmp / 5; 35052774f206SBjoern A. Zeeb 35062774f206SBjoern A. Zeeb if (tindex >= ARRAY_SIZE(table_fraction)) 35072774f206SBjoern A. Zeeb tindex = ARRAY_SIZE(table_fraction) - 1; 35082774f206SBjoern A. Zeeb 35092774f206SBjoern A. Zeeb val_fractiond_b = table_fraction[tindex]; 35102774f206SBjoern A. Zeeb 35112774f206SBjoern A. Zeeb result = val_integerd_b * 100 - val_fractiond_b; 35122774f206SBjoern A. Zeeb 35132774f206SBjoern A. Zeeb return result; 35142774f206SBjoern A. Zeeb } 35152774f206SBjoern A. Zeeb 35162774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_gainloss_result(struct rtw_dev *rtwdev, u8 path) 35172774f206SBjoern A. Zeeb { 35182774f206SBjoern A. Zeeb u8 result; 35192774f206SBjoern A. Zeeb 35202774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 35212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x1); 35222774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060000); 35232774f206SBjoern A. Zeeb 35242774f206SBjoern A. Zeeb result = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, 0x000000f0); 35252774f206SBjoern A. Zeeb 35262774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); 35272774f206SBjoern A. Zeeb 35282774f206SBjoern A. Zeeb return result; 35292774f206SBjoern A. Zeeb } 35302774f206SBjoern A. Zeeb 35312774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_agc_gain_chk(struct rtw_dev *rtwdev, u8 path, 35322774f206SBjoern A. Zeeb u8 limited_pga) 35332774f206SBjoern A. Zeeb { 35342774f206SBjoern A. Zeeb u8 result = 0; 35352774f206SBjoern A. Zeeb u16 dgain; 35362774f206SBjoern A. Zeeb 35372774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 35382774f206SBjoern A. Zeeb dgain = rtw8822c_dpk_dgain_read(rtwdev, path); 35392774f206SBjoern A. Zeeb 35402774f206SBjoern A. Zeeb if (dgain > 1535 && !limited_pga) 35412774f206SBjoern A. Zeeb return RTW_DPK_GAIN_LESS; 35422774f206SBjoern A. Zeeb else if (dgain < 768 && !limited_pga) 35432774f206SBjoern A. Zeeb return RTW_DPK_GAIN_LARGE; 35442774f206SBjoern A. Zeeb else 35452774f206SBjoern A. Zeeb return result; 35462774f206SBjoern A. Zeeb } 35472774f206SBjoern A. Zeeb 35482774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_agc_loss_chk(struct rtw_dev *rtwdev, u8 path) 35492774f206SBjoern A. Zeeb { 35502774f206SBjoern A. Zeeb u32 loss, loss_db; 35512774f206SBjoern A. Zeeb 35522774f206SBjoern A. Zeeb loss = rtw8822c_dpk_pas_read(rtwdev, path); 35532774f206SBjoern A. Zeeb if (loss < 0x4000000) 35542774f206SBjoern A. Zeeb return RTW_DPK_GL_LESS; 35552774f206SBjoern A. Zeeb loss_db = 3 * rtw8822c_psd_log2base(loss >> 13) - 3870; 35562774f206SBjoern A. Zeeb 35572774f206SBjoern A. Zeeb if (loss_db > 1000) 35582774f206SBjoern A. Zeeb return RTW_DPK_GL_LARGE; 35592774f206SBjoern A. Zeeb else if (loss_db < 250) 35602774f206SBjoern A. Zeeb return RTW_DPK_GL_LESS; 35612774f206SBjoern A. Zeeb else 35622774f206SBjoern A. Zeeb return RTW_DPK_AGC_OUT; 35632774f206SBjoern A. Zeeb } 35642774f206SBjoern A. Zeeb 35652774f206SBjoern A. Zeeb struct rtw8822c_dpk_data { 35662774f206SBjoern A. Zeeb u8 txbb; 35672774f206SBjoern A. Zeeb u8 pga; 35682774f206SBjoern A. Zeeb u8 limited_pga; 35692774f206SBjoern A. Zeeb u8 agc_cnt; 35702774f206SBjoern A. Zeeb bool loss_only; 35712774f206SBjoern A. Zeeb bool gain_only; 35722774f206SBjoern A. Zeeb u8 path; 35732774f206SBjoern A. Zeeb }; 35742774f206SBjoern A. Zeeb 35752774f206SBjoern A. Zeeb static u8 rtw8822c_gain_check_state(struct rtw_dev *rtwdev, 35762774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 35772774f206SBjoern A. Zeeb { 35782774f206SBjoern A. Zeeb u8 state; 35792774f206SBjoern A. Zeeb 35802774f206SBjoern A. Zeeb data->txbb = (u8)rtw_read_rf(rtwdev, data->path, RF_TX_GAIN, 35812774f206SBjoern A. Zeeb BIT_GAIN_TXBB); 35822774f206SBjoern A. Zeeb data->pga = (u8)rtw_read_rf(rtwdev, data->path, RF_MODE_TRXAGC, 35832774f206SBjoern A. Zeeb BIT_RXAGC); 35842774f206SBjoern A. Zeeb 35852774f206SBjoern A. Zeeb if (data->loss_only) { 35862774f206SBjoern A. Zeeb state = RTW_DPK_LOSS_CHECK; 35872774f206SBjoern A. Zeeb goto check_end; 35882774f206SBjoern A. Zeeb } 35892774f206SBjoern A. Zeeb 35902774f206SBjoern A. Zeeb state = rtw8822c_dpk_agc_gain_chk(rtwdev, data->path, 35912774f206SBjoern A. Zeeb data->limited_pga); 35922774f206SBjoern A. Zeeb if (state == RTW_DPK_GAIN_CHECK && data->gain_only) 35932774f206SBjoern A. Zeeb state = RTW_DPK_AGC_OUT; 35942774f206SBjoern A. Zeeb else if (state == RTW_DPK_GAIN_CHECK) 35952774f206SBjoern A. Zeeb state = RTW_DPK_LOSS_CHECK; 35962774f206SBjoern A. Zeeb 35972774f206SBjoern A. Zeeb check_end: 35982774f206SBjoern A. Zeeb data->agc_cnt++; 35992774f206SBjoern A. Zeeb if (data->agc_cnt >= 6) 36002774f206SBjoern A. Zeeb state = RTW_DPK_AGC_OUT; 36012774f206SBjoern A. Zeeb 36022774f206SBjoern A. Zeeb return state; 36032774f206SBjoern A. Zeeb } 36042774f206SBjoern A. Zeeb 36052774f206SBjoern A. Zeeb static u8 rtw8822c_gain_large_state(struct rtw_dev *rtwdev, 36062774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 36072774f206SBjoern A. Zeeb { 36082774f206SBjoern A. Zeeb u8 pga = data->pga; 36092774f206SBjoern A. Zeeb 36102774f206SBjoern A. Zeeb if (pga > 0xe) 36112774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); 36122774f206SBjoern A. Zeeb else if (pga > 0xb && pga < 0xf) 36132774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0); 36142774f206SBjoern A. Zeeb else if (pga < 0xc) 36152774f206SBjoern A. Zeeb data->limited_pga = 1; 36162774f206SBjoern A. Zeeb 36172774f206SBjoern A. Zeeb return RTW_DPK_GAIN_CHECK; 36182774f206SBjoern A. Zeeb } 36192774f206SBjoern A. Zeeb 36202774f206SBjoern A. Zeeb static u8 rtw8822c_gain_less_state(struct rtw_dev *rtwdev, 36212774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 36222774f206SBjoern A. Zeeb { 36232774f206SBjoern A. Zeeb u8 pga = data->pga; 36242774f206SBjoern A. Zeeb 36252774f206SBjoern A. Zeeb if (pga < 0xc) 36262774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); 36272774f206SBjoern A. Zeeb else if (pga > 0xb && pga < 0xf) 36282774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); 36292774f206SBjoern A. Zeeb else if (pga > 0xe) 36302774f206SBjoern A. Zeeb data->limited_pga = 1; 36312774f206SBjoern A. Zeeb 36322774f206SBjoern A. Zeeb return RTW_DPK_GAIN_CHECK; 36332774f206SBjoern A. Zeeb } 36342774f206SBjoern A. Zeeb 36352774f206SBjoern A. Zeeb static u8 rtw8822c_gl_state(struct rtw_dev *rtwdev, 36362774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data, u8 is_large) 36372774f206SBjoern A. Zeeb { 36382774f206SBjoern A. Zeeb u8 txbb_bound[] = {0x1f, 0}; 36392774f206SBjoern A. Zeeb 36402774f206SBjoern A. Zeeb if (data->txbb == txbb_bound[is_large]) 36412774f206SBjoern A. Zeeb return RTW_DPK_AGC_OUT; 36422774f206SBjoern A. Zeeb 36432774f206SBjoern A. Zeeb if (is_large == 1) 36442774f206SBjoern A. Zeeb data->txbb -= 2; 36452774f206SBjoern A. Zeeb else 36462774f206SBjoern A. Zeeb data->txbb += 3; 36472774f206SBjoern A. Zeeb 36482774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, data->path, RF_TX_GAIN, BIT_GAIN_TXBB, data->txbb); 36492774f206SBjoern A. Zeeb data->limited_pga = 0; 36502774f206SBjoern A. Zeeb 36512774f206SBjoern A. Zeeb return RTW_DPK_GAIN_CHECK; 36522774f206SBjoern A. Zeeb } 36532774f206SBjoern A. Zeeb 36542774f206SBjoern A. Zeeb static u8 rtw8822c_gl_large_state(struct rtw_dev *rtwdev, 36552774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 36562774f206SBjoern A. Zeeb { 36572774f206SBjoern A. Zeeb return rtw8822c_gl_state(rtwdev, data, 1); 36582774f206SBjoern A. Zeeb } 36592774f206SBjoern A. Zeeb 36602774f206SBjoern A. Zeeb static u8 rtw8822c_gl_less_state(struct rtw_dev *rtwdev, 36612774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 36622774f206SBjoern A. Zeeb { 36632774f206SBjoern A. Zeeb return rtw8822c_gl_state(rtwdev, data, 0); 36642774f206SBjoern A. Zeeb } 36652774f206SBjoern A. Zeeb 36662774f206SBjoern A. Zeeb static u8 rtw8822c_loss_check_state(struct rtw_dev *rtwdev, 36672774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) 36682774f206SBjoern A. Zeeb { 36692774f206SBjoern A. Zeeb u8 path = data->path; 36702774f206SBjoern A. Zeeb u8 state; 36712774f206SBjoern A. Zeeb 36722774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_GAIN_LOSS); 36732774f206SBjoern A. Zeeb state = rtw8822c_dpk_agc_loss_chk(rtwdev, path); 36742774f206SBjoern A. Zeeb 36752774f206SBjoern A. Zeeb return state; 36762774f206SBjoern A. Zeeb } 36772774f206SBjoern A. Zeeb 36782774f206SBjoern A. Zeeb static u8 (*dpk_state[])(struct rtw_dev *rtwdev, 36792774f206SBjoern A. Zeeb struct rtw8822c_dpk_data *data) = { 36802774f206SBjoern A. Zeeb rtw8822c_gain_check_state, rtw8822c_gain_large_state, 36812774f206SBjoern A. Zeeb rtw8822c_gain_less_state, rtw8822c_gl_large_state, 36822774f206SBjoern A. Zeeb rtw8822c_gl_less_state, rtw8822c_loss_check_state }; 36832774f206SBjoern A. Zeeb 36842774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_pas_agc(struct rtw_dev *rtwdev, u8 path, 36852774f206SBjoern A. Zeeb bool gain_only, bool loss_only) 36862774f206SBjoern A. Zeeb { 36872774f206SBjoern A. Zeeb struct rtw8822c_dpk_data data = {0}; 36882774f206SBjoern A. Zeeb u8 (*func)(struct rtw_dev *rtwdev, struct rtw8822c_dpk_data *data); 36892774f206SBjoern A. Zeeb u8 state = RTW_DPK_GAIN_CHECK; 36902774f206SBjoern A. Zeeb 36912774f206SBjoern A. Zeeb data.loss_only = loss_only; 36922774f206SBjoern A. Zeeb data.gain_only = gain_only; 36932774f206SBjoern A. Zeeb data.path = path; 36942774f206SBjoern A. Zeeb 36952774f206SBjoern A. Zeeb for (;;) { 36962774f206SBjoern A. Zeeb func = dpk_state[state]; 36972774f206SBjoern A. Zeeb state = func(rtwdev, &data); 36982774f206SBjoern A. Zeeb if (state == RTW_DPK_AGC_OUT) 36992774f206SBjoern A. Zeeb break; 37002774f206SBjoern A. Zeeb } 37012774f206SBjoern A. Zeeb 37022774f206SBjoern A. Zeeb return data.txbb; 37032774f206SBjoern A. Zeeb } 37042774f206SBjoern A. Zeeb 37052774f206SBjoern A. Zeeb static bool rtw8822c_dpk_coef_iq_check(struct rtw_dev *rtwdev, 37062774f206SBjoern A. Zeeb u16 coef_i, u16 coef_q) 37072774f206SBjoern A. Zeeb { 37082774f206SBjoern A. Zeeb if (coef_i == 0x1000 || coef_i == 0x0fff || 37092774f206SBjoern A. Zeeb coef_q == 0x1000 || coef_q == 0x0fff) 37102774f206SBjoern A. Zeeb return true; 37112774f206SBjoern A. Zeeb 37122774f206SBjoern A. Zeeb return false; 37132774f206SBjoern A. Zeeb } 37142774f206SBjoern A. Zeeb 37152774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_coef_transfer(struct rtw_dev *rtwdev) 37162774f206SBjoern A. Zeeb { 37172774f206SBjoern A. Zeeb u32 reg = 0; 37182774f206SBjoern A. Zeeb u16 coef_i = 0, coef_q = 0; 37192774f206SBjoern A. Zeeb 37202774f206SBjoern A. Zeeb reg = rtw_read32(rtwdev, REG_STAT_RPT); 37212774f206SBjoern A. Zeeb 37222774f206SBjoern A. Zeeb coef_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD) & 0x1fff; 37232774f206SBjoern A. Zeeb coef_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD) & 0x1fff; 37242774f206SBjoern A. Zeeb 37252774f206SBjoern A. Zeeb coef_q = ((0x2000 - coef_q) & 0x1fff) - 1; 37262774f206SBjoern A. Zeeb 37272774f206SBjoern A. Zeeb reg = (coef_i << 16) | coef_q; 37282774f206SBjoern A. Zeeb 37292774f206SBjoern A. Zeeb return reg; 37302774f206SBjoern A. Zeeb } 37312774f206SBjoern A. Zeeb 37322774f206SBjoern A. Zeeb static const u32 rtw8822c_dpk_get_coef_tbl[] = { 37332774f206SBjoern A. Zeeb 0x000400f0, 0x040400f0, 0x080400f0, 0x010400f0, 0x050400f0, 37342774f206SBjoern A. Zeeb 0x090400f0, 0x020400f0, 0x060400f0, 0x0a0400f0, 0x030400f0, 37352774f206SBjoern A. Zeeb 0x070400f0, 0x0b0400f0, 0x0c0400f0, 0x100400f0, 0x0d0400f0, 37362774f206SBjoern A. Zeeb 0x110400f0, 0x0e0400f0, 0x120400f0, 0x0f0400f0, 0x130400f0, 37372774f206SBjoern A. Zeeb }; 37382774f206SBjoern A. Zeeb 37392774f206SBjoern A. Zeeb static void rtw8822c_dpk_coef_tbl_apply(struct rtw_dev *rtwdev, u8 path) 37402774f206SBjoern A. Zeeb { 37412774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 37422774f206SBjoern A. Zeeb int i; 37432774f206SBjoern A. Zeeb 37442774f206SBjoern A. Zeeb for (i = 0; i < 20; i++) { 37452774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 37462774f206SBjoern A. Zeeb rtw8822c_dpk_get_coef_tbl[i]); 37472774f206SBjoern A. Zeeb dpk_info->coef[path][i] = rtw8822c_dpk_coef_transfer(rtwdev); 37482774f206SBjoern A. Zeeb } 37492774f206SBjoern A. Zeeb } 37502774f206SBjoern A. Zeeb 37512774f206SBjoern A. Zeeb static void rtw8822c_dpk_get_coef(struct rtw_dev *rtwdev, u8 path) 37522774f206SBjoern A. Zeeb { 37532774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); 37542774f206SBjoern A. Zeeb 37552774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 37562774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x0); 37572774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL0_S0, 0x30000080); 37582774f206SBjoern A. Zeeb } else if (path == RF_PATH_B) { 37592774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x1); 37602774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL0_S1, 0x30000080); 37612774f206SBjoern A. Zeeb } 37622774f206SBjoern A. Zeeb 37632774f206SBjoern A. Zeeb rtw8822c_dpk_coef_tbl_apply(rtwdev, path); 37642774f206SBjoern A. Zeeb } 37652774f206SBjoern A. Zeeb 37662774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_coef_read(struct rtw_dev *rtwdev, u8 path) 37672774f206SBjoern A. Zeeb { 37682774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 37692774f206SBjoern A. Zeeb u8 addr, result = 1; 37702774f206SBjoern A. Zeeb u16 coef_i, coef_q; 37712774f206SBjoern A. Zeeb 37722774f206SBjoern A. Zeeb for (addr = 0; addr < 20; addr++) { 37732774f206SBjoern A. Zeeb coef_i = FIELD_GET(0x1fff0000, dpk_info->coef[path][addr]); 37742774f206SBjoern A. Zeeb coef_q = FIELD_GET(0x1fff, dpk_info->coef[path][addr]); 37752774f206SBjoern A. Zeeb 37762774f206SBjoern A. Zeeb if (rtw8822c_dpk_coef_iq_check(rtwdev, coef_i, coef_q)) { 37772774f206SBjoern A. Zeeb result = 0; 37782774f206SBjoern A. Zeeb break; 37792774f206SBjoern A. Zeeb } 37802774f206SBjoern A. Zeeb } 37812774f206SBjoern A. Zeeb return result; 37822774f206SBjoern A. Zeeb } 37832774f206SBjoern A. Zeeb 37842774f206SBjoern A. Zeeb static void rtw8822c_dpk_coef_write(struct rtw_dev *rtwdev, u8 path, u8 result) 37852774f206SBjoern A. Zeeb { 37862774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 37872774f206SBjoern A. Zeeb u16 reg[DPK_RF_PATH_NUM] = {0x1b0c, 0x1b64}; 37882774f206SBjoern A. Zeeb u32 coef; 37892774f206SBjoern A. Zeeb u8 addr; 37902774f206SBjoern A. Zeeb 37912774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); 37922774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 37932774f206SBjoern A. Zeeb 37942774f206SBjoern A. Zeeb for (addr = 0; addr < 20; addr++) { 37952774f206SBjoern A. Zeeb if (result == 0) { 37962774f206SBjoern A. Zeeb if (addr == 3) 37972774f206SBjoern A. Zeeb coef = 0x04001fff; 37982774f206SBjoern A. Zeeb else 37992774f206SBjoern A. Zeeb coef = 0x00001fff; 38002774f206SBjoern A. Zeeb } else { 38012774f206SBjoern A. Zeeb coef = dpk_info->coef[path][addr]; 38022774f206SBjoern A. Zeeb } 38032774f206SBjoern A. Zeeb rtw_write32(rtwdev, reg[path] + addr * 4, coef); 38042774f206SBjoern A. Zeeb } 38052774f206SBjoern A. Zeeb } 38062774f206SBjoern A. Zeeb 38072774f206SBjoern A. Zeeb static void rtw8822c_dpk_fill_result(struct rtw_dev *rtwdev, u32 dpk_txagc, 38082774f206SBjoern A. Zeeb u8 path, u8 result) 38092774f206SBjoern A. Zeeb { 38102774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 38112774f206SBjoern A. Zeeb 38122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 38132774f206SBjoern A. Zeeb 38142774f206SBjoern A. Zeeb if (result) 38152774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DPD_AGC, (u8)(dpk_txagc - 6)); 38162774f206SBjoern A. Zeeb else 38172774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DPD_AGC, 0x00); 38182774f206SBjoern A. Zeeb 38192774f206SBjoern A. Zeeb dpk_info->result[path] = result; 38202774f206SBjoern A. Zeeb dpk_info->dpk_txagc[path] = rtw_read8(rtwdev, REG_DPD_AGC); 38212774f206SBjoern A. Zeeb 38222774f206SBjoern A. Zeeb rtw8822c_dpk_coef_write(rtwdev, path, result); 38232774f206SBjoern A. Zeeb } 38242774f206SBjoern A. Zeeb 38252774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_gainloss(struct rtw_dev *rtwdev, u8 path) 38262774f206SBjoern A. Zeeb { 38272774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 38282774f206SBjoern A. Zeeb u8 tx_agc, tx_bb, ori_txbb, ori_txagc, tx_agc_search, t1, t2; 38292774f206SBjoern A. Zeeb 38302774f206SBjoern A. Zeeb ori_txbb = rtw8822c_dpk_rf_setting(rtwdev, path); 38312774f206SBjoern A. Zeeb ori_txagc = (u8)rtw_read_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_TXAGC); 38322774f206SBjoern A. Zeeb 38332774f206SBjoern A. Zeeb rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 38342774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 38352774f206SBjoern A. Zeeb rtw8822c_dpk_dgain_read(rtwdev, path); 38362774f206SBjoern A. Zeeb 38372774f206SBjoern A. Zeeb if (rtw8822c_dpk_dc_corr_check(rtwdev, path)) { 38382774f206SBjoern A. Zeeb rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 38392774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 38402774f206SBjoern A. Zeeb rtw8822c_dpk_dc_corr_check(rtwdev, path); 38412774f206SBjoern A. Zeeb } 38422774f206SBjoern A. Zeeb 38432774f206SBjoern A. Zeeb t1 = rtw8822c_dpk_thermal_read(rtwdev, path); 38442774f206SBjoern A. Zeeb tx_bb = rtw8822c_dpk_pas_agc(rtwdev, path, false, true); 38452774f206SBjoern A. Zeeb tx_agc_search = rtw8822c_dpk_gainloss_result(rtwdev, path); 38462774f206SBjoern A. Zeeb 38472774f206SBjoern A. Zeeb if (tx_bb < tx_agc_search) 38482774f206SBjoern A. Zeeb tx_bb = 0; 38492774f206SBjoern A. Zeeb else 38502774f206SBjoern A. Zeeb tx_bb = tx_bb - tx_agc_search; 38512774f206SBjoern A. Zeeb 38522774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_TX_GAIN, BIT_GAIN_TXBB, tx_bb); 38532774f206SBjoern A. Zeeb 38542774f206SBjoern A. Zeeb tx_agc = ori_txagc - (ori_txbb - tx_bb); 38552774f206SBjoern A. Zeeb 38562774f206SBjoern A. Zeeb t2 = rtw8822c_dpk_thermal_read(rtwdev, path); 38572774f206SBjoern A. Zeeb 38582774f206SBjoern A. Zeeb dpk_info->thermal_dpk_delta[path] = abs(t2 - t1); 38592774f206SBjoern A. Zeeb 38602774f206SBjoern A. Zeeb return tx_agc; 38612774f206SBjoern A. Zeeb } 38622774f206SBjoern A. Zeeb 38632774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_by_path(struct rtw_dev *rtwdev, u32 tx_agc, u8 path) 38642774f206SBjoern A. Zeeb { 38652774f206SBjoern A. Zeeb u8 result; 38662774f206SBjoern A. Zeeb 38672774f206SBjoern A. Zeeb result = rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DO_DPK); 38682774f206SBjoern A. Zeeb 38692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 38702774f206SBjoern A. Zeeb 38712774f206SBjoern A. Zeeb result = result | (u8)rtw_read32_mask(rtwdev, REG_DPD_CTL1_S0, BIT(26)); 38722774f206SBjoern A. Zeeb 38732774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x33e14); 38742774f206SBjoern A. Zeeb 38752774f206SBjoern A. Zeeb rtw8822c_dpk_get_coef(rtwdev, path); 38762774f206SBjoern A. Zeeb 38772774f206SBjoern A. Zeeb return result; 38782774f206SBjoern A. Zeeb } 38792774f206SBjoern A. Zeeb 38802774f206SBjoern A. Zeeb static void rtw8822c_dpk_cal_gs(struct rtw_dev *rtwdev, u8 path) 38812774f206SBjoern A. Zeeb { 38822774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 38832774f206SBjoern A. Zeeb u32 tmp_gs = 0; 38842774f206SBjoern A. Zeeb 38852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 38862774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_BYPASS_DPD, 0x0); 38872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 38882774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); 38892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x1); 38902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 38912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0xf); 38922774f206SBjoern A. Zeeb 38932774f206SBjoern A. Zeeb if (path == RF_PATH_A) { 38942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 38952774f206SBjoern A. Zeeb 0x1066680); 38962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 0x1); 38972774f206SBjoern A. Zeeb } else { 38982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 38992774f206SBjoern A. Zeeb 0x1066680); 39002774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 0x1); 39012774f206SBjoern A. Zeeb } 39022774f206SBjoern A. Zeeb 39032774f206SBjoern A. Zeeb if (dpk_info->dpk_bw == DPK_CHANNEL_WIDTH_80) { 39042774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x80001310); 39052774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x00001310); 39062774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x810000db); 39072774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x010000db); 39082774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); 39092774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL15, 39102774f206SBjoern A. Zeeb 0x05020000 | (BIT(path) << 28)); 39112774f206SBjoern A. Zeeb } else { 39122774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x8200190c); 39132774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x0200190c); 39142774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x8301ee14); 39152774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x0301ee14); 39162774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); 39172774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL15, 39182774f206SBjoern A. Zeeb 0x05020008 | (BIT(path) << 28)); 39192774f206SBjoern A. Zeeb } 39202774f206SBjoern A. Zeeb 39212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0, MASKBYTE3, 0x8 | path); 39222774f206SBjoern A. Zeeb 39232774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_CAL_PWR); 39242774f206SBjoern A. Zeeb 39252774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL15, MASKBYTE3, 0x0); 39262774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 39272774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); 39282774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x0); 39292774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 39302774f206SBjoern A. Zeeb 39312774f206SBjoern A. Zeeb if (path == RF_PATH_A) 39322774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 0x5b); 39332774f206SBjoern A. Zeeb else 39342774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 0x5b); 39352774f206SBjoern A. Zeeb 39362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); 39372774f206SBjoern A. Zeeb 39382774f206SBjoern A. Zeeb tmp_gs = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, BIT_RPT_DGAIN); 39392774f206SBjoern A. Zeeb tmp_gs = (tmp_gs * 910) >> 10; 39402774f206SBjoern A. Zeeb tmp_gs = DIV_ROUND_CLOSEST(tmp_gs, 10); 39412774f206SBjoern A. Zeeb 39422774f206SBjoern A. Zeeb if (path == RF_PATH_A) 39432774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, tmp_gs); 39442774f206SBjoern A. Zeeb else 39452774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, tmp_gs); 39462774f206SBjoern A. Zeeb 39472774f206SBjoern A. Zeeb dpk_info->dpk_gs[path] = tmp_gs; 39482774f206SBjoern A. Zeeb } 39492774f206SBjoern A. Zeeb 39502774f206SBjoern A. Zeeb static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) 39512774f206SBjoern A. Zeeb { 39522774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 39532774f206SBjoern A. Zeeb u32 offset[DPK_RF_PATH_NUM] = {0, 0x58}; 39542774f206SBjoern A. Zeeb u32 i_scaling; 39552774f206SBjoern A. Zeeb u8 path; 39562774f206SBjoern A. Zeeb 39572774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); 39582774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 39592774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x00001148); 39602774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_NCTL0, 0x00001149); 39612774f206SBjoern A. Zeeb 39622774f206SBjoern A. Zeeb check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55); 39632774f206SBjoern A. Zeeb 39642774f206SBjoern A. Zeeb rtw_write8(rtwdev, 0x1b10, 0x0); 39652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); 39662774f206SBjoern A. Zeeb 39672774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 39682774f206SBjoern A. Zeeb i_scaling = 0x16c00 / dpk_info->dpk_gs[path]; 39692774f206SBjoern A. Zeeb 39702774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b18 + offset[path], MASKHWORD, 39712774f206SBjoern A. Zeeb i_scaling); 39722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 39732774f206SBjoern A. Zeeb GENMASK(31, 28), 0x9); 39742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 39752774f206SBjoern A. Zeeb GENMASK(31, 28), 0x1); 39762774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 39772774f206SBjoern A. Zeeb GENMASK(31, 28), 0x0); 39782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0 + offset[path], 39792774f206SBjoern A. Zeeb BIT(14), 0x0); 39802774f206SBjoern A. Zeeb } 39812774f206SBjoern A. Zeeb } 39822774f206SBjoern A. Zeeb 39832774f206SBjoern A. Zeeb static void rtw8822c_dpk_on(struct rtw_dev *rtwdev, u8 path) 39842774f206SBjoern A. Zeeb { 39852774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 39862774f206SBjoern A. Zeeb 39872774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); 39882774f206SBjoern A. Zeeb 39892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 39902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 39912774f206SBjoern A. Zeeb 39922774f206SBjoern A. Zeeb if (test_bit(path, dpk_info->dpk_path_ok)) 39932774f206SBjoern A. Zeeb rtw8822c_dpk_cal_gs(rtwdev, path); 39942774f206SBjoern A. Zeeb } 39952774f206SBjoern A. Zeeb 39962774f206SBjoern A. Zeeb static bool rtw8822c_dpk_check_pass(struct rtw_dev *rtwdev, bool is_fail, 39972774f206SBjoern A. Zeeb u32 dpk_txagc, u8 path) 39982774f206SBjoern A. Zeeb { 39992774f206SBjoern A. Zeeb bool result; 40002774f206SBjoern A. Zeeb 40012774f206SBjoern A. Zeeb if (!is_fail) { 40022774f206SBjoern A. Zeeb if (rtw8822c_dpk_coef_read(rtwdev, path)) 40032774f206SBjoern A. Zeeb result = true; 40042774f206SBjoern A. Zeeb else 40052774f206SBjoern A. Zeeb result = false; 40062774f206SBjoern A. Zeeb } else { 40072774f206SBjoern A. Zeeb result = false; 40082774f206SBjoern A. Zeeb } 40092774f206SBjoern A. Zeeb 40102774f206SBjoern A. Zeeb rtw8822c_dpk_fill_result(rtwdev, dpk_txagc, path, result); 40112774f206SBjoern A. Zeeb 40122774f206SBjoern A. Zeeb return result; 40132774f206SBjoern A. Zeeb } 40142774f206SBjoern A. Zeeb 40152774f206SBjoern A. Zeeb static void rtw8822c_dpk_result_reset(struct rtw_dev *rtwdev) 40162774f206SBjoern A. Zeeb { 40172774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 40182774f206SBjoern A. Zeeb u8 path; 40192774f206SBjoern A. Zeeb 40202774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 40212774f206SBjoern A. Zeeb clear_bit(path, dpk_info->dpk_path_ok); 40222774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 40232774f206SBjoern A. Zeeb 0x8 | (path << 1)); 40242774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b58, 0x0000007f, 0x0); 40252774f206SBjoern A. Zeeb 40262774f206SBjoern A. Zeeb dpk_info->dpk_txagc[path] = 0; 40272774f206SBjoern A. Zeeb dpk_info->result[path] = 0; 40282774f206SBjoern A. Zeeb dpk_info->dpk_gs[path] = 0x5b; 40292774f206SBjoern A. Zeeb dpk_info->pre_pwsf[path] = 0; 40302774f206SBjoern A. Zeeb dpk_info->thermal_dpk[path] = rtw8822c_dpk_thermal_read(rtwdev, 40312774f206SBjoern A. Zeeb path); 40322774f206SBjoern A. Zeeb } 40332774f206SBjoern A. Zeeb } 40342774f206SBjoern A. Zeeb 40352774f206SBjoern A. Zeeb static void rtw8822c_dpk_calibrate(struct rtw_dev *rtwdev, u8 path) 40362774f206SBjoern A. Zeeb { 40372774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 40382774f206SBjoern A. Zeeb u32 dpk_txagc; 40392774f206SBjoern A. Zeeb u8 dpk_fail; 40402774f206SBjoern A. Zeeb 40412774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk start\n", path); 40422774f206SBjoern A. Zeeb 40432774f206SBjoern A. Zeeb dpk_txagc = rtw8822c_dpk_gainloss(rtwdev, path); 40442774f206SBjoern A. Zeeb 40452774f206SBjoern A. Zeeb dpk_fail = rtw8822c_dpk_by_path(rtwdev, dpk_txagc, path); 40462774f206SBjoern A. Zeeb 40472774f206SBjoern A. Zeeb if (!rtw8822c_dpk_check_pass(rtwdev, dpk_fail, dpk_txagc, path)) 40482774f206SBjoern A. Zeeb rtw_err(rtwdev, "failed to do dpk calibration\n"); 40492774f206SBjoern A. Zeeb 40502774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk finish\n", path); 40512774f206SBjoern A. Zeeb 40522774f206SBjoern A. Zeeb if (dpk_info->result[path]) 40532774f206SBjoern A. Zeeb set_bit(path, dpk_info->dpk_path_ok); 40542774f206SBjoern A. Zeeb } 40552774f206SBjoern A. Zeeb 40562774f206SBjoern A. Zeeb static void rtw8822c_dpk_path_select(struct rtw_dev *rtwdev) 40572774f206SBjoern A. Zeeb { 40582774f206SBjoern A. Zeeb rtw8822c_dpk_calibrate(rtwdev, RF_PATH_A); 40592774f206SBjoern A. Zeeb rtw8822c_dpk_calibrate(rtwdev, RF_PATH_B); 40602774f206SBjoern A. Zeeb rtw8822c_dpk_on(rtwdev, RF_PATH_A); 40612774f206SBjoern A. Zeeb rtw8822c_dpk_on(rtwdev, RF_PATH_B); 40622774f206SBjoern A. Zeeb rtw8822c_dpk_cal_coef1(rtwdev); 40632774f206SBjoern A. Zeeb } 40642774f206SBjoern A. Zeeb 40652774f206SBjoern A. Zeeb static void rtw8822c_dpk_enable_disable(struct rtw_dev *rtwdev) 40662774f206SBjoern A. Zeeb { 40672774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 40682774f206SBjoern A. Zeeb u32 mask = BIT(15) | BIT(14); 40692774f206SBjoern A. Zeeb 40702774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 40712774f206SBjoern A. Zeeb 40722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 40732774f206SBjoern A. Zeeb dpk_info->is_dpk_pwr_on); 40742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 40752774f206SBjoern A. Zeeb dpk_info->is_dpk_pwr_on); 40762774f206SBjoern A. Zeeb 40772774f206SBjoern A. Zeeb if (test_bit(RF_PATH_A, dpk_info->dpk_path_ok)) { 40782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, mask, 0x0); 40792774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DPD_CTL0_S0, dpk_info->dpk_gs[RF_PATH_A]); 40802774f206SBjoern A. Zeeb } 40812774f206SBjoern A. Zeeb if (test_bit(RF_PATH_B, dpk_info->dpk_path_ok)) { 40822774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, mask, 0x0); 40832774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DPD_CTL0_S1, dpk_info->dpk_gs[RF_PATH_B]); 40842774f206SBjoern A. Zeeb } 40852774f206SBjoern A. Zeeb } 40862774f206SBjoern A. Zeeb 40872774f206SBjoern A. Zeeb static void rtw8822c_dpk_reload_data(struct rtw_dev *rtwdev) 40882774f206SBjoern A. Zeeb { 40892774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 40902774f206SBjoern A. Zeeb u8 path; 40912774f206SBjoern A. Zeeb 40922774f206SBjoern A. Zeeb if (!test_bit(RF_PATH_A, dpk_info->dpk_path_ok) && 40932774f206SBjoern A. Zeeb !test_bit(RF_PATH_B, dpk_info->dpk_path_ok) && 40942774f206SBjoern A. Zeeb dpk_info->dpk_ch == 0) 40952774f206SBjoern A. Zeeb return; 40962774f206SBjoern A. Zeeb 40972774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 40982774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 40992774f206SBjoern A. Zeeb 0x8 | (path << 1)); 41002774f206SBjoern A. Zeeb if (dpk_info->dpk_band == RTW_BAND_2G) 41012774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); 41022774f206SBjoern A. Zeeb else 41032774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); 41042774f206SBjoern A. Zeeb 41052774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DPD_AGC, dpk_info->dpk_txagc[path]); 41062774f206SBjoern A. Zeeb 41072774f206SBjoern A. Zeeb rtw8822c_dpk_coef_write(rtwdev, path, 41082774f206SBjoern A. Zeeb test_bit(path, dpk_info->dpk_path_ok)); 41092774f206SBjoern A. Zeeb 41102774f206SBjoern A. Zeeb rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); 41112774f206SBjoern A. Zeeb 41122774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 41132774f206SBjoern A. Zeeb 41142774f206SBjoern A. Zeeb if (path == RF_PATH_A) 41152774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 41162774f206SBjoern A. Zeeb dpk_info->dpk_gs[path]); 41172774f206SBjoern A. Zeeb else 41182774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 41192774f206SBjoern A. Zeeb dpk_info->dpk_gs[path]); 41202774f206SBjoern A. Zeeb } 41212774f206SBjoern A. Zeeb rtw8822c_dpk_cal_coef1(rtwdev); 41222774f206SBjoern A. Zeeb } 41232774f206SBjoern A. Zeeb 41242774f206SBjoern A. Zeeb static bool rtw8822c_dpk_reload(struct rtw_dev *rtwdev) 41252774f206SBjoern A. Zeeb { 41262774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 41272774f206SBjoern A. Zeeb u8 channel; 41282774f206SBjoern A. Zeeb 41292774f206SBjoern A. Zeeb dpk_info->is_reload = false; 41302774f206SBjoern A. Zeeb 41314f3b2bbaSBjoern A. Zeeb #if defined(__linux__) 41322774f206SBjoern A. Zeeb channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK) & 0xff); 41334f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__) 41344f3b2bbaSBjoern A. Zeeb channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK) & 0xff); 41354f3b2bbaSBjoern A. Zeeb #endif 41362774f206SBjoern A. Zeeb 41372774f206SBjoern A. Zeeb if (channel == dpk_info->dpk_ch) { 41382774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 41392774f206SBjoern A. Zeeb "[DPK] DPK reload for CH%d!!\n", dpk_info->dpk_ch); 41402774f206SBjoern A. Zeeb rtw8822c_dpk_reload_data(rtwdev); 41412774f206SBjoern A. Zeeb dpk_info->is_reload = true; 41422774f206SBjoern A. Zeeb } 41432774f206SBjoern A. Zeeb 41442774f206SBjoern A. Zeeb return dpk_info->is_reload; 41452774f206SBjoern A. Zeeb } 41462774f206SBjoern A. Zeeb 41472774f206SBjoern A. Zeeb static void rtw8822c_do_dpk(struct rtw_dev *rtwdev) 41482774f206SBjoern A. Zeeb { 41492774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 41502774f206SBjoern A. Zeeb struct rtw_backup_info bckp[DPK_BB_REG_NUM]; 41512774f206SBjoern A. Zeeb u32 rf_reg_backup[DPK_RF_REG_NUM][DPK_RF_PATH_NUM]; 41522774f206SBjoern A. Zeeb u32 bb_reg[DPK_BB_REG_NUM] = { 41532774f206SBjoern A. Zeeb 0x520, 0x820, 0x824, 0x1c3c, 0x1d58, 0x1864, 41542774f206SBjoern A. Zeeb 0x4164, 0x180c, 0x410c, 0x186c, 0x416c, 41552774f206SBjoern A. Zeeb 0x1a14, 0x1e70, 0x80c, 0x1d70, 0x1e7c, 0x18a4, 0x41a4}; 41562774f206SBjoern A. Zeeb u32 rf_reg[DPK_RF_REG_NUM] = { 41572774f206SBjoern A. Zeeb 0x0, 0x1a, 0x55, 0x63, 0x87, 0x8f, 0xde}; 41582774f206SBjoern A. Zeeb u8 path; 41592774f206SBjoern A. Zeeb 41602774f206SBjoern A. Zeeb if (!dpk_info->is_dpk_pwr_on) { 41612774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] Skip DPK due to DPD PWR off\n"); 41622774f206SBjoern A. Zeeb return; 41632774f206SBjoern A. Zeeb } else if (rtw8822c_dpk_reload(rtwdev)) { 41642774f206SBjoern A. Zeeb return; 41652774f206SBjoern A. Zeeb } 41662774f206SBjoern A. Zeeb 41672774f206SBjoern A. Zeeb for (path = RF_PATH_A; path < DPK_RF_PATH_NUM; path++) 41682774f206SBjoern A. Zeeb ewma_thermal_init(&dpk_info->avg_thermal[path]); 41692774f206SBjoern A. Zeeb 41702774f206SBjoern A. Zeeb rtw8822c_dpk_information(rtwdev); 41712774f206SBjoern A. Zeeb 41722774f206SBjoern A. Zeeb rtw8822c_dpk_backup_registers(rtwdev, bb_reg, DPK_BB_REG_NUM, bckp); 41732774f206SBjoern A. Zeeb rtw8822c_dpk_backup_rf_registers(rtwdev, rf_reg, rf_reg_backup); 41742774f206SBjoern A. Zeeb 41752774f206SBjoern A. Zeeb rtw8822c_dpk_mac_bb_setting(rtwdev); 41762774f206SBjoern A. Zeeb rtw8822c_dpk_afe_setting(rtwdev, true); 41772774f206SBjoern A. Zeeb rtw8822c_dpk_pre_setting(rtwdev); 41782774f206SBjoern A. Zeeb rtw8822c_dpk_result_reset(rtwdev); 41792774f206SBjoern A. Zeeb rtw8822c_dpk_path_select(rtwdev); 41802774f206SBjoern A. Zeeb rtw8822c_dpk_afe_setting(rtwdev, false); 41812774f206SBjoern A. Zeeb rtw8822c_dpk_enable_disable(rtwdev); 41822774f206SBjoern A. Zeeb 41832774f206SBjoern A. Zeeb rtw8822c_dpk_reload_rf_registers(rtwdev, rf_reg, rf_reg_backup); 41842774f206SBjoern A. Zeeb for (path = 0; path < rtwdev->hal.rf_path_num; path++) 41852774f206SBjoern A. Zeeb rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 41862774f206SBjoern A. Zeeb rtw8822c_dpk_restore_registers(rtwdev, DPK_BB_REG_NUM, bckp); 41872774f206SBjoern A. Zeeb } 41882774f206SBjoern A. Zeeb 41892774f206SBjoern A. Zeeb static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev) 41902774f206SBjoern A. Zeeb { 41912774f206SBjoern A. Zeeb rtw8822c_rfk_power_save(rtwdev, false); 41922774f206SBjoern A. Zeeb rtw8822c_do_gapk(rtwdev); 41932774f206SBjoern A. Zeeb rtw8822c_do_iqk(rtwdev); 41942774f206SBjoern A. Zeeb rtw8822c_do_dpk(rtwdev); 41952774f206SBjoern A. Zeeb rtw8822c_rfk_power_save(rtwdev, true); 41962774f206SBjoern A. Zeeb } 41972774f206SBjoern A. Zeeb 41982774f206SBjoern A. Zeeb static void rtw8822c_dpk_track(struct rtw_dev *rtwdev) 41992774f206SBjoern A. Zeeb { 42002774f206SBjoern A. Zeeb struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 42012774f206SBjoern A. Zeeb u8 path; 42022774f206SBjoern A. Zeeb u8 thermal_value[DPK_RF_PATH_NUM] = {0}; 42032774f206SBjoern A. Zeeb s8 offset[DPK_RF_PATH_NUM], delta_dpk[DPK_RF_PATH_NUM]; 42042774f206SBjoern A. Zeeb 42052774f206SBjoern A. Zeeb if (dpk_info->thermal_dpk[0] == 0 && dpk_info->thermal_dpk[1] == 0) 42062774f206SBjoern A. Zeeb return; 42072774f206SBjoern A. Zeeb 42082774f206SBjoern A. Zeeb for (path = 0; path < DPK_RF_PATH_NUM; path++) { 42092774f206SBjoern A. Zeeb thermal_value[path] = rtw8822c_dpk_thermal_read(rtwdev, path); 42102774f206SBjoern A. Zeeb ewma_thermal_add(&dpk_info->avg_thermal[path], 42112774f206SBjoern A. Zeeb thermal_value[path]); 42122774f206SBjoern A. Zeeb thermal_value[path] = 42132774f206SBjoern A. Zeeb ewma_thermal_read(&dpk_info->avg_thermal[path]); 42142774f206SBjoern A. Zeeb delta_dpk[path] = dpk_info->thermal_dpk[path] - 42152774f206SBjoern A. Zeeb thermal_value[path]; 42162774f206SBjoern A. Zeeb offset[path] = delta_dpk[path] - 42172774f206SBjoern A. Zeeb dpk_info->thermal_dpk_delta[path]; 42182774f206SBjoern A. Zeeb offset[path] &= 0x7f; 42192774f206SBjoern A. Zeeb 42202774f206SBjoern A. Zeeb if (offset[path] != dpk_info->pre_pwsf[path]) { 42212774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 42222774f206SBjoern A. Zeeb 0x8 | (path << 1)); 42232774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x1b58, GENMASK(6, 0), 42242774f206SBjoern A. Zeeb offset[path]); 42252774f206SBjoern A. Zeeb dpk_info->pre_pwsf[path] = offset[path]; 42262774f206SBjoern A. Zeeb } 42272774f206SBjoern A. Zeeb } 42282774f206SBjoern A. Zeeb } 42292774f206SBjoern A. Zeeb 42302774f206SBjoern A. Zeeb #define XCAP_EXTEND(val) ({typeof(val) _v = (val); _v | _v << 7; }) 42312774f206SBjoern A. Zeeb static void rtw8822c_set_crystal_cap_reg(struct rtw_dev *rtwdev, u8 crystal_cap) 42322774f206SBjoern A. Zeeb { 42332774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 42342774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 42352774f206SBjoern A. Zeeb u32 val = 0; 42362774f206SBjoern A. Zeeb 42372774f206SBjoern A. Zeeb val = XCAP_EXTEND(crystal_cap); 42382774f206SBjoern A. Zeeb cfo->crystal_cap = crystal_cap; 42392774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, BIT_XCAP_0, val); 42402774f206SBjoern A. Zeeb } 42412774f206SBjoern A. Zeeb 42422774f206SBjoern A. Zeeb static void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap) 42432774f206SBjoern A. Zeeb { 42442774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 42452774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 42462774f206SBjoern A. Zeeb 42472774f206SBjoern A. Zeeb if (cfo->crystal_cap == crystal_cap) 42482774f206SBjoern A. Zeeb return; 42492774f206SBjoern A. Zeeb 42502774f206SBjoern A. Zeeb rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap); 42512774f206SBjoern A. Zeeb } 42522774f206SBjoern A. Zeeb 42532774f206SBjoern A. Zeeb static void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev) 42542774f206SBjoern A. Zeeb { 42552774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 42562774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 42572774f206SBjoern A. Zeeb 42582774f206SBjoern A. Zeeb cfo->is_adjust = true; 42592774f206SBjoern A. Zeeb 42602774f206SBjoern A. Zeeb if (cfo->crystal_cap > rtwdev->efuse.crystal_cap) 42612774f206SBjoern A. Zeeb rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1); 42622774f206SBjoern A. Zeeb else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap) 42632774f206SBjoern A. Zeeb rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1); 42642774f206SBjoern A. Zeeb } 42652774f206SBjoern A. Zeeb 42662774f206SBjoern A. Zeeb static void rtw8822c_cfo_init(struct rtw_dev *rtwdev) 42672774f206SBjoern A. Zeeb { 42682774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 42692774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 42702774f206SBjoern A. Zeeb 42712774f206SBjoern A. Zeeb cfo->crystal_cap = rtwdev->efuse.crystal_cap; 42722774f206SBjoern A. Zeeb cfo->is_adjust = true; 42732774f206SBjoern A. Zeeb } 42742774f206SBjoern A. Zeeb 42752774f206SBjoern A. Zeeb #define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); }) 42762774f206SBjoern A. Zeeb static s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num) 42772774f206SBjoern A. Zeeb { 42782774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 42792774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 42802774f206SBjoern A. Zeeb s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum; 42812774f206SBjoern A. Zeeb u8 i; 42822774f206SBjoern A. Zeeb 42832774f206SBjoern A. Zeeb for (i = 0; i < path_num; i++) { 42842774f206SBjoern A. Zeeb cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]); 42852774f206SBjoern A. Zeeb 42862774f206SBjoern A. Zeeb if (cfo->cfo_cnt[i]) 42872774f206SBjoern A. Zeeb cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i]; 42882774f206SBjoern A. Zeeb else 42892774f206SBjoern A. Zeeb cfo_avg = 0; 42902774f206SBjoern A. Zeeb 42912774f206SBjoern A. Zeeb cfo_path_sum += cfo_avg; 42922774f206SBjoern A. Zeeb } 42932774f206SBjoern A. Zeeb 42942774f206SBjoern A. Zeeb for (i = 0; i < path_num; i++) { 42952774f206SBjoern A. Zeeb cfo->cfo_tail[i] = 0; 42962774f206SBjoern A. Zeeb cfo->cfo_cnt[i] = 0; 42972774f206SBjoern A. Zeeb } 42982774f206SBjoern A. Zeeb 42992774f206SBjoern A. Zeeb return cfo_path_sum / path_num; 43002774f206SBjoern A. Zeeb } 43012774f206SBjoern A. Zeeb 43022774f206SBjoern A. Zeeb static void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg) 43032774f206SBjoern A. Zeeb { 43042774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 43052774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 43062774f206SBjoern A. Zeeb 43072774f206SBjoern A. Zeeb if (!cfo->is_adjust) { 43082774f206SBjoern A. Zeeb if (abs(cfo_avg) > CFO_TRK_ENABLE_TH) 43092774f206SBjoern A. Zeeb cfo->is_adjust = true; 43102774f206SBjoern A. Zeeb } else { 43112774f206SBjoern A. Zeeb if (abs(cfo_avg) <= CFO_TRK_STOP_TH) 43122774f206SBjoern A. Zeeb cfo->is_adjust = false; 43132774f206SBjoern A. Zeeb } 43142774f206SBjoern A. Zeeb 43152774f206SBjoern A. Zeeb if (!rtw_coex_disabled(rtwdev)) { 43162774f206SBjoern A. Zeeb cfo->is_adjust = false; 43172774f206SBjoern A. Zeeb rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); 43182774f206SBjoern A. Zeeb } 43192774f206SBjoern A. Zeeb } 43202774f206SBjoern A. Zeeb 43212774f206SBjoern A. Zeeb static void rtw8822c_cfo_track(struct rtw_dev *rtwdev) 43222774f206SBjoern A. Zeeb { 43232774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 43242774f206SBjoern A. Zeeb struct rtw_cfo_track *cfo = &dm_info->cfo_track; 43252774f206SBjoern A. Zeeb u8 path_num = rtwdev->hal.rf_path_num; 43262774f206SBjoern A. Zeeb s8 crystal_cap = cfo->crystal_cap; 43272774f206SBjoern A. Zeeb s32 cfo_avg = 0; 43282774f206SBjoern A. Zeeb 43292774f206SBjoern A. Zeeb if (rtwdev->sta_cnt != 1) { 43302774f206SBjoern A. Zeeb rtw8822c_cfo_tracking_reset(rtwdev); 43312774f206SBjoern A. Zeeb return; 43322774f206SBjoern A. Zeeb } 43332774f206SBjoern A. Zeeb 43342774f206SBjoern A. Zeeb if (cfo->packet_count == cfo->packet_count_pre) 43352774f206SBjoern A. Zeeb return; 43362774f206SBjoern A. Zeeb 43372774f206SBjoern A. Zeeb cfo->packet_count_pre = cfo->packet_count; 43382774f206SBjoern A. Zeeb cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num); 43392774f206SBjoern A. Zeeb rtw8822c_cfo_need_adjust(rtwdev, cfo_avg); 43402774f206SBjoern A. Zeeb 43412774f206SBjoern A. Zeeb if (cfo->is_adjust) { 43422774f206SBjoern A. Zeeb if (cfo_avg > CFO_TRK_ADJ_TH) 43432774f206SBjoern A. Zeeb crystal_cap++; 43442774f206SBjoern A. Zeeb else if (cfo_avg < -CFO_TRK_ADJ_TH) 43452774f206SBjoern A. Zeeb crystal_cap--; 43462774f206SBjoern A. Zeeb 43472774f206SBjoern A. Zeeb crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK); 43482774f206SBjoern A. Zeeb rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap); 43492774f206SBjoern A. Zeeb } 43502774f206SBjoern A. Zeeb } 43512774f206SBjoern A. Zeeb 43522774f206SBjoern A. Zeeb static const struct rtw_phy_cck_pd_reg 43532774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[RTW_CHANNEL_WIDTH_40 + 1][RTW_RF_PATH_MAX] = { 43542774f206SBjoern A. Zeeb { 43552774f206SBjoern A. Zeeb {0x1ac8, 0x00ff, 0x1ad0, 0x01f}, 43562774f206SBjoern A. Zeeb {0x1ac8, 0xff00, 0x1ad0, 0x3e0} 43572774f206SBjoern A. Zeeb }, 43582774f206SBjoern A. Zeeb { 43592774f206SBjoern A. Zeeb {0x1acc, 0x00ff, 0x1ad0, 0x01F00000}, 43602774f206SBjoern A. Zeeb {0x1acc, 0xff00, 0x1ad0, 0x3E000000} 43612774f206SBjoern A. Zeeb }, 43622774f206SBjoern A. Zeeb }; 43632774f206SBjoern A. Zeeb 43642774f206SBjoern A. Zeeb #define RTW_CCK_PD_MAX 255 43652774f206SBjoern A. Zeeb #define RTW_CCK_CS_MAX 31 43662774f206SBjoern A. Zeeb #define RTW_CCK_CS_ERR1 27 43672774f206SBjoern A. Zeeb #define RTW_CCK_CS_ERR2 29 43682774f206SBjoern A. Zeeb static void 43692774f206SBjoern A. Zeeb rtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev, 43702774f206SBjoern A. Zeeb s8 pd_diff, s8 cs_diff, u8 bw, u8 nrx) 43712774f206SBjoern A. Zeeb { 43722774f206SBjoern A. Zeeb u32 pd, cs; 43732774f206SBjoern A. Zeeb 43742774f206SBjoern A. Zeeb if (WARN_ON(bw > RTW_CHANNEL_WIDTH_40 || nrx >= RTW_RF_PATH_MAX)) 43752774f206SBjoern A. Zeeb return; 43762774f206SBjoern A. Zeeb 43772774f206SBjoern A. Zeeb pd = rtw_read32_mask(rtwdev, 43782774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].reg_pd, 43792774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].mask_pd); 43802774f206SBjoern A. Zeeb cs = rtw_read32_mask(rtwdev, 43812774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].reg_cs, 43822774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].mask_cs); 43832774f206SBjoern A. Zeeb pd += pd_diff; 43842774f206SBjoern A. Zeeb cs += cs_diff; 43852774f206SBjoern A. Zeeb if (pd > RTW_CCK_PD_MAX) 43862774f206SBjoern A. Zeeb pd = RTW_CCK_PD_MAX; 43872774f206SBjoern A. Zeeb if (cs == RTW_CCK_CS_ERR1 || cs == RTW_CCK_CS_ERR2) 43882774f206SBjoern A. Zeeb cs++; 43892774f206SBjoern A. Zeeb else if (cs > RTW_CCK_CS_MAX) 43902774f206SBjoern A. Zeeb cs = RTW_CCK_CS_MAX; 43912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 43922774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].reg_pd, 43932774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].mask_pd, 43942774f206SBjoern A. Zeeb pd); 43952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 43962774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].reg_cs, 43972774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[bw][nrx].mask_cs, 43982774f206SBjoern A. Zeeb cs); 43992774f206SBjoern A. Zeeb 44002774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_PHY, 44012774f206SBjoern A. Zeeb "is_linked=%d, bw=%d, nrx=%d, cs_ratio=0x%x, pd_th=0x%x\n", 44022774f206SBjoern A. Zeeb rtw_is_assoc(rtwdev), bw, nrx, cs, pd); 44032774f206SBjoern A. Zeeb } 44042774f206SBjoern A. Zeeb 44052774f206SBjoern A. Zeeb static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) 44062774f206SBjoern A. Zeeb { 44072774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 44082774f206SBjoern A. Zeeb s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8}; 44092774f206SBjoern A. Zeeb s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4}; 44102774f206SBjoern A. Zeeb u8 cur_lvl; 44112774f206SBjoern A. Zeeb u8 nrx, bw; 44122774f206SBjoern A. Zeeb 44132774f206SBjoern A. Zeeb nrx = (u8)rtw_read32_mask(rtwdev, 0x1a2c, 0x60000); 44142774f206SBjoern A. Zeeb bw = (u8)rtw_read32_mask(rtwdev, 0x9b0, 0xc); 44152774f206SBjoern A. Zeeb 44162774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d) bw=%d nr=%d cck_fa_avg=%d\n", 44172774f206SBjoern A. Zeeb dm_info->cck_pd_lv[bw][nrx], new_lvl, bw, nrx, 44182774f206SBjoern A. Zeeb dm_info->cck_fa_avg); 44192774f206SBjoern A. Zeeb 44202774f206SBjoern A. Zeeb if (dm_info->cck_pd_lv[bw][nrx] == new_lvl) 44212774f206SBjoern A. Zeeb return; 44222774f206SBjoern A. Zeeb 44232774f206SBjoern A. Zeeb cur_lvl = dm_info->cck_pd_lv[bw][nrx]; 44242774f206SBjoern A. Zeeb 44252774f206SBjoern A. Zeeb /* update cck pd info */ 44262774f206SBjoern A. Zeeb dm_info->cck_fa_avg = CCK_FA_AVG_RESET; 44272774f206SBjoern A. Zeeb 44282774f206SBjoern A. Zeeb rtw8822c_phy_cck_pd_set_reg(rtwdev, 44292774f206SBjoern A. Zeeb pd_lvl[new_lvl] - pd_lvl[cur_lvl], 44302774f206SBjoern A. Zeeb cs_lvl[new_lvl] - cs_lvl[cur_lvl], 44312774f206SBjoern A. Zeeb bw, nrx); 44322774f206SBjoern A. Zeeb dm_info->cck_pd_lv[bw][nrx] = new_lvl; 44332774f206SBjoern A. Zeeb } 44342774f206SBjoern A. Zeeb 44352774f206SBjoern A. Zeeb #define PWR_TRACK_MASK 0x7f 44362774f206SBjoern A. Zeeb static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) 44372774f206SBjoern A. Zeeb { 44382774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 44392774f206SBjoern A. Zeeb 44402774f206SBjoern A. Zeeb switch (rf_path) { 44412774f206SBjoern A. Zeeb case RF_PATH_A: 44422774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK, 44432774f206SBjoern A. Zeeb dm_info->delta_power_index[rf_path]); 44442774f206SBjoern A. Zeeb break; 44452774f206SBjoern A. Zeeb case RF_PATH_B: 44462774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK, 44472774f206SBjoern A. Zeeb dm_info->delta_power_index[rf_path]); 44482774f206SBjoern A. Zeeb break; 44492774f206SBjoern A. Zeeb default: 44502774f206SBjoern A. Zeeb break; 44512774f206SBjoern A. Zeeb } 44522774f206SBjoern A. Zeeb } 44532774f206SBjoern A. Zeeb 44542774f206SBjoern A. Zeeb static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path) 44552774f206SBjoern A. Zeeb { 44562774f206SBjoern A. Zeeb u8 thermal_value; 44572774f206SBjoern A. Zeeb 44582774f206SBjoern A. Zeeb if (rtwdev->efuse.thermal_meter[path] == 0xff) 44592774f206SBjoern A. Zeeb return; 44602774f206SBjoern A. Zeeb 44612774f206SBjoern A. Zeeb thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); 44622774f206SBjoern A. Zeeb rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); 44632774f206SBjoern A. Zeeb } 44642774f206SBjoern A. Zeeb 44652774f206SBjoern A. Zeeb static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, 44662774f206SBjoern A. Zeeb struct rtw_swing_table *swing_table, 44672774f206SBjoern A. Zeeb u8 path) 44682774f206SBjoern A. Zeeb { 44692774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 44702774f206SBjoern A. Zeeb u8 delta; 44712774f206SBjoern A. Zeeb 44722774f206SBjoern A. Zeeb delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); 44732774f206SBjoern A. Zeeb dm_info->delta_power_index[path] = 44742774f206SBjoern A. Zeeb rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, 44752774f206SBjoern A. Zeeb delta); 44762774f206SBjoern A. Zeeb rtw8822c_pwrtrack_set(rtwdev, path); 44772774f206SBjoern A. Zeeb } 44782774f206SBjoern A. Zeeb 44792774f206SBjoern A. Zeeb static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) 44802774f206SBjoern A. Zeeb { 44812774f206SBjoern A. Zeeb struct rtw_swing_table swing_table; 44822774f206SBjoern A. Zeeb u8 i; 44832774f206SBjoern A. Zeeb 44842774f206SBjoern A. Zeeb rtw_phy_config_swing_table(rtwdev, &swing_table); 44852774f206SBjoern A. Zeeb 44862774f206SBjoern A. Zeeb for (i = 0; i < rtwdev->hal.rf_path_num; i++) 44872774f206SBjoern A. Zeeb rtw8822c_pwr_track_stats(rtwdev, i); 44882774f206SBjoern A. Zeeb if (rtw_phy_pwrtrack_need_lck(rtwdev)) 44892774f206SBjoern A. Zeeb rtw8822c_do_lck(rtwdev); 44902774f206SBjoern A. Zeeb for (i = 0; i < rtwdev->hal.rf_path_num; i++) 44912774f206SBjoern A. Zeeb rtw8822c_pwr_track_path(rtwdev, &swing_table, i); 44922774f206SBjoern A. Zeeb } 44932774f206SBjoern A. Zeeb 44942774f206SBjoern A. Zeeb static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) 44952774f206SBjoern A. Zeeb { 44962774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 44972774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 44982774f206SBjoern A. Zeeb 44992774f206SBjoern A. Zeeb if (efuse->power_track_type != 0) 45002774f206SBjoern A. Zeeb return; 45012774f206SBjoern A. Zeeb 45022774f206SBjoern A. Zeeb if (!dm_info->pwr_trk_triggered) { 45032774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 45042774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00); 45052774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 45062774f206SBjoern A. Zeeb 45072774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 45082774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00); 45092774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 45102774f206SBjoern A. Zeeb 45112774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = true; 45122774f206SBjoern A. Zeeb return; 45132774f206SBjoern A. Zeeb } 45142774f206SBjoern A. Zeeb 45152774f206SBjoern A. Zeeb __rtw8822c_pwr_track(rtwdev); 45162774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 45172774f206SBjoern A. Zeeb } 45182774f206SBjoern A. Zeeb 45192774f206SBjoern A. Zeeb static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev) 45202774f206SBjoern A. Zeeb { 45212774f206SBjoern A. Zeeb rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX); 45222774f206SBjoern A. Zeeb 45232774f206SBjoern A. Zeeb /* mac edcca state setting */ 45242774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA); 45252774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN); 45262774f206SBjoern A. Zeeb 45272774f206SBjoern A. Zeeb /* edcca decistion opt */ 45282774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION); 45292774f206SBjoern A. Zeeb } 45302774f206SBjoern A. Zeeb 45312774f206SBjoern A. Zeeb static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) 45322774f206SBjoern A. Zeeb { 45332774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 45342774f206SBjoern A. Zeeb s8 l2h, h2l; 45352774f206SBjoern A. Zeeb u8 igi; 45362774f206SBjoern A. Zeeb 45372774f206SBjoern A. Zeeb igi = dm_info->igi_history[0]; 45382774f206SBjoern A. Zeeb if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { 45392774f206SBjoern A. Zeeb l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); 45402774f206SBjoern A. Zeeb h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; 45412774f206SBjoern A. Zeeb } else { 45422774f206SBjoern A. Zeeb if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF) 45432774f206SBjoern A. Zeeb l2h = igi + EDCCA_ADC_BACKOFF; 45442774f206SBjoern A. Zeeb else 45452774f206SBjoern A. Zeeb l2h = dm_info->l2h_th_ini; 45462774f206SBjoern A. Zeeb h2l = l2h - EDCCA_L2H_H2L_DIFF; 45472774f206SBjoern A. Zeeb } 45482774f206SBjoern A. Zeeb 45492774f206SBjoern A. Zeeb rtw_phy_set_edcca_th(rtwdev, l2h, h2l); 45502774f206SBjoern A. Zeeb } 45512774f206SBjoern A. Zeeb 4552*a0ccc12fSBjoern A. Zeeb static void rtw8822c_led_set(struct led_classdev *led, 4553*a0ccc12fSBjoern A. Zeeb enum led_brightness brightness) 4554*a0ccc12fSBjoern A. Zeeb { 4555*a0ccc12fSBjoern A. Zeeb struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); 4556*a0ccc12fSBjoern A. Zeeb u32 ledcfg; 4557*a0ccc12fSBjoern A. Zeeb 4558*a0ccc12fSBjoern A. Zeeb ledcfg = rtw_read32(rtwdev, REG_LED_CFG); 4559*a0ccc12fSBjoern A. Zeeb u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); 4560*a0ccc12fSBjoern A. Zeeb ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; 4561*a0ccc12fSBjoern A. Zeeb 4562*a0ccc12fSBjoern A. Zeeb if (brightness == LED_OFF) 4563*a0ccc12fSBjoern A. Zeeb ledcfg |= BIT_LED2_SV; 4564*a0ccc12fSBjoern A. Zeeb else 4565*a0ccc12fSBjoern A. Zeeb ledcfg &= ~BIT_LED2_SV; 4566*a0ccc12fSBjoern A. Zeeb 4567*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_LED_CFG, ledcfg); 4568*a0ccc12fSBjoern A. Zeeb } 4569*a0ccc12fSBjoern A. Zeeb 457090aac0d8SBjoern A. Zeeb static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, 457190aac0d8SBjoern A. Zeeb struct rtw_tx_pkt_info *pkt_info, 457290aac0d8SBjoern A. Zeeb u8 *txdesc) 457390aac0d8SBjoern A. Zeeb { 457490aac0d8SBjoern A. Zeeb const struct rtw_chip_info *chip = rtwdev->chip; 457590aac0d8SBjoern A. Zeeb size_t words; 457690aac0d8SBjoern A. Zeeb 457790aac0d8SBjoern A. Zeeb words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2; 457890aac0d8SBjoern A. Zeeb 457990aac0d8SBjoern A. Zeeb fill_txdesc_checksum_common(txdesc, words); 458090aac0d8SBjoern A. Zeeb } 458190aac0d8SBjoern A. Zeeb 45822774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { 45832774f206SBjoern A. Zeeb {0x0086, 45842774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 45852774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 45862774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 45872774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 45882774f206SBjoern A. Zeeb {0x0086, 45892774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 45902774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 45912774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 45922774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 45932774f206SBjoern A. Zeeb {0x002E, 45942774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 45952774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 45962774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 45972774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 45982774f206SBjoern A. Zeeb {0x002D, 45992774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46002774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46012774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46022774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 46032774f206SBjoern A. Zeeb {0x007F, 46042774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46052774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46062774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46072774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7), 0}, 46082774f206SBjoern A. Zeeb {0x004A, 46092774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46102774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 46112774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46122774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 46132774f206SBjoern A. Zeeb {0x0005, 46142774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46152774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46162774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46172774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, 46182774f206SBjoern A. Zeeb {0xFFFF, 46192774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46202774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46212774f206SBjoern A. Zeeb 0, 46222774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 46232774f206SBjoern A. Zeeb }; 46242774f206SBjoern A. Zeeb 46252774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822c[] = { 46262774f206SBjoern A. Zeeb {0x0000, 46272774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46282774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 46292774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46302774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), 0}, 46312774f206SBjoern A. Zeeb {0x0005, 46322774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46332774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46342774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46352774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, 46362774f206SBjoern A. Zeeb {0x0075, 46372774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46382774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 46392774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46402774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 46412774f206SBjoern A. Zeeb {0x0006, 46422774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46432774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46442774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46452774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 46462774f206SBjoern A. Zeeb {0x0075, 46472774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46482774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 46492774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46502774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 46512774f206SBjoern A. Zeeb {0xFF1A, 46522774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46532774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 46542774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46552774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 46562774f206SBjoern A. Zeeb {0x002E, 46572774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46582774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46592774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46602774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3), 0}, 46612774f206SBjoern A. Zeeb {0x0006, 46622774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46632774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46642774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46652774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 46662774f206SBjoern A. Zeeb {0x0005, 46672774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46682774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46692774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46702774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, 46712774f206SBjoern A. Zeeb {0x1018, 46722774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46732774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46742774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46752774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 46762774f206SBjoern A. Zeeb {0x0005, 46772774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46782774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46792774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46802774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 46812774f206SBjoern A. Zeeb {0x0005, 46822774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46832774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 46842774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46852774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(0), 0}, 46862774f206SBjoern A. Zeeb {0x0074, 46872774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46882774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 46892774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46902774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 46912774f206SBjoern A. Zeeb {0x0071, 46922774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46932774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 46942774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 46952774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(4), 0}, 46962774f206SBjoern A. Zeeb {0x0062, 46972774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 46982774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 46992774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47002774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 47012774f206SBjoern A. Zeeb (BIT(7) | BIT(6) | BIT(5))}, 47022774f206SBjoern A. Zeeb {0x0061, 47032774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47042774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 47052774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47062774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, 47072774f206SBjoern A. Zeeb {0x001F, 47082774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47092774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47102774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47112774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, 47122774f206SBjoern A. Zeeb {0x00EF, 47132774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47142774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47152774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47162774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, 47172774f206SBjoern A. Zeeb {0x1045, 47182774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47192774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47202774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47212774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, 47222774f206SBjoern A. Zeeb {0x0010, 47232774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47242774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47252774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47262774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 47272774f206SBjoern A. Zeeb {0x1064, 47282774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47292774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47302774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47312774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 47322774f206SBjoern A. Zeeb {0xFFFF, 47332774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47342774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47352774f206SBjoern A. Zeeb 0, 47362774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 47372774f206SBjoern A. Zeeb }; 47382774f206SBjoern A. Zeeb 47392774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822c[] = { 47402774f206SBjoern A. Zeeb {0x0093, 47412774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47422774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47432774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47442774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3), 0}, 47452774f206SBjoern A. Zeeb {0x001F, 47462774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47472774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47482774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47492774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 47502774f206SBjoern A. Zeeb {0x00EF, 47512774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47522774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47532774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47542774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 47552774f206SBjoern A. Zeeb {0x1045, 47562774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47572774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47582774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47592774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(4), 0}, 47602774f206SBjoern A. Zeeb {0xFF1A, 47612774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47622774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 47632774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47642774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x30}, 47652774f206SBjoern A. Zeeb {0x0049, 47662774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47672774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47682774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47692774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 47702774f206SBjoern A. Zeeb {0x0006, 47712774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47722774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47732774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47742774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 47752774f206SBjoern A. Zeeb {0x0002, 47762774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47772774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47782774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47792774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 47802774f206SBjoern A. Zeeb {0x0005, 47812774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47822774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47832774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47842774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 47852774f206SBjoern A. Zeeb {0x0005, 47862774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47872774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47882774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47892774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), 0}, 47902774f206SBjoern A. Zeeb {0x0000, 47912774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47922774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 47932774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 47942774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 47952774f206SBjoern A. Zeeb {0xFFFF, 47962774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 47972774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 47982774f206SBjoern A. Zeeb 0, 47992774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 48002774f206SBjoern A. Zeeb }; 48012774f206SBjoern A. Zeeb 48022774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = { 48032774f206SBjoern A. Zeeb {0x0005, 48042774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48052774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 48062774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48072774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, 48082774f206SBjoern A. Zeeb {0x0007, 48092774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48102774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 48112774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48122774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 48132774f206SBjoern A. Zeeb {0x0067, 48142774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48152774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 48162774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48172774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), 0}, 48182774f206SBjoern A. Zeeb {0x004A, 48192774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48202774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 48212774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48222774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 48232774f206SBjoern A. Zeeb {0x0081, 48242774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48252774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 48262774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48272774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, 48282774f206SBjoern A. Zeeb {0x0090, 48292774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48302774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 48312774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48322774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 48332774f206SBjoern A. Zeeb {0x0092, 48342774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48352774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 48362774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48372774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x20}, 48382774f206SBjoern A. Zeeb {0x0093, 48392774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48402774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 48412774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48422774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x04}, 48432774f206SBjoern A. Zeeb {0x0005, 48442774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48452774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 48462774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48472774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, 48482774f206SBjoern A. Zeeb {0x0005, 48492774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48502774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 48512774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 48522774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 48532774f206SBjoern A. Zeeb {0x0086, 48542774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48552774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 48562774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 48572774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 48582774f206SBjoern A. Zeeb {0xFFFF, 48592774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 48602774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 48612774f206SBjoern A. Zeeb 0, 48622774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 48632774f206SBjoern A. Zeeb }; 48642774f206SBjoern A. Zeeb 4865*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = { 48662774f206SBjoern A. Zeeb trans_carddis_to_cardemu_8822c, 48672774f206SBjoern A. Zeeb trans_cardemu_to_act_8822c, 48682774f206SBjoern A. Zeeb NULL 48692774f206SBjoern A. Zeeb }; 48702774f206SBjoern A. Zeeb 4871*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = { 48722774f206SBjoern A. Zeeb trans_act_to_cardemu_8822c, 48732774f206SBjoern A. Zeeb trans_cardemu_to_carddis_8822c, 48742774f206SBjoern A. Zeeb NULL 48752774f206SBjoern A. Zeeb }; 48762774f206SBjoern A. Zeeb 48772774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb2_param_8822c[] = { 48782774f206SBjoern A. Zeeb {0xFFFF, 0x00, 48792774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 48802774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 48812774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 48822774f206SBjoern A. Zeeb }; 48832774f206SBjoern A. Zeeb 48842774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb3_param_8822c[] = { 48852774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 48862774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 48872774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 48882774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 48892774f206SBjoern A. Zeeb }; 48902774f206SBjoern A. Zeeb 48912774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen1_param_8822c[] = { 48922774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 48932774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 48942774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 48952774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 48962774f206SBjoern A. Zeeb }; 48972774f206SBjoern A. Zeeb 48982774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen2_param_8822c[] = { 48992774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 49002774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 49012774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 49022774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 49032774f206SBjoern A. Zeeb }; 49042774f206SBjoern A. Zeeb 49052774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para_table phy_para_table_8822c = { 49062774f206SBjoern A. Zeeb .usb2_para = usb2_param_8822c, 49072774f206SBjoern A. Zeeb .usb3_para = usb3_param_8822c, 49082774f206SBjoern A. Zeeb .gen1_para = pcie_gen1_param_8822c, 49092774f206SBjoern A. Zeeb .gen2_para = pcie_gen2_param_8822c, 49102774f206SBjoern A. Zeeb .n_usb2_para = ARRAY_SIZE(usb2_param_8822c), 49112774f206SBjoern A. Zeeb .n_usb3_para = ARRAY_SIZE(usb2_param_8822c), 49122774f206SBjoern A. Zeeb .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8822c), 49132774f206SBjoern A. Zeeb .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), 49142774f206SBjoern A. Zeeb }; 49152774f206SBjoern A. Zeeb 49162774f206SBjoern A. Zeeb static const struct rtw_hw_reg rtw8822c_dig[] = { 49172774f206SBjoern A. Zeeb [0] = { .addr = 0x1d70, .mask = 0x7f }, 49182774f206SBjoern A. Zeeb [1] = { .addr = 0x1d70, .mask = 0x7f00 }, 49192774f206SBjoern A. Zeeb }; 49202774f206SBjoern A. Zeeb 49212774f206SBjoern A. Zeeb static const struct rtw_ltecoex_addr rtw8822c_ltecoex_addr = { 49222774f206SBjoern A. Zeeb .ctrl = LTECOEX_ACCESS_CTRL, 49232774f206SBjoern A. Zeeb .wdata = LTECOEX_WRITE_DATA, 49242774f206SBjoern A. Zeeb .rdata = LTECOEX_READ_DATA, 49252774f206SBjoern A. Zeeb }; 49262774f206SBjoern A. Zeeb 49272774f206SBjoern A. Zeeb static const struct rtw_page_table page_table_8822c[] = { 49282774f206SBjoern A. Zeeb {64, 64, 64, 64, 1}, 49292774f206SBjoern A. Zeeb {64, 64, 64, 64, 1}, 49302774f206SBjoern A. Zeeb {64, 64, 0, 0, 1}, 49312774f206SBjoern A. Zeeb {64, 64, 64, 0, 1}, 49322774f206SBjoern A. Zeeb {64, 64, 64, 64, 1}, 49332774f206SBjoern A. Zeeb }; 49342774f206SBjoern A. Zeeb 49352774f206SBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8822c[] = { 49362774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 49372774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 49382774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 49392774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 49402774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 49412774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 49422774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 49432774f206SBjoern A. Zeeb RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, 49442774f206SBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 49452774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 49462774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 49472774f206SBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 49482774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 49492774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 49502774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 49512774f206SBjoern A. Zeeb }; 49522774f206SBjoern A. Zeeb 4953*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8822c = { 49542774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_EXTRA] = { 49552774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, 49562774f206SBjoern A. Zeeb }, 49572774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_LOW] = { 49582774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, 49592774f206SBjoern A. Zeeb }, 49602774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_NORMAL] = { 49612774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, 49622774f206SBjoern A. Zeeb }, 49632774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_HIGH] = { 49642774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, 49652774f206SBjoern A. Zeeb }, 49662774f206SBjoern A. Zeeb .wsize = true, 49672774f206SBjoern A. Zeeb }; 49682774f206SBjoern A. Zeeb 4969*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8822c_ops = { 4970*a0ccc12fSBjoern A. Zeeb .power_on = rtw_power_on, 4971*a0ccc12fSBjoern A. Zeeb .power_off = rtw_power_off, 49722774f206SBjoern A. Zeeb .phy_set_param = rtw8822c_phy_set_param, 49732774f206SBjoern A. Zeeb .read_efuse = rtw8822c_read_efuse, 4974*a0ccc12fSBjoern A. Zeeb .query_phy_status = query_phy_status, 49752774f206SBjoern A. Zeeb .set_channel = rtw8822c_set_channel, 49762774f206SBjoern A. Zeeb .mac_init = rtw8822c_mac_init, 49772774f206SBjoern A. Zeeb .dump_fw_crash = rtw8822c_dump_fw_crash, 49782774f206SBjoern A. Zeeb .read_rf = rtw_phy_read_rf, 49792774f206SBjoern A. Zeeb .write_rf = rtw_phy_write_rf_reg_mix, 49802774f206SBjoern A. Zeeb .set_tx_power_index = rtw8822c_set_tx_power_index, 49812774f206SBjoern A. Zeeb .set_antenna = rtw8822c_set_antenna, 49822774f206SBjoern A. Zeeb .cfg_ldo25 = rtw8822c_cfg_ldo25, 49832774f206SBjoern A. Zeeb .false_alarm_statistics = rtw8822c_false_alarm_statistics, 49842774f206SBjoern A. Zeeb .dpk_track = rtw8822c_dpk_track, 49852774f206SBjoern A. Zeeb .phy_calibration = rtw8822c_phy_calibration, 49862774f206SBjoern A. Zeeb .cck_pd_set = rtw8822c_phy_cck_pd_set, 49872774f206SBjoern A. Zeeb .pwr_track = rtw8822c_pwr_track, 49882774f206SBjoern A. Zeeb .config_bfee = rtw8822c_bf_config_bfee, 49892774f206SBjoern A. Zeeb .set_gid_table = rtw_bf_set_gid_table, 49902774f206SBjoern A. Zeeb .cfg_csi_rate = rtw_bf_cfg_csi_rate, 49912774f206SBjoern A. Zeeb .adaptivity_init = rtw8822c_adaptivity_init, 49922774f206SBjoern A. Zeeb .adaptivity = rtw8822c_adaptivity, 49932774f206SBjoern A. Zeeb .cfo_init = rtw8822c_cfo_init, 49942774f206SBjoern A. Zeeb .cfo_track = rtw8822c_cfo_track, 49952774f206SBjoern A. Zeeb .config_tx_path = rtw8822c_config_tx_path, 49969c951734SBjoern A. Zeeb .config_txrx_mode = rtw8822c_config_trx_mode, 4997*a0ccc12fSBjoern A. Zeeb .led_set = rtw8822c_led_set, 499890aac0d8SBjoern A. Zeeb .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, 49992774f206SBjoern A. Zeeb 50002774f206SBjoern A. Zeeb .coex_set_init = rtw8822c_coex_cfg_init, 50012774f206SBjoern A. Zeeb .coex_set_ant_switch = NULL, 50022774f206SBjoern A. Zeeb .coex_set_gnt_fix = rtw8822c_coex_cfg_gnt_fix, 50032774f206SBjoern A. Zeeb .coex_set_gnt_debug = rtw8822c_coex_cfg_gnt_debug, 50042774f206SBjoern A. Zeeb .coex_set_rfe_type = rtw8822c_coex_cfg_rfe_type, 50052774f206SBjoern A. Zeeb .coex_set_wl_tx_power = rtw8822c_coex_cfg_wl_tx_power, 50062774f206SBjoern A. Zeeb .coex_set_wl_rx_gain = rtw8822c_coex_cfg_wl_rx_gain, 50072774f206SBjoern A. Zeeb }; 50082774f206SBjoern A. Zeeb 50092774f206SBjoern A. Zeeb /* Shared-Antenna Coex Table */ 50102774f206SBjoern A. Zeeb static const struct coex_table_para table_sant_8822c[] = { 50112774f206SBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-0 */ 50122774f206SBjoern A. Zeeb {0x55555555, 0x55555555}, 50132774f206SBjoern A. Zeeb {0x66555555, 0x66555555}, 50142774f206SBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 50152774f206SBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 50162774f206SBjoern A. Zeeb {0xfafafafa, 0xfafafafa}, /* case-5 */ 50172774f206SBjoern A. Zeeb {0x6a5a5555, 0xaaaaaaaa}, 50182774f206SBjoern A. Zeeb {0x6a5a56aa, 0x6a5a56aa}, 50192774f206SBjoern A. Zeeb {0x6a5a5a5a, 0x6a5a5a5a}, 50202774f206SBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 50212774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-10 */ 50222774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5aaa}, 50232774f206SBjoern A. Zeeb {0x66555555, 0x5a5a5aaa}, 50242774f206SBjoern A. Zeeb {0x66555555, 0x6aaa5aaa}, 50252774f206SBjoern A. Zeeb {0x66555555, 0xaaaa5aaa}, 50262774f206SBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, /* case-15 */ 50272774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 50282774f206SBjoern A. Zeeb {0xffff55ff, 0x6afa5afa}, 50292774f206SBjoern A. Zeeb {0xaaffffaa, 0xfafafafa}, 50302774f206SBjoern A. Zeeb {0xaa5555aa, 0x5a5a5a5a}, 50312774f206SBjoern A. Zeeb {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 50322774f206SBjoern A. Zeeb {0xaa5555aa, 0xaaaaaaaa}, 50332774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 50342774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 50352774f206SBjoern A. Zeeb {0xffffffff, 0x55555555}, 50362774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5aaa}, /* case-25 */ 50372774f206SBjoern A. Zeeb {0x55555555, 0x5a5a5a5a}, 50382774f206SBjoern A. Zeeb {0x55555555, 0xaaaaaaaa}, 50392774f206SBjoern A. Zeeb {0x55555555, 0x6a5a6a5a}, 50402774f206SBjoern A. Zeeb {0x66556655, 0x66556655}, 50412774f206SBjoern A. Zeeb {0x66556aaa, 0x6a5a6aaa}, /*case-30*/ 50422774f206SBjoern A. Zeeb {0xffffffff, 0x5aaa5aaa}, 50432774f206SBjoern A. Zeeb {0x56555555, 0x5a5a5aaa}, 50449c951734SBjoern A. Zeeb {0xdaffdaff, 0xdaffdaff}, 50459c951734SBjoern A. Zeeb {0xddffddff, 0xddffddff}, 50462774f206SBjoern A. Zeeb }; 50472774f206SBjoern A. Zeeb 50482774f206SBjoern A. Zeeb /* Non-Shared-Antenna Coex Table */ 50492774f206SBjoern A. Zeeb static const struct coex_table_para table_nsant_8822c[] = { 50502774f206SBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-100 */ 50512774f206SBjoern A. Zeeb {0x55555555, 0x55555555}, 50522774f206SBjoern A. Zeeb {0x66555555, 0x66555555}, 50532774f206SBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 50542774f206SBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 50552774f206SBjoern A. Zeeb {0xfafafafa, 0xfafafafa}, /* case-105 */ 50562774f206SBjoern A. Zeeb {0x5afa5afa, 0x5afa5afa}, 50572774f206SBjoern A. Zeeb {0x55555555, 0xfafafafa}, 50582774f206SBjoern A. Zeeb {0x66555555, 0xfafafafa}, 50592774f206SBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 50602774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-110 */ 50612774f206SBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, 50622774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 50632774f206SBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 50642774f206SBjoern A. Zeeb {0xffff55ff, 0xaaaaaaaa}, 50652774f206SBjoern A. Zeeb {0xffff55ff, 0xffff55ff}, /* case-115 */ 50662774f206SBjoern A. Zeeb {0xaaffffaa, 0x5afa5afa}, 50672774f206SBjoern A. Zeeb {0xaaffffaa, 0xaaaaaaaa}, 50682774f206SBjoern A. Zeeb {0xffffffff, 0xfafafafa}, 50692774f206SBjoern A. Zeeb {0xffffffff, 0x5afa5afa}, 50702774f206SBjoern A. Zeeb {0xffffffff, 0xaaaaaaaa}, /* case-120 */ 50712774f206SBjoern A. Zeeb {0x55ff55ff, 0x5afa5afa}, 50722774f206SBjoern A. Zeeb {0x55ff55ff, 0xaaaaaaaa}, 50732774f206SBjoern A. Zeeb {0x55ff55ff, 0x55ff55ff} 50742774f206SBjoern A. Zeeb }; 50752774f206SBjoern A. Zeeb 50762774f206SBjoern A. Zeeb /* Shared-Antenna TDMA */ 50772774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_sant_8822c[] = { 50782774f206SBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 50792774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 50802774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 50812774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x11} }, 50822774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 50832774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ 50842774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 50852774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 50862774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 50872774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 50882774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 50892774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x14} }, 50902774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x10, 0x14} }, 50912774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, 50922774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 50932774f206SBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ 50942774f206SBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 50952774f206SBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 50962774f206SBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 50972774f206SBjoern A. Zeeb { {0x51, 0x20, 0x03, 0x10, 0x50} }, 50982774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ 50992774f206SBjoern A. Zeeb { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 51002774f206SBjoern A. Zeeb { {0x51, 0x0c, 0x03, 0x10, 0x54} }, 51012774f206SBjoern A. Zeeb { {0x55, 0x08, 0x03, 0x10, 0x54} }, 51022774f206SBjoern A. Zeeb { {0x65, 0x10, 0x03, 0x11, 0x10} }, 51032774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ 51042774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x50} }, 51052774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x11} } 51062774f206SBjoern A. Zeeb }; 51072774f206SBjoern A. Zeeb 51082774f206SBjoern A. Zeeb /* Non-Shared-Antenna TDMA */ 51092774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_nsant_8822c[] = { 51102774f206SBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */ 51112774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, 51122774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 51132774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x11} }, 51142774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 51152774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ 51162774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 51172774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 51182774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 51192774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 51202774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ 51212774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x14} }, 51222774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x10, 0x14} }, 51232774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, 51242774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 51252774f206SBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ 51262774f206SBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 51272774f206SBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 51282774f206SBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 51292774f206SBjoern A. Zeeb { {0x51, 0x20, 0x03, 0x10, 0x50} }, 51302774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ 51312774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x50} } 51322774f206SBjoern A. Zeeb }; 51332774f206SBjoern A. Zeeb 51342774f206SBjoern A. Zeeb /* rssi in percentage % (dbm = % - 100) */ 51352774f206SBjoern A. Zeeb static const u8 wl_rssi_step_8822c[] = {60, 50, 44, 30}; 51362774f206SBjoern A. Zeeb static const u8 bt_rssi_step_8822c[] = {8, 15, 20, 25}; 51372774f206SBjoern A. Zeeb static const struct coex_5g_afh_map afh_5g_8822c[] = { {0, 0, 0} }; 51382774f206SBjoern A. Zeeb 51392774f206SBjoern A. Zeeb /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ 51402774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8822c[] = { 51412774f206SBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 51422774f206SBjoern A. Zeeb {0, 16, false, 7}, /* for WL-CPT */ 51432774f206SBjoern A. Zeeb {8, 17, true, 4}, 51442774f206SBjoern A. Zeeb {7, 18, true, 4}, 51452774f206SBjoern A. Zeeb {6, 19, true, 4}, 51469c951734SBjoern A. Zeeb {5, 20, true, 4}, 51479c951734SBjoern A. Zeeb {0, 21, true, 4} /* for gamg hid */ 51482774f206SBjoern A. Zeeb }; 51492774f206SBjoern A. Zeeb 51502774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8822c[] = { 51512774f206SBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 51522774f206SBjoern A. Zeeb {0, 16, false, 7}, /* for WL-CPT */ 51532774f206SBjoern A. Zeeb {3, 24, true, 5}, 51542774f206SBjoern A. Zeeb {2, 26, true, 5}, 51552774f206SBjoern A. Zeeb {1, 27, true, 5}, 51569c951734SBjoern A. Zeeb {0, 28, true, 5}, 51579c951734SBjoern A. Zeeb {0, 28, true, 5} /* for gamg hid */ 51582774f206SBjoern A. Zeeb }; 51592774f206SBjoern A. Zeeb 51602774f206SBjoern A. Zeeb #if defined(__linux__) 51612774f206SBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); 51622774f206SBjoern A. Zeeb #elif defined(__FreeBSD__) 51632774f206SBjoern A. Zeeb rtw88_static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); 51642774f206SBjoern A. Zeeb #endif 51652774f206SBjoern A. Zeeb 51662774f206SBjoern A. Zeeb static const u8 51672774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 51682774f206SBjoern A. Zeeb { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 51692774f206SBjoern A. Zeeb 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 51702774f206SBjoern A. Zeeb 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 51712774f206SBjoern A. Zeeb { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 51722774f206SBjoern A. Zeeb 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 51732774f206SBjoern A. Zeeb 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 51742774f206SBjoern A. Zeeb { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 51752774f206SBjoern A. Zeeb 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 51762774f206SBjoern A. Zeeb 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 51772774f206SBjoern A. Zeeb }; 51782774f206SBjoern A. Zeeb 51792774f206SBjoern A. Zeeb static const u8 51802774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 51812774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 51822774f206SBjoern A. Zeeb 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 51832774f206SBjoern A. Zeeb 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 51842774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 51852774f206SBjoern A. Zeeb 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 51862774f206SBjoern A. Zeeb 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 51872774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 51882774f206SBjoern A. Zeeb 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 51892774f206SBjoern A. Zeeb 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 51902774f206SBjoern A. Zeeb }; 51912774f206SBjoern A. Zeeb 51922774f206SBjoern A. Zeeb static const u8 51932774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 51942774f206SBjoern A. Zeeb { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 51952774f206SBjoern A. Zeeb 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 51962774f206SBjoern A. Zeeb 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 51972774f206SBjoern A. Zeeb { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 51982774f206SBjoern A. Zeeb 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 51992774f206SBjoern A. Zeeb 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 52002774f206SBjoern A. Zeeb { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 52012774f206SBjoern A. Zeeb 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 52022774f206SBjoern A. Zeeb 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 52032774f206SBjoern A. Zeeb }; 52042774f206SBjoern A. Zeeb 52052774f206SBjoern A. Zeeb static const u8 52062774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 52072774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52082774f206SBjoern A. Zeeb 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 52092774f206SBjoern A. Zeeb 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 52102774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52112774f206SBjoern A. Zeeb 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 52122774f206SBjoern A. Zeeb 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 52132774f206SBjoern A. Zeeb { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52142774f206SBjoern A. Zeeb 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 52152774f206SBjoern A. Zeeb 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 52162774f206SBjoern A. Zeeb }; 52172774f206SBjoern A. Zeeb 52182774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { 52192774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 52202774f206SBjoern A. Zeeb 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, 52212774f206SBjoern A. Zeeb 17, 18, 19, 20, 20, 21, 22, 23, 24, 25 52222774f206SBjoern A. Zeeb }; 52232774f206SBjoern A. Zeeb 52242774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { 52252774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52262774f206SBjoern A. Zeeb 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 52272774f206SBjoern A. Zeeb 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 52282774f206SBjoern A. Zeeb }; 52292774f206SBjoern A. Zeeb 52302774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { 52312774f206SBjoern A. Zeeb 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 52322774f206SBjoern A. Zeeb 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 52332774f206SBjoern A. Zeeb 13, 14, 15, 15, 16, 17, 17, 18, 19, 19 52342774f206SBjoern A. Zeeb }; 52352774f206SBjoern A. Zeeb 52362774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { 52372774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52382774f206SBjoern A. Zeeb 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 52392774f206SBjoern A. Zeeb 19, 20, 21, 22, 23, 24, 25, 25, 26, 27 52402774f206SBjoern A. Zeeb }; 52412774f206SBjoern A. Zeeb 52422774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { 52432774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 52442774f206SBjoern A. Zeeb 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 52452774f206SBjoern A. Zeeb 17, 18, 19, 20, 21, 22, 23, 23, 24, 25 52462774f206SBjoern A. Zeeb }; 52472774f206SBjoern A. Zeeb 52482774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { 52492774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52502774f206SBjoern A. Zeeb 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 52512774f206SBjoern A. Zeeb 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 52522774f206SBjoern A. Zeeb }; 52532774f206SBjoern A. Zeeb 52542774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { 52552774f206SBjoern A. Zeeb 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 52562774f206SBjoern A. Zeeb 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 52572774f206SBjoern A. Zeeb 15, 16, 17, 18, 18, 19, 20, 21, 21, 22 52582774f206SBjoern A. Zeeb }; 52592774f206SBjoern A. Zeeb 52602774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { 52612774f206SBjoern A. Zeeb 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 52622774f206SBjoern A. Zeeb 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 52632774f206SBjoern A. Zeeb 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 52642774f206SBjoern A. Zeeb }; 52652774f206SBjoern A. Zeeb 5266*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = { 52672774f206SBjoern A. Zeeb .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], 52682774f206SBjoern A. Zeeb .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], 52692774f206SBjoern A. Zeeb .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], 52702774f206SBjoern A. Zeeb .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], 52712774f206SBjoern A. Zeeb .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], 52722774f206SBjoern A. Zeeb .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], 52732774f206SBjoern A. Zeeb .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], 52742774f206SBjoern A. Zeeb .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], 52752774f206SBjoern A. Zeeb .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], 52762774f206SBjoern A. Zeeb .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], 52772774f206SBjoern A. Zeeb .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], 52782774f206SBjoern A. Zeeb .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], 52792774f206SBjoern A. Zeeb .pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n, 52802774f206SBjoern A. Zeeb .pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p, 52812774f206SBjoern A. Zeeb .pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n, 52822774f206SBjoern A. Zeeb .pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p, 52832774f206SBjoern A. Zeeb .pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n, 52842774f206SBjoern A. Zeeb .pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p, 52852774f206SBjoern A. Zeeb .pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n, 52862774f206SBjoern A. Zeeb .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, 52872774f206SBjoern A. Zeeb }; 52882774f206SBjoern A. Zeeb 5289*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { 5290*a0ccc12fSBjoern A. Zeeb [0] = RTW_DEF_RFE(8822c, 0, 0, 0), 5291*a0ccc12fSBjoern A. Zeeb [1] = RTW_DEF_RFE(8822c, 0, 0, 0), 5292*a0ccc12fSBjoern A. Zeeb [2] = RTW_DEF_RFE(8822c, 0, 0, 0), 5293*a0ccc12fSBjoern A. Zeeb [3] = RTW_DEF_RFE(8822c, 0, 0, 0), 5294*a0ccc12fSBjoern A. Zeeb [4] = RTW_DEF_RFE(8822c, 0, 0, 0), 5295*a0ccc12fSBjoern A. Zeeb [5] = RTW_DEF_RFE(8822c, 0, 5, 0), 5296*a0ccc12fSBjoern A. Zeeb [6] = RTW_DEF_RFE(8822c, 0, 0, 0), 5297*a0ccc12fSBjoern A. Zeeb }; 5298*a0ccc12fSBjoern A. Zeeb 5299*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { 53002774f206SBjoern A. Zeeb [EDCCA_TH_L2H_IDX] = { 53012774f206SBjoern A. Zeeb {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 53022774f206SBjoern A. Zeeb }, 53032774f206SBjoern A. Zeeb [EDCCA_TH_H2L_IDX] = { 53042774f206SBjoern A. Zeeb {.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80 53052774f206SBjoern A. Zeeb }, 53062774f206SBjoern A. Zeeb }; 53072774f206SBjoern A. Zeeb 53082774f206SBjoern A. Zeeb #ifdef CONFIG_PM 53092774f206SBjoern A. Zeeb static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = { 53102774f206SBjoern A. Zeeb .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | 53112774f206SBjoern A. Zeeb WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 53122774f206SBjoern A. Zeeb WIPHY_WOWLAN_NET_DETECT, 53132774f206SBjoern A. Zeeb .n_patterns = RTW_MAX_PATTERN_NUM, 53142774f206SBjoern A. Zeeb .pattern_max_len = RTW_MAX_PATTERN_SIZE, 53152774f206SBjoern A. Zeeb .pattern_min_len = 1, 53162774f206SBjoern A. Zeeb .max_nd_match_sets = 4, 53172774f206SBjoern A. Zeeb }; 53182774f206SBjoern A. Zeeb #endif 53192774f206SBjoern A. Zeeb 53202774f206SBjoern A. Zeeb static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = { 53212774f206SBjoern A. Zeeb {0x1860, BIT(3), RTW_REG_DOMAIN_MAC8}, 53222774f206SBjoern A. Zeeb {0x4160, BIT(3), RTW_REG_DOMAIN_MAC8}, 53232774f206SBjoern A. Zeeb {0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8}, 53242774f206SBjoern A. Zeeb {0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32}, 53252774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 53262774f206SBjoern A. Zeeb {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 53272774f206SBjoern A. Zeeb {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 53282774f206SBjoern A. Zeeb {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 53292774f206SBjoern A. Zeeb {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 53302774f206SBjoern A. Zeeb {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, 53312774f206SBjoern A. Zeeb {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 53322774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 53332774f206SBjoern A. Zeeb {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, 53342774f206SBjoern A. Zeeb {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, 53352774f206SBjoern A. Zeeb {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, 53362774f206SBjoern A. Zeeb {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, 53372774f206SBjoern A. Zeeb {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, 53382774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 53392774f206SBjoern A. Zeeb {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 53402774f206SBjoern A. Zeeb {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 53412774f206SBjoern A. Zeeb {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, 53422774f206SBjoern A. Zeeb {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 53432774f206SBjoern A. Zeeb }; 53442774f206SBjoern A. Zeeb 53459c951734SBjoern A. Zeeb const struct rtw_chip_info rtw8822c_hw_spec = { 53462774f206SBjoern A. Zeeb .ops = &rtw8822c_ops, 53472774f206SBjoern A. Zeeb .id = RTW_CHIP_TYPE_8822C, 53482774f206SBjoern A. Zeeb .fw_name = "rtw88/rtw8822c_fw.bin", 53492774f206SBjoern A. Zeeb .wlan_cpu = RTW_WCPU_11AC, 53502774f206SBjoern A. Zeeb .tx_pkt_desc_sz = 48, 53512774f206SBjoern A. Zeeb .tx_buf_desc_sz = 16, 53522774f206SBjoern A. Zeeb .rx_pkt_desc_sz = 24, 53532774f206SBjoern A. Zeeb .rx_buf_desc_sz = 8, 53542774f206SBjoern A. Zeeb .phy_efuse_size = 512, 53552774f206SBjoern A. Zeeb .log_efuse_size = 768, 53562774f206SBjoern A. Zeeb .ptct_efuse_size = 124, 53572774f206SBjoern A. Zeeb .txff_size = 262144, 53582774f206SBjoern A. Zeeb .rxff_size = 24576, 53592774f206SBjoern A. Zeeb .fw_rxff_size = 12288, 536090aac0d8SBjoern A. Zeeb .rsvd_drv_pg_num = 16, 53612774f206SBjoern A. Zeeb .txgi_factor = 2, 53622774f206SBjoern A. Zeeb .is_pwr_by_rate_dec = false, 53632774f206SBjoern A. Zeeb .max_power_index = 0x7f, 53642774f206SBjoern A. Zeeb .csi_buf_pg_num = 50, 53652774f206SBjoern A. Zeeb .band = RTW_BAND_2G | RTW_BAND_5G, 536690aac0d8SBjoern A. Zeeb .page_size = TX_PAGE_SIZE, 53672774f206SBjoern A. Zeeb .dig_min = 0x20, 536811c53278SBjoern A. Zeeb .usb_tx_agg_desc_num = 3, 5369*a0ccc12fSBjoern A. Zeeb .hw_feature_report = true, 5370*a0ccc12fSBjoern A. Zeeb .c2h_ra_report_size = 7, 5371*a0ccc12fSBjoern A. Zeeb .old_datarate_fb_limit = false, 53722774f206SBjoern A. Zeeb .default_1ss_tx_path = BB_PATH_A, 53732774f206SBjoern A. Zeeb .path_div_supported = true, 53742774f206SBjoern A. Zeeb .ht_supported = true, 53752774f206SBjoern A. Zeeb .vht_supported = true, 53762774f206SBjoern A. Zeeb .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK) | BIT(LPS_DEEP_MODE_PG), 53772774f206SBjoern A. Zeeb .sys_func_en = 0xD8, 53782774f206SBjoern A. Zeeb .pwr_on_seq = card_enable_flow_8822c, 53792774f206SBjoern A. Zeeb .pwr_off_seq = card_disable_flow_8822c, 53802774f206SBjoern A. Zeeb .page_table = page_table_8822c, 53812774f206SBjoern A. Zeeb .rqpn_table = rqpn_table_8822c, 53822774f206SBjoern A. Zeeb .prioq_addrs = &prioq_addrs_8822c, 53832774f206SBjoern A. Zeeb .intf_table = &phy_para_table_8822c, 53842774f206SBjoern A. Zeeb .dig = rtw8822c_dig, 53852774f206SBjoern A. Zeeb .dig_cck = NULL, 53862774f206SBjoern A. Zeeb .rf_base_addr = {0x3c00, 0x4c00}, 53872774f206SBjoern A. Zeeb .rf_sipi_addr = {0x1808, 0x4108}, 53882774f206SBjoern A. Zeeb .ltecoex_addr = &rtw8822c_ltecoex_addr, 53892774f206SBjoern A. Zeeb .mac_tbl = &rtw8822c_mac_tbl, 53902774f206SBjoern A. Zeeb .agc_tbl = &rtw8822c_agc_tbl, 53912774f206SBjoern A. Zeeb .bb_tbl = &rtw8822c_bb_tbl, 53922774f206SBjoern A. Zeeb .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, 53932774f206SBjoern A. Zeeb .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, 53942774f206SBjoern A. Zeeb .rfe_defs = rtw8822c_rfe_defs, 53952774f206SBjoern A. Zeeb .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), 53962774f206SBjoern A. Zeeb .en_dis_dpd = true, 53972774f206SBjoern A. Zeeb .dpd_ratemask = DIS_DPD_RATEALL, 53982774f206SBjoern A. Zeeb .iqk_threshold = 8, 53992774f206SBjoern A. Zeeb .lck_threshold = 8, 54002774f206SBjoern A. Zeeb .bfer_su_max_num = 2, 54012774f206SBjoern A. Zeeb .bfer_mu_max_num = 1, 54022774f206SBjoern A. Zeeb .rx_ldpc = true, 54032774f206SBjoern A. Zeeb .tx_stbc = true, 54042774f206SBjoern A. Zeeb .edcca_th = rtw8822c_edcca_th, 54052774f206SBjoern A. Zeeb .l2h_th_ini_cs = 60, 54062774f206SBjoern A. Zeeb .l2h_th_ini_ad = 45, 54079c951734SBjoern A. Zeeb .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, 54082774f206SBjoern A. Zeeb 54092774f206SBjoern A. Zeeb #ifdef CONFIG_PM 54102774f206SBjoern A. Zeeb .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", 54112774f206SBjoern A. Zeeb .wowlan_stub = &rtw_wowlan_stub_8822c, 54122774f206SBjoern A. Zeeb .max_sched_scan_ssids = 4, 54132774f206SBjoern A. Zeeb #endif 541490aac0d8SBjoern A. Zeeb .max_scan_ie_len = (RTW_PROBE_PG_CNT - 1) * TX_PAGE_SIZE, 54159c951734SBjoern A. Zeeb .coex_para_ver = 0x22020720, 54169c951734SBjoern A. Zeeb .bt_desired_ver = 0x20, 54172774f206SBjoern A. Zeeb .scbd_support = true, 54182774f206SBjoern A. Zeeb .new_scbd10_def = true, 54192774f206SBjoern A. Zeeb .ble_hid_profile_support = true, 54209c951734SBjoern A. Zeeb .wl_mimo_ps_support = true, 54212774f206SBjoern A. Zeeb .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 54222774f206SBjoern A. Zeeb .bt_rssi_type = COEX_BTRSSI_DBM, 54232774f206SBjoern A. Zeeb .ant_isolation = 15, 54242774f206SBjoern A. Zeeb .rssi_tolerance = 2, 54252774f206SBjoern A. Zeeb .wl_rssi_step = wl_rssi_step_8822c, 54262774f206SBjoern A. Zeeb .bt_rssi_step = bt_rssi_step_8822c, 54272774f206SBjoern A. Zeeb .table_sant_num = ARRAY_SIZE(table_sant_8822c), 54282774f206SBjoern A. Zeeb .table_sant = table_sant_8822c, 54292774f206SBjoern A. Zeeb .table_nsant_num = ARRAY_SIZE(table_nsant_8822c), 54302774f206SBjoern A. Zeeb .table_nsant = table_nsant_8822c, 54312774f206SBjoern A. Zeeb .tdma_sant_num = ARRAY_SIZE(tdma_sant_8822c), 54322774f206SBjoern A. Zeeb .tdma_sant = tdma_sant_8822c, 54332774f206SBjoern A. Zeeb .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822c), 54342774f206SBjoern A. Zeeb .tdma_nsant = tdma_nsant_8822c, 54352774f206SBjoern A. Zeeb .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822c), 54362774f206SBjoern A. Zeeb .wl_rf_para_tx = rf_para_tx_8822c, 54372774f206SBjoern A. Zeeb .wl_rf_para_rx = rf_para_rx_8822c, 54382774f206SBjoern A. Zeeb .bt_afh_span_bw20 = 0x24, 54392774f206SBjoern A. Zeeb .bt_afh_span_bw40 = 0x36, 54402774f206SBjoern A. Zeeb .afh_5g_num = ARRAY_SIZE(afh_5g_8822c), 54412774f206SBjoern A. Zeeb .afh_5g = afh_5g_8822c, 54422774f206SBjoern A. Zeeb 54432774f206SBjoern A. Zeeb .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), 54442774f206SBjoern A. Zeeb .coex_info_hw_regs = coex_info_hw_regs_8822c, 54452774f206SBjoern A. Zeeb 54462774f206SBjoern A. Zeeb .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, 54472774f206SBjoern A. Zeeb .fwcd_segs = &rtw8822c_fwcd_segs, 54482774f206SBjoern A. Zeeb }; 54492774f206SBjoern A. Zeeb EXPORT_SYMBOL(rtw8822c_hw_spec); 54502774f206SBjoern A. Zeeb 54512774f206SBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8822c_fw.bin"); 54522774f206SBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8822c_wow_fw.bin"); 54532774f206SBjoern A. Zeeb 54542774f206SBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation"); 54552774f206SBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822c driver"); 54562774f206SBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL"); 5457