Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 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; |
Dan Carpenter | 8328553 | 2010-11-12 08:11:13 +0300 | [diff] [blame] | 40 | int PollingCnt = 20; |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 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); |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame^] | 115 | /* Enable AFE Macro Block's Bandgap and Enable AFE Macro |
Larry Finger | 2865d42 | 2010-08-20 10:15:30 -0500 | [diff] [blame] | 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 | /* Attatch 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 | /* Attatch 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 | |
| 293 | unsigned 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 | |
| 313 | unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter) |
| 314 | { |
| 315 | r8712_usb_read_port_cancel(padapter); |
| 316 | return _SUCCESS; |
| 317 | } |