1 /* 2 * Copyright 2009-2011 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17 * MA 02111-1307 USA 18 */ 19 20 #include <common.h> 21 #include <asm/types.h> 22 #include <asm/io.h> 23 #include <asm/fsl_enet.h> 24 #include <asm/fsl_dtsec.h> 25 #include <fsl_mdio.h> 26 #include <phy.h> 27 28 #include "fm.h" 29 30 #define RCTRL_INIT (RCTRL_GRS | RCTRL_UPROM) 31 #define TCTRL_INIT TCTRL_GTS 32 #define MACCFG1_INIT MACCFG1_SOFT_RST 33 34 #define MACCFG2_INIT (MACCFG2_PRE_LEN(0x7) | MACCFG2_LEN_CHECK | \ 35 MACCFG2_PAD_CRC | MACCFG2_FULL_DUPLEX | \ 36 MACCFG2_IF_MODE_NIBBLE) 37 38 /* MAXFRM - maximum frame length register */ 39 #define MAXFRM_MASK 0x00003fff 40 41 static void dtsec_init_mac(struct fsl_enet_mac *mac) 42 { 43 struct dtsec *regs = mac->base; 44 45 /* soft reset */ 46 out_be32(®s->maccfg1, MACCFG1_SOFT_RST); 47 udelay(1000); 48 49 /* clear soft reset, Rx/Tx MAC disable */ 50 out_be32(®s->maccfg1, 0); 51 52 /* graceful stop rx */ 53 out_be32(®s->rctrl, RCTRL_INIT); 54 udelay(1000); 55 56 /* graceful stop tx */ 57 out_be32(®s->tctrl, TCTRL_INIT); 58 udelay(1000); 59 60 /* disable all interrupts */ 61 out_be32(®s->imask, IMASK_MASK_ALL); 62 63 /* clear all events */ 64 out_be32(®s->ievent, IEVENT_CLEAR_ALL); 65 66 /* set the max Rx length */ 67 out_be32(®s->maxfrm, mac->max_rx_len & MAXFRM_MASK); 68 69 /* set the ecntrl to reset value */ 70 out_be32(®s->ecntrl, ECNTRL_DEFAULT); 71 72 /* 73 * Rx length check, no strip CRC for Rx, pad and append CRC for Tx, 74 * full duplex 75 */ 76 out_be32(®s->maccfg2, MACCFG2_INIT); 77 } 78 79 static void dtsec_enable_mac(struct fsl_enet_mac *mac) 80 { 81 struct dtsec *regs = mac->base; 82 83 /* enable Rx/Tx MAC */ 84 setbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); 85 86 /* clear the graceful Rx stop */ 87 clrbits_be32(®s->rctrl, RCTRL_GRS); 88 89 /* clear the graceful Tx stop */ 90 clrbits_be32(®s->tctrl, TCTRL_GTS); 91 } 92 93 static void dtsec_disable_mac(struct fsl_enet_mac *mac) 94 { 95 struct dtsec *regs = mac->base; 96 97 /* graceful Rx stop */ 98 setbits_be32(®s->rctrl, RCTRL_GRS); 99 100 /* graceful Tx stop */ 101 setbits_be32(®s->tctrl, TCTRL_GTS); 102 103 /* disable Rx/Tx MAC */ 104 clrbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); 105 } 106 107 static void dtsec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr) 108 { 109 struct dtsec *regs = mac->base; 110 u32 mac_addr1, mac_addr2; 111 112 /* 113 * if a station address of 0x12345678ABCD, perform a write to 114 * MACSTNADDR1 of 0xCDAB7856, MACSTNADDR2 of 0x34120000 115 */ 116 mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \ 117 (mac_addr[3] << 8) | (mac_addr[2]); 118 out_be32(®s->macstnaddr1, mac_addr1); 119 120 mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000; 121 out_be32(®s->macstnaddr2, mac_addr2); 122 } 123 124 static void dtsec_set_interface_mode(struct fsl_enet_mac *mac, 125 phy_interface_t type, int speed) 126 { 127 struct dtsec *regs = mac->base; 128 u32 ecntrl, maccfg2; 129 130 /* clear all bits relative with interface mode */ 131 ecntrl = in_be32(®s->ecntrl); 132 ecntrl &= ~(ECNTRL_TBIM | ECNTRL_GMIIM | ECNTRL_RPM | 133 ECNTRL_R100M | ECNTRL_SGMIIM); 134 135 maccfg2 = in_be32(®s->maccfg2); 136 maccfg2 &= ~MACCFG2_IF_MODE_MASK; 137 138 if (speed == SPEED_1000) 139 maccfg2 |= MACCFG2_IF_MODE_BYTE; 140 else 141 maccfg2 |= MACCFG2_IF_MODE_NIBBLE; 142 143 /* set interface mode */ 144 switch (type) { 145 case PHY_INTERFACE_MODE_GMII: 146 ecntrl |= ECNTRL_GMIIM; 147 break; 148 case PHY_INTERFACE_MODE_RGMII: 149 ecntrl |= (ECNTRL_GMIIM | ECNTRL_RPM); 150 if (speed == SPEED_100) 151 ecntrl |= ECNTRL_R100M; 152 break; 153 case PHY_INTERFACE_MODE_RMII: 154 if (speed == SPEED_100) 155 ecntrl |= ECNTRL_R100M; 156 break; 157 case PHY_INTERFACE_MODE_SGMII: 158 ecntrl |= (ECNTRL_SGMIIM | ECNTRL_TBIM); 159 if (speed == SPEED_100) 160 ecntrl |= ECNTRL_R100M; 161 break; 162 default: 163 break; 164 } 165 166 out_be32(®s->ecntrl, ecntrl); 167 out_be32(®s->maccfg2, maccfg2); 168 } 169 170 void init_dtsec(struct fsl_enet_mac *mac, void *base, 171 void *phyregs, int max_rx_len) 172 { 173 mac->base = base; 174 mac->phyregs = phyregs; 175 mac->max_rx_len = max_rx_len; 176 mac->init_mac = dtsec_init_mac; 177 mac->enable_mac = dtsec_enable_mac; 178 mac->disable_mac = dtsec_disable_mac; 179 mac->set_mac_addr = dtsec_set_mac_addr; 180 mac->set_if_mode = dtsec_set_interface_mode; 181 } 182