1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Ethernet driver for TI K2HK EVM.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2012-2014
5*4882a593Smuzhiyun * Texas Instruments Incorporated, <www.ti.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun #include <common.h>
10*4882a593Smuzhiyun #include <command.h>
11*4882a593Smuzhiyun #include <console.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <dm.h>
14*4882a593Smuzhiyun #include <dm/lists.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <net.h>
17*4882a593Smuzhiyun #include <phy.h>
18*4882a593Smuzhiyun #include <errno.h>
19*4882a593Smuzhiyun #include <miiphy.h>
20*4882a593Smuzhiyun #include <malloc.h>
21*4882a593Smuzhiyun #include <asm/ti-common/keystone_nav.h>
22*4882a593Smuzhiyun #include <asm/ti-common/keystone_net.h>
23*4882a593Smuzhiyun #include <asm/ti-common/keystone_serdes.h>
24*4882a593Smuzhiyun #include <asm/arch/psc_defs.h>
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #ifndef CONFIG_DM_ETH
29*4882a593Smuzhiyun unsigned int emac_open;
30*4882a593Smuzhiyun static struct mii_dev *mdio_bus;
31*4882a593Smuzhiyun static unsigned int sys_has_mdio = 1;
32*4882a593Smuzhiyun #endif
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #ifdef KEYSTONE2_EMAC_GIG_ENABLE
35*4882a593Smuzhiyun #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
36*4882a593Smuzhiyun #else
37*4882a593Smuzhiyun #define emac_gigabit_enable(x) /* no gigabit to enable */
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define RX_BUFF_NUMS 24
41*4882a593Smuzhiyun #define RX_BUFF_LEN 1520
42*4882a593Smuzhiyun #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
43*4882a593Smuzhiyun #define SGMII_ANEG_TIMEOUT 4000
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun #ifndef CONFIG_DM_ETH
48*4882a593Smuzhiyun struct rx_buff_desc net_rx_buffs = {
49*4882a593Smuzhiyun .buff_ptr = rx_buffs,
50*4882a593Smuzhiyun .num_buffs = RX_BUFF_NUMS,
51*4882a593Smuzhiyun .buff_len = RX_BUFF_LEN,
52*4882a593Smuzhiyun .rx_flow = 22,
53*4882a593Smuzhiyun };
54*4882a593Smuzhiyun #endif
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #ifdef CONFIG_DM_ETH
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun enum link_type {
59*4882a593Smuzhiyun LINK_TYPE_SGMII_MAC_TO_MAC_AUTO = 0,
60*4882a593Smuzhiyun LINK_TYPE_SGMII_MAC_TO_PHY_MODE = 1,
61*4882a593Smuzhiyun LINK_TYPE_SGMII_MAC_TO_MAC_FORCED_MODE = 2,
62*4882a593Smuzhiyun LINK_TYPE_SGMII_MAC_TO_FIBRE_MODE = 3,
63*4882a593Smuzhiyun LINK_TYPE_SGMII_MAC_TO_PHY_NO_MDIO_MODE = 4,
64*4882a593Smuzhiyun LINK_TYPE_RGMII_LINK_MAC_PHY = 5,
65*4882a593Smuzhiyun LINK_TYPE_RGMII_LINK_MAC_MAC_FORCED = 6,
66*4882a593Smuzhiyun LINK_TYPE_RGMII_LINK_MAC_PHY_NO_MDIO = 7,
67*4882a593Smuzhiyun LINK_TYPE_10G_MAC_TO_PHY_MODE = 10,
68*4882a593Smuzhiyun LINK_TYPE_10G_MAC_TO_MAC_FORCED_MODE = 11,
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \
72*4882a593Smuzhiyun ((mac)[2] << 16) | ((mac)[3] << 24))
73*4882a593Smuzhiyun #define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8))
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #ifdef CONFIG_KSNET_NETCP_V1_0
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun #define EMAC_EMACSW_BASE_OFS 0x90800
78*4882a593Smuzhiyun #define EMAC_EMACSW_PORT_BASE_OFS (EMAC_EMACSW_BASE_OFS + 0x60)
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /* CPSW Switch slave registers */
81*4882a593Smuzhiyun #define CPGMACSL_REG_SA_LO 0x10
82*4882a593Smuzhiyun #define CPGMACSL_REG_SA_HI 0x14
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun #define DEVICE_EMACSW_BASE(base, x) ((base) + EMAC_EMACSW_PORT_BASE_OFS + \
85*4882a593Smuzhiyun (x) * 0x30)
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #elif defined CONFIG_KSNET_NETCP_V1_5
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #define EMAC_EMACSW_PORT_BASE_OFS 0x222000
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* CPSW Switch slave registers */
92*4882a593Smuzhiyun #define CPGMACSL_REG_SA_LO 0x308
93*4882a593Smuzhiyun #define CPGMACSL_REG_SA_HI 0x30c
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #define DEVICE_EMACSW_BASE(base, x) ((base) + EMAC_EMACSW_PORT_BASE_OFS + \
96*4882a593Smuzhiyun (x) * 0x1000)
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun #endif
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun struct ks2_eth_priv {
102*4882a593Smuzhiyun struct udevice *dev;
103*4882a593Smuzhiyun struct phy_device *phydev;
104*4882a593Smuzhiyun struct mii_dev *mdio_bus;
105*4882a593Smuzhiyun int phy_addr;
106*4882a593Smuzhiyun phy_interface_t phy_if;
107*4882a593Smuzhiyun int sgmii_link_type;
108*4882a593Smuzhiyun void *mdio_base;
109*4882a593Smuzhiyun struct rx_buff_desc net_rx_buffs;
110*4882a593Smuzhiyun struct pktdma_cfg *netcp_pktdma;
111*4882a593Smuzhiyun void *hd;
112*4882a593Smuzhiyun int slave_port;
113*4882a593Smuzhiyun enum link_type link_type;
114*4882a593Smuzhiyun bool emac_open;
115*4882a593Smuzhiyun bool has_mdio;
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun #endif
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* MDIO */
120*4882a593Smuzhiyun
keystone2_mdio_reset(struct mii_dev * bus)121*4882a593Smuzhiyun static int keystone2_mdio_reset(struct mii_dev *bus)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun u_int32_t clkdiv;
124*4882a593Smuzhiyun struct mdio_regs *adap_mdio = bus->priv;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE |
129*4882a593Smuzhiyun MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE,
130*4882a593Smuzhiyun &adap_mdio->control);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
133*4882a593Smuzhiyun ;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun return 0;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /**
139*4882a593Smuzhiyun * keystone2_mdio_read - read a PHY register via MDIO interface.
140*4882a593Smuzhiyun * Blocks until operation is complete.
141*4882a593Smuzhiyun */
keystone2_mdio_read(struct mii_dev * bus,int addr,int devad,int reg)142*4882a593Smuzhiyun static int keystone2_mdio_read(struct mii_dev *bus,
143*4882a593Smuzhiyun int addr, int devad, int reg)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun int tmp;
146*4882a593Smuzhiyun struct mdio_regs *adap_mdio = bus->priv;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
149*4882a593Smuzhiyun ;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ |
152*4882a593Smuzhiyun ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16),
153*4882a593Smuzhiyun &adap_mdio->useraccess0);
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /* Wait for command to complete */
156*4882a593Smuzhiyun while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
157*4882a593Smuzhiyun ;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun if (tmp & MDIO_USERACCESS0_ACK)
160*4882a593Smuzhiyun return tmp & 0xffff;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun return -1;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /**
166*4882a593Smuzhiyun * keystone2_mdio_write - write to a PHY register via MDIO interface.
167*4882a593Smuzhiyun * Blocks until operation is complete.
168*4882a593Smuzhiyun */
keystone2_mdio_write(struct mii_dev * bus,int addr,int devad,int reg,u16 val)169*4882a593Smuzhiyun static int keystone2_mdio_write(struct mii_dev *bus,
170*4882a593Smuzhiyun int addr, int devad, int reg, u16 val)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun struct mdio_regs *adap_mdio = bus->priv;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
175*4882a593Smuzhiyun ;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE |
178*4882a593Smuzhiyun ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) |
179*4882a593Smuzhiyun (val & 0xffff), &adap_mdio->useraccess0);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /* Wait for command to complete */
182*4882a593Smuzhiyun while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
183*4882a593Smuzhiyun ;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun return 0;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun #ifndef CONFIG_DM_ETH
189*4882a593Smuzhiyun static void __attribute__((unused))
keystone2_eth_gigabit_enable(struct eth_device * dev)190*4882a593Smuzhiyun keystone2_eth_gigabit_enable(struct eth_device *dev)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun u_int16_t data;
193*4882a593Smuzhiyun struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (sys_has_mdio) {
196*4882a593Smuzhiyun data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr,
197*4882a593Smuzhiyun MDIO_DEVAD_NONE, 0);
198*4882a593Smuzhiyun /* speed selection MSB */
199*4882a593Smuzhiyun if (!(data & (1 << 6)))
200*4882a593Smuzhiyun return;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /*
204*4882a593Smuzhiyun * Check if link detected is giga-bit
205*4882a593Smuzhiyun * If Gigabit mode detected, enable gigbit in MAC
206*4882a593Smuzhiyun */
207*4882a593Smuzhiyun writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) +
208*4882a593Smuzhiyun CPGMACSL_REG_CTL) |
209*4882a593Smuzhiyun EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
210*4882a593Smuzhiyun DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun #else
213*4882a593Smuzhiyun static void __attribute__((unused))
keystone2_eth_gigabit_enable(struct udevice * dev)214*4882a593Smuzhiyun keystone2_eth_gigabit_enable(struct udevice *dev)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
217*4882a593Smuzhiyun u_int16_t data;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun if (priv->has_mdio) {
220*4882a593Smuzhiyun data = keystone2_mdio_read(priv->mdio_bus, priv->phy_addr,
221*4882a593Smuzhiyun MDIO_DEVAD_NONE, 0);
222*4882a593Smuzhiyun /* speed selection MSB */
223*4882a593Smuzhiyun if (!(data & (1 << 6)))
224*4882a593Smuzhiyun return;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /*
228*4882a593Smuzhiyun * Check if link detected is giga-bit
229*4882a593Smuzhiyun * If Gigabit mode detected, enable gigbit in MAC
230*4882a593Smuzhiyun */
231*4882a593Smuzhiyun writel(readl(DEVICE_EMACSL_BASE(priv->slave_port - 1) +
232*4882a593Smuzhiyun CPGMACSL_REG_CTL) |
233*4882a593Smuzhiyun EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
234*4882a593Smuzhiyun DEVICE_EMACSL_BASE(priv->slave_port - 1) + CPGMACSL_REG_CTL);
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun #endif
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun #ifdef CONFIG_SOC_K2G
keystone_rgmii_config(struct phy_device * phy_dev)239*4882a593Smuzhiyun int keystone_rgmii_config(struct phy_device *phy_dev)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun unsigned int i, status;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun i = 0;
244*4882a593Smuzhiyun do {
245*4882a593Smuzhiyun if (i > SGMII_ANEG_TIMEOUT) {
246*4882a593Smuzhiyun puts(" TIMEOUT !\n");
247*4882a593Smuzhiyun phy_dev->link = 0;
248*4882a593Smuzhiyun return 0;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun if (ctrlc()) {
252*4882a593Smuzhiyun puts("user interrupt!\n");
253*4882a593Smuzhiyun phy_dev->link = 0;
254*4882a593Smuzhiyun return -EINTR;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun if ((i++ % 500) == 0)
258*4882a593Smuzhiyun printf(".");
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun udelay(1000); /* 1 ms */
261*4882a593Smuzhiyun status = readl(RGMII_STATUS_REG);
262*4882a593Smuzhiyun } while (!(status & RGMII_REG_STATUS_LINK));
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun puts(" done\n");
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun return 0;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun #else
keystone_sgmii_config(struct phy_device * phy_dev,int port,int interface)269*4882a593Smuzhiyun int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun unsigned int i, status, mask;
272*4882a593Smuzhiyun unsigned int mr_adv_ability, control;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun switch (interface) {
275*4882a593Smuzhiyun case SGMII_LINK_MAC_MAC_AUTONEG:
276*4882a593Smuzhiyun mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
277*4882a593Smuzhiyun SGMII_REG_MR_ADV_LINK |
278*4882a593Smuzhiyun SGMII_REG_MR_ADV_FULL_DUPLEX |
279*4882a593Smuzhiyun SGMII_REG_MR_ADV_GIG_MODE);
280*4882a593Smuzhiyun control = (SGMII_REG_CONTROL_MASTER |
281*4882a593Smuzhiyun SGMII_REG_CONTROL_AUTONEG);
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun break;
284*4882a593Smuzhiyun case SGMII_LINK_MAC_PHY:
285*4882a593Smuzhiyun case SGMII_LINK_MAC_PHY_FORCED:
286*4882a593Smuzhiyun mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
287*4882a593Smuzhiyun control = SGMII_REG_CONTROL_AUTONEG;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun break;
290*4882a593Smuzhiyun case SGMII_LINK_MAC_MAC_FORCED:
291*4882a593Smuzhiyun mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
292*4882a593Smuzhiyun SGMII_REG_MR_ADV_LINK |
293*4882a593Smuzhiyun SGMII_REG_MR_ADV_FULL_DUPLEX |
294*4882a593Smuzhiyun SGMII_REG_MR_ADV_GIG_MODE);
295*4882a593Smuzhiyun control = SGMII_REG_CONTROL_MASTER;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun break;
298*4882a593Smuzhiyun case SGMII_LINK_MAC_FIBER:
299*4882a593Smuzhiyun mr_adv_ability = 0x20;
300*4882a593Smuzhiyun control = SGMII_REG_CONTROL_AUTONEG;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun break;
303*4882a593Smuzhiyun default:
304*4882a593Smuzhiyun mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
305*4882a593Smuzhiyun control = SGMII_REG_CONTROL_AUTONEG;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun __raw_writel(0, SGMII_CTL_REG(port));
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /*
311*4882a593Smuzhiyun * Wait for the SerDes pll to lock,
312*4882a593Smuzhiyun * but don't trap if lock is never read
313*4882a593Smuzhiyun */
314*4882a593Smuzhiyun for (i = 0; i < 1000; i++) {
315*4882a593Smuzhiyun udelay(2000);
316*4882a593Smuzhiyun status = __raw_readl(SGMII_STATUS_REG(port));
317*4882a593Smuzhiyun if ((status & SGMII_REG_STATUS_LOCK) != 0)
318*4882a593Smuzhiyun break;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
322*4882a593Smuzhiyun __raw_writel(control, SGMII_CTL_REG(port));
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun mask = SGMII_REG_STATUS_LINK;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (control & SGMII_REG_CONTROL_AUTONEG)
328*4882a593Smuzhiyun mask |= SGMII_REG_STATUS_AUTONEG;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun status = __raw_readl(SGMII_STATUS_REG(port));
331*4882a593Smuzhiyun if ((status & mask) == mask)
332*4882a593Smuzhiyun return 0;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun printf("\n%s Waiting for SGMII auto negotiation to complete",
335*4882a593Smuzhiyun phy_dev->dev->name);
336*4882a593Smuzhiyun while ((status & mask) != mask) {
337*4882a593Smuzhiyun /*
338*4882a593Smuzhiyun * Timeout reached ?
339*4882a593Smuzhiyun */
340*4882a593Smuzhiyun if (i > SGMII_ANEG_TIMEOUT) {
341*4882a593Smuzhiyun puts(" TIMEOUT !\n");
342*4882a593Smuzhiyun phy_dev->link = 0;
343*4882a593Smuzhiyun return 0;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun if (ctrlc()) {
347*4882a593Smuzhiyun puts("user interrupt!\n");
348*4882a593Smuzhiyun phy_dev->link = 0;
349*4882a593Smuzhiyun return -EINTR;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun if ((i++ % 500) == 0)
353*4882a593Smuzhiyun printf(".");
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun udelay(1000); /* 1 ms */
356*4882a593Smuzhiyun status = __raw_readl(SGMII_STATUS_REG(port));
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun puts(" done\n");
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return 0;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun #endif
363*4882a593Smuzhiyun
mac_sl_reset(u32 port)364*4882a593Smuzhiyun int mac_sl_reset(u32 port)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun u32 i, v;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (port >= DEVICE_N_GMACSL_PORTS)
369*4882a593Smuzhiyun return GMACSL_RET_INVALID_PORT;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /* Set the soft reset bit */
372*4882a593Smuzhiyun writel(CPGMAC_REG_RESET_VAL_RESET,
373*4882a593Smuzhiyun DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun /* Wait for the bit to clear */
376*4882a593Smuzhiyun for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
377*4882a593Smuzhiyun v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
378*4882a593Smuzhiyun if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
379*4882a593Smuzhiyun CPGMAC_REG_RESET_VAL_RESET)
380*4882a593Smuzhiyun return GMACSL_RET_OK;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun /* Timeout on the reset */
384*4882a593Smuzhiyun return GMACSL_RET_WARN_RESET_INCOMPLETE;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
mac_sl_config(u_int16_t port,struct mac_sl_cfg * cfg)387*4882a593Smuzhiyun int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun u32 v, i;
390*4882a593Smuzhiyun int ret = GMACSL_RET_OK;
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun if (port >= DEVICE_N_GMACSL_PORTS)
393*4882a593Smuzhiyun return GMACSL_RET_INVALID_PORT;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
396*4882a593Smuzhiyun cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
397*4882a593Smuzhiyun ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun /* Must wait if the device is undergoing reset */
401*4882a593Smuzhiyun for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
402*4882a593Smuzhiyun v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
403*4882a593Smuzhiyun if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
404*4882a593Smuzhiyun CPGMAC_REG_RESET_VAL_RESET)
405*4882a593Smuzhiyun break;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
409*4882a593Smuzhiyun return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN);
412*4882a593Smuzhiyun writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun #ifndef CONFIG_SOC_K2HK
415*4882a593Smuzhiyun /* Map RX packet flow priority to 0 */
416*4882a593Smuzhiyun writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP);
417*4882a593Smuzhiyun #endif
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun return ret;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun
ethss_config(u32 ctl,u32 max_pkt_size)422*4882a593Smuzhiyun int ethss_config(u32 ctl, u32 max_pkt_size)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun u32 i;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /* Max length register */
427*4882a593Smuzhiyun writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN);
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /* Control register */
430*4882a593Smuzhiyun writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun /* All statistics enabled by default */
433*4882a593Smuzhiyun writel(CPSW_REG_VAL_STAT_ENABLE_ALL,
434*4882a593Smuzhiyun DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun /* Reset and enable the ALE */
437*4882a593Smuzhiyun writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
438*4882a593Smuzhiyun CPSW_REG_VAL_ALE_CTL_BYPASS,
439*4882a593Smuzhiyun DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun /* All ports put into forward mode */
442*4882a593Smuzhiyun for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
443*4882a593Smuzhiyun writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE,
444*4882a593Smuzhiyun DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i));
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
ethss_start(void)449*4882a593Smuzhiyun int ethss_start(void)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun int i;
452*4882a593Smuzhiyun struct mac_sl_cfg cfg;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER;
455*4882a593Smuzhiyun cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
458*4882a593Smuzhiyun mac_sl_reset(i);
459*4882a593Smuzhiyun mac_sl_config(i, &cfg);
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun return 0;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
ethss_stop(void)465*4882a593Smuzhiyun int ethss_stop(void)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun int i;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
470*4882a593Smuzhiyun mac_sl_reset(i);
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun return 0;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun struct ks2_serdes ks2_serdes_sgmii_156p25mhz = {
476*4882a593Smuzhiyun .clk = SERDES_CLOCK_156P25M,
477*4882a593Smuzhiyun .rate = SERDES_RATE_5G,
478*4882a593Smuzhiyun .rate_mode = SERDES_QUARTER_RATE,
479*4882a593Smuzhiyun .intf = SERDES_PHY_SGMII,
480*4882a593Smuzhiyun .loopback = 0,
481*4882a593Smuzhiyun };
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun #ifndef CONFIG_SOC_K2G
keystone2_net_serdes_setup(void)484*4882a593Smuzhiyun static void keystone2_net_serdes_setup(void)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE,
487*4882a593Smuzhiyun &ks2_serdes_sgmii_156p25mhz,
488*4882a593Smuzhiyun CONFIG_KSNET_SERDES_LANES_PER_SGMII);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun #if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L)
491*4882a593Smuzhiyun ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE,
492*4882a593Smuzhiyun &ks2_serdes_sgmii_156p25mhz,
493*4882a593Smuzhiyun CONFIG_KSNET_SERDES_LANES_PER_SGMII);
494*4882a593Smuzhiyun #endif
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun /* wait till setup */
497*4882a593Smuzhiyun udelay(5000);
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun #endif
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun #ifndef CONFIG_DM_ETH
502*4882a593Smuzhiyun
keystone2_eth_read_mac_addr(struct eth_device * dev)503*4882a593Smuzhiyun int keystone2_eth_read_mac_addr(struct eth_device *dev)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun struct eth_priv_t *eth_priv;
506*4882a593Smuzhiyun u32 maca = 0;
507*4882a593Smuzhiyun u32 macb = 0;
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun eth_priv = (struct eth_priv_t *)dev->priv;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun /* Read the e-fuse mac address */
512*4882a593Smuzhiyun if (eth_priv->slave_port == 1) {
513*4882a593Smuzhiyun maca = __raw_readl(MAC_ID_BASE_ADDR);
514*4882a593Smuzhiyun macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun dev->enetaddr[0] = (macb >> 8) & 0xff;
518*4882a593Smuzhiyun dev->enetaddr[1] = (macb >> 0) & 0xff;
519*4882a593Smuzhiyun dev->enetaddr[2] = (maca >> 24) & 0xff;
520*4882a593Smuzhiyun dev->enetaddr[3] = (maca >> 16) & 0xff;
521*4882a593Smuzhiyun dev->enetaddr[4] = (maca >> 8) & 0xff;
522*4882a593Smuzhiyun dev->enetaddr[5] = (maca >> 0) & 0xff;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun return 0;
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
cpmac_drv_send(u32 * buffer,int num_bytes,int slave_port_num)527*4882a593Smuzhiyun int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
530*4882a593Smuzhiyun num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun return ksnav_send(&netcp_pktdma, buffer,
533*4882a593Smuzhiyun num_bytes, (slave_port_num) << 16);
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun /* Eth device open */
keystone2_eth_open(struct eth_device * dev,bd_t * bis)537*4882a593Smuzhiyun static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
540*4882a593Smuzhiyun struct phy_device *phy_dev = eth_priv->phy_dev;
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun debug("+ emac_open\n");
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun net_rx_buffs.rx_flow = eth_priv->rx_flow;
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun sys_has_mdio =
547*4882a593Smuzhiyun (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun if (sys_has_mdio)
550*4882a593Smuzhiyun keystone2_mdio_reset(mdio_bus);
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun #ifdef CONFIG_SOC_K2G
553*4882a593Smuzhiyun keystone_rgmii_config(phy_dev);
554*4882a593Smuzhiyun #else
555*4882a593Smuzhiyun keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1,
556*4882a593Smuzhiyun eth_priv->sgmii_link_type);
557*4882a593Smuzhiyun #endif
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun udelay(10000);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun /* On chip switch configuration */
562*4882a593Smuzhiyun ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun /* TODO: add error handling code */
565*4882a593Smuzhiyun if (qm_init()) {
566*4882a593Smuzhiyun printf("ERROR: qm_init()\n");
567*4882a593Smuzhiyun return -1;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) {
570*4882a593Smuzhiyun qm_close();
571*4882a593Smuzhiyun printf("ERROR: netcp_init()\n");
572*4882a593Smuzhiyun return -1;
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun /*
576*4882a593Smuzhiyun * Streaming switch configuration. If not present this
577*4882a593Smuzhiyun * statement is defined to void in target.h.
578*4882a593Smuzhiyun * If present this is usually defined to a series of register writes
579*4882a593Smuzhiyun */
580*4882a593Smuzhiyun hw_config_streaming_switch();
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun if (sys_has_mdio) {
583*4882a593Smuzhiyun keystone2_mdio_reset(mdio_bus);
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun phy_startup(phy_dev);
586*4882a593Smuzhiyun if (phy_dev->link == 0) {
587*4882a593Smuzhiyun ksnav_close(&netcp_pktdma);
588*4882a593Smuzhiyun qm_close();
589*4882a593Smuzhiyun return -1;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun emac_gigabit_enable(dev);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun ethss_start();
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun debug("- emac_open\n");
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun emac_open = 1;
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun return 0;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun /* Eth device close */
keystone2_eth_close(struct eth_device * dev)605*4882a593Smuzhiyun void keystone2_eth_close(struct eth_device *dev)
606*4882a593Smuzhiyun {
607*4882a593Smuzhiyun struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
608*4882a593Smuzhiyun struct phy_device *phy_dev = eth_priv->phy_dev;
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun debug("+ emac_close\n");
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun if (!emac_open)
613*4882a593Smuzhiyun return;
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun ethss_stop();
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun ksnav_close(&netcp_pktdma);
618*4882a593Smuzhiyun qm_close();
619*4882a593Smuzhiyun phy_shutdown(phy_dev);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun emac_open = 0;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun debug("- emac_close\n");
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /*
627*4882a593Smuzhiyun * This function sends a single packet on the network and returns
628*4882a593Smuzhiyun * positive number (number of bytes transmitted) or negative for error
629*4882a593Smuzhiyun */
keystone2_eth_send_packet(struct eth_device * dev,void * packet,int length)630*4882a593Smuzhiyun static int keystone2_eth_send_packet(struct eth_device *dev,
631*4882a593Smuzhiyun void *packet, int length)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun int ret_status = -1;
634*4882a593Smuzhiyun struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
635*4882a593Smuzhiyun struct phy_device *phy_dev = eth_priv->phy_dev;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun genphy_update_link(phy_dev);
638*4882a593Smuzhiyun if (phy_dev->link == 0)
639*4882a593Smuzhiyun return -1;
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
642*4882a593Smuzhiyun return ret_status;
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun return length;
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun /*
648*4882a593Smuzhiyun * This function handles receipt of a packet from the network
649*4882a593Smuzhiyun */
keystone2_eth_rcv_packet(struct eth_device * dev)650*4882a593Smuzhiyun static int keystone2_eth_rcv_packet(struct eth_device *dev)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun void *hd;
653*4882a593Smuzhiyun int pkt_size;
654*4882a593Smuzhiyun u32 *pkt;
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size);
657*4882a593Smuzhiyun if (hd == NULL)
658*4882a593Smuzhiyun return 0;
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun net_process_received_packet((uchar *)pkt, pkt_size);
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun ksnav_release_rxhd(&netcp_pktdma, hd);
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun return pkt_size;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun #ifdef CONFIG_MCAST_TFTP
keystone2_eth_bcast_addr(struct eth_device * dev,u32 ip,u8 set)668*4882a593Smuzhiyun static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set)
669*4882a593Smuzhiyun {
670*4882a593Smuzhiyun return 0;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun #endif
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun /*
675*4882a593Smuzhiyun * This function initializes the EMAC hardware.
676*4882a593Smuzhiyun */
keystone2_emac_initialize(struct eth_priv_t * eth_priv)677*4882a593Smuzhiyun int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
678*4882a593Smuzhiyun {
679*4882a593Smuzhiyun int res;
680*4882a593Smuzhiyun struct eth_device *dev;
681*4882a593Smuzhiyun struct phy_device *phy_dev;
682*4882a593Smuzhiyun struct mdio_regs *adap_mdio = (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun dev = malloc(sizeof(struct eth_device));
685*4882a593Smuzhiyun if (dev == NULL)
686*4882a593Smuzhiyun return -1;
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun memset(dev, 0, sizeof(struct eth_device));
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun strcpy(dev->name, eth_priv->int_name);
691*4882a593Smuzhiyun dev->priv = eth_priv;
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun keystone2_eth_read_mac_addr(dev);
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun dev->iobase = 0;
696*4882a593Smuzhiyun dev->init = keystone2_eth_open;
697*4882a593Smuzhiyun dev->halt = keystone2_eth_close;
698*4882a593Smuzhiyun dev->send = keystone2_eth_send_packet;
699*4882a593Smuzhiyun dev->recv = keystone2_eth_rcv_packet;
700*4882a593Smuzhiyun #ifdef CONFIG_MCAST_TFTP
701*4882a593Smuzhiyun dev->mcast = keystone2_eth_bcast_addr;
702*4882a593Smuzhiyun #endif
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun eth_register(dev);
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun /* Register MDIO bus if it's not registered yet */
707*4882a593Smuzhiyun if (!mdio_bus) {
708*4882a593Smuzhiyun mdio_bus = mdio_alloc();
709*4882a593Smuzhiyun mdio_bus->read = keystone2_mdio_read;
710*4882a593Smuzhiyun mdio_bus->write = keystone2_mdio_write;
711*4882a593Smuzhiyun mdio_bus->reset = keystone2_mdio_reset;
712*4882a593Smuzhiyun mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR;
713*4882a593Smuzhiyun strcpy(mdio_bus->name, "ethernet-mdio");
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun res = mdio_register(mdio_bus);
716*4882a593Smuzhiyun if (res)
717*4882a593Smuzhiyun return res;
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun #ifndef CONFIG_SOC_K2G
721*4882a593Smuzhiyun keystone2_net_serdes_setup();
722*4882a593Smuzhiyun #endif
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun /* Create phy device and bind it with driver */
725*4882a593Smuzhiyun #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
726*4882a593Smuzhiyun phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
727*4882a593Smuzhiyun dev, eth_priv->phy_if);
728*4882a593Smuzhiyun phy_config(phy_dev);
729*4882a593Smuzhiyun #else
730*4882a593Smuzhiyun phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
731*4882a593Smuzhiyun eth_priv->phy_if);
732*4882a593Smuzhiyun phy_dev->dev = dev;
733*4882a593Smuzhiyun #endif
734*4882a593Smuzhiyun eth_priv->phy_dev = phy_dev;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun return 0;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun #else
740*4882a593Smuzhiyun
ks2_eth_start(struct udevice * dev)741*4882a593Smuzhiyun static int ks2_eth_start(struct udevice *dev)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun #ifdef CONFIG_SOC_K2G
746*4882a593Smuzhiyun keystone_rgmii_config(priv->phydev);
747*4882a593Smuzhiyun #else
748*4882a593Smuzhiyun keystone_sgmii_config(priv->phydev, priv->slave_port - 1,
749*4882a593Smuzhiyun priv->sgmii_link_type);
750*4882a593Smuzhiyun #endif
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun udelay(10000);
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun /* On chip switch configuration */
755*4882a593Smuzhiyun ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun qm_init();
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun if (ksnav_init(priv->netcp_pktdma, &priv->net_rx_buffs)) {
760*4882a593Smuzhiyun pr_err("ksnav_init failed\n");
761*4882a593Smuzhiyun goto err_knav_init;
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun /*
765*4882a593Smuzhiyun * Streaming switch configuration. If not present this
766*4882a593Smuzhiyun * statement is defined to void in target.h.
767*4882a593Smuzhiyun * If present this is usually defined to a series of register writes
768*4882a593Smuzhiyun */
769*4882a593Smuzhiyun hw_config_streaming_switch();
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun if (priv->has_mdio) {
772*4882a593Smuzhiyun keystone2_mdio_reset(priv->mdio_bus);
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun phy_startup(priv->phydev);
775*4882a593Smuzhiyun if (priv->phydev->link == 0) {
776*4882a593Smuzhiyun pr_err("phy startup failed\n");
777*4882a593Smuzhiyun goto err_phy_start;
778*4882a593Smuzhiyun }
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun emac_gigabit_enable(dev);
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun ethss_start();
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun priv->emac_open = true;
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun return 0;
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun err_phy_start:
790*4882a593Smuzhiyun ksnav_close(priv->netcp_pktdma);
791*4882a593Smuzhiyun err_knav_init:
792*4882a593Smuzhiyun qm_close();
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun return -EFAULT;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
ks2_eth_send(struct udevice * dev,void * packet,int length)797*4882a593Smuzhiyun static int ks2_eth_send(struct udevice *dev, void *packet, int length)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun genphy_update_link(priv->phydev);
802*4882a593Smuzhiyun if (priv->phydev->link == 0)
803*4882a593Smuzhiyun return -1;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
806*4882a593Smuzhiyun length = EMAC_MIN_ETHERNET_PKT_SIZE;
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun return ksnav_send(priv->netcp_pktdma, (u32 *)packet,
809*4882a593Smuzhiyun length, (priv->slave_port) << 16);
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun
ks2_eth_recv(struct udevice * dev,int flags,uchar ** packetp)812*4882a593Smuzhiyun static int ks2_eth_recv(struct udevice *dev, int flags, uchar **packetp)
813*4882a593Smuzhiyun {
814*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
815*4882a593Smuzhiyun int pkt_size;
816*4882a593Smuzhiyun u32 *pkt = NULL;
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun priv->hd = ksnav_recv(priv->netcp_pktdma, &pkt, &pkt_size);
819*4882a593Smuzhiyun if (priv->hd == NULL)
820*4882a593Smuzhiyun return -EAGAIN;
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun *packetp = (uchar *)pkt;
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun return pkt_size;
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun
ks2_eth_free_pkt(struct udevice * dev,uchar * packet,int length)827*4882a593Smuzhiyun static int ks2_eth_free_pkt(struct udevice *dev, uchar *packet,
828*4882a593Smuzhiyun int length)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun ksnav_release_rxhd(priv->netcp_pktdma, priv->hd);
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun return 0;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun
ks2_eth_stop(struct udevice * dev)837*4882a593Smuzhiyun static void ks2_eth_stop(struct udevice *dev)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun if (!priv->emac_open)
842*4882a593Smuzhiyun return;
843*4882a593Smuzhiyun ethss_stop();
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun ksnav_close(priv->netcp_pktdma);
846*4882a593Smuzhiyun qm_close();
847*4882a593Smuzhiyun phy_shutdown(priv->phydev);
848*4882a593Smuzhiyun priv->emac_open = false;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun
ks2_eth_read_rom_hwaddr(struct udevice * dev)851*4882a593Smuzhiyun int ks2_eth_read_rom_hwaddr(struct udevice *dev)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
854*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
855*4882a593Smuzhiyun u32 maca = 0;
856*4882a593Smuzhiyun u32 macb = 0;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun /* Read the e-fuse mac address */
859*4882a593Smuzhiyun if (priv->slave_port == 1) {
860*4882a593Smuzhiyun maca = __raw_readl(MAC_ID_BASE_ADDR);
861*4882a593Smuzhiyun macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun pdata->enetaddr[0] = (macb >> 8) & 0xff;
865*4882a593Smuzhiyun pdata->enetaddr[1] = (macb >> 0) & 0xff;
866*4882a593Smuzhiyun pdata->enetaddr[2] = (maca >> 24) & 0xff;
867*4882a593Smuzhiyun pdata->enetaddr[3] = (maca >> 16) & 0xff;
868*4882a593Smuzhiyun pdata->enetaddr[4] = (maca >> 8) & 0xff;
869*4882a593Smuzhiyun pdata->enetaddr[5] = (maca >> 0) & 0xff;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun return 0;
872*4882a593Smuzhiyun }
873*4882a593Smuzhiyun
ks2_eth_write_hwaddr(struct udevice * dev)874*4882a593Smuzhiyun int ks2_eth_write_hwaddr(struct udevice *dev)
875*4882a593Smuzhiyun {
876*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
877*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun writel(mac_hi(pdata->enetaddr),
880*4882a593Smuzhiyun DEVICE_EMACSW_BASE(pdata->iobase, priv->slave_port - 1) +
881*4882a593Smuzhiyun CPGMACSL_REG_SA_HI);
882*4882a593Smuzhiyun writel(mac_lo(pdata->enetaddr),
883*4882a593Smuzhiyun DEVICE_EMACSW_BASE(pdata->iobase, priv->slave_port - 1) +
884*4882a593Smuzhiyun CPGMACSL_REG_SA_LO);
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun return 0;
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun
ks2_eth_probe(struct udevice * dev)889*4882a593Smuzhiyun static int ks2_eth_probe(struct udevice *dev)
890*4882a593Smuzhiyun {
891*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
892*4882a593Smuzhiyun struct mii_dev *mdio_bus;
893*4882a593Smuzhiyun int ret;
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun priv->dev = dev;
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun /* These clock enables has to be moved to common location */
898*4882a593Smuzhiyun if (cpu_is_k2g())
899*4882a593Smuzhiyun writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG);
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun /* By default, select PA PLL clock as PA clock source */
902*4882a593Smuzhiyun #ifndef CONFIG_SOC_K2G
903*4882a593Smuzhiyun if (psc_enable_module(KS2_LPSC_PA))
904*4882a593Smuzhiyun return -EACCES;
905*4882a593Smuzhiyun #endif
906*4882a593Smuzhiyun if (psc_enable_module(KS2_LPSC_CPGMAC))
907*4882a593Smuzhiyun return -EACCES;
908*4882a593Smuzhiyun if (psc_enable_module(KS2_LPSC_CRYPTO))
909*4882a593Smuzhiyun return -EACCES;
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun if (cpu_is_k2e() || cpu_is_k2l())
912*4882a593Smuzhiyun pll_pa_clk_sel();
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun priv->net_rx_buffs.buff_ptr = rx_buffs;
916*4882a593Smuzhiyun priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS;
917*4882a593Smuzhiyun priv->net_rx_buffs.buff_len = RX_BUFF_LEN;
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun if (priv->slave_port == 1) {
920*4882a593Smuzhiyun /*
921*4882a593Smuzhiyun * Register MDIO bus for slave 0 only, other slave have
922*4882a593Smuzhiyun * to re-use the same
923*4882a593Smuzhiyun */
924*4882a593Smuzhiyun mdio_bus = mdio_alloc();
925*4882a593Smuzhiyun if (!mdio_bus) {
926*4882a593Smuzhiyun pr_err("MDIO alloc failed\n");
927*4882a593Smuzhiyun return -ENOMEM;
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun priv->mdio_bus = mdio_bus;
930*4882a593Smuzhiyun mdio_bus->read = keystone2_mdio_read;
931*4882a593Smuzhiyun mdio_bus->write = keystone2_mdio_write;
932*4882a593Smuzhiyun mdio_bus->reset = keystone2_mdio_reset;
933*4882a593Smuzhiyun mdio_bus->priv = priv->mdio_base;
934*4882a593Smuzhiyun sprintf(mdio_bus->name, "ethernet-mdio");
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun ret = mdio_register(mdio_bus);
937*4882a593Smuzhiyun if (ret) {
938*4882a593Smuzhiyun pr_err("MDIO bus register failed\n");
939*4882a593Smuzhiyun return ret;
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun } else {
942*4882a593Smuzhiyun /* Get the MDIO bus from slave 0 device */
943*4882a593Smuzhiyun struct ks2_eth_priv *parent_priv;
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun parent_priv = dev_get_priv(dev->parent);
946*4882a593Smuzhiyun priv->mdio_bus = parent_priv->mdio_bus;
947*4882a593Smuzhiyun }
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun #ifndef CONFIG_SOC_K2G
950*4882a593Smuzhiyun keystone2_net_serdes_setup();
951*4882a593Smuzhiyun #endif
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun priv->netcp_pktdma = &netcp_pktdma;
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun if (priv->has_mdio) {
956*4882a593Smuzhiyun priv->phydev = phy_connect(priv->mdio_bus, priv->phy_addr,
957*4882a593Smuzhiyun dev, priv->phy_if);
958*4882a593Smuzhiyun phy_config(priv->phydev);
959*4882a593Smuzhiyun }
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun return 0;
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun
ks2_eth_remove(struct udevice * dev)964*4882a593Smuzhiyun int ks2_eth_remove(struct udevice *dev)
965*4882a593Smuzhiyun {
966*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
967*4882a593Smuzhiyun
968*4882a593Smuzhiyun free(priv->phydev);
969*4882a593Smuzhiyun mdio_unregister(priv->mdio_bus);
970*4882a593Smuzhiyun mdio_free(priv->mdio_bus);
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun return 0;
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun static const struct eth_ops ks2_eth_ops = {
976*4882a593Smuzhiyun .start = ks2_eth_start,
977*4882a593Smuzhiyun .send = ks2_eth_send,
978*4882a593Smuzhiyun .recv = ks2_eth_recv,
979*4882a593Smuzhiyun .free_pkt = ks2_eth_free_pkt,
980*4882a593Smuzhiyun .stop = ks2_eth_stop,
981*4882a593Smuzhiyun .read_rom_hwaddr = ks2_eth_read_rom_hwaddr,
982*4882a593Smuzhiyun .write_hwaddr = ks2_eth_write_hwaddr,
983*4882a593Smuzhiyun };
984*4882a593Smuzhiyun
ks2_eth_bind_slaves(struct udevice * dev,int gbe,int * gbe_0)985*4882a593Smuzhiyun static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun const void *fdt = gd->fdt_blob;
988*4882a593Smuzhiyun struct udevice *sl_dev;
989*4882a593Smuzhiyun int interfaces;
990*4882a593Smuzhiyun int sec_slave;
991*4882a593Smuzhiyun int slave;
992*4882a593Smuzhiyun int ret;
993*4882a593Smuzhiyun char *slave_name;
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun interfaces = fdt_subnode_offset(fdt, gbe, "interfaces");
996*4882a593Smuzhiyun fdt_for_each_subnode(slave, fdt, interfaces) {
997*4882a593Smuzhiyun int slave_no;
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun slave_no = fdtdec_get_int(fdt, slave, "slave-port", -ENOENT);
1000*4882a593Smuzhiyun if (slave_no == -ENOENT)
1001*4882a593Smuzhiyun continue;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun if (slave_no == 0) {
1004*4882a593Smuzhiyun /* This is the current eth device */
1005*4882a593Smuzhiyun *gbe_0 = slave;
1006*4882a593Smuzhiyun } else {
1007*4882a593Smuzhiyun /* Slave devices to be registered */
1008*4882a593Smuzhiyun slave_name = malloc(20);
1009*4882a593Smuzhiyun snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
1010*4882a593Smuzhiyun ret = device_bind_driver_to_node(dev, "eth_ks2_sl",
1011*4882a593Smuzhiyun slave_name, offset_to_ofnode(slave),
1012*4882a593Smuzhiyun &sl_dev);
1013*4882a593Smuzhiyun if (ret) {
1014*4882a593Smuzhiyun pr_err("ks2_net - not able to bind slave interfaces\n");
1015*4882a593Smuzhiyun return ret;
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun }
1018*4882a593Smuzhiyun }
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun sec_slave = fdt_subnode_offset(fdt, gbe, "secondary-slave-ports");
1021*4882a593Smuzhiyun fdt_for_each_subnode(slave, fdt, sec_slave) {
1022*4882a593Smuzhiyun int slave_no;
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun slave_no = fdtdec_get_int(fdt, slave, "slave-port", -ENOENT);
1025*4882a593Smuzhiyun if (slave_no == -ENOENT)
1026*4882a593Smuzhiyun continue;
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun /* Slave devices to be registered */
1029*4882a593Smuzhiyun slave_name = malloc(20);
1030*4882a593Smuzhiyun snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
1031*4882a593Smuzhiyun ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name,
1032*4882a593Smuzhiyun offset_to_ofnode(slave), &sl_dev);
1033*4882a593Smuzhiyun if (ret) {
1034*4882a593Smuzhiyun pr_err("ks2_net - not able to bind slave interfaces\n");
1035*4882a593Smuzhiyun return ret;
1036*4882a593Smuzhiyun }
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun return 0;
1040*4882a593Smuzhiyun }
1041*4882a593Smuzhiyun
ks2_eth_parse_slave_interface(int netcp,int slave,struct ks2_eth_priv * priv,struct eth_pdata * pdata)1042*4882a593Smuzhiyun static int ks2_eth_parse_slave_interface(int netcp, int slave,
1043*4882a593Smuzhiyun struct ks2_eth_priv *priv,
1044*4882a593Smuzhiyun struct eth_pdata *pdata)
1045*4882a593Smuzhiyun {
1046*4882a593Smuzhiyun const void *fdt = gd->fdt_blob;
1047*4882a593Smuzhiyun int mdio;
1048*4882a593Smuzhiyun int phy;
1049*4882a593Smuzhiyun int dma_count;
1050*4882a593Smuzhiyun u32 dma_channel[8];
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun priv->slave_port = fdtdec_get_int(fdt, slave, "slave-port", -1);
1053*4882a593Smuzhiyun priv->net_rx_buffs.rx_flow = priv->slave_port * 8;
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun /* U-Boot slave port number starts with 1 instead of 0 */
1056*4882a593Smuzhiyun priv->slave_port += 1;
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun dma_count = fdtdec_get_int_array_count(fdt, netcp,
1059*4882a593Smuzhiyun "ti,navigator-dmas",
1060*4882a593Smuzhiyun dma_channel, 8);
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun if (dma_count > (2 * priv->slave_port)) {
1063*4882a593Smuzhiyun int dma_idx;
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun dma_idx = priv->slave_port * 2 - 1;
1066*4882a593Smuzhiyun priv->net_rx_buffs.rx_flow = dma_channel[dma_idx];
1067*4882a593Smuzhiyun }
1068*4882a593Smuzhiyun
1069*4882a593Smuzhiyun priv->link_type = fdtdec_get_int(fdt, slave, "link-interface", -1);
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun phy = fdtdec_lookup_phandle(fdt, slave, "phy-handle");
1072*4882a593Smuzhiyun if (phy >= 0) {
1073*4882a593Smuzhiyun priv->phy_addr = fdtdec_get_int(fdt, phy, "reg", -1);
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun mdio = fdt_parent_offset(fdt, phy);
1076*4882a593Smuzhiyun if (mdio < 0) {
1077*4882a593Smuzhiyun pr_err("mdio dt not found\n");
1078*4882a593Smuzhiyun return -ENODEV;
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun priv->mdio_base = (void *)fdtdec_get_addr(fdt, mdio, "reg");
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun if (priv->link_type == LINK_TYPE_SGMII_MAC_TO_PHY_MODE) {
1084*4882a593Smuzhiyun priv->phy_if = PHY_INTERFACE_MODE_SGMII;
1085*4882a593Smuzhiyun pdata->phy_interface = priv->phy_if;
1086*4882a593Smuzhiyun priv->sgmii_link_type = SGMII_LINK_MAC_PHY;
1087*4882a593Smuzhiyun priv->has_mdio = true;
1088*4882a593Smuzhiyun } else if (priv->link_type == LINK_TYPE_RGMII_LINK_MAC_PHY) {
1089*4882a593Smuzhiyun priv->phy_if = PHY_INTERFACE_MODE_RGMII;
1090*4882a593Smuzhiyun pdata->phy_interface = priv->phy_if;
1091*4882a593Smuzhiyun priv->has_mdio = true;
1092*4882a593Smuzhiyun }
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun return 0;
1095*4882a593Smuzhiyun }
1096*4882a593Smuzhiyun
ks2_sl_eth_ofdata_to_platdata(struct udevice * dev)1097*4882a593Smuzhiyun static int ks2_sl_eth_ofdata_to_platdata(struct udevice *dev)
1098*4882a593Smuzhiyun {
1099*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
1100*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
1101*4882a593Smuzhiyun const void *fdt = gd->fdt_blob;
1102*4882a593Smuzhiyun int slave = dev_of_offset(dev);
1103*4882a593Smuzhiyun int interfaces;
1104*4882a593Smuzhiyun int gbe;
1105*4882a593Smuzhiyun int netcp_devices;
1106*4882a593Smuzhiyun int netcp;
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun interfaces = fdt_parent_offset(fdt, slave);
1109*4882a593Smuzhiyun gbe = fdt_parent_offset(fdt, interfaces);
1110*4882a593Smuzhiyun netcp_devices = fdt_parent_offset(fdt, gbe);
1111*4882a593Smuzhiyun netcp = fdt_parent_offset(fdt, netcp_devices);
1112*4882a593Smuzhiyun
1113*4882a593Smuzhiyun ks2_eth_parse_slave_interface(netcp, slave, priv, pdata);
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun pdata->iobase = fdtdec_get_addr(fdt, netcp, "reg");
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun return 0;
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun
ks2_eth_ofdata_to_platdata(struct udevice * dev)1120*4882a593Smuzhiyun static int ks2_eth_ofdata_to_platdata(struct udevice *dev)
1121*4882a593Smuzhiyun {
1122*4882a593Smuzhiyun struct ks2_eth_priv *priv = dev_get_priv(dev);
1123*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
1124*4882a593Smuzhiyun const void *fdt = gd->fdt_blob;
1125*4882a593Smuzhiyun int gbe_0 = -ENODEV;
1126*4882a593Smuzhiyun int netcp_devices;
1127*4882a593Smuzhiyun int gbe;
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun netcp_devices = fdt_subnode_offset(fdt, dev_of_offset(dev),
1130*4882a593Smuzhiyun "netcp-devices");
1131*4882a593Smuzhiyun gbe = fdt_subnode_offset(fdt, netcp_devices, "gbe");
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun ks2_eth_bind_slaves(dev, gbe, &gbe_0);
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun ks2_eth_parse_slave_interface(dev_of_offset(dev), gbe_0, priv, pdata);
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun pdata->iobase = devfdt_get_addr(dev);
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun return 0;
1140*4882a593Smuzhiyun }
1141*4882a593Smuzhiyun
1142*4882a593Smuzhiyun static const struct udevice_id ks2_eth_ids[] = {
1143*4882a593Smuzhiyun { .compatible = "ti,netcp-1.0" },
1144*4882a593Smuzhiyun { }
1145*4882a593Smuzhiyun };
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun U_BOOT_DRIVER(eth_ks2_slave) = {
1148*4882a593Smuzhiyun .name = "eth_ks2_sl",
1149*4882a593Smuzhiyun .id = UCLASS_ETH,
1150*4882a593Smuzhiyun .ofdata_to_platdata = ks2_sl_eth_ofdata_to_platdata,
1151*4882a593Smuzhiyun .probe = ks2_eth_probe,
1152*4882a593Smuzhiyun .remove = ks2_eth_remove,
1153*4882a593Smuzhiyun .ops = &ks2_eth_ops,
1154*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct ks2_eth_priv),
1155*4882a593Smuzhiyun .platdata_auto_alloc_size = sizeof(struct eth_pdata),
1156*4882a593Smuzhiyun .flags = DM_FLAG_ALLOC_PRIV_DMA,
1157*4882a593Smuzhiyun };
1158*4882a593Smuzhiyun
1159*4882a593Smuzhiyun U_BOOT_DRIVER(eth_ks2) = {
1160*4882a593Smuzhiyun .name = "eth_ks2",
1161*4882a593Smuzhiyun .id = UCLASS_ETH,
1162*4882a593Smuzhiyun .of_match = ks2_eth_ids,
1163*4882a593Smuzhiyun .ofdata_to_platdata = ks2_eth_ofdata_to_platdata,
1164*4882a593Smuzhiyun .probe = ks2_eth_probe,
1165*4882a593Smuzhiyun .remove = ks2_eth_remove,
1166*4882a593Smuzhiyun .ops = &ks2_eth_ops,
1167*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct ks2_eth_priv),
1168*4882a593Smuzhiyun .platdata_auto_alloc_size = sizeof(struct eth_pdata),
1169*4882a593Smuzhiyun .flags = DM_FLAG_ALLOC_PRIV_DMA,
1170*4882a593Smuzhiyun };
1171*4882a593Smuzhiyun #endif
1172