1 /* 2 * Copyright 2009-2011 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <asm/types.h> 9 #include <asm/io.h> 10 #include <fsl_dtsec.h> 11 #include <fsl_mdio.h> 12 #include <phy.h> 13 14 #include "fm.h" 15 16 #define RCTRL_INIT (RCTRL_GRS | RCTRL_UPROM) 17 #define TCTRL_INIT TCTRL_GTS 18 #define MACCFG1_INIT MACCFG1_SOFT_RST 19 20 #define MACCFG2_INIT (MACCFG2_PRE_LEN(0x7) | MACCFG2_LEN_CHECK | \ 21 MACCFG2_PAD_CRC | MACCFG2_FULL_DUPLEX | \ 22 MACCFG2_IF_MODE_NIBBLE) 23 24 /* MAXFRM - maximum frame length register */ 25 #define MAXFRM_MASK 0x00003fff 26 27 static void dtsec_init_mac(struct fsl_enet_mac *mac) 28 { 29 struct dtsec *regs = mac->base; 30 31 /* soft reset */ 32 out_be32(®s->maccfg1, MACCFG1_SOFT_RST); 33 udelay(1000); 34 35 /* clear soft reset, Rx/Tx MAC disable */ 36 out_be32(®s->maccfg1, 0); 37 38 /* graceful stop rx */ 39 out_be32(®s->rctrl, RCTRL_INIT); 40 udelay(1000); 41 42 /* graceful stop tx */ 43 out_be32(®s->tctrl, TCTRL_INIT); 44 udelay(1000); 45 46 /* disable all interrupts */ 47 out_be32(®s->imask, IMASK_MASK_ALL); 48 49 /* clear all events */ 50 out_be32(®s->ievent, IEVENT_CLEAR_ALL); 51 52 /* set the max Rx length */ 53 out_be32(®s->maxfrm, mac->max_rx_len & MAXFRM_MASK); 54 55 /* set the ecntrl to reset value */ 56 out_be32(®s->ecntrl, ECNTRL_DEFAULT); 57 58 /* 59 * Rx length check, no strip CRC for Rx, pad and append CRC for Tx, 60 * full duplex 61 */ 62 out_be32(®s->maccfg2, MACCFG2_INIT); 63 } 64 65 static void dtsec_enable_mac(struct fsl_enet_mac *mac) 66 { 67 struct dtsec *regs = mac->base; 68 69 /* enable Rx/Tx MAC */ 70 setbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); 71 72 /* clear the graceful Rx stop */ 73 clrbits_be32(®s->rctrl, RCTRL_GRS); 74 75 /* clear the graceful Tx stop */ 76 clrbits_be32(®s->tctrl, TCTRL_GTS); 77 } 78 79 static void dtsec_disable_mac(struct fsl_enet_mac *mac) 80 { 81 struct dtsec *regs = mac->base; 82 83 /* graceful Rx stop */ 84 setbits_be32(®s->rctrl, RCTRL_GRS); 85 86 /* graceful Tx stop */ 87 setbits_be32(®s->tctrl, TCTRL_GTS); 88 89 /* disable Rx/Tx MAC */ 90 clrbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); 91 } 92 93 static void dtsec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr) 94 { 95 struct dtsec *regs = mac->base; 96 u32 mac_addr1, mac_addr2; 97 98 /* 99 * if a station address of 0x12345678ABCD, perform a write to 100 * MACSTNADDR1 of 0xCDAB7856, MACSTNADDR2 of 0x34120000 101 */ 102 mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \ 103 (mac_addr[3] << 8) | (mac_addr[2]); 104 out_be32(®s->macstnaddr1, mac_addr1); 105 106 mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000; 107 out_be32(®s->macstnaddr2, mac_addr2); 108 } 109 110 static void dtsec_set_interface_mode(struct fsl_enet_mac *mac, 111 phy_interface_t type, int speed) 112 { 113 struct dtsec *regs = mac->base; 114 u32 ecntrl, maccfg2; 115 116 /* clear all bits relative with interface mode */ 117 ecntrl = in_be32(®s->ecntrl); 118 ecntrl &= ~(ECNTRL_TBIM | ECNTRL_GMIIM | ECNTRL_RPM | 119 ECNTRL_R100M | ECNTRL_SGMIIM); 120 121 maccfg2 = in_be32(®s->maccfg2); 122 maccfg2 &= ~MACCFG2_IF_MODE_MASK; 123 124 if (speed == SPEED_1000) 125 maccfg2 |= MACCFG2_IF_MODE_BYTE; 126 else 127 maccfg2 |= MACCFG2_IF_MODE_NIBBLE; 128 129 /* set interface mode */ 130 switch (type) { 131 case PHY_INTERFACE_MODE_GMII: 132 ecntrl |= ECNTRL_GMIIM; 133 break; 134 case PHY_INTERFACE_MODE_RGMII: 135 ecntrl |= (ECNTRL_GMIIM | ECNTRL_RPM); 136 if (speed == SPEED_100) 137 ecntrl |= ECNTRL_R100M; 138 break; 139 case PHY_INTERFACE_MODE_RMII: 140 if (speed == SPEED_100) 141 ecntrl |= ECNTRL_R100M; 142 break; 143 case PHY_INTERFACE_MODE_SGMII: 144 ecntrl |= (ECNTRL_SGMIIM | ECNTRL_TBIM); 145 if (speed == SPEED_100) 146 ecntrl |= ECNTRL_R100M; 147 break; 148 default: 149 break; 150 } 151 152 out_be32(®s->ecntrl, ecntrl); 153 out_be32(®s->maccfg2, maccfg2); 154 } 155 156 void init_dtsec(struct fsl_enet_mac *mac, void *base, 157 void *phyregs, int max_rx_len) 158 { 159 mac->base = base; 160 mac->phyregs = phyregs; 161 mac->max_rx_len = max_rx_len; 162 mac->init_mac = dtsec_init_mac; 163 mac->enable_mac = dtsec_enable_mac; 164 mac->disable_mac = dtsec_disable_mac; 165 mac->set_mac_addr = dtsec_set_mac_addr; 166 mac->set_if_mode = dtsec_set_interface_mode; 167 } 168