xref: /openbmc/u-boot/drivers/net/pfe_eth/pfe_eth.c (revision 704744f8)
1 /*
2  * Copyright 2015-2016 Freescale Semiconductor, Inc.
3  * Copyright 2017 NXP
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <dm/platform_data/pfe_dm_eth.h>
11 #include <net.h>
12 #include <net/pfe_eth/pfe_eth.h>
13 #include <net/pfe_eth/pfe_mdio.h>
14 
15 struct gemac_s gem_info[] = {
16 	/* PORT_0 configuration */
17 	{
18 		/* GEMAC config */
19 		.gemac_speed = PFE_MAC_SPEED_1000M,
20 		.gemac_duplex = DUPLEX_FULL,
21 
22 		/* phy iface */
23 		.phy_address = CONFIG_PFE_EMAC1_PHY_ADDR,
24 		.phy_mode = PHY_INTERFACE_MODE_SGMII,
25 	},
26 	/* PORT_1 configuration */
27 	{
28 		/* GEMAC config */
29 		.gemac_speed = PFE_MAC_SPEED_1000M,
30 		.gemac_duplex = DUPLEX_FULL,
31 
32 		/* phy iface */
33 		.phy_address = CONFIG_PFE_EMAC2_PHY_ADDR,
34 		.phy_mode = PHY_INTERFACE_MODE_RGMII_TXID,
35 	},
36 };
37 
38 static inline void pfe_gemac_enable(void *gemac_base)
39 {
40 	writel(readl(gemac_base + EMAC_ECNTRL_REG) |
41 		EMAC_ECNTRL_ETHER_EN, gemac_base + EMAC_ECNTRL_REG);
42 }
43 
44 static inline void pfe_gemac_disable(void *gemac_base)
45 {
46 	writel(readl(gemac_base + EMAC_ECNTRL_REG) &
47 		~EMAC_ECNTRL_ETHER_EN, gemac_base + EMAC_ECNTRL_REG);
48 }
49 
50 static inline void pfe_gemac_set_speed(void *gemac_base, u32 speed)
51 {
52 	struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
53 	u32 ecr = readl(gemac_base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
54 	u32 rcr = readl(gemac_base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
55 	u32 rgmii_pcr = in_be32(&scfg->rgmiipcr) &
56 			~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M);
57 
58 	if (speed == _1000BASET) {
59 		ecr |= EMAC_ECNTRL_SPEED;
60 		rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M;
61 	} else if (speed != _100BASET) {
62 		rcr |= EMAC_RCNTRL_RMII_10T;
63 		rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M;
64 	}
65 
66 	writel(ecr, gemac_base + EMAC_ECNTRL_REG);
67 	out_be32(&scfg->rgmiipcr, rgmii_pcr | SCFG_RGMIIPCR_SETFD);
68 
69 	/* remove loop back */
70 	rcr &= ~EMAC_RCNTRL_LOOP;
71 	/* enable flow control */
72 	rcr |= EMAC_RCNTRL_FCE;
73 
74 	/* Enable MII mode */
75 	rcr |= EMAC_RCNTRL_MII_MODE;
76 
77 	writel(rcr, gemac_base + EMAC_RCNTRL_REG);
78 
79 	/* Enable Tx full duplex */
80 	writel(readl(gemac_base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN,
81 	       gemac_base + EMAC_TCNTRL_REG);
82 }
83 
84 static int pfe_eth_write_hwaddr(struct udevice *dev)
85 {
86 	struct pfe_eth_dev *priv = dev_get_priv(dev);
87 	struct gemac_s *gem = priv->gem;
88 	struct eth_pdata *pdata = dev_get_platdata(dev);
89 	uchar *mac = pdata->enetaddr;
90 
91 	writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],
92 	       gem->gemac_base + EMAC_PHY_ADDR_LOW);
93 	writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, gem->gemac_base +
94 	       EMAC_PHY_ADDR_HIGH);
95 	return 0;
96 }
97 
98 /** Stops or Disables GEMAC pointing to this eth iface.
99  *
100  * @param[in]   edev    Pointer to eth device structure.
101  *
102  * @return      none
103  */
104 static inline void pfe_eth_stop(struct udevice *dev)
105 {
106 	struct pfe_eth_dev *priv = dev_get_priv(dev);
107 
108 	pfe_gemac_disable(priv->gem->gemac_base);
109 
110 	gpi_disable(priv->gem->egpi_base);
111 }
112 
113 static int pfe_eth_start(struct udevice *dev)
114 {
115 	struct pfe_eth_dev *priv = dev_get_priv(dev);
116 	struct gemac_s *gem = priv->gem;
117 	int speed;
118 
119 	/* set ethernet mac address */
120 	pfe_eth_write_hwaddr(dev);
121 
122 	writel(EMAC_TFWR, gem->gemac_base + EMAC_TFWR_STR_FWD);
123 	writel(EMAC_RX_SECTION_FULL_32, gem->gemac_base + EMAC_RX_SECTIOM_FULL);
124 	writel(EMAC_TRUNC_FL_16K, gem->gemac_base + EMAC_TRUNC_FL);
125 	writel(EMAC_TX_SECTION_EMPTY_30, gem->gemac_base
126 	       + EMAC_TX_SECTION_EMPTY);
127 	writel(EMAC_MIBC_NO_CLR_NO_DIS, gem->gemac_base
128 	       + EMAC_MIB_CTRL_STS_REG);
129 
130 #ifdef CONFIG_PHYLIB
131 	/* Start up the PHY */
132 	if (phy_startup(priv->phydev)) {
133 		printf("Could not initialize PHY %s\n",
134 		       priv->phydev->dev->name);
135 		return -1;
136 	}
137 	speed = priv->phydev->speed;
138 	printf("Speed detected %x\n", speed);
139 	if (priv->phydev->duplex == DUPLEX_HALF) {
140 		printf("Half duplex not supported\n");
141 		return -1;
142 	}
143 #endif
144 
145 	pfe_gemac_set_speed(gem->gemac_base, speed);
146 
147 	/* Enable GPI */
148 	gpi_enable(gem->egpi_base);
149 
150 	/* Enable GEMAC */
151 	pfe_gemac_enable(gem->gemac_base);
152 
153 	return 0;
154 }
155 
156 static int pfe_eth_send(struct udevice *dev, void *packet, int length)
157 {
158 	struct pfe_eth_dev *priv = (struct pfe_eth_dev *)dev->priv;
159 
160 	int rc;
161 	int i = 0;
162 
163 	rc = pfe_send(priv->gemac_port, packet, length);
164 
165 	if (rc < 0) {
166 		printf("Tx Queue full\n");
167 		return rc;
168 	}
169 
170 	while (1) {
171 		rc = pfe_tx_done();
172 		if (rc == 0)
173 			break;
174 
175 		udelay(100);
176 		i++;
177 		if (i == 30000)
178 			printf("Tx timeout, send failed\n");
179 		break;
180 	}
181 
182 	return 0;
183 }
184 
185 static int pfe_eth_recv(struct udevice *dev, int flags, uchar **packetp)
186 {
187 	struct pfe_eth_dev *priv = dev_get_priv(dev);
188 	uchar *pkt_buf;
189 	int len;
190 	int phy_port;
191 
192 	len = pfe_recv(&pkt_buf, &phy_port);
193 
194 	if (len == 0)
195 		return -EAGAIN; /* no packet in rx */
196 	else if  (len < 0)
197 		return -EAGAIN;
198 
199 	debug("Rx pkt: pkt_buf(0x%p), phy_port(%d), len(%d)\n", pkt_buf,
200 	      phy_port, len);
201 	if (phy_port != priv->gemac_port)  {
202 		printf("Rx pkt not on expected port\n");
203 		return -EAGAIN;
204 	}
205 
206 	*packetp = pkt_buf;
207 
208 	return len;
209 }
210 
211 static int pfe_eth_probe(struct udevice *dev)
212 {
213 	struct pfe_eth_dev *priv = dev_get_priv(dev);
214 	struct pfe_ddr_address *pfe_addr;
215 	struct pfe_eth_pdata *pdata = dev_get_platdata(dev);
216 	int ret = 0;
217 	static int init_done;
218 
219 	if (!init_done) {
220 		pfe_addr = (struct pfe_ddr_address *)malloc(sizeof
221 						    (struct pfe_ddr_address));
222 		if (!pfe_addr)
223 			return -ENOMEM;
224 
225 		pfe_addr->ddr_pfe_baseaddr =
226 				(void *)pdata->pfe_ddr_addr.ddr_pfe_baseaddr;
227 		pfe_addr->ddr_pfe_phys_baseaddr =
228 		(unsigned long)pdata->pfe_ddr_addr.ddr_pfe_phys_baseaddr;
229 
230 		debug("ddr_pfe_baseaddr: %p, ddr_pfe_phys_baseaddr: %08x\n",
231 		      pfe_addr->ddr_pfe_baseaddr,
232 		      (u32)pfe_addr->ddr_pfe_phys_baseaddr);
233 
234 		ret = pfe_drv_init(pfe_addr);
235 		if (ret)
236 			return ret;
237 
238 		init_pfe_scfg_dcfg_regs();
239 		init_done = 1;
240 	}
241 
242 	priv->gemac_port = pdata->pfe_eth_pdata_mac.phy_interface;
243 	priv->gem = &gem_info[priv->gemac_port];
244 	priv->dev = dev;
245 
246 	switch (priv->gemac_port)  {
247 	case EMAC_PORT_0:
248 	default:
249 		priv->gem->gemac_base = EMAC1_BASE_ADDR;
250 		priv->gem->egpi_base = EGPI1_BASE_ADDR;
251 		break;
252 	case EMAC_PORT_1:
253 		priv->gem->gemac_base = EMAC2_BASE_ADDR;
254 		priv->gem->egpi_base = EGPI2_BASE_ADDR;
255 		break;
256 	}
257 
258 	ret = pfe_eth_board_init(dev);
259 	if (ret)
260 		return ret;
261 
262 #if defined(CONFIG_PHYLIB)
263 	ret = pfe_phy_configure(priv, pdata->pfe_eth_pdata_mac.phy_interface,
264 				gem_info[priv->gemac_port].phy_address);
265 #endif
266 	return ret;
267 }
268 
269 static int pfe_eth_bind(struct udevice *dev)
270 {
271 	struct pfe_eth_pdata *pdata = dev_get_platdata(dev);
272 	char name[20];
273 
274 	sprintf(name, "pfe_eth%u", pdata->pfe_eth_pdata_mac.phy_interface);
275 
276 	return device_set_name(dev, name);
277 }
278 
279 static const struct eth_ops pfe_eth_ops = {
280 	.start		= pfe_eth_start,
281 	.send		= pfe_eth_send,
282 	.recv		= pfe_eth_recv,
283 	.free_pkt	= pfe_eth_free_pkt,
284 	.stop		= pfe_eth_stop,
285 	.write_hwaddr	= pfe_eth_write_hwaddr,
286 };
287 
288 U_BOOT_DRIVER(pfe_eth) = {
289 	.name	= "pfe_eth",
290 	.id	= UCLASS_ETH,
291 	.bind	= pfe_eth_bind,
292 	.probe	= pfe_eth_probe,
293 	.remove = pfe_eth_remove,
294 	.ops	= &pfe_eth_ops,
295 	.priv_auto_alloc_size = sizeof(struct pfe_eth_dev),
296 	.platdata_auto_alloc_size = sizeof(struct pfe_eth_pdata)
297 };
298