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
36u8 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		r8712_write8(padapter, SPS0_CTRL + 1, 0x53);
201		r8712_write8(padapter, SPS0_CTRL, 0x57);
202		val8 = r8712_read8(padapter, AFE_MISC);
203		/*Bandgap*/
204		r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN));
205		r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
206			     AFE_MISC_MBEN | AFE_MISC_I32_EN));
207		/* Enable PLL Power (LDOA15V) */
208		val8 = r8712_read8(padapter, LDOA15_CTRL);
209		r8712_write8(padapter, LDOA15_CTRL, (val8 | LDA15_EN));
210		/* Enable LDOV12D block */
211		val8 = r8712_read8(padapter, LDOV12D_CTRL);
212		r8712_write8(padapter, LDOV12D_CTRL, (val8 | LDV12_EN));
213		val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
214		r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 | 0x08));
215		/* Engineer Packet CP test Enable */
216		val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
217		r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x20));
218		/* Support 64k IMEM */
219		val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
220		r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 & 0x68));
221		/* Enable AFE clock */
222		val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1);
223		r8712_write8(padapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb));
224		/* Enable AFE PLL Macro Block */
225		val8 = r8712_read8(padapter, AFE_PLL_CTRL);
226		r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11));
227		/* Some sample will download fw failure. The clock will be
228		 * stable with 500 us delay after reset the PLL
229		 * TODO: When usleep is added to kernel, change next 3
230		 * udelay(500) to usleep(500)
231		 */
232		udelay(500);
233		r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x51));
234		udelay(500);
235		r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11));
236		udelay(500);
237		/* Attach AFE PLL to MACTOP/BB/PCIe Digital */
238		val8 = r8712_read8(padapter, SYS_ISO_CTRL);
239		r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE));
240		/* Switch to 40M clock */
241		r8712_write8(padapter, SYS_CLKR, 0x00);
242		/* CPU Clock and 80M Clock SSC Disable to overcome FW download
243		 * fail timing issue.
244		 */
245		val8 = r8712_read8(padapter, SYS_CLKR);
246		r8712_write8(padapter, SYS_CLKR, (val8 | 0xa0));
247		/* Enable MAC clock */
248		val8 = r8712_read8(padapter, SYS_CLKR + 1);
249		r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x18));
250		/* Revised POS, */
251		r8712_write8(padapter, PMC_FSM, 0x02);
252		/* Enable Core digital and enable IOREG R/W */
253		val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
254		r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x08));
255		/* Enable REG_EN */
256		val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
257		r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x80));
258		/* Switch the control path to FW */
259		val8 = r8712_read8(padapter, SYS_CLKR + 1);
260		r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF);
261		r8712_write8(padapter, CR, 0xFC);
262		r8712_write8(padapter, CR + 1, 0x37);
263		/* Fix the RX FIFO issue(usb error), 970410 */
264		val8 = r8712_read8(padapter, 0x1025FE5c);
265		r8712_write8(padapter, 0x1025FE5c, (val8 | BIT(7)));
266		/* For power save, used this in the bit file after 970621 */
267		val8 = r8712_read8(padapter, SYS_CLKR);
268		r8712_write8(padapter, SYS_CLKR, val8 & (~CPU_CLKSEL));
269		/* Revised for 8051 ROM code wrong operation. */
270		r8712_write8(padapter, 0x1025fe1c, 0x80);
271		/* To make sure that TxDMA can ready to download FW.
272		 * We should reset TxDMA if IMEM RPT was not ready.
273		 */
274		do {
275			val8 = r8712_read8(padapter, TCR);
276			if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE)
277				break;
278			udelay(5); /* PlatformStallExecution(5); */
279		} while (PollingCnt--);	/* Delay 1ms */
280
281		if (PollingCnt <= 0) {
282			val8 = r8712_read8(padapter, CR);
283			r8712_write8(padapter, CR, val8&(~_TXDMA_EN));
284			udelay(2); /* PlatformStallExecution(2); */
285			/* Reset TxDMA */
286			r8712_write8(padapter, CR, val8|_TXDMA_EN);
287		}
288	} else
289		ret = _FAIL;
290	return ret;
291}
292
293unsigned int r8712_usb_inirp_init(struct _adapter *padapter)
294{
295	u8 i;
296	struct recv_buf *precvbuf;
297	struct intf_hdl *pintfhdl = &padapter->pio_queue->intf;
298	struct recv_priv *precvpriv = &(padapter->recvpriv);
299
300	precvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */
301	/* issue Rx irp to receive data */
302	precvbuf = (struct recv_buf *)precvpriv->precv_buf;
303	for (i = 0; i < NR_RECVBUFF; i++) {
304		if (r8712_usb_read_port(pintfhdl, precvpriv->ff_hwaddr, 0,
305		   (unsigned char *)precvbuf) == false)
306			return _FAIL;
307		precvbuf++;
308		precvpriv->free_recv_buf_queue_cnt--;
309	}
310	return _SUCCESS;
311}
312
313unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter)
314{
315	r8712_usb_read_port_cancel(padapter);
316	return _SUCCESS;
317}
318