]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
c916d7c9 KG |
2 | /* |
3 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | |
c916d7c9 KG |
4 | */ |
5 | ||
d678a59d | 6 | #include <common.h> |
c916d7c9 KG |
7 | #include <asm/types.h> |
8 | #include <asm/io.h> | |
8225b2fd | 9 | #include <fsl_dtsec.h> |
c916d7c9 KG |
10 | #include <fsl_mdio.h> |
11 | #include <phy.h> | |
c05ed00a | 12 | #include <linux/delay.h> |
c916d7c9 KG |
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; | |
30381716 | 160 | mac->phyregs = phyregs; |
c916d7c9 KG |
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 | } |