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