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