xref: /wlan-driver/qca-wifi-host-cmn/hif/src/mp_dev.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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