1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include "odm_precomp.h"
9 
10 #include <phy.h>
11 
check_condition(struct adapter * adapt,const u32 condition)12 static bool check_condition(struct adapter *adapt, const u32  condition)
13 {
14 	struct odm_dm_struct *odm = &adapt->HalData->odmpriv;
15 	u32 _board = odm->BoardType;
16 	u32 _platform = odm->SupportPlatform;
17 	u32 _interface = odm->SupportInterface;
18 	u32 cond;
19 
20 	if (condition == 0xCDCDCDCD)
21 		return true;
22 
23 	cond = condition & 0x000000FF;
24 	if ((_board == cond) && cond != 0x00)
25 		return false;
26 
27 	cond = condition & 0x0000FF00;
28 	cond >>= 8;
29 	if ((_interface & cond) == 0 && cond != 0x07)
30 		return false;
31 
32 	cond = condition & 0x00FF0000;
33 	cond >>= 16;
34 	if ((_platform & cond) == 0 && cond != 0x0F)
35 		return false;
36 	return true;
37 }
38 
39 /* RadioA_1T.TXT */
40 
41 static u32 Array_RadioA_1T_8188E[] = {
42 		0x000, 0x00030000,
43 		0x008, 0x00084000,
44 		0x018, 0x00000407,
45 		0x019, 0x00000012,
46 		0x01E, 0x00080009,
47 		0x01F, 0x00000880,
48 		0x02F, 0x0001A060,
49 		0x03F, 0x00000000,
50 		0x042, 0x000060C0,
51 		0x057, 0x000D0000,
52 		0x058, 0x000BE180,
53 		0x067, 0x00001552,
54 		0x083, 0x00000000,
55 		0x0B0, 0x000FF8FC,
56 		0x0B1, 0x00054400,
57 		0x0B2, 0x000CCC19,
58 		0x0B4, 0x00043003,
59 		0x0B6, 0x0004953E,
60 		0x0B7, 0x0001C718,
61 		0x0B8, 0x000060FF,
62 		0x0B9, 0x00080001,
63 		0x0BA, 0x00040000,
64 		0x0BB, 0x00000400,
65 		0x0BF, 0x000C0000,
66 		0x0C2, 0x00002400,
67 		0x0C3, 0x00000009,
68 		0x0C4, 0x00040C91,
69 		0x0C5, 0x00099999,
70 		0x0C6, 0x000000A3,
71 		0x0C7, 0x00088820,
72 		0x0C8, 0x00076C06,
73 		0x0C9, 0x00000000,
74 		0x0CA, 0x00080000,
75 		0x0DF, 0x00000180,
76 		0x0EF, 0x000001A0,
77 		0x051, 0x0006B27D,
78 		0xFF0F041F, 0xABCD,
79 		0x052, 0x0007E4DD,
80 		0xCDCDCDCD, 0xCDCD,
81 		0x052, 0x0007E49D,
82 		0xFF0F041F, 0xDEAD,
83 		0x053, 0x00000073,
84 		0x056, 0x00051FF3,
85 		0x035, 0x00000086,
86 		0x035, 0x00000186,
87 		0x035, 0x00000286,
88 		0x036, 0x00001C25,
89 		0x036, 0x00009C25,
90 		0x036, 0x00011C25,
91 		0x036, 0x00019C25,
92 		0x0B6, 0x00048538,
93 		0x018, 0x00000C07,
94 		0x05A, 0x0004BD00,
95 		0x019, 0x000739D0,
96 		0x034, 0x0000ADF3,
97 		0x034, 0x00009DF0,
98 		0x034, 0x00008DED,
99 		0x034, 0x00007DEA,
100 		0x034, 0x00006DE7,
101 		0x034, 0x000054EE,
102 		0x034, 0x000044EB,
103 		0x034, 0x000034E8,
104 		0x034, 0x0000246B,
105 		0x034, 0x00001468,
106 		0x034, 0x0000006D,
107 		0x000, 0x00030159,
108 		0x084, 0x00068200,
109 		0x086, 0x000000CE,
110 		0x087, 0x00048A00,
111 		0x08E, 0x00065540,
112 		0x08F, 0x00088000,
113 		0x0EF, 0x000020A0,
114 		0x03B, 0x000F02B0,
115 		0x03B, 0x000EF7B0,
116 		0x03B, 0x000D4FB0,
117 		0x03B, 0x000CF060,
118 		0x03B, 0x000B0090,
119 		0x03B, 0x000A0080,
120 		0x03B, 0x00090080,
121 		0x03B, 0x0008F780,
122 		0x03B, 0x000722B0,
123 		0x03B, 0x0006F7B0,
124 		0x03B, 0x00054FB0,
125 		0x03B, 0x0004F060,
126 		0x03B, 0x00030090,
127 		0x03B, 0x00020080,
128 		0x03B, 0x00010080,
129 		0x03B, 0x0000F780,
130 		0x0EF, 0x000000A0,
131 		0x000, 0x00010159,
132 		0x018, 0x0000F407,
133 		0xFFE, 0x00000000,
134 		0xFFE, 0x00000000,
135 		0x01F, 0x00080003,
136 		0xFFE, 0x00000000,
137 		0xFFE, 0x00000000,
138 		0x01E, 0x00000001,
139 		0x01F, 0x00080000,
140 		0x000, 0x00033E60,
141 };
142 
143 #define READ_NEXT_PAIR(v1, v2, i)	\
144 do {								\
145 	i += 2; v1 = array[i];			\
146 	v2 = array[i + 1];				\
147 } while (0)
148 
149 #define RFREG_OFFSET_MASK 0xfffff
150 #define B3WIREADDREAALENGTH 0x400
151 #define B3WIREDATALENGTH 0x800
152 #define BRFSI_RFENV 0x10
153 
rtl_rfreg_delay(struct adapter * adapt,enum rf_radio_path rfpath,u32 addr,u32 mask,u32 data)154 static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u32 addr, u32 mask, u32 data)
155 {
156 	if (addr == 0xfe) {
157 		mdelay(50);
158 	} else if (addr == 0xfd) {
159 		mdelay(5);
160 	} else if (addr == 0xfc) {
161 		mdelay(1);
162 	} else if (addr == 0xfb) {
163 		udelay(50);
164 	} else if (addr == 0xfa) {
165 		udelay(5);
166 	} else if (addr == 0xf9) {
167 		udelay(1);
168 	} else {
169 		phy_set_rf_reg(adapt, rfpath, addr, mask, data);
170 		udelay(1);
171 	}
172 }
173 
rtl8188e_config_rf_reg(struct adapter * adapt,u32 addr,u32 data)174 static void rtl8188e_config_rf_reg(struct adapter *adapt, u32 addr, u32 data)
175 {
176 	u32 content = 0x1000; /*RF Content: radio_a_txt*/
177 	u32 maskforphyset = content & 0xE000;
178 
179 	rtl_rfreg_delay(adapt, RF_PATH_A, addr | maskforphyset,
180 			RFREG_OFFSET_MASK,
181 			data);
182 }
183 
rtl88e_phy_config_rf_with_headerfile(struct adapter * adapt)184 static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt)
185 {
186 	u32 i;
187 	u32 array_len = ARRAY_SIZE(Array_RadioA_1T_8188E);
188 	u32 *array = Array_RadioA_1T_8188E;
189 
190 	for (i = 0; i < array_len; i += 2) {
191 		u32 v1 = array[i];
192 		u32 v2 = array[i + 1];
193 
194 		if (v1 < 0xCDCDCDCD) {
195 			rtl8188e_config_rf_reg(adapt, v1, v2);
196 			continue;
197 		} else {
198 			if (!check_condition(adapt, array[i])) {
199 				READ_NEXT_PAIR(v1, v2, i);
200 				while (v2 != 0xDEAD && v2 != 0xCDEF &&
201 				       v2 != 0xCDCD && i < array_len - 2)
202 					READ_NEXT_PAIR(v1, v2, i);
203 				i -= 2;
204 			} else {
205 				READ_NEXT_PAIR(v1, v2, i);
206 				while (v2 != 0xDEAD && v2 != 0xCDEF &&
207 				       v2 != 0xCDCD && i < array_len - 2) {
208 					rtl8188e_config_rf_reg(adapt, v1, v2);
209 					READ_NEXT_PAIR(v1, v2, i);
210 				}
211 
212 				while (v2 != 0xDEAD && i < array_len - 2)
213 					READ_NEXT_PAIR(v1, v2, i);
214 			}
215 		}
216 	}
217 	return true;
218 }
219 
rtl88eu_phy_rf_config(struct adapter * adapt)220 bool rtl88eu_phy_rf_config(struct adapter *adapt)
221 {
222 	struct hal_data_8188e *hal_data = adapt->HalData;
223 	u32 u4val = 0;
224 	bool rtstatus;
225 	struct bb_reg_def *pphyreg;
226 
227 	pphyreg = &hal_data->PHYRegDef[RF90_PATH_A];
228 	u4val = phy_query_bb_reg(adapt, pphyreg->rfintfs, BRFSI_RFENV);
229 
230 	phy_set_bb_reg(adapt, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
231 	udelay(1);
232 
233 	phy_set_bb_reg(adapt, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
234 	udelay(1);
235 
236 	phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, B3WIREADDREAALENGTH, 0x0);
237 	udelay(1);
238 
239 	phy_set_bb_reg(adapt, pphyreg->rfHSSIPara2, B3WIREDATALENGTH, 0x0);
240 	udelay(1);
241 
242 	rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt);
243 
244 	phy_set_bb_reg(adapt, pphyreg->rfintfs, BRFSI_RFENV, u4val);
245 
246 	return rtstatus;
247 }
248