1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6 * Linux device driver for RTL8192SU
8 * Modifications for inclusion into the Linux staging tree are
9 * Copyright(c) 2010 Larry Finger. All rights reserved.
11 * Contact information:
15 ******************************************************************************/
17 #define _HCI_HAL_INIT_C_
19 #include "osdep_service.h"
20 #include "drv_types.h"
22 #include "usb_osintf.h"
24 u8 r8712_usb_hal_bus_init(struct _adapter *adapter)
29 struct registry_priv *registrypriv = &adapter->registrypriv;
31 if (registrypriv->chip_version == RTL8712_FPGA) {
33 /* switch to 80M clock */
34 r8712_write8(adapter, SYS_CLKR, val8);
35 val8 = r8712_read8(adapter, SPS1_CTRL);
37 /* enable VSPS12 LDO Macro block */
38 r8712_write8(adapter, SPS1_CTRL, val8);
39 val8 = r8712_read8(adapter, AFE_MISC);
41 /* Enable AFE Macro Block's Bandgap */
42 r8712_write8(adapter, AFE_MISC, val8);
43 val8 = r8712_read8(adapter, LDOA15_CTRL);
45 /* enable LDOA15 block */
46 r8712_write8(adapter, LDOA15_CTRL, val8);
47 val8 = r8712_read8(adapter, SPS1_CTRL);
49 /* Enable VSPS12_SW Macro Block */
50 r8712_write8(adapter, SPS1_CTRL, val8);
51 val8 = r8712_read8(adapter, AFE_MISC);
53 /* Enable AFE Macro Block's Mbias */
54 r8712_write8(adapter, AFE_MISC, val8);
55 val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1);
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);
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);
65 /* enable AFE clock */
66 r8712_write8(adapter, AFE_XTAL_CTRL + 1, val8);
67 val8 = r8712_read8(adapter, AFE_PLL_CTRL);
69 /* Enable AFE PLL Macro Block */
70 r8712_write8(adapter, AFE_PLL_CTRL, val8);
72 /* release isolation AFE PLL & MD */
73 r8712_write8(adapter, SYS_ISO_CTRL, val8);
74 val8 = r8712_read8(adapter, SYS_CLKR + 1);
76 /* enable MAC clock */
77 r8712_write8(adapter, SYS_CLKR + 1, val8);
78 val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
80 /* enable Core digital and enable IOREG R/W */
81 r8712_write8(adapter, SYS_FUNC_EN + 1, val8);
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);
90 r8712_write8(adapter, CR, val8);
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
106 val8 = r8712_read8(adapter, AFE_MISC);
107 r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
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));
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));
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));
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));
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
169 r8712_write8(adapter, 0x37, 0xb0);
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
176 val8 = r8712_read8(adapter, SYS_CLKR + 1);
179 r8712_write8(adapter, SYS_CLKR + 1, val8);
181 val8 = r8712_read8(adapter, SYS_FUNC_EN + 1);
183 r8712_write8(adapter, SYS_FUNC_EN + 1, val8);
186 /* Enable AFE Macro Block's Bandgap and Enable AFE Macro
189 r8712_write8(adapter, SPS0_CTRL + 1, 0x53);
190 r8712_write8(adapter, SPS0_CTRL, 0x57);
191 val8 = r8712_read8(adapter, AFE_MISC);
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)
222 r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x51));
224 r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11));
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
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));
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));
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.
264 val8 = r8712_read8(adapter, TCR);
265 if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE)
267 udelay(5); /* PlatformStallExecution(5); */
268 } while (PollingCnt--); /* Delay 1ms */
270 if (PollingCnt <= 0) {
271 val8 = r8712_read8(adapter, CR);
272 r8712_write8(adapter, CR, val8 & (~_TXDMA_EN));
273 udelay(2); /* PlatformStallExecution(2); */
275 r8712_write8(adapter, CR, val8 | _TXDMA_EN);
283 unsigned int r8712_usb_inirp_init(struct _adapter *adapter)
286 struct recv_buf *recvbuf;
287 struct intf_hdl *intfhdl = &adapter->pio_queue->intf;
288 struct recv_priv *recvpriv = &(adapter->recvpriv);
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)
298 recvpriv->free_recv_buf_queue_cnt--;
303 unsigned int r8712_usb_inirp_deinit(struct _adapter *adapter)
305 r8712_usb_read_port_cancel(adapter);