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