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