1df482650SStephan Linz /* 2df482650SStephan Linz * Xilinx xps_ll_temac ethernet driver for u-boot 3df482650SStephan Linz * 4df482650SStephan Linz * LL_TEMAC interface 5df482650SStephan Linz * 6df482650SStephan Linz * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> 7df482650SStephan Linz * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> 8df482650SStephan Linz * Copyright (C) 2008 - 2011 PetaLogix 9df482650SStephan Linz * 10df482650SStephan Linz * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver 11df482650SStephan Linz * Copyright (C) 2008 Nissin Systems Co.,Ltd. 12df482650SStephan Linz * March 2008 created 13df482650SStephan Linz * 14*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 15df482650SStephan Linz * 16df482650SStephan Linz * [0]: http://www.xilinx.com/support/documentation 17df482650SStephan Linz * 18df482650SStephan Linz * [S]: [0]/ip_documentation/xps_ll_temac.pdf 19df482650SStephan Linz * [A]: [0]/application_notes/xapp1041.pdf 20df482650SStephan Linz */ 21df482650SStephan Linz #ifndef _XILINX_LL_TEMAC_ 22df482650SStephan Linz #define _XILINX_LL_TEMAC_ 23df482650SStephan Linz 24df482650SStephan Linz #include <config.h> 25df482650SStephan Linz #include <net.h> 26df482650SStephan Linz #include <phy.h> 27df482650SStephan Linz #include <miiphy.h> 28df482650SStephan Linz 29df482650SStephan Linz #include <asm/types.h> 30df482650SStephan Linz #include <asm/byteorder.h> 31df482650SStephan Linz 32df482650SStephan Linz #include "xilinx_ll_temac_sdma.h" 33df482650SStephan Linz 34df482650SStephan Linz #if !defined(__BIG_ENDIAN) 35df482650SStephan Linz # error LL_TEMAC requires big endianess 36df482650SStephan Linz #endif 37df482650SStephan Linz 38df482650SStephan Linz /* 39df482650SStephan Linz * TEMAC Memory and Register Definition 40df482650SStephan Linz * 41df482650SStephan Linz * [1]: [0]/ip_documentation/xps_ll_temac.pdf 42df482650SStephan Linz * page 19, Memory and Register Descriptions 43df482650SStephan Linz */ 44df482650SStephan Linz struct temac_reg { 45df482650SStephan Linz /* direct soft registers (low part) */ 46df482650SStephan Linz u32 raf; /* Reset and Address Filter */ 47df482650SStephan Linz u32 tpf; /* Transmit Pause Frame */ 48df482650SStephan Linz u32 ifgp; /* Transmit Inter Frame Gap Adjustment */ 49df482650SStephan Linz u32 is; /* Interrupt Status */ 50df482650SStephan Linz u32 ip; /* Interrupt Pending */ 51df482650SStephan Linz u32 ie; /* Interrupt Enable */ 52df482650SStephan Linz u32 ttag; /* Transmit VLAN Tag */ 53df482650SStephan Linz u32 rtag; /* Receive VLAN Tag */ 54df482650SStephan Linz /* hard TEMAC registers */ 55df482650SStephan Linz u32 msw; /* Most Significant Word Data */ 56df482650SStephan Linz u32 lsw; /* Least Significant Word Data */ 57df482650SStephan Linz u32 ctl; /* Control */ 58df482650SStephan Linz u32 rdy; /* Ready Status */ 59df482650SStephan Linz /* direct soft registers (high part) */ 60df482650SStephan Linz u32 uawl; /* Unicast Address Word Lower */ 61df482650SStephan Linz u32 uawu; /* Unicast Address Word Upper */ 62df482650SStephan Linz u32 tpid0; /* VLAN TPID Word 0 */ 63df482650SStephan Linz u32 tpid1; /* VLAN TPID Word 1 */ 64df482650SStephan Linz }; 65df482650SStephan Linz 66df482650SStephan Linz /* Reset and Address Filter Registers (raf), [1] p25 */ 67df482650SStephan Linz #define RAF_SR (1 << 13) 68df482650SStephan Linz #define RAF_EMFE (1 << 12) 69df482650SStephan Linz #define RAF_NFE (1 << 11) 70df482650SStephan Linz #define RAF_RVSTM_POS 9 71df482650SStephan Linz #define RAF_RVSTM_MASK (3 << RAF_RVSTM_POS) 72df482650SStephan Linz #define RAF_TVSTM_POS 7 73df482650SStephan Linz #define RAF_TVSTM_MASK (3 << RAF_TVSTM_POS) 74df482650SStephan Linz #define RAF_RVTM_POS 5 75df482650SStephan Linz #define RAF_RVTM_MASK (3 << RAF_RVTM_POS) 76df482650SStephan Linz #define RAF_TVTM_POS 3 77df482650SStephan Linz #define RAF_TVTM_MASK (3 << RAF_TVTM_POS) 78df482650SStephan Linz #define RAF_BCREJ (1 << 2) 79df482650SStephan Linz #define RAF_MCREJ (1 << 1) 80df482650SStephan Linz #define RAF_HTRST (1 << 0) 81df482650SStephan Linz 82df482650SStephan Linz /* Transmit Pause Frame Registers (tpf), [1] p28 */ 83df482650SStephan Linz #define TPF_TPFV_POS 0 84df482650SStephan Linz #define TPF_TPFV_MASK (0xFFFF << TPF_TPFV_POS) 85df482650SStephan Linz 86df482650SStephan Linz /* Transmit Inter Frame Gap Adjustment Registers (ifgp), [1] p28 */ 87df482650SStephan Linz #define IFGP_POS 0 88df482650SStephan Linz #define IFGP_MASK (0xFF << IFGP_POS) 89df482650SStephan Linz 90df482650SStephan Linz /* Interrupt Status, Pending, Enable Registers (is, ip, ie), [1] p29-33 */ 91df482650SStephan Linz #define ISPE_MR (1 << 7) 92df482650SStephan Linz #define ISPE_RDL (1 << 6) 93df482650SStephan Linz #define ISPE_TC (1 << 5) 94df482650SStephan Linz #define ISPE_RFO (1 << 4) 95df482650SStephan Linz #define ISPE_RR (1 << 3) 96df482650SStephan Linz #define ISPE_RC (1 << 2) 97df482650SStephan Linz #define ISPE_AN (1 << 1) 98df482650SStephan Linz #define ISPE_HAC (1 << 0) 99df482650SStephan Linz 100df482650SStephan Linz /* Transmit, Receive VLAN Tag Registers (ttag, rtag), [1] p34-35 */ 101df482650SStephan Linz #define TRTAG_TPID_POS 16 102df482650SStephan Linz #define TRTAG_TPID_MASK (0xFFFF << TRTAG_TPID_POS) 103df482650SStephan Linz #define TRTAG_PRIO_POS 13 104df482650SStephan Linz #define TRTAG_PRIO_MASK (7 << TRTAG_PRIO_POS) 105df482650SStephan Linz #define TRTAG_CFI (1 << 12) 106df482650SStephan Linz #define TRTAG_VID_POS 0 107df482650SStephan Linz #define TRTAG_VID_MASK (0xFFF << TRTAG_VID_POS) 108df482650SStephan Linz 109df482650SStephan Linz /* Most, Least Significant Word Data Register (msw, lsw), [1] p46 */ 110df482650SStephan Linz #define MLSW_POS 0 111df482650SStephan Linz #define MLSW_MASK (~0UL << MLSW_POS) 112df482650SStephan Linz 113df482650SStephan Linz /* LSW Data Register for PHY addresses (lsw), [1] p66 */ 114df482650SStephan Linz #define LSW_REGAD_POS 0 115df482650SStephan Linz #define LSW_REGAD_MASK (0x1F << LSW_REGAD_POS) 116df482650SStephan Linz #define LSW_PHYAD_POS 5 117df482650SStephan Linz #define LSW_PHYAD_MASK (0x1F << LSW_PHYAD_POS) 118df482650SStephan Linz 119df482650SStephan Linz /* LSW Data Register for PHY data (lsw), [1] p66 */ 120df482650SStephan Linz #define LSW_REGDAT_POS 0 121df482650SStephan Linz #define LSW_REGDAT_MASK (0xFFFF << LSW_REGDAT_POS) 122df482650SStephan Linz 123df482650SStephan Linz /* Control Register (ctl), [1] p47 */ 124df482650SStephan Linz #define CTL_WEN (1 << 15) 125df482650SStephan Linz #define CTL_ADDR_POS 0 126df482650SStephan Linz #define CTL_ADDR_MASK (0x3FF << CTL_ADDR_POS) 127df482650SStephan Linz 128df482650SStephan Linz /* Ready Status Register Ethernet (rdy), [1] p48 */ 129df482650SStephan Linz #define RSE_HACS_RDY (1 << 14) 130df482650SStephan Linz #define RSE_CFG_WR (1 << 6) 131df482650SStephan Linz #define RSE_CFG_RR (1 << 5) 132df482650SStephan Linz #define RSE_AF_WR (1 << 4) 133df482650SStephan Linz #define RSE_AF_RR (1 << 3) 134df482650SStephan Linz #define RSE_MIIM_WR (1 << 2) 135df482650SStephan Linz #define RSE_MIIM_RR (1 << 1) 136df482650SStephan Linz #define RSE_FABR_RR (1 << 0) 137df482650SStephan Linz 138df482650SStephan Linz /* Unicast Address Word Lower, Upper Registers (uawl, uawu), [1] p35-36 */ 139df482650SStephan Linz #define UAWL_UADDR_POS 0 140df482650SStephan Linz #define UAWL_UADDR_MASK (~0UL << UAWL_UADDR_POS) 141df482650SStephan Linz #define UAWU_UADDR_POS 0 142df482650SStephan Linz #define UAWU_UADDR_MASK (0xFFFF << UAWU_UADDR_POS) 143df482650SStephan Linz 144df482650SStephan Linz /* VLAN TPID Word 0, 1 Registers (tpid0, tpid1), [1] p37 */ 145df482650SStephan Linz #define TPID0_V0_POS 0 146df482650SStephan Linz #define TPID0_V0_MASK (0xFFFF << TPID0_V0_POS) 147df482650SStephan Linz #define TPID0_V1_POS 16 148df482650SStephan Linz #define TPID0_V1_MASK (0xFFFF << TPID0_V1_POS) 149df482650SStephan Linz #define TPID1_V2_POS 0 150df482650SStephan Linz #define TPID1_V2_MASK (0xFFFF << TPID1_V2_POS) 151df482650SStephan Linz #define TPID1_V3_POS 16 152df482650SStephan Linz #define TPID1_V3_MASK (0xFFFF << TPID1_V3_POS) 153df482650SStephan Linz 154df482650SStephan Linz /* 155df482650SStephan Linz * TEMAC Indirectly Addressable Register Index Enumeration 156df482650SStephan Linz * 157df482650SStephan Linz * [0]: http://www.xilinx.com/support/documentation 158df482650SStephan Linz * 159df482650SStephan Linz * [1]: [0]/ip_documentation/xps_ll_temac.pdf 160df482650SStephan Linz * page 23, PLB Indirectly Addressable TEMAC Registers 161df482650SStephan Linz */ 162df482650SStephan Linz enum temac_ctrl { 163df482650SStephan Linz TEMAC_RCW0 = 0x200, 164df482650SStephan Linz TEMAC_RCW1 = 0x240, 165df482650SStephan Linz TEMAC_TC = 0x280, 166df482650SStephan Linz TEMAC_FCC = 0x2C0, 167df482650SStephan Linz TEMAC_EMMC = 0x300, 168df482650SStephan Linz TEMAC_PHYC = 0x320, 169df482650SStephan Linz TEMAC_MC = 0x340, 170df482650SStephan Linz TEMAC_UAW0 = 0x380, 171df482650SStephan Linz TEMAC_UAW1 = 0x384, 172df482650SStephan Linz TEMAC_MAW0 = 0x388, 173df482650SStephan Linz TEMAC_MAW1 = 0x38C, 174df482650SStephan Linz TEMAC_AFM = 0x390, 175df482650SStephan Linz TEMAC_TIS = 0x3A0, 176df482650SStephan Linz TEMAC_TIE = 0x3A4, 177df482650SStephan Linz TEMAC_MIIMWD = 0x3B0, 178df482650SStephan Linz TEMAC_MIIMAI = 0x3B4 179df482650SStephan Linz }; 180df482650SStephan Linz 181df482650SStephan Linz /* Receive Configuration Word 0, 1 Registers (RCW0, RCW1), [1] p50-51 */ 182df482650SStephan Linz #define RCW0_PADDR_POS 0 183df482650SStephan Linz #define RCW0_PADDR_MASK (~0UL << RCW_PADDR_POS) 184df482650SStephan Linz #define RCW1_RST (1 << 31) 185df482650SStephan Linz #define RCW1_JUM (1 << 30) 186df482650SStephan Linz #define RCW1_FCS (1 << 29) 187df482650SStephan Linz #define RCW1_RX (1 << 28) 188df482650SStephan Linz #define RCW1_VLAN (1 << 27) 189df482650SStephan Linz #define RCW1_HD (1 << 26) 190df482650SStephan Linz #define RCW1_LT_DIS (1 << 25) 191df482650SStephan Linz #define RCW1_PADDR_POS 0 192df482650SStephan Linz #define RCW1_PADDR_MASK (0xFFFF << RCW_PADDR_POS) 193df482650SStephan Linz 194df482650SStephan Linz /* Transmit Configuration Registers (TC), [1] p52 */ 195df482650SStephan Linz #define TC_RST (1 << 31) 196df482650SStephan Linz #define TC_JUM (1 << 30) 197df482650SStephan Linz #define TC_FCS (1 << 29) 198df482650SStephan Linz #define TC_TX (1 << 28) 199df482650SStephan Linz #define TC_VLAN (1 << 27) 200df482650SStephan Linz #define TC_HD (1 << 26) 201df482650SStephan Linz #define TC_IFG (1 << 25) 202df482650SStephan Linz 203df482650SStephan Linz /* Flow Control Configuration Registers (FCC), [1] p54 */ 204df482650SStephan Linz #define FCC_FCTX (1 << 30) 205df482650SStephan Linz #define FCC_FCRX (1 << 29) 206df482650SStephan Linz 207df482650SStephan Linz /* Ethernet MAC Mode Configuration Registers (EMMC), [1] p54 */ 208df482650SStephan Linz #define EMMC_LSPD_POS 30 209df482650SStephan Linz #define EMMC_LSPD_MASK (3 << EMMC_LSPD_POS) 210df482650SStephan Linz #define EMMC_LSPD_1000 (2 << EMMC_LSPD_POS) 211df482650SStephan Linz #define EMMC_LSPD_100 (1 << EMMC_LSPD_POS) 212df482650SStephan Linz #define EMMC_LSPD_10 0 213df482650SStephan Linz #define EMMC_RGMII (1 << 29) 214df482650SStephan Linz #define EMMC_SGMII (1 << 28) 215df482650SStephan Linz #define EMMC_GPCS (1 << 27) 216df482650SStephan Linz #define EMMC_HOST (1 << 26) 217df482650SStephan Linz #define EMMC_TX16 (1 << 25) 218df482650SStephan Linz #define EMMC_RX16 (1 << 24) 219df482650SStephan Linz 220df482650SStephan Linz /* RGMII/SGMII Configuration Registers (PHYC), [1] p56 */ 221df482650SStephan Linz #define PHYC_SLSPD_POS 30 222df482650SStephan Linz #define PHYC_SLSPD_MASK (3 << EMMC_SLSPD_POS) 223df482650SStephan Linz #define PHYC_SLSPD_1000 (2 << EMMC_SLSPD_POS) 224df482650SStephan Linz #define PHYC_SLSPD_100 (1 << EMMC_SLSPD_POS) 225df482650SStephan Linz #define PHYC_SLSPD_10 0 226df482650SStephan Linz #define PHYC_RLSPD_POS 2 227df482650SStephan Linz #define PHYC_RLSPD_MASK (3 << EMMC_RLSPD_POS) 228df482650SStephan Linz #define PHYC_RLSPD_1000 (2 << EMMC_RLSPD_POS) 229df482650SStephan Linz #define PHYC_RLSPD_100 (1 << EMMC_RLSPD_POS) 230df482650SStephan Linz #define PHYC_RLSPD_10 0 231df482650SStephan Linz #define PHYC_RGMII_HD (1 << 1) 232df482650SStephan Linz #define PHYC_RGMII_LINK (1 << 0) 233df482650SStephan Linz 234df482650SStephan Linz /* Management Configuration Registers (MC), [1] p57 */ 235df482650SStephan Linz #define MC_MDIOEN (1 << 6) 236df482650SStephan Linz #define MC_CLKDIV_POS 0 237df482650SStephan Linz #define MC_CLKDIV_MASK (0x3F << MC_CLKDIV_POS) 238df482650SStephan Linz 239df482650SStephan Linz /* 240df482650SStephan Linz * fHOSTCLK fMDC = fHOSTCLK 241df482650SStephan Linz * fMDC = ------------------- ---------> MC_CLKDIV = -------- - 1 242df482650SStephan Linz * (1 + MC_CLKDIV) * 2 2.5 MHz 5MHz 243df482650SStephan Linz */ 244df482650SStephan Linz #define MC_CLKDIV(f, m) ((f / (2 * m)) - 1) 245df482650SStephan Linz #define MC_CLKDIV_25(f) MC_CLKDIV(f, 2500000) 246df482650SStephan Linz #define MC_CLKDIV_20(f) MC_CLKDIV(f, 2000000) 247df482650SStephan Linz #define MC_CLKDIV_15(f) MC_CLKDIV(f, 1500000) 248df482650SStephan Linz #define MC_CLKDIV_10(f) MC_CLKDIV(f, 1000000) 249df482650SStephan Linz 250df482650SStephan Linz /* Unicast Address Word 0, 1 Registers (UAW0, UAW1), [1] p58-59 */ 251df482650SStephan Linz #define UAW0_UADDR_POS 0 252df482650SStephan Linz #define UAW0_UADDR_MASK (~0UL << UAW0_UADDR_POS) 253df482650SStephan Linz #define UAW1_UADDR_POS 0 254df482650SStephan Linz #define UAW1_UADDR_MASK (0xFFFF << UAW1_UADDR_POS) 255df482650SStephan Linz 256df482650SStephan Linz /* Multicast Address Word 0, 1 Registers (MAW0, MAW1), [1] p60 */ 257df482650SStephan Linz #define MAW0_MADDR_POS 0 258df482650SStephan Linz #define MAW0_MADDR_MASK (~0UL << MAW0_MADDR_POS) 259df482650SStephan Linz #define MAW1_RNW (1 << 23) 260df482650SStephan Linz #define MAW1_MAIDX_POS 16 261df482650SStephan Linz #define MAW1_MAIDX_MASK (3 << MAW1_MAIDX_POS) 262df482650SStephan Linz #define MAW1_MADDR_POS 0 263df482650SStephan Linz #define MAW1_MADDR_MASK (0xFFFF << MAW1_MADDR_POS) 264df482650SStephan Linz 265df482650SStephan Linz /* Address Filter Mode Registers (AFM), [1] p63 */ 266df482650SStephan Linz #define AFM_PM (1 << 31) 267df482650SStephan Linz 268df482650SStephan Linz /* Interrupt Status, Enable Registers (TIS, TIE), [1] p63-65 */ 269df482650SStephan Linz #define TISE_CFG_W (1 << 6) 270df482650SStephan Linz #define TISE_CFG_R (1 << 5) 271df482650SStephan Linz #define TISE_AF_W (1 << 4) 272df482650SStephan Linz #define TISE_AF_R (1 << 3) 273df482650SStephan Linz #define TISE_MIIM_W (1 << 2) 274df482650SStephan Linz #define TISE_MIIM_R (1 << 1) 275df482650SStephan Linz #define TISE_FABR_R (1 << 0) 276df482650SStephan Linz 277df482650SStephan Linz /* MII Management Write Data Registers (MIIMWD), [1] p66 */ 278df482650SStephan Linz #define MIIMWD_DATA_POS 0 279df482650SStephan Linz #define MIIMWD_DATA_MASK (0xFFFF << MIIMWD_DATA_POS) 280df482650SStephan Linz 281df482650SStephan Linz /* Ethernet interface ready status */ 282df482650SStephan Linz int ll_temac_check_status(struct temac_reg *regs, u32 mask); 283df482650SStephan Linz 284df482650SStephan Linz /* Indirect write to ll_temac. */ 285df482650SStephan Linz int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data); 286df482650SStephan Linz 287df482650SStephan Linz /* Indirect read from ll_temac. */ 288df482650SStephan Linz int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data); 289df482650SStephan Linz 290df482650SStephan Linz struct ll_temac { 291df482650SStephan Linz phys_addr_t ctrladdr; 292df482650SStephan Linz phys_addr_t sdma_reg_addr[SDMA_CTRL_REGNUMS]; 293df482650SStephan Linz 294df482650SStephan Linz unsigned (*in32)(phys_addr_t); 295df482650SStephan Linz void (*out32)(phys_addr_t, unsigned); 296df482650SStephan Linz 297df482650SStephan Linz int (*ctrlinit) (struct eth_device *); 298df482650SStephan Linz int (*ctrlhalt) (struct eth_device *); 299df482650SStephan Linz int (*ctrlreset) (struct eth_device *); 300df482650SStephan Linz 301df482650SStephan Linz int phyaddr; 302df482650SStephan Linz struct phy_device *phydev; 303df482650SStephan Linz struct mii_dev *bus; 304df482650SStephan Linz char mdio_busname[MDIO_NAME_LEN]; 305df482650SStephan Linz }; 306df482650SStephan Linz 307df482650SStephan Linz #endif /* _XILINX_LL_TEMAC_ */ 308