1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2013-2014, 2016-2018, 2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name *
4*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
5*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
6*5113495bSYour Name * above copyright notice and this permission notice appear in all
7*5113495bSYour Name * copies.
8*5113495bSYour Name *
9*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
17*5113495bSYour Name */
18*5113495bSYour Name
19*5113495bSYour Name #include "hif_io32.h"
20*5113495bSYour Name #include "hif_debug.h"
21*5113495bSYour Name #include "mp_dev.h"
22*5113495bSYour Name
23*5113495bSYour Name /*chaninfo*/
24*5113495bSYour Name #define CHANINFOMEM_S2_READ_MASK 0x00000008
25*5113495bSYour Name #define CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK 0x00000001
26*5113495bSYour Name #define CHANINFO_CTRL_CHANINFOMEM_BW_MASK 0x00000030
27*5113495bSYour Name #define MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK 0x00000007
28*5113495bSYour Name
29*5113495bSYour Name /*agc*/
30*5113495bSYour Name #define GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK 0x00040000
31*5113495bSYour Name #define GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK 0x00080000
32*5113495bSYour Name #define GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK 0x00100000
33*5113495bSYour Name #define GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK 0x00200000
34*5113495bSYour Name #define AGC_HISTORY_DUMP_MASK (\
35*5113495bSYour Name GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK| \
36*5113495bSYour Name GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK| \
37*5113495bSYour Name GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK| \
38*5113495bSYour Name GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK \
39*5113495bSYour Name )
40*5113495bSYour Name
41*5113495bSYour Name #define BB_chaninfo_ctrl 0x1a370
42*5113495bSYour Name #define BB_multichain_enable 0x1a2a0
43*5113495bSYour Name #define BB_chn_tables_intf_addr 0x19894
44*5113495bSYour Name #define BB_chn1_tables_intf_addr 0x1a894
45*5113495bSYour Name #define BB_chn_tables_intf_data 0x19898
46*5113495bSYour Name #define BB_chn1_tables_intf_data 0x1a898
47*5113495bSYour Name #define BB_gains_min_offsets 0x19e08
48*5113495bSYour Name #define BB_chaninfo_tab_b0 0x03200
49*5113495bSYour Name #define BB_chaninfo_tab_b1 0x03300
50*5113495bSYour Name #define BB_watchdog_status 0x1a7c0
51*5113495bSYour Name #define BB_watchdog_ctrl_1 0x1a7c4
52*5113495bSYour Name #define BB_watchdog_ctrl_2 0x1a7c8
53*5113495bSYour Name #define BB_watchdog_status_B 0x1a7e0
54*5113495bSYour Name
55*5113495bSYour Name
56*5113495bSYour Name #define PHY_BB_CHN_TABLES_INTF_ADDR 0x19894
57*5113495bSYour Name #define PHY_BB_CHN_TABLES_INTF_DATA 0x19898
58*5113495bSYour Name
59*5113495bSYour Name #define PHY_BB_CHN1_TABLES_INTF_ADDR 0x1a894
60*5113495bSYour Name #define PHY_BB_CHN1_TABLES_INTF_DATA 0x1a898
61*5113495bSYour Name
62*5113495bSYour Name
63*5113495bSYour Name struct priv_ctrl_ctx {
64*5113495bSYour Name uint32_t chaninfo_ctrl_orig;
65*5113495bSYour Name uint32_t gain_min_offsets_orig;
66*5113495bSYour Name uint32_t anyreg_start;
67*5113495bSYour Name uint32_t anyreg_len;
68*5113495bSYour Name };
69*5113495bSYour Name
70*5113495bSYour Name static struct priv_ctrl_ctx g_priv_dump_ctx;
71*5113495bSYour Name
set_target_reg_bits(struct hif_softc * scn,void __iomem * mem,uint32_t reg,uint32_t bitmask,uint32_t val)72*5113495bSYour Name static inline void set_target_reg_bits(struct hif_softc *scn,
73*5113495bSYour Name void __iomem *mem, uint32_t reg,
74*5113495bSYour Name uint32_t bitmask, uint32_t val)
75*5113495bSYour Name {
76*5113495bSYour Name uint32_t value = hif_read32_mb(scn, mem + (reg));
77*5113495bSYour Name uint32_t shift = 0;
78*5113495bSYour Name
79*5113495bSYour Name value &= ~(bitmask);
80*5113495bSYour Name while (!((bitmask >> shift) & 0x01))
81*5113495bSYour Name shift++;
82*5113495bSYour Name
83*5113495bSYour Name value |= (((val) << shift) & (bitmask));
84*5113495bSYour Name hif_write32_mb(scn, mem + (reg), value);
85*5113495bSYour Name }
86*5113495bSYour Name
get_target_reg_bits(struct hif_softc * scn,void __iomem * mem,uint32_t reg,uint32_t bitmask)87*5113495bSYour Name static inline uint32_t get_target_reg_bits(struct hif_softc *scn,
88*5113495bSYour Name void __iomem *mem,
89*5113495bSYour Name uint32_t reg, uint32_t bitmask)
90*5113495bSYour Name {
91*5113495bSYour Name uint32_t value = hif_read32_mb(scn, mem + (reg));
92*5113495bSYour Name uint32_t shift = 0;
93*5113495bSYour Name
94*5113495bSYour Name while (!((bitmask >> shift) & 0x01))
95*5113495bSYour Name shift++;
96*5113495bSYour Name
97*5113495bSYour Name return (value >> shift) & bitmask;
98*5113495bSYour Name }
99*5113495bSYour Name
priv_start_cap_chaninfo(struct hif_softc * scn)100*5113495bSYour Name void priv_start_cap_chaninfo(struct hif_softc *scn)
101*5113495bSYour Name {
102*5113495bSYour Name set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
103*5113495bSYour Name CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK, 1);
104*5113495bSYour Name }
105*5113495bSYour Name
priv_start_agc(struct hif_softc * scn)106*5113495bSYour Name void priv_start_agc(struct hif_softc *scn)
107*5113495bSYour Name {
108*5113495bSYour Name g_priv_dump_ctx.gain_min_offsets_orig =
109*5113495bSYour Name hif_read32_mb(scn, scn->mem + BB_gains_min_offsets);
110*5113495bSYour Name set_target_reg_bits(scn, scn->mem, BB_gains_min_offsets,
111*5113495bSYour Name AGC_HISTORY_DUMP_MASK,
112*5113495bSYour Name 0x0f);
113*5113495bSYour Name }
114*5113495bSYour Name
priv_stop_agc(struct hif_softc * scn)115*5113495bSYour Name static void priv_stop_agc(struct hif_softc *scn)
116*5113495bSYour Name {
117*5113495bSYour Name set_target_reg_bits(scn, scn->mem, BB_gains_min_offsets,
118*5113495bSYour Name AGC_HISTORY_DUMP_MASK,
119*5113495bSYour Name 0);
120*5113495bSYour Name }
121*5113495bSYour Name
priv_dump_chaninfo(struct hif_softc * scn)122*5113495bSYour Name void priv_dump_chaninfo(struct hif_softc *scn)
123*5113495bSYour Name {
124*5113495bSYour Name uint32_t bw, val;
125*5113495bSYour Name uint32_t len, i, tmp;
126*5113495bSYour Name uint32_t chain_mask;
127*5113495bSYour Name uint32_t chain0, chain1;
128*5113495bSYour Name
129*5113495bSYour Name chain_mask =
130*5113495bSYour Name get_target_reg_bits(scn, scn->mem, BB_multichain_enable,
131*5113495bSYour Name MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
132*5113495bSYour Name chain0 = chain_mask & 1;
133*5113495bSYour Name chain1 = chain_mask & 2;
134*5113495bSYour Name
135*5113495bSYour Name hif_info("E");
136*5113495bSYour Name bw = get_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
137*5113495bSYour Name CHANINFO_CTRL_CHANINFOMEM_BW_MASK);
138*5113495bSYour Name
139*5113495bSYour Name if (bw == 0)
140*5113495bSYour Name len = 53;
141*5113495bSYour Name else if (bw == 1)
142*5113495bSYour Name len = 57;
143*5113495bSYour Name else if (bw == 2)
144*5113495bSYour Name len = 59 * 2 - 1;
145*5113495bSYour Name else
146*5113495bSYour Name len = 60 * 2 + 61 * 2;
147*5113495bSYour Name
148*5113495bSYour Name /*
149*5113495bSYour Name * each tone is 16 bit valid, write to 32bit buffer each.
150*5113495bSYour Name * bw==0(legacy20): 53 tones.
151*5113495bSYour Name * bw==1(ht/vht20): 57 tones.
152*5113495bSYour Name * bw==2(ht/vht40): 59+58 tones.
153*5113495bSYour Name * bw==3(vht80): 60*2+61*2 tones.
154*5113495bSYour Name */
155*5113495bSYour Name
156*5113495bSYour Name if (chain0) {
157*5113495bSYour Name hif_write32_mb(scn, scn->mem + BB_chn_tables_intf_addr,
158*5113495bSYour Name 0x80003200);
159*5113495bSYour Name }
160*5113495bSYour Name if (chain1) {
161*5113495bSYour Name hif_write32_mb(scn, scn->mem + BB_chn1_tables_intf_addr,
162*5113495bSYour Name 0x80003200);
163*5113495bSYour Name }
164*5113495bSYour Name
165*5113495bSYour Name set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
166*5113495bSYour Name CHANINFOMEM_S2_READ_MASK, 0);
167*5113495bSYour Name
168*5113495bSYour Name if (chain0) {
169*5113495bSYour Name if (bw < 2) {
170*5113495bSYour Name len = (bw == 0) ? 53 : 57;
171*5113495bSYour Name for (i = 0; i < len; i++) {
172*5113495bSYour Name val = hif_read32_mb(scn, scn->mem +
173*5113495bSYour Name BB_chn_tables_intf_data) &
174*5113495bSYour Name 0x0000ffff;
175*5113495bSYour Name qdf_debug("0x%x\t", val);
176*5113495bSYour Name if (i % 4 == 0)
177*5113495bSYour Name qdf_debug("\n");
178*5113495bSYour Name }
179*5113495bSYour Name } else {
180*5113495bSYour Name len = (bw == 2) ? 59 : 60;
181*5113495bSYour Name for (i = 0; i < len; i++) {
182*5113495bSYour Name tmp = hif_read32_mb(scn, scn->mem +
183*5113495bSYour Name BB_chn_tables_intf_data);
184*5113495bSYour Name qdf_debug("0x%x\t", ((tmp >> 16) & 0x0000ffff));
185*5113495bSYour Name qdf_debug("0x%x\t", (tmp & 0x0000ffff));
186*5113495bSYour Name if (i % 2 == 0)
187*5113495bSYour Name qdf_debug("\n");
188*5113495bSYour Name }
189*5113495bSYour Name if (bw > 2) {
190*5113495bSYour Name /* bw == 3 for vht80 */
191*5113495bSYour Name hif_write32_mb(scn, scn->mem +
192*5113495bSYour Name BB_chn_tables_intf_addr,
193*5113495bSYour Name 0x80003300);
194*5113495bSYour Name len = 61;
195*5113495bSYour Name for (i = 0; i < len; i++) {
196*5113495bSYour Name tmp = hif_read32_mb(scn, scn->mem +
197*5113495bSYour Name BB_chn_tables_intf_data);
198*5113495bSYour Name qdf_debug("0x%x\t",
199*5113495bSYour Name ((tmp >> 16) & 0x0000ffff));
200*5113495bSYour Name qdf_debug("0x%x\t", (tmp & 0x0000ffff));
201*5113495bSYour Name if (i % 2 == 0)
202*5113495bSYour Name qdf_debug("\n");
203*5113495bSYour Name }
204*5113495bSYour Name }
205*5113495bSYour Name }
206*5113495bSYour Name }
207*5113495bSYour Name if (chain1) {
208*5113495bSYour Name if (bw < 2) {
209*5113495bSYour Name len = (bw == 0) ? 53 : 57;
210*5113495bSYour Name for (i = 0; i < len; i++) {
211*5113495bSYour Name val =
212*5113495bSYour Name hif_read32_mb(scn, scn->mem +
213*5113495bSYour Name BB_chn1_tables_intf_data) &
214*5113495bSYour Name 0x0000ffff;
215*5113495bSYour Name qdf_debug("0x%x\t", val);
216*5113495bSYour Name if (i % 4 == 0)
217*5113495bSYour Name qdf_debug("\n");
218*5113495bSYour Name }
219*5113495bSYour Name } else {
220*5113495bSYour Name len = (bw == 2) ? 59 : 60;
221*5113495bSYour Name for (i = 0; i < len; i++) {
222*5113495bSYour Name tmp =
223*5113495bSYour Name hif_read32_mb(scn, scn->mem +
224*5113495bSYour Name BB_chn1_tables_intf_data);
225*5113495bSYour Name qdf_debug("0x%x", (tmp >> 16) & 0x0000ffff);
226*5113495bSYour Name qdf_debug("0x%x", tmp & 0x0000ffff);
227*5113495bSYour Name if (i % 2 == 0)
228*5113495bSYour Name qdf_debug("\n");
229*5113495bSYour Name }
230*5113495bSYour Name if (bw > 2) {
231*5113495bSYour Name /* bw == 3 for vht80 */
232*5113495bSYour Name hif_write32_mb(scn, scn->mem +
233*5113495bSYour Name BB_chn1_tables_intf_addr,
234*5113495bSYour Name 0x80003300);
235*5113495bSYour Name len = 61;
236*5113495bSYour Name for (i = 0; i < len; i++) {
237*5113495bSYour Name tmp =
238*5113495bSYour Name hif_read32_mb(scn, scn->mem +
239*5113495bSYour Name BB_chn1_tables_intf_data);
240*5113495bSYour Name qdf_debug("0x%x\t",
241*5113495bSYour Name ((tmp >> 16) & 0x0000ffff));
242*5113495bSYour Name qdf_debug("0x%x\t", (tmp & 0x0000ffff));
243*5113495bSYour Name if (i % 2 == 0)
244*5113495bSYour Name qdf_debug("\n");
245*5113495bSYour Name }
246*5113495bSYour Name }
247*5113495bSYour Name }
248*5113495bSYour Name }
249*5113495bSYour Name hif_info("X");
250*5113495bSYour Name }
251*5113495bSYour Name
priv_dump_agc(struct hif_softc * scn)252*5113495bSYour Name void priv_dump_agc(struct hif_softc *scn)
253*5113495bSYour Name {
254*5113495bSYour Name int i, len = 30; /* check this value for Rome and Peregrine */
255*5113495bSYour Name uint32_t chain0, chain1, chain_mask, val;
256*5113495bSYour Name
257*5113495bSYour Name if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
258*5113495bSYour Name return;
259*5113495bSYour Name
260*5113495bSYour Name chain_mask =
261*5113495bSYour Name get_target_reg_bits(scn, scn->mem, BB_multichain_enable,
262*5113495bSYour Name MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
263*5113495bSYour Name chain0 = chain_mask & 1;
264*5113495bSYour Name chain1 = chain_mask & 2;
265*5113495bSYour Name
266*5113495bSYour Name len = len << 1; /* each agc item is 64bit, total*2 */
267*5113495bSYour Name priv_stop_agc(scn);
268*5113495bSYour Name
269*5113495bSYour Name set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
270*5113495bSYour Name CHANINFOMEM_S2_READ_MASK, 0);
271*5113495bSYour Name
272*5113495bSYour Name hif_info("AGC history buffer dump: E");
273*5113495bSYour Name if (chain0) {
274*5113495bSYour Name for (i = 0; i < len; i++) {
275*5113495bSYour Name hif_write32_mb(scn, scn->mem +
276*5113495bSYour Name PHY_BB_CHN_TABLES_INTF_ADDR,
277*5113495bSYour Name BB_chaninfo_tab_b0 + i * 4);
278*5113495bSYour Name val = hif_read32_mb(scn, scn->mem +
279*5113495bSYour Name PHY_BB_CHN_TABLES_INTF_DATA);
280*5113495bSYour Name qdf_debug("0x%x\t", val);
281*5113495bSYour Name if (i % 4 == 0)
282*5113495bSYour Name qdf_debug("\n");
283*5113495bSYour Name }
284*5113495bSYour Name }
285*5113495bSYour Name if (chain1) {
286*5113495bSYour Name for (i = 0; i < len; i++) {
287*5113495bSYour Name hif_write32_mb(scn, scn->mem +
288*5113495bSYour Name PHY_BB_CHN1_TABLES_INTF_ADDR,
289*5113495bSYour Name BB_chaninfo_tab_b0 + i * 4);
290*5113495bSYour Name val = hif_read32_mb(scn, scn->mem +
291*5113495bSYour Name PHY_BB_CHN1_TABLES_INTF_DATA);
292*5113495bSYour Name qdf_debug("0x%x\t", val);
293*5113495bSYour Name if (i % 4 == 0)
294*5113495bSYour Name qdf_debug("\n");
295*5113495bSYour Name }
296*5113495bSYour Name }
297*5113495bSYour Name hif_info("AGC history buffer dump X");
298*5113495bSYour Name /* restore original value */
299*5113495bSYour Name hif_write32_mb(scn, scn->mem + BB_gains_min_offsets,
300*5113495bSYour Name g_priv_dump_ctx.gain_min_offsets_orig);
301*5113495bSYour Name
302*5113495bSYour Name Q_TARGET_ACCESS_END(scn);
303*5113495bSYour Name
304*5113495bSYour Name }
305*5113495bSYour Name
priv_dump_bbwatchdog(struct hif_softc * scn)306*5113495bSYour Name void priv_dump_bbwatchdog(struct hif_softc *scn)
307*5113495bSYour Name {
308*5113495bSYour Name uint32_t val;
309*5113495bSYour Name
310*5113495bSYour Name hif_info("BB watchdog dump E");
311*5113495bSYour Name val = hif_read32_mb(scn, scn->mem + BB_watchdog_status);
312*5113495bSYour Name qdf_debug("0x%x\t", val);
313*5113495bSYour Name val = hif_read32_mb(scn, scn->mem + BB_watchdog_ctrl_1);
314*5113495bSYour Name qdf_debug("0x%x\t", val);
315*5113495bSYour Name val = hif_read32_mb(scn, scn->mem + BB_watchdog_ctrl_2);
316*5113495bSYour Name qdf_debug("0x%x\t", val);
317*5113495bSYour Name val = hif_read32_mb(scn, scn->mem + BB_watchdog_status_B);
318*5113495bSYour Name qdf_debug("0x%x", val);
319*5113495bSYour Name hif_info("BB watchdog dump X");
320*5113495bSYour Name }
321