GNU Linux-libre 4.14.262-gnu1
[releases.git] / drivers / staging / rtl8712 / usb_halinit.c
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 }