/* * Routines to handle host CPU related functions * * $Id: 8192cd_host.c,v 1.1 2012/05/04 13:48:37 jimmylin Exp $ * * Copyright (c) 2012 Realtek Semiconductor Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #define _8192CD_HOST_C_ #ifdef __KERNEL__ #include #include #include #include //#include #include #include #include #include #include #endif #include "./8192cd_cfg.h" #ifdef __KERNEL__ #ifdef __LINUX_2_6__ #include #include #include #endif #elif defined(__ECOS) #include #include #include #include #include #else #include "./sys-support.h" #endif #include "./8192cd.h" #include "./8192cd_headers.h" #include "./8192cd_debug.h" #ifdef CONFIG_RTL8672 #ifdef USE_RLX_BSP #include #include #ifdef CONFIG_RTL_8196C #undef CONFIG_RTL_8196C #endif #ifdef CONFIG_RTL8196C_REVISION_B #undef CONFIG_RTL8196C_REVISION_B #endif #else #include #include "../../../arch/mips/realtek/rtl8672/gpio.h" #endif #elif defined(__ECOS) #else #if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL8196B) #include #endif #if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL8196C) #include #endif #endif #if defined(CONFIG_RTL_819X) && defined(__LINUX_2_6__) #if !defined(USE_RLX_BSP) #include #else #include #endif #endif #ifndef REG32 #define REG32(reg) (*(volatile unsigned int *)(reg)) #endif #ifdef CONFIG_RTL_92D_DMDP void Sw_PCIE_Func(int func) { #if (RTL_USED_PCIE_SLOT==1) REG32(0xb8b2100c)=REG32(0xb8b2100c)|func; // switch to function # #else REG32(0xb8b0100c)=REG32(0xb8b0100c)|func; // switch to function # #endif } #endif #if !defined(CONFIG_NET_PCI) && (defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X)) #define MAX_PAYLOAD_SIZE_128B 0x00 #ifndef __ECOS #if !(defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8196E)) int rtl8196b_pci_reset(unsigned long conf_addr) { /* If PCI needs to be reset, put code here. * Note: * Software may need to do hot reset for a period of time, say ~100us. * Here we put 2ms. */ //Modified for PCIE PHY parameter due to RD center suggestion by Jason 12252009 WRITE_MEM32(0xb8000044, 0x9);//Enable PCIE PLL delay_ms(10); REG32(0xb8000010)=REG32(0xb8000010)|(0x500); //Active LX & PCIE Clock in 8196B system register delay_ms(10); WRITE_MEM32(0xb800003C, 0x1);//PORT0 PCIE PHY MDIO Reset delay_ms(10); WRITE_MEM32(0xb800003C, 0x3);//PORT0 PCIE PHY MDIO Reset delay_ms(10); WRITE_MEM32(0xb8000040, 0x1);//PORT1 PCIE PHY MDIO Reset delay_ms(10); WRITE_MEM32(0xb8000040, 0x3);//PORT1 PCIE PHY MDIO Reset delay_ms(10); WRITE_MEM32(0xb8b01008, 0x1);// PCIE PHY Reset Close:Port 0 delay_ms(10); WRITE_MEM32(0xb8b01008, 0x81);// PCIE PHY Reset On:Port 0 delay_ms(10); #ifdef PIN_208 WRITE_MEM32(0xb8b21008, 0x1);// PCIE PHY Reset Close:Port 1 delay_ms(10); WRITE_MEM32(0xb8b21008, 0x81);// PCIE PHY Reset On:Port 1 delay_ms(10); #endif #ifdef OUT_CYSTALL WRITE_MEM32(0xb8b01000, 0xcc011901);// PCIE PHY Reset On:Port 0 delay_ms(10); #ifdef PIN_208 WRITE_MEM32(0xb8b21000, 0xcc011901);// PCIE PHY Reset On:Port 1 delay_ms(10); #endif #endif REG32(0xb8000010)=REG32(0xb8000010)|(0x01000000); //PCIE PHY Reset On:Port 0 delay_ms(10); #if (defined(__LINUX_2_6__) && defined(USE_RLX_BSP)) || defined(__ECOS) WRITE_MEM32(BSP_PCIE0_H_PWRCR, READ_MEM32(BSP_PCIE0_H_PWRCR) & 0xFFFFFF7F); #ifdef PIN_208 WRITE_MEM32(BSP_PCIE1_H_PWRCR, READ_MEM32(BSP_PCIE1_H_PWRCR) & 0xFFFFFF7F); #endif delay_ms(100); WRITE_MEM32(BSP_PCIE0_H_PWRCR, READ_MEM32(BSP_PCIE0_H_PWRCR) | 0x00000080); #ifdef PIN_208 WRITE_MEM32(BSP_PCIE1_H_PWRCR, READ_MEM32(BSP_PCIE1_H_PWRCR) | 0x00000080); #endif #else WRITE_MEM32(PCIE0_H_PWRCR, READ_MEM32(PCIE0_H_PWRCR) & 0xFFFFFF7F); #ifdef PIN_208 WRITE_MEM32(PCIE1_H_PWRCR, READ_MEM32(PCIE1_H_PWRCR) & 0xFFFFFF7F); #endif delay_ms(100); WRITE_MEM32(PCIE0_H_PWRCR, READ_MEM32(PCIE0_H_PWRCR) | 0x00000080); #ifdef PIN_208 WRITE_MEM32(PCIE1_H_PWRCR, READ_MEM32(PCIE1_H_PWRCR) | 0x00000080); #endif #endif delay_ms(10); if ((READ_MEM32(0xb8b00728)&0x1f)!=0x11) { _DEBUG_INFO("PCIE LINK FAIL\n"); return FAIL; } // Enable PCIE host #if (defined(__LINUX_2_6__) && defined(USE_RLX_BSP)) || defined(__ECOS) WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif return SUCCESS; } #endif // !defined(CONFIG_NET_PCI) && (defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X)) #endif #endif #if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8198B) #define MAX_PAYLOAD_SIZE_128B 0x00 #ifndef CONFIG_RTL_8198B #define CLK_MANAGE 0xb8000010 #endif #define PCIE0_RC_EXT_BASE (0xb8b01000) #define PCIE1_RC_EXT_BASE (0xb8b21000) //RC Extended register #define PCIE0_MDIO (PCIE0_RC_EXT_BASE+0x00) #define PCIE1_MDIO (PCIE1_RC_EXT_BASE+0x00) //MDIO #define PCIE_MDIO_DATA_OFFSET (16) #define PCIE_MDIO_DATA_MASK (0xffff <=0x01) { #ifdef CONFIG_RTL_88E_SUPPORT //HostPCIe_SetPhyMdioWrite(portnum, 0xa, 0x4437); //HostPCIe_SetPhyMdioWrite(portnum, 0x1, 0x36a3); #endif HostPCIe_SetPhyMdioWrite(portnum, 0x3, 0x0486); HostPCIe_SetPhyMdioWrite(portnum, 0x4, 0xf144); HostPCIe_SetPhyMdioWrite(portnum, 0xc, 0x097f); } else { HostPCIe_SetPhyMdioWrite(portnum, 0xc, 0x0171); HostPCIe_SetPhyMdioWrite(portnum, 0x4, 0xf544); } HostPCIe_SetPhyMdioWrite(portnum, 0x6, 0x7081); HostPCIe_SetPhyMdioWrite(portnum, 0x8, 0x901c); HostPCIe_SetPhyMdioWrite(portnum, 0x9, 0x0ebc); #else #if defined(CONFIG_RTL_8196E) if ((REG32(BSP_REVR) & 0xFFFFF000) == BSP_RTL8196E) #else if ((REG32(BSP_REVR) >= BSP_RTL8198_REVISION_B) || ((REG32(BSP_REVR) & 0xFFFFF000) == BSP_RTL8197D)) #endif { HostPCIe_SetPhyMdioWrite(portnum, 0, 0xD086); //bokai tell, and fix HostPCIe_SetPhyMdioWrite(portnum, 1, 0x0003); HostPCIe_SetPhyMdioWrite(portnum, 2, 0x4d19); ///1119 bokai #ifdef CONFIG_WLAN_HAL_8192EE HostPCIe_SetPhyMdioWrite(portnum, 4, 0x5000); // disable spread spectrum in 92E #else #ifdef CONFIG_PHY_EAT_40MHZ HostPCIe_SetPhyMdioWrite(portnum, 4, 0x7C00); #else HostPCIe_SetPhyMdioWrite(portnum, 4, 0x7000); #endif #endif #if defined(CONFIG_AUTO_PCIE_PHY_SCAN) && (defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_819XD)) if ((REG32(0xb8000008)&0x2000000)==0x2000000) //40MHz { HostPCIe_SetPhyMdioWrite(portnum, 4, 0x7C00); HostPCIe_SetPhyMdioWrite(portnum, 5, 0x09DB); //40M //1119 bokai HostPCIe_SetPhyMdioWrite(portnum, 6, 0x4048); //40M HostPCIe_SetPhyMdioWrite(portnum, 7, 0x41ff); HostPCIe_SetPhyMdioWrite(portnum, 8, 0x13F6); } else //25MHz { printk("98 - 25MHz Clock Source\n"); HostPCIe_SetPhyMdioWrite(portnum, 4, 0x7000); HostPCIe_SetPhyMdioWrite(portnum, 5, 0x0B13); HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf048); //25M HostPCIe_SetPhyMdioWrite(portnum, 7, 0xa7ff); //-0.5% HostPCIe_SetPhyMdioWrite(portnum, 8, 0x0c56); } #else #ifdef CONFIG_PHY_EAT_40MHZ printk("98 - 40MHz Clock Source\n"); HostPCIe_SetPhyMdioWrite(portnum, 5, 0x09DB); //40M //1119 bokai HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf048); //40M //HostPCIe_SetPhyMdioWrite(portnum, 5, 0x08db); //40M //HostPCIe_SetPhyMdioWrite(portnum, 6, 0xF148); //40M #else printk("98 - 25MHz Clock Source\n"); HostPCIe_SetPhyMdioWrite(portnum, 5, 0x0B13); HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf048); //25M #endif #endif #if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) #else HostPCIe_SetPhyMdioWrite(portnum, 8, 0x18d7); //peisi tune #endif //saving more power, 8196c pe-si tune HostPCIe_SetPhyMdioWrite(portnum, 0x09, 0x539c); HostPCIe_SetPhyMdioWrite(portnum, 0x0a, 0x20eb); HostPCIe_SetPhyMdioWrite(portnum, 0x0d, 0x1766); #if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) #ifdef CONFIG_WLAN_HAL_8881A HostPCIe_SetPhyMdioWrite(portnum, 0x0b, 0x0311); //for sloving low performance #else HostPCIe_SetPhyMdioWrite(portnum, 0x0b, 0x0711); //for sloving low performance #endif #else HostPCIe_SetPhyMdioWrite(portnum, 0x0b, 0x0511); //for sloving low performance #endif #if defined(CONFIG_RTL_8196E) HostPCIe_SetPhyMdioWrite(portnum, 0xf, 0x0f0f); #else HostPCIe_SetPhyMdioWrite(portnum, 0xf, 0x0a00); #endif HostPCIe_SetPhyMdioWrite(portnum, 0x19, 0xFCE0); HostPCIe_SetPhyMdioWrite(portnum, 0x1a, 0x7e40); //formal chip, reg 0x1a.4=0 HostPCIe_SetPhyMdioWrite(portnum, 0x1b, 0xFC01); //formal chip reg 0x1b.0=1 HostPCIe_SetPhyMdioWrite(portnum, 0x1e, 0xC280); } else #endif { #ifndef CONFIG_WLAN_HAL_8881A HostPCIe_SetPhyMdioWrite(portnum, 0, 0xD087); HostPCIe_SetPhyMdioWrite(portnum, 1, 0x0003); HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf448); //new HostPCIe_SetPhyMdioWrite(portnum, 6, 0x408); //avoid noise infuse //15-12=0, 7-5=0, 0448 HostPCIe_SetPhyMdioWrite(portnum, 7, 0x31ff); HostPCIe_SetPhyMdioWrite(portnum, 8, 0x18d5); //new HostPCIe_SetPhyMdioWrite(portnum, 9, 0x531c); HostPCIe_SetPhyMdioWrite(portnum, 0xd, 0x1766); HostPCIe_SetPhyMdioWrite(portnum, 0xf, 0x0010);//ori HostPCIe_SetPhyMdioWrite(portnum, 0x19, 0xFCE0); HostPCIe_SetPhyMdioWrite(portnum, 0x1e, 0xC280); #endif } #endif } //--------------------------------------- PCIE_Device_PERST(portnum); PCIE_PHY_Reset(portnum); #ifdef CONFIG_RTL_ULINKER { extern void eth_led_recover(void); eth_led_recover(); } #endif delay_ms(500); delay_ms(500); status=PCIE_Check_Link(portnum); if(status==FAIL) return FAIL; SET_BAR: if (portnum==0) { // Enable PCIE host if (pcie_reset_done[portnum] == 0) { #if (defined(__LINUX_2_6__) && defined(USE_RLX_BSP)) || defined(__ECOS) WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif pcie_reset_done[portnum] = 1; } #ifdef CONFIG_RTL_92D_DMDP else { Sw_PCIE_Func(1); //choose the PCIE port number WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B Sw_PCIE_Func(0); } #endif } else if (portnum==1) { // Enable PCIE host #if (defined(__LINUX_2_6__) && defined(USE_RLX_BSP)) || defined(__ECOS) if (pcie_reset_done[portnum] == 0) { WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B pcie_reset_done[portnum] = 1; } #ifdef CONFIG_RTL_92D_DMDP else { Sw_PCIE_Func(1); //choose the PCIE port number WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B Sw_PCIE_Func(0); } #endif #else /* defined(__LINUX_2_6__) && defined(USE_RLX_BSP) */ WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif /* defined(__LINUX_2_6__) && defined(USE_RLX_BSP) */ } else return FAIL; delay_ms(500); return SUCCESS; } #endif #elif defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C) static int pcie_reset_done[2] = {0}; #ifdef CONFIG_RTL8672 #ifdef USE_RLX_BSP #define PCI_MISC BSP_PCI_MISC #define MISC_IP_SEL BSP_IP_SEL #define EN_PCIE BSP_EN_PCIE #define PCI_MISC BSP_PCI_MISC #define MISC_PINSR BSP_MISC_PINSR #define CLKSEL BSP_CLKSEL #endif //USE_RLX_BSP unsigned char clk_src_40M = 0; struct pcie_para{ unsigned char port; unsigned char reg; unsigned short value; }; enum clk_source{ CLK35_328_6166 = 0, //6166 35.328M clk CLK25_6166, //6166 25M clk CLK35_328_8676, //8676 35.328M clk CLK40_8676, //8676 40M clk CLK40_8686, //8686 40M clk CLK25_8686, //8686 25M clk CLK35_328_8676S, //8676S 35.328M clk CLK40_8676S, //8676 40M clk CLK25_8685_P0, //8685 25M clk CLK25_8685_P1, //8685 25M clk NOT_DEFINED_CLK }; struct pcie_para ePHY[][29] = { { {0, 1, 0x0003}, {0, 2, 0x2d18}, {0, 3, 0x6d09}, {0, 4, 0x5000}, {0, 0, 0x1046}, {0, 6, 0x0068}, {0, 5, 0x0bcb}, {0, 7, 0x30ff}, {0, 8, 0x18d7}, {0, 9, 0x530c}, {0, 0xa, 0x00e8}, {0, 0xb, 0x0511}, {0, 0xc, 0x0828}, {0, 0xd, 0x17a6}, {0, 0xe, 0x98c5}, {0, 0xf, 0x0f0f}, {0, 0x10, 0x000c}, {0, 0x11, 0x3c00}, {0, 0x12, 0xfc00}, {0, 0x13, 0x0c81}, {0, 0x14, 0xde01}, {0, 0x19, 0xfc20}, {0, 0x1a, 0xfc00}, {0, 0x1b, 0xfc00}, {0, 0x1c, 0xfc00}, {0, 0x1d, 0xa0eb}, {0, 0x1e, 0xc280}, {0, 0x1f, 0x05e0}, {0xff,0xff,0xffff}}, //6166 35.328M clk { {0, 1, 0x0003}, {0, 2, 0x2d18}, {0, 3, 0x6d09}, {0, 4, 0x5000}, {0, 0, 0x1047}, {0, 6, 0xf848}, {0, 5, 0x08ab}, {0, 7, 0x30ff}, {0, 8, 0x18d7}, {0, 9, 0x530c}, {0, 0xa, 0x00e8}, {0, 0xb, 0x0511}, {0, 0xc, 0x0828}, {0, 0xd, 0x17a6}, {0, 0xe, 0x98c5}, {0, 0xf, 0x0f0f}, {0, 0x10, 0x000c}, {0, 0x11, 0x3c00}, {0, 0x12, 0xfc00}, {0, 0x13, 0x0c81}, {0, 0x14, 0xde01}, {0, 0x19, 0xfc20}, {0, 0x1a, 0xfc00}, {0, 0x1b, 0xfc00}, {0, 0x1c, 0xfc00}, {0, 0x1d, 0xa0eb}, {0, 0x1e, 0xc280}, {0, 0x1f, 0x05e0}, {0xff,0xff,0xffff}}, //6166 25M clk { {0, 1, 0x0003}, {0, 2, 0x2d18}, {0, 3, 0x4d09}, {0, 4, 0x5c3f}, {0, 0, 0x1046}, {0, 6, 0x9048}, {0, 5, 0x2213}, {0, 7, 0x31ff}, {0, 8, 0x18d7}, {0, 9, 0x539c}, {0, 0xa, 0x00e8}, {0, 0xb, 0x0711}, {0, 0xc, 0x0828}, {0, 0xd, 0x17a6}, {0, 0xe, 0x98c5}, {0, 0xf, 0x0f0f}, {0, 0x10, 0x000c}, {0, 0x11, 0x3c00}, {0, 0x12, 0xfc00}, {0, 0x13, 0x0c81}, {0, 0x14, 0xde01}, {0, 0x19, 0xfce0}, {0, 0x1a, 0x7c00}, {0, 0x1b, 0xfc00}, {0, 0x1c, 0xfc00}, {0, 0x1d, 0xa0eb}, {0, 0x1e, 0xc280}, {0, 0x1f, 0x0600}, {0xff,0xff,0xffff}}, //8676 35.328M clk { {0, 1, 0x0003}, {0, 2, 0x2d18}, {0, 3, 0x4d09}, {0, 4, 0x5000}, {0, 0, 0x1047}, {0, 6, 0x9148}, {0, 5, 0x23cb}, {0, 7, 0x31ff}, {0, 8, 0x18d7}, {0, 9, 0x539c}, {0, 0xa, 0x00e8}, {0, 0xb, 0x0711}, {0, 0xc, 0x0828}, {0, 0xd, 0x17a6}, {0, 0xe, 0x98c5}, {0, 0xf, 0x0f0f}, {0, 0x10, 0x000c}, {0, 0x11, 0x3c00}, {0, 0x12, 0xfc00}, {0, 0x13, 0x0c81}, {0, 0x14, 0xde01}, {0, 0x19, 0xfce0}, {0, 0x1a, 0x7c00}, {0, 0x1b, 0xfc00}, {0, 0x1c, 0xfc00}, {0, 0x1d, 0xa0eb}, {0, 0x1e, 0xc280}, {0, 0x1f, 0x0600}, {0xff,0xff,0xffff}}, //8676 40M clk { {0, 0, 0x1086}, {0, 4, 0x5800}, {0, 5, 0x05d3}, {0, 6, 0xf048}, {0, 0xb, 0x0711}, {0, 0xd, 0x1766}, {0, 0xf, 0x0a00}, {0, 0x1d, 0xa0eb}, {0xff,0xff,0xffff}},//8686 40M clk { {0, 6, 0xf848}, {0, 0xb, 0x0711}, {0, 0xd, 0x1766}, {0, 0xf, 0x0a00}, {0, 0x01d, 0xa0eb}, {1, 4, 0xf56b}, {1, 6, 0x5881}, {1, 8, 0x6c1c}, {1, 9, 0x0fbf}, {1, 0xb, 0x7bb0}, {0xff,0xff,0xffff}},//8686 25M clk { {0, 1, 0x06a3}, {0, 2, 0x4300}, {0, 3, 0x0400}, {0, 4, 0xd546}, {0, 0, 0x0000}, {0, 6, 0xb880}, {0, 5, 0x8101}, {0, 7, 0x7c40}, {0, 8, 0x901c}, {0, 9, 0x0c9c}, {0, 0xa, 0x4037}, {0, 0xb, 0x03b0}, {0, 0xc, 0x0261}, {0xff,0xff,0xffff}}, //8676S 35.328M clk { {0, 1, 0x06a3}, {0, 2, 0x4300}, {0, 3, 0x0400}, {0, 4, 0xd546}, {0, 0, 0x0000}, {0, 6, 0xb880}, {0, 5, 0x8101}, {0, 7, 0x7c40}, {0, 8, 0x901c}, {0, 9, 0x0c9c}, {0, 0xa, 0x4037}, {0, 0xb, 0x03b0}, {0, 0xc, 0x0261}, {0xff,0xff,0xffff}}, //8676S 40M clk { {0, 0, 0x404c}, {0, 1, 0x16a3}, {0, 2, 0x6340}, {0, 3, 0x370d}, {0, 4, 0x856a}, {0, 5, 0x8109}, {0, 6, 0x6081}, {0, 7, 0x5400}, {0, 8, 0x9000}, {0, 9, 0x0ccc}, {0, 0xa, 0x4437}, {0, 0xb, 0x0230}, {0, 0xc, 0x0021}, {0, 0xd, 0x0000}, {0, 0xe, 0x0000}, {0, 0x1f, 0x0000}, {0xff,0xff,0xffff}}, //8685 25M clk { {1, 0, 0x404c}, {1, 1, 0x16a3}, {1, 2, 0x6340}, {1, 3, 0x370d}, {1, 4, 0x856a}, {1, 5, 0x8109}, {1, 6, 0x6081}, {1, 7, 0x5400}, {1, 8, 0x9000}, {1, 9, 0x0ccc}, {1, 0xa, 0x4437}, {1, 0xb, 0x0230}, {1, 0xc, 0x0021}, {1, 0xd, 0x0000}, {1, 0xe, 0x0000}, {1, 0x1f, 0x0000}, {0xff,0xff,0xffff}} //8685 25M clk }; int PCIE_reset_procedure(int portnum, int Use_External_PCIE_CLK, int mdio_reset, unsigned long conf_addr) { extern void PCIE_reset_pin(int *reset); #ifdef CONFIG_USE_PCIE_SLOT_1 extern void PCIE1_reset_pin(int *reset); #endif int PCIE_gpio_RST, i, idx; unsigned int PCIE_D_CFG0, PCIE_H_CFG, PCIE_H_PWRCR; unsigned int ENABLE_PCIE = EN_PCIE; if (portnum==0) { PCIE_D_CFG0 = BSP_PCIE0_D_CFG0; PCIE_H_CFG = BSP_PCIE0_H_CFG; PCIE_H_PWRCR = BSP_PCIE0_H_PWRCR; #ifdef CONFIG_USE_PCIE_SLOT_1 } else if(portnum==1) { PCIE_D_CFG0 = BSP_PCIE1_D_CFG0; PCIE_H_CFG = BSP_PCIE1_H_CFG; PCIE_H_PWRCR = BSP_PCIE1_H_PWRCR; ENABLE_PCIE = BSP_ENABLE_PCIE1; #endif } else { printk("Error: portnum=%d\n", portnum); return FAIL; } if (pcie_reset_done[portnum]) goto SET_BAR; #ifdef CONFIG_USE_PCIE_SLOT_1 if (portnum==1) PCIE1_reset_pin(&PCIE_gpio_RST); else #endif PCIE_reset_pin(&PCIE_gpio_RST); // 0. Assert PCIE Device Reset gpioClear(PCIE_gpio_RST); gpioConfig(PCIE_gpio_RST, GPIO_FUNC_OUTPUT); delay_ms(10); // 1. PCIE phy mdio reset #ifndef CONFIG_RTL8676S REG32(PCI_MISC) = BSP_PCI_MDIO_RESET_ASSERT; REG32(PCI_MISC) = BSP_PCI_MDIO_RESET_RELEASE; #endif // 2. PCIE MAC reset REG32(MISC_IP_SEL) &= ~ENABLE_PCIE; REG32(MISC_IP_SEL) |= ENABLE_PCIE; if(mdio_reset) { //printk("Do MDIO_RESET\n"); // 5.MDIO Reset #ifndef CONFIG_RTL8676S REG32(PCI_MISC) = BSP_PCI_MDIO_RESET_RELEASE; #endif } // 6. PCIE PHY Reset REG32(PCIE_H_PWRCR) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1 REG32(PCIE_H_PWRCR) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1 delay_ms(100); //---------------------------------------- if (mdio_reset) { if (IS_6166 && (REG32(MISC_PINSR) & CLKSEL)) idx = CLK35_328_6166; else if (IS_6166 && !(REG32(MISC_PINSR) & CLKSEL)) idx = CLK25_6166; else if (IS_RTL8676 && !(REG32(MISC_PINSR) & CLKSEL)) idx = CLK35_328_8676; else if (IS_RTL8676 && (REG32(MISC_PINSR) & CLKSEL)) idx = CLK40_8676; else if (IS_RTL8686 && (REG32(MISC_PINSR) & CLKSEL)){ printk("8686 40Mhz\n"); idx = CLK40_8686; } else if(IS_RTL8686 && !(REG32(MISC_PINSR) & CLKSEL)){ printk("8686 25Mhz\n"); idx = CLK25_8686; } else if (IS_RTL8676S && !(REG32(MISC_PINSR) & CLKSEL)) idx = CLK35_328_8676S; else if (IS_RTL8676S && (REG32(MISC_PINSR) & CLKSEL)) idx = CLK40_8676S; else if (IS_RTL8685){ if (portnum==0){ printk("8685 pcie port 0\n"); idx = CLK25_8685_P0; } else{ printk("8685 pcie port 1\n"); idx = CLK25_8685_P1; } } else idx = NOT_DEFINED_CLK; if (CLK40_8676 == idx) clk_src_40M = 1; for (i = 0; NOT_DEFINED_CLK != idx; ) { if(ePHY[idx][i].port != 0xff){ if(portnum == ePHY[idx][i].port) HostPCIe_SetPhyMdioWrite(ePHY[idx][i].port, ePHY[idx][i].reg, ePHY[idx][i].value); i++; } else break; } } // 7. PCIE Device Reset gpioSet(PCIE_gpio_RST); // wait for LinkUP i = 100; while(--i) { if((REG32(PCIE_H_CFG + 0x0728)&0x1f)==0x11) break; delay_ms(10); } if (i == 0) { printk("Warring!! Port %d WLan device PCIE Link Failed, State=0x%x\n", portnum, REG32(PCIE_H_CFG + 0x0728)); printk("Reset PCIE Host PHY and try again...\n"); // 4. PCIE PHY Reset REG32(PCIE_H_PWRCR) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1 REG32(PCIE_H_PWRCR) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1 // wait for LinkUP i = 100; while(--i) { if( (REG32(PCIE_H_CFG + 0x0728)&0x1f)==0x11) break; delay_ms(100); } if (i == 0) printk("%s[%d]: Error!! Port %d WLan device PCIE Link failed, State=0x%x\n", __FUNCTION__, __LINE__, portnum, REG32(PCIE_H_CFG + 0x0728)); } delay_ms(100); // 8. Set BAR REG32(PCIE_D_CFG0 + 0x10) = 0x18c00001; REG32(PCIE_D_CFG0 + 0x18) = 0x19000004; REG32(PCIE_D_CFG0 + 0x04) = 0x00180007; REG32(PCIE_H_CFG + 0x04) = 0x00100007; printk("Find Port_num=%d, Vender_Device_ID=0x%X\n", portnum, REG32(PCIE_D_CFG0 + 0x00) ); if(i==0) { printk("Cannot LinkUP (0x%08X)\n", REG32(PCIE_H_CFG + 0x0728)); return FAIL; } SET_BAR: // Enable PCIE host if (pcie_reset_done[portnum] == 0) { WRITE_MEM32(PCIE_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B set_rtl8192cd_gpio(); pcie_reset_done[portnum] = 1; } #ifdef CONFIG_RTL_92D_DMDP else { Sw_PCIE_Func(1); //choose the PCIE port number WRITE_MEM32(PCIE_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); Sw_PCIE_Func(0); } #endif return SUCCESS; } #else int PCIE_reset_procedure(int portnum, int Use_External_PCIE_CLK, int mdio_reset,unsigned long conf_addr) { int i=100; #define SYS_PCIE_PHY0 (0xb8000000 +0x50) //PCIE Register #define CLK_MANAGE 0xb8000010 #define PCIE_PHY0_REG 0xb8b01000 //#define PCIE_PHY1_REG 0xb8b21000 #define PCIE_PHY0 0xb8b01008 // #define PCIE_PHY1 0xb8b21008 int port =0; if (pcie_reset_done[portnum]) goto SET_BAR; //2.Active LX & PCIE Clock REG32(CLK_MANAGE) |= (1<<11); //enable active_pcie0 delay_ms(100); #if 1 if(mdio_reset) { //printk("Do MDIO_RESET\n"); // 3.MDIO Reset REG32(SYS_PCIE_PHY0) = (1<<3) |(0<<1) | (0<<0); //mdio reset=0, REG32(SYS_PCIE_PHY0) = (1<<3) |(0<<1) | (1<<0); //mdio reset=1, REG32(SYS_PCIE_PHY0) = (1<<3) |(1<<1) | (1<<0); //bit1 load_done=1 } //4. PCIE PHY Reset REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1 REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1 delay_ms(100); #endif delay_ms(100); //---------------------------------------- if(mdio_reset) { if (REG32(REVR) == RTL8196C_REVISION_A) { HostPCIe_SetPhyMdioWrite(port, 0, 0x5027); HostPCIe_SetPhyMdioWrite(port, 2, 0x6d18); HostPCIe_SetPhyMdioWrite(port, 6, 0x8828); HostPCIe_SetPhyMdioWrite(port, 7, 0x30ff); HostPCIe_SetPhyMdioWrite(port, 8, 0x18d7); HostPCIe_SetPhyMdioWrite(port, 0xa, 0xe9); HostPCIe_SetPhyMdioWrite(port, 0xb, 0x0511); HostPCIe_SetPhyMdioWrite(port, 0xd, 0x15b6); HostPCIe_SetPhyMdioWrite(port, 0xf, 0x0f0f); #if 1 // PHY_EAT_40MHZ HostPCIe_SetPhyMdioWrite(port, 5, 0xbcb); //[9:3]=1111001 (binary) 121 (10) HostPCIe_SetPhyMdioWrite(port, 6, 0x8128); //[11]=0 [9:8]=01 #endif /* emdiow 0 5027 emdiow 2 6d18 emdiow 6 8828 emdiow 7 30ff emdiow 8 18dd emdiow a e9 emdiow b 0511 emdiow d 15b6 emdiow f 0f0f */ } else { HostPCIe_SetPhyMdioWrite(port, 0, 0xD087); HostPCIe_SetPhyMdioWrite(port, 1, 0x0003); HostPCIe_SetPhyMdioWrite(port, 2, 0x4d18); #ifdef CONFIG_PHY_EAT_40MHZ printk("96C - 40MHz Clock Source\n"); #ifdef HIGH_POWER_EXT_PA HostPCIe_SetPhyMdioWrite(port, 5, 0x0BF3); //40M #else HostPCIe_SetPhyMdioWrite(port, 5, 0x0BCB); //40M #endif HostPCIe_SetPhyMdioWrite(port, 6, 0xF148); //40M #else printk("96C - 25MHz Clock Source\n"); HostPCIe_SetPhyMdioWrite(port, 6, 0xf848); //25M #endif HostPCIe_SetPhyMdioWrite(port, 7, 0x31ff); HostPCIe_SetPhyMdioWrite(port, 8, 0x18d7); HostPCIe_SetPhyMdioWrite(port, 9, 0x539c); HostPCIe_SetPhyMdioWrite(port, 0xa, 0x20eb); HostPCIe_SetPhyMdioWrite(port, 0xb, 0x0511); HostPCIe_SetPhyMdioWrite(port, 0xd, 0x1764); HostPCIe_SetPhyMdioWrite(port, 0xf, 0x0a00); #ifdef HAVING_FIB HostPCIe_SetPhyMdioWrite(port,8, 0x18dd); HostPCIe_SetPhyMdioWrite(port, 0xd, 0x1776); #endif HostPCIe_SetPhyMdioWrite(port, 0x19, 0xFCE0); HostPCIe_SetPhyMdioWrite(port, 0x1e, 0xC280); } } //--------------------------------------- // 6. PCIE Device Reset #ifndef CONFIG_RTL_8196C_iNIC REG32(CLK_MANAGE) &= ~(1<<12); //perst=0 off. delay_ms(300); #endif //mark_inic , from jason patch #ifdef CONFIG_RTL_8196C_iNIC iNIC_PCIE_Device_PERST(); #endif #if defined(CONFIG_RTL_8196CS) || defined(CONFIG_RTL_8197B) GPIO6_PCIE_Device_PERST(); #endif //4. PCIE PHY Reset REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1 REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1 delay_ms(300); #ifndef CONFIG_RTL_8196C_iNIC REG32(CLK_MANAGE) |= (1<<12); //PERST=1 #endif //4. PCIE PHY Reset //prom_printf("\nCLK_MANAGE(0x%x)=0x%x\n\n",CLK_MANAGE,READ_MEM32(CLK_MANAGE)); delay_ms(100); #if 1 //wait for LinkUP while(--i) { if( (REG32(0xb8b00728)&0x1f)==0x11) break; delay_ms(100); } if(i==0) { printk("i=%x Cannot LinkUP \n",i); return FAIL; } #endif SET_BAR: if (port==0) { // Enable PCIE host if (pcie_reset_done[portnum] == 0) { #if defined(__LINUX_2_6__) && defined(USE_RLX_BSP) WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif pcie_reset_done[portnum] = 1; } #ifdef CONFIG_RTL_92D_DMDP else { Sw_PCIE_Func(1); //choose the PCIE port number #if defined(__LINUX_2_6__) && defined(USE_RLX_BSP) WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif Sw_PCIE_Func(0); } #endif } else if (port==1) { // Enable PCIE host if (pcie_reset_done[portnum] == 0) { #if defined(__LINUX_2_6__) && defined(USE_RLX_BSP) WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif pcie_reset_done[portnum] = 1; } #ifdef CONFIG_RTL_92D_DMDP else { Sw_PCIE_Func(1); #if defined(__LINUX_2_6__) && defined(USE_RLX_BSP) //choose the PCIE port number WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #else WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007); WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B #endif Sw_PCIE_Func(0); } #endif } else return FAIL; return SUCCESS; } #endif void HostPCIe_Close(void) { REG32(0xb8b10044) &= (~(3)); REG32(0xb8b10044) |= (3); HostPCIe_SetPhyMdioWrite(0, 0xf, 0x0708); //.DeActive LX & PCIE Clock #ifdef CONFIG_RTL8672 REG32(MISC_IP_SEL) &= ~EN_PCIE; //enable active_pcie0 #else REG32(CLK_MANAGE) &=(0xFFFFFFFF- (1<<11)); //enable active_pcie0 #endif pcie_reset_done[0]=0; } #endif /* #elif (defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C)) */ #endif /* !defined(CONFIG_NET_PCI) */ #endif #ifdef CONFIG_RTL8671 /*6/7/04 hrchen, invalidate the dcache with a 0->1 transition*/ #ifdef CONFIG_CPU_RLX4181 int r3k_flush_dcache_range(int a, int b) { int garbage_tmp; __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0 %0, $20\n\t" "nop\n\t" "nop\n\t" "andi %0, 0xFDFF\n\t" "mtc0 %0, $20\n\t" "nop\n\t" "nop\n\t" "ori %0, 0x200\n\t" "mtc0 %0, $20\n\t" "nop\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : "=r" (garbage_tmp)); return 0; } #else int r3k_flush_dcache_range(int a, int b) { int garbage_tmp; __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0 %0, $20\n\t" "nop\n\t" "nop\n\t" "andi %0, 0xFFFE\n\t" "mtc0 %0, $20\n\t" "nop\n\t" "nop\n\t" "ori %0, 1\n\t" "mtc0 %0, $20\n\t" "nop\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : "=r" (garbage_tmp)); return 0; } #endif #ifdef _USE_DRAM_ //init DRAM void r3k_enable_DRAM(void) { int tmp, tmp1; //--- initialize and start COP3 __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0 %0,$12\n\t" "nop\n\t" "lui %1,0x8000\n\t" "or %1,%0\n\t" "mtc0 %1,$12\n\t" "nop\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : "=r" (tmp), "=r" (tmp1)); //set base __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mtc3 %0, $4 # $4: d-ram base\n\t" "nop\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : : "r" (DRAM_START_ADDR&0x0fffffff)); //set size __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mtc3 %0, $5 # $5: d-ram top\n\t" "nop\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : : "r" (R3K_DRAM_SIZE-1)); //clear DRAM __asm__ __volatile__( "1:\n\t" "sw $0,0(%1)\n\t" "addiu %1,4\n\t" "bne %0,%1,1b\n\t" "nop\n\t" ".set\tat\n\t" ".set\treorder" : : "r" (DRAM_START_ADDR+R3K_DRAM_SIZE), "r" (DRAM_START_ADDR)); } #endif // _USE_DRAM_ #endif // CONFIG_RTL8671