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