/****************************************************************************** * usb_halinit.c * * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. * Linux device driver for RTL8192SU * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * * Contact information: * WLAN FAE <wlanfae@realtek.com> * Larry Finger <Larry.Finger@lwfinger.net> * ******************************************************************************/ #define _HCI_HAL_INIT_C_ #include "osdep_service.h" #include "drv_types.h" #include "usb_ops.h" #include "usb_osintf.h" u8 r8712_usb_hal_bus_init(struct _adapter *padapter) { u8 val8 = 0; u8 ret = _SUCCESS; int PollingCnt = 20; struct registry_priv *pregistrypriv = &padapter->registrypriv; if (pregistrypriv->chip_version == RTL8712_FPGA) { val8 = 0x01; /* switch to 80M clock */ r8712_write8(padapter, SYS_CLKR, val8); val8 = r8712_read8(padapter, SPS1_CTRL); val8 = val8 | 0x01; /* enable VSPS12 LDO Macro block */ r8712_write8(padapter, SPS1_CTRL, val8); val8 = r8712_read8(padapter, AFE_MISC); val8 = val8 | 0x01; /* Enable AFE Macro Block's Bandgap */ r8712_write8(padapter, AFE_MISC, val8); val8 = r8712_read8(padapter, LDOA15_CTRL); val8 = val8 | 0x01; /* enable LDOA15 block */ r8712_write8(padapter, LDOA15_CTRL, val8); val8 = r8712_read8(padapter, SPS1_CTRL); val8 = val8 | 0x02; /* Enable VSPS12_SW Macro Block */ r8712_write8(padapter, SPS1_CTRL, val8); val8 = r8712_read8(padapter, AFE_MISC); val8 = val8 | 0x02; /* Enable AFE Macro Block's Mbias */ r8712_write8(padapter, AFE_MISC, val8); val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); val8 = val8 | 0x08; /* isolate PCIe Analog 1.2V to PCIe 3.3V and PCIE Digital */ r8712_write8(padapter, SYS_ISO_CTRL + 1, val8); val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); val8 = val8 & 0xEF; /* attatch AFE PLL to MACTOP/BB/PCIe Digital */ r8712_write8(padapter, SYS_ISO_CTRL + 1, val8); val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1); val8 = val8 & 0xFB; /* enable AFE clock */ r8712_write8(padapter, AFE_XTAL_CTRL + 1, val8); val8 = r8712_read8(padapter, AFE_PLL_CTRL); val8 = val8 | 0x01; /* Enable AFE PLL Macro Block */ r8712_write8(padapter, AFE_PLL_CTRL, val8); val8 = 0xEE; /* release isolation AFE PLL & MD */ r8712_write8(padapter, SYS_ISO_CTRL, val8); val8 = r8712_read8(padapter, SYS_CLKR + 1); val8 = val8 | 0x08; /* enable MAC clock */ r8712_write8(padapter, SYS_CLKR + 1, val8); val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); val8 = val8 | 0x08; /* enable Core digital and enable IOREG R/W */ r8712_write8(padapter, SYS_FUNC_EN + 1, val8); val8 = val8 | 0x80; /* enable REG_EN */ r8712_write8(padapter, SYS_FUNC_EN + 1, val8); val8 = r8712_read8(padapter, SYS_CLKR + 1); val8 = (val8 | 0x80) & 0xBF; /* switch the control path */ r8712_write8(padapter, SYS_CLKR + 1, val8); val8 = 0xFC; r8712_write8(padapter, CR, val8); val8 = 0x37; r8712_write8(padapter, CR + 1, val8); /* reduce EndPoint & init it */ r8712_write8(padapter, 0x102500ab, r8712_read8(padapter, 0x102500ab) | BIT(6) | BIT(7)); /* consideration of power consumption - init */ r8712_write8(padapter, 0x10250008, r8712_read8(padapter, 0x10250008) & 0xfffffffb); } else if (pregistrypriv->chip_version == RTL8712_1stCUT) { /* Initialization for power on sequence, */ r8712_write8(padapter, SPS0_CTRL + 1, 0x53); r8712_write8(padapter, SPS0_CTRL, 0x57); /* Enable AFE Macro Block's Bandgap and Enable AFE Macro * Block's Mbias */ val8 = r8712_read8(padapter, AFE_MISC); r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN | AFE_MISC_MBEN)); /* Enable LDOA15 block */ val8 = r8712_read8(padapter, LDOA15_CTRL); r8712_write8(padapter, LDOA15_CTRL, (val8 | LDA15_EN)); val8 = r8712_read8(padapter, SPS1_CTRL); r8712_write8(padapter, SPS1_CTRL, (val8 | SPS1_LDEN)); msleep(20); /* Enable Switch Regulator Block */ val8 = r8712_read8(padapter, SPS1_CTRL); r8712_write8(padapter, SPS1_CTRL, (val8 | SPS1_SWEN)); r8712_write32(padapter, SPS1_CTRL, 0x00a7b267); val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); /* Engineer Packet CP test Enable */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x20)); val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 & 0x6F)); /* Enable AFE clock */ val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1); r8712_write8(padapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); /* Enable AFE PLL Macro Block */ val8 = r8712_read8(padapter, AFE_PLL_CTRL); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ val8 = r8712_read8(padapter, SYS_CLKR); r8712_write8(padapter, SYS_CLKR, val8 & (~SYS_CLKSEL)); /* SSC Disable */ val8 = r8712_read8(padapter, SYS_CLKR); /* Enable MAC clock */ val8 = r8712_read8(padapter, SYS_CLKR + 1); r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x18)); /* Revised POS, */ r8712_write8(padapter, PMC_FSM, 0x02); /* Enable Core digital and enable IOREG R/W */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x08)); /* Enable REG_EN */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x80)); /* Switch the control path to FW */ val8 = r8712_read8(padapter, SYS_CLKR + 1); r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); r8712_write8(padapter, CR, 0xFC); r8712_write8(padapter, CR + 1, 0x37); /* Fix the RX FIFO issue(usb error), */ val8 = r8712_read8(padapter, 0x1025FE5c); r8712_write8(padapter, 0x1025FE5c, (val8|BIT(7))); val8 = r8712_read8(padapter, 0x102500ab); r8712_write8(padapter, 0x102500ab, (val8|BIT(6)|BIT(7))); /* For power save, used this in the bit file after 970621 */ val8 = r8712_read8(padapter, SYS_CLKR); r8712_write8(padapter, SYS_CLKR, val8&(~CPU_CLKSEL)); } else if (pregistrypriv->chip_version == RTL8712_2ndCUT || pregistrypriv->chip_version == RTL8712_3rdCUT) { /* Initialization for power on sequence, * E-Fuse leakage prevention sequence */ r8712_write8(padapter, 0x37, 0xb0); msleep(20); r8712_write8(padapter, 0x37, 0x30); /* Set control path switch to HW control and reset Digital Core, * CPU Core and MAC I/O to solve FW download fail when system * from resume sate. */ val8 = r8712_read8(padapter, SYS_CLKR + 1); if (val8 & 0x80) { val8 &= 0x3f; r8712_write8(padapter, SYS_CLKR + 1, val8); } val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); val8 &= 0x73; r8712_write8(padapter, SYS_FUNC_EN + 1, val8); msleep(20); /* Revised POS, */ /* Enable AFE Macro Block's Bandgap and Enable AFE Macro * Block's Mbias */ r8712_write8(padapter, SPS0_CTRL + 1, 0x53); r8712_write8(padapter, SPS0_CTRL, 0x57); val8 = r8712_read8(padapter, AFE_MISC); /*Bandgap*/ r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN)); r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN | AFE_MISC_MBEN | AFE_MISC_I32_EN)); /* Enable PLL Power (LDOA15V) */ val8 = r8712_read8(padapter, LDOA15_CTRL); r8712_write8(padapter, LDOA15_CTRL, (val8 | LDA15_EN)); /* Enable LDOV12D block */ val8 = r8712_read8(padapter, LDOV12D_CTRL); r8712_write8(padapter, LDOV12D_CTRL, (val8 | LDV12_EN)); val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); /* Engineer Packet CP test Enable */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x20)); /* Support 64k IMEM */ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1); r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 & 0x68)); /* Enable AFE clock */ val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1); r8712_write8(padapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); /* Enable AFE PLL Macro Block */ val8 = r8712_read8(padapter, AFE_PLL_CTRL); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); /* Some sample will download fw failure. The clock will be * stable with 500 us delay after reset the PLL * TODO: When usleep is added to kernel, change next 3 * udelay(500) to usleep(500) */ udelay(500); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x51)); udelay(500); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); udelay(500); /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ r8712_write8(padapter, SYS_CLKR, 0x00); /* CPU Clock and 80M Clock SSC Disable to overcome FW download * fail timing issue. */ val8 = r8712_read8(padapter, SYS_CLKR); r8712_write8(padapter, SYS_CLKR, (val8 | 0xa0)); /* Enable MAC clock */ val8 = r8712_read8(padapter, SYS_CLKR + 1); r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x18)); /* Revised POS, */ r8712_write8(padapter, PMC_FSM, 0x02); /* Enable Core digital and enable IOREG R/W */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x08)); /* Enable REG_EN */ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1); r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x80)); /* Switch the control path to FW */ val8 = r8712_read8(padapter, SYS_CLKR + 1); r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); r8712_write8(padapter, CR, 0xFC); r8712_write8(padapter, CR + 1, 0x37); /* Fix the RX FIFO issue(usb error), 970410 */ val8 = r8712_read8(padapter, 0x1025FE5c); r8712_write8(padapter, 0x1025FE5c, (val8 | BIT(7))); /* For power save, used this in the bit file after 970621 */ val8 = r8712_read8(padapter, SYS_CLKR); r8712_write8(padapter, SYS_CLKR, val8 & (~CPU_CLKSEL)); /* Revised for 8051 ROM code wrong operation. */ r8712_write8(padapter, 0x1025fe1c, 0x80); /* To make sure that TxDMA can ready to download FW. * We should reset TxDMA if IMEM RPT was not ready. */ do { val8 = r8712_read8(padapter, TCR); if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE) break; udelay(5); /* PlatformStallExecution(5); */ } while (PollingCnt--); /* Delay 1ms */ if (PollingCnt <= 0) { val8 = r8712_read8(padapter, CR); r8712_write8(padapter, CR, val8&(~_TXDMA_EN)); udelay(2); /* PlatformStallExecution(2); */ /* Reset TxDMA */ r8712_write8(padapter, CR, val8|_TXDMA_EN); } } else ret = _FAIL; return ret; } unsigned int r8712_usb_inirp_init(struct _adapter *padapter) { u8 i; struct recv_buf *precvbuf; struct intf_hdl *pintfhdl = &padapter->pio_queue->intf; struct recv_priv *precvpriv = &(padapter->recvpriv); precvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */ /* issue Rx irp to receive data */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; for (i = 0; i < NR_RECVBUFF; i++) { if (r8712_usb_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf) == false) return _FAIL; precvbuf++; precvpriv->free_recv_buf_queue_cnt--; } return _SUCCESS; } unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter) { r8712_usb_read_port_cancel(padapter); return _SUCCESS; }