xref: /linux/drivers/staging/rtl8712/usb_halinit.c (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  * usb_halinit.c
4  *
5  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6  * Linux device driver for RTL8192SU
7  *
8  * Modifications for inclusion into the Linux staging tree are
9  * Copyright(c) 2010 Larry Finger. All rights reserved.
10  *
11  * Contact information:
12  * WLAN FAE <wlanfae@realtek.com>
13  * Larry Finger <Larry.Finger@lwfinger.net>
14  *
15  ******************************************************************************/
16 
17 #define _HCI_HAL_INIT_C_
18 
19 #include "osdep_service.h"
20 #include "drv_types.h"
21 #include "usb_ops.h"
22 #include "usb_osintf.h"
23 
r8712_usb_hal_bus_init(struct _adapter * adapter)24 u8 r8712_usb_hal_bus_init(struct _adapter *adapter)
25 {
26 	u8 val8 = 0;
27 	u8 ret = _SUCCESS;
28 	int PollingCnt = 20;
29 	struct registry_priv *registrypriv = &adapter->registrypriv;
30 
31 	if (registrypriv->chip_version == RTL8712_FPGA) {
32 		val8 = 0x01;
33 		/* switch to 80M clock */
34 		r8712_write8(adapter, SYS_CLKR, val8);
35 		val8 = r8712_read8(adapter, SPS1_CTRL);
36 		val8 = val8 | 0x01;
37 		/* enable VSPS12 LDO Macro block */
38 		r8712_write8(adapter, SPS1_CTRL, val8);
39 		val8 = r8712_read8(adapter, AFE_MISC);
40 		val8 = val8 | 0x01;
41 		/* Enable AFE Macro Block's Bandgap */
42 		r8712_write8(adapter, AFE_MISC, val8);
43 		val8 = r8712_read8(adapter, LDOA15_CTRL);
44 		val8 = val8 | 0x01;
45 		/* enable LDOA15 block */
46 		r8712_write8(adapter, LDOA15_CTRL, val8);
47 		val8 = r8712_read8(adapter, SPS1_CTRL);
48 		val8 = val8 | 0x02;
49 		/* Enable VSPS12_SW Macro Block */
50 		r8712_write8(adapter, SPS1_CTRL, val8);
51 		val8 = r8712_read8(adapter, AFE_MISC);
52 		val8 = val8 | 0x02;
53 		/* Enable AFE Macro Block's Mbias */
54 		r8712_write8(adapter, AFE_MISC, val8);
55 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
56 		val8 = val8 | 0x08;
57 		/* isolate PCIe Analog 1.2V to PCIe 3.3V and PCIE Digital */
58 		r8712_write8(adapter, SYS_ISO_CTRL + 1, val8);
59 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
60 		val8 = val8 & 0xEF;
61 		/* attach AFE PLL to MACTOP/BB/PCIe Digital */
62 		r8712_write8(adapter, SYS_ISO_CTRL + 1, val8);
63 		val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1);
64 		val8 = val8 & 0xFB;
65 		/* enable AFE clock */
66 		r8712_write8(adapter, AFE_XTAL_CTRL + 1, val8);
67 		val8 = r8712_read8(adapter, AFE_PLL_CTRL);
68 		val8 = val8 | 0x01;
69 		/* Enable AFE PLL Macro Block */
70 		r8712_write8(adapter, AFE_PLL_CTRL, val8);
71 		val8 = 0xEE;
72 		/* release isolation AFE PLL & MD */
73 		r8712_write8(adapter, SYS_ISO_CTRL, val8);
74 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
75 		val8 = val8 | 0x08;
76 		/* enable MAC clock */
77 		r8712_write8(adapter, SYS_CLKR + 1, val8);
78 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
79 		val8 = val8 | 0x08;
80 		/* enable Core digital and enable IOREG R/W */
81 		r8712_write8(adapter, SYS_FUNC_EN + 1, val8);
82 		val8 = val8 | 0x80;
83 		/* enable REG_EN */
84 		r8712_write8(adapter, SYS_FUNC_EN + 1, val8);
85 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
86 		val8 = (val8 | 0x80) & 0xBF;
87 		/* switch the control path */
88 		r8712_write8(adapter, SYS_CLKR + 1, val8);
89 		val8 = 0xFC;
90 		r8712_write8(adapter, CR, val8);
91 		val8 = 0x37;
92 		r8712_write8(adapter, CR + 1, val8);
93 		/* reduce EndPoint & init it */
94 		r8712_write8(adapter, 0x102500ab, r8712_read8(adapter,
95 			     0x102500ab) | BIT(6) | BIT(7));
96 		/* consideration of power consumption - init */
97 		r8712_write8(adapter, 0x10250008, r8712_read8(adapter,
98 			     0x10250008) & 0xfffffffb);
99 	} else if (registrypriv->chip_version == RTL8712_1stCUT) {
100 		/* Initialization for power on sequence, */
101 		r8712_write8(adapter, SPS0_CTRL + 1, 0x53);
102 		r8712_write8(adapter, SPS0_CTRL, 0x57);
103 		/* Enable AFE Macro Block's Bandgap and Enable AFE Macro
104 		 * Block's Mbias
105 		 */
106 		val8 = r8712_read8(adapter, AFE_MISC);
107 		r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
108 			     AFE_MISC_MBEN));
109 		/* Enable LDOA15 block */
110 		val8 = r8712_read8(adapter, LDOA15_CTRL);
111 		r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN));
112 		val8 = r8712_read8(adapter, SPS1_CTRL);
113 		r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_LDEN));
114 		msleep(20);
115 		/* Enable Switch Regulator Block */
116 		val8 = r8712_read8(adapter, SPS1_CTRL);
117 		r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_SWEN));
118 		r8712_write32(adapter, SPS1_CTRL, 0x00a7b267);
119 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
120 		r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08));
121 		/* Engineer Packet CP test Enable */
122 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
123 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20));
124 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
125 		r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x6F));
126 		/* Enable AFE clock */
127 		val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1);
128 		r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb));
129 		/* Enable AFE PLL Macro Block */
130 		val8 = r8712_read8(adapter, AFE_PLL_CTRL);
131 		r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11));
132 		/* Attach AFE PLL to MACTOP/BB/PCIe Digital */
133 		val8 = r8712_read8(adapter, SYS_ISO_CTRL);
134 		r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE));
135 		/* Switch to 40M clock */
136 		val8 = r8712_read8(adapter, SYS_CLKR);
137 		r8712_write8(adapter, SYS_CLKR, val8 & (~SYS_CLKSEL));
138 		/* SSC Disable */
139 		val8 = r8712_read8(adapter, SYS_CLKR);
140 		/* Enable MAC clock */
141 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
142 		r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18));
143 		/* Revised POS, */
144 		r8712_write8(adapter, PMC_FSM, 0x02);
145 		/* Enable Core digital and enable IOREG R/W */
146 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
147 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08));
148 		/* Enable REG_EN */
149 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
150 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80));
151 		/* Switch the control path to FW */
152 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
153 		r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF);
154 		r8712_write8(adapter, CR, 0xFC);
155 		r8712_write8(adapter, CR + 1, 0x37);
156 		/* Fix the RX FIFO issue(usb error), */
157 		val8 = r8712_read8(adapter, 0x1025FE5c);
158 		r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7)));
159 		val8 = r8712_read8(adapter, 0x102500ab);
160 		r8712_write8(adapter, 0x102500ab, (val8 | BIT(6) | BIT(7)));
161 		/* For power save, used this in the bit file after 970621 */
162 		val8 = r8712_read8(adapter, SYS_CLKR);
163 		r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL));
164 	} else if (registrypriv->chip_version == RTL8712_2ndCUT ||
165 		   registrypriv->chip_version == RTL8712_3rdCUT) {
166 		/* Initialization for power on sequence,
167 		 * E-Fuse leakage prevention sequence
168 		 */
169 		r8712_write8(adapter, 0x37, 0xb0);
170 		msleep(20);
171 		r8712_write8(adapter, 0x37, 0x30);
172 		/* Set control path switch to HW control and reset Digital Core,
173 		 * CPU Core and MAC I/O to solve FW download fail when system
174 		 * from resume sate.
175 		 */
176 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
177 		if (val8 & 0x80) {
178 			val8 &= 0x3f;
179 			r8712_write8(adapter, SYS_CLKR + 1, val8);
180 		}
181 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
182 		val8 &= 0x73;
183 		r8712_write8(adapter, SYS_FUNC_EN + 1, val8);
184 		msleep(20);
185 		/* Revised POS, */
186 		/* Enable AFE Macro Block's Bandgap and Enable AFE Macro
187 		 * Block's Mbias
188 		 */
189 		r8712_write8(adapter, SPS0_CTRL + 1, 0x53);
190 		r8712_write8(adapter, SPS0_CTRL, 0x57);
191 		val8 = r8712_read8(adapter, AFE_MISC);
192 		/*Bandgap*/
193 		r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN));
194 		r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
195 			     AFE_MISC_MBEN | AFE_MISC_I32_EN));
196 		/* Enable PLL Power (LDOA15V) */
197 		val8 = r8712_read8(adapter, LDOA15_CTRL);
198 		r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN));
199 		/* Enable LDOV12D block */
200 		val8 = r8712_read8(adapter, LDOV12D_CTRL);
201 		r8712_write8(adapter, LDOV12D_CTRL, (val8 | LDV12_EN));
202 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
203 		r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08));
204 		/* Engineer Packet CP test Enable */
205 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
206 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20));
207 		/* Support 64k IMEM */
208 		val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
209 		r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x68));
210 		/* Enable AFE clock */
211 		val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1);
212 		r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb));
213 		/* Enable AFE PLL Macro Block */
214 		val8 = r8712_read8(adapter, AFE_PLL_CTRL);
215 		r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11));
216 		/* Some sample will download fw failure. The clock will be
217 		 * stable with 500 us delay after reset the PLL
218 		 * TODO: When usleep is added to kernel, change next 3
219 		 * udelay(500) to usleep(500)
220 		 */
221 		udelay(500);
222 		r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x51));
223 		udelay(500);
224 		r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11));
225 		udelay(500);
226 		/* Attach AFE PLL to MACTOP/BB/PCIe Digital */
227 		val8 = r8712_read8(adapter, SYS_ISO_CTRL);
228 		r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE));
229 		/* Switch to 40M clock */
230 		r8712_write8(adapter, SYS_CLKR, 0x00);
231 		/* CPU Clock and 80M Clock SSC Disable to overcome FW download
232 		 * fail timing issue.
233 		 */
234 		val8 = r8712_read8(adapter, SYS_CLKR);
235 		r8712_write8(adapter, SYS_CLKR, (val8 | 0xa0));
236 		/* Enable MAC clock */
237 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
238 		r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18));
239 		/* Revised POS, */
240 		r8712_write8(adapter, PMC_FSM, 0x02);
241 		/* Enable Core digital and enable IOREG R/W */
242 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
243 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08));
244 		/* Enable REG_EN */
245 		val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
246 		r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80));
247 		/* Switch the control path to FW */
248 		val8 = r8712_read8(adapter, SYS_CLKR + 1);
249 		r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF);
250 		r8712_write8(adapter, CR, 0xFC);
251 		r8712_write8(adapter, CR + 1, 0x37);
252 		/* Fix the RX FIFO issue(usb error), 970410 */
253 		val8 = r8712_read8(adapter, 0x1025FE5c);
254 		r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7)));
255 		/* For power save, used this in the bit file after 970621 */
256 		val8 = r8712_read8(adapter, SYS_CLKR);
257 		r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL));
258 		/* Revised for 8051 ROM code wrong operation. */
259 		r8712_write8(adapter, 0x1025fe1c, 0x80);
260 		/* To make sure that TxDMA can ready to download FW.
261 		 * We should reset TxDMA if IMEM RPT was not ready.
262 		 */
263 		do {
264 			val8 = r8712_read8(adapter, TCR);
265 			if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE)
266 				break;
267 			udelay(5); /* PlatformStallExecution(5); */
268 		} while (PollingCnt--);	/* Delay 1ms */
269 
270 		if (PollingCnt <= 0) {
271 			val8 = r8712_read8(adapter, CR);
272 			r8712_write8(adapter, CR, val8 & (~_TXDMA_EN));
273 			udelay(2); /* PlatformStallExecution(2); */
274 			/* Reset TxDMA */
275 			r8712_write8(adapter, CR, val8 | _TXDMA_EN);
276 		}
277 	} else {
278 		ret = _FAIL;
279 	}
280 	return ret;
281 }
282 
r8712_usb_inirp_init(struct _adapter * adapter)283 unsigned int r8712_usb_inirp_init(struct _adapter *adapter)
284 {
285 	u8 i;
286 	struct recv_buf *recvbuf;
287 	struct intf_hdl *intfhdl = &adapter->pio_queue->intf;
288 	struct recv_priv *recvpriv = &(adapter->recvpriv);
289 
290 	recvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */
291 	/* issue Rx irp to receive data */
292 	recvbuf = (struct recv_buf *)recvpriv->precv_buf;
293 	for (i = 0; i < NR_RECVBUFF; i++) {
294 		if (r8712_usb_read_port(intfhdl, recvpriv->ff_hwaddr, 0,
295 					(unsigned char *)recvbuf) == false)
296 			return _FAIL;
297 		recvbuf++;
298 		recvpriv->free_recv_buf_queue_cnt--;
299 	}
300 	return _SUCCESS;
301 }
302 
r8712_usb_inirp_deinit(struct _adapter * adapter)303 unsigned int r8712_usb_inirp_deinit(struct _adapter *adapter)
304 {
305 	r8712_usb_read_port_cancel(adapter);
306 	return _SUCCESS;
307 }
308