blob: 63f33611cb6a77fc39f58b29c4a9a81246fe73be [file] [log] [blame]
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -04001/*
2 * Ethernet driver for TI K2HK EVM.
3 *
4 * (C) Copyright 2012-2014
5 * Texas Instruments Incorporated, <www.ti.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9#include <common.h>
10#include <command.h>
11
12#include <net.h>
13#include <miiphy.h>
14#include <malloc.h>
Khoronzhuk, Ivanef454712014-09-05 19:02:47 +030015#include <asm/ti-common/keystone_nav.h>
Khoronzhuk, Ivan0935cac2014-09-29 22:17:22 +030016#include <asm/ti-common/keystone_net.h>
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +030017#include <asm/ti-common/keystone_serdes.h>
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -040018
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -040019unsigned int emac_open;
20static unsigned int sys_has_mdio = 1;
21
22#ifdef KEYSTONE2_EMAC_GIG_ENABLE
23#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
24#else
25#define emac_gigabit_enable(x) /* no gigabit to enable */
26#endif
27
28#define RX_BUFF_NUMS 24
29#define RX_BUFF_LEN 1520
30#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
31
32static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
33
34struct rx_buff_desc net_rx_buffs = {
35 .buff_ptr = rx_buffs,
36 .num_buffs = RX_BUFF_NUMS,
37 .buff_len = RX_BUFF_LEN,
38 .rx_flow = 22,
39};
40
41static void keystone2_eth_mdio_enable(void);
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +030042static void keystone2_net_serdes_setup(void);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -040043
44static int gen_get_link_speed(int phy_addr);
45
46/* EMAC Addresses */
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -040047static volatile struct mdio_regs *adap_mdio =
48 (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
49
50int keystone2_eth_read_mac_addr(struct eth_device *dev)
51{
52 struct eth_priv_t *eth_priv;
53 u32 maca = 0;
54 u32 macb = 0;
55
56 eth_priv = (struct eth_priv_t *)dev->priv;
57
58 /* Read the e-fuse mac address */
59 if (eth_priv->slave_port == 1) {
60 maca = __raw_readl(MAC_ID_BASE_ADDR);
61 macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
62 }
63
64 dev->enetaddr[0] = (macb >> 8) & 0xff;
65 dev->enetaddr[1] = (macb >> 0) & 0xff;
66 dev->enetaddr[2] = (maca >> 24) & 0xff;
67 dev->enetaddr[3] = (maca >> 16) & 0xff;
68 dev->enetaddr[4] = (maca >> 8) & 0xff;
69 dev->enetaddr[5] = (maca >> 0) & 0xff;
70
71 return 0;
72}
73
74static void keystone2_eth_mdio_enable(void)
75{
76 u_int32_t clkdiv;
77
78 clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
79
80 writel((clkdiv & 0xffff) |
81 MDIO_CONTROL_ENABLE |
82 MDIO_CONTROL_FAULT |
83 MDIO_CONTROL_FAULT_ENABLE,
84 &adap_mdio->control);
85
86 while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
87 ;
88}
89
90/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
91int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
92{
93 int tmp;
94
95 while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
96 ;
97
98 writel(MDIO_USERACCESS0_GO |
99 MDIO_USERACCESS0_WRITE_READ |
100 ((reg_num & 0x1f) << 21) |
101 ((phy_addr & 0x1f) << 16),
102 &adap_mdio->useraccess0);
103
104 /* Wait for command to complete */
105 while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
106 ;
107
108 if (tmp & MDIO_USERACCESS0_ACK) {
109 *data = tmp & 0xffff;
110 return 0;
111 }
112
113 *data = -1;
114 return -1;
115}
116
117/*
118 * Write to a PHY register via MDIO inteface.
119 * Blocks until operation is complete.
120 */
121int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
122{
123 while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
124 ;
125
126 writel(MDIO_USERACCESS0_GO |
127 MDIO_USERACCESS0_WRITE_WRITE |
128 ((reg_num & 0x1f) << 21) |
129 ((phy_addr & 0x1f) << 16) |
130 (data & 0xffff),
131 &adap_mdio->useraccess0);
132
133 /* Wait for command to complete */
134 while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
135 ;
136
137 return 0;
138}
139
140/* PHY functions for a generic PHY */
141static int gen_get_link_speed(int phy_addr)
142{
143 u_int16_t tmp;
144
145 if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
146 (tmp & 0x04)) {
147 return 0;
148 }
149
150 return -1;
151}
152
153static void __attribute__((unused))
154 keystone2_eth_gigabit_enable(struct eth_device *dev)
155{
156 u_int16_t data;
157 struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
158
159 if (sys_has_mdio) {
160 if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
161 !(data & (1 << 6))) /* speed selection MSB */
162 return;
163 }
164
165 /*
166 * Check if link detected is giga-bit
167 * If Gigabit mode detected, enable gigbit in MAC
168 */
Hao Zhangb2cfe322014-09-29 22:17:20 +0300169 writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) +
170 CPGMACSL_REG_CTL) |
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400171 EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
Hao Zhangb2cfe322014-09-29 22:17:20 +0300172 DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400173}
174
175int keystone_sgmii_link_status(int port)
176{
177 u32 status = 0;
178
179 status = __raw_readl(SGMII_STATUS_REG(port));
180
181 return status & SGMII_REG_STATUS_LINK;
182}
183
184
185int keystone_get_link_status(struct eth_device *dev)
186{
187 struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
188 int sgmii_link;
189 int link_state = 0;
190#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
191 int j;
192
193 for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
194 j++) {
195#endif
196 sgmii_link =
197 keystone_sgmii_link_status(eth_priv->slave_port - 1);
198
199 if (sgmii_link) {
200 link_state = 1;
201
202 if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
203 if (gen_get_link_speed(eth_priv->phy_addr))
204 link_state = 0;
205 }
206#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
207 }
208#endif
209 return link_state;
210}
211
212int keystone_sgmii_config(int port, int interface)
213{
214 unsigned int i, status, mask;
215 unsigned int mr_adv_ability, control;
216
217 switch (interface) {
218 case SGMII_LINK_MAC_MAC_AUTONEG:
219 mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
220 SGMII_REG_MR_ADV_LINK |
221 SGMII_REG_MR_ADV_FULL_DUPLEX |
222 SGMII_REG_MR_ADV_GIG_MODE);
223 control = (SGMII_REG_CONTROL_MASTER |
224 SGMII_REG_CONTROL_AUTONEG);
225
226 break;
227 case SGMII_LINK_MAC_PHY:
228 case SGMII_LINK_MAC_PHY_FORCED:
229 mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
230 control = SGMII_REG_CONTROL_AUTONEG;
231
232 break;
233 case SGMII_LINK_MAC_MAC_FORCED:
234 mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
235 SGMII_REG_MR_ADV_LINK |
236 SGMII_REG_MR_ADV_FULL_DUPLEX |
237 SGMII_REG_MR_ADV_GIG_MODE);
238 control = SGMII_REG_CONTROL_MASTER;
239
240 break;
241 case SGMII_LINK_MAC_FIBER:
242 mr_adv_ability = 0x20;
243 control = SGMII_REG_CONTROL_AUTONEG;
244
245 break;
246 default:
247 mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
248 control = SGMII_REG_CONTROL_AUTONEG;
249 }
250
251 __raw_writel(0, SGMII_CTL_REG(port));
252
253 /*
254 * Wait for the SerDes pll to lock,
255 * but don't trap if lock is never read
256 */
257 for (i = 0; i < 1000; i++) {
258 udelay(2000);
259 status = __raw_readl(SGMII_STATUS_REG(port));
260 if ((status & SGMII_REG_STATUS_LOCK) != 0)
261 break;
262 }
263
264 __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
265 __raw_writel(control, SGMII_CTL_REG(port));
266
267
268 mask = SGMII_REG_STATUS_LINK;
269
270 if (control & SGMII_REG_CONTROL_AUTONEG)
271 mask |= SGMII_REG_STATUS_AUTONEG;
272
273 for (i = 0; i < 1000; i++) {
274 status = __raw_readl(SGMII_STATUS_REG(port));
275 if ((status & mask) == mask)
276 break;
277 }
278
279 return 0;
280}
281
282int mac_sl_reset(u32 port)
283{
284 u32 i, v;
285
286 if (port >= DEVICE_N_GMACSL_PORTS)
287 return GMACSL_RET_INVALID_PORT;
288
289 /* Set the soft reset bit */
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300290 writel(CPGMAC_REG_RESET_VAL_RESET,
291 DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400292
293 /* Wait for the bit to clear */
294 for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300295 v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400296 if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
297 CPGMAC_REG_RESET_VAL_RESET)
298 return GMACSL_RET_OK;
299 }
300
301 /* Timeout on the reset */
302 return GMACSL_RET_WARN_RESET_INCOMPLETE;
303}
304
305int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
306{
307 u32 v, i;
308 int ret = GMACSL_RET_OK;
309
310 if (port >= DEVICE_N_GMACSL_PORTS)
311 return GMACSL_RET_INVALID_PORT;
312
313 if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
314 cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
315 ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
316 }
317
318 /* Must wait if the device is undergoing reset */
319 for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300320 v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400321 if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
322 CPGMAC_REG_RESET_VAL_RESET)
323 break;
324 }
325
326 if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
327 return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
328
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300329 writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN);
330 writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400331
332 return ret;
333}
334
335int ethss_config(u32 ctl, u32 max_pkt_size)
336{
337 u32 i;
338
339 /* Max length register */
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300340 writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400341
342 /* Control register */
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300343 writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400344
345 /* All statistics enabled by default */
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300346 writel(CPSW_REG_VAL_STAT_ENABLE_ALL,
347 DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400348
349 /* Reset and enable the ALE */
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300350 writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
351 CPSW_REG_VAL_ALE_CTL_BYPASS,
352 DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400353
354 /* All ports put into forward mode */
355 for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
Khoronzhuk, Ivane6c94282014-08-28 16:07:45 +0300356 writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE,
357 DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i));
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400358
359 return 0;
360}
361
362int ethss_start(void)
363{
364 int i;
365 struct mac_sl_cfg cfg;
366
367 cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER;
368 cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
369
370 for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
371 mac_sl_reset(i);
372 mac_sl_config(i, &cfg);
373 }
374
375 return 0;
376}
377
378int ethss_stop(void)
379{
380 int i;
381
382 for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
383 mac_sl_reset(i);
384
385 return 0;
386}
387
388int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
389{
390 if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
391 num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
392
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300393 return ksnav_send(&netcp_pktdma, buffer,
394 num_bytes, (slave_port_num) << 16);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400395}
396
397/* Eth device open */
398static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
399{
400 u_int32_t clkdiv;
401 int link;
402 struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
403
404 debug("+ emac_open\n");
405
406 net_rx_buffs.rx_flow = eth_priv->rx_flow;
407
408 sys_has_mdio =
409 (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
410
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +0300411 keystone2_net_serdes_setup();
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400412
413 if (sys_has_mdio)
414 keystone2_eth_mdio_enable();
415
416 keystone_sgmii_config(eth_priv->slave_port - 1,
417 eth_priv->sgmii_link_type);
418
419 udelay(10000);
420
421 /* On chip switch configuration */
422 ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
423
424 /* TODO: add error handling code */
425 if (qm_init()) {
426 printf("ERROR: qm_init()\n");
427 return -1;
428 }
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300429 if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) {
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400430 qm_close();
431 printf("ERROR: netcp_init()\n");
432 return -1;
433 }
434
435 /*
436 * Streaming switch configuration. If not present this
437 * statement is defined to void in target.h.
438 * If present this is usually defined to a series of register writes
439 */
440 hw_config_streaming_switch();
441
442 if (sys_has_mdio) {
443 /* Init MDIO & get link state */
444 clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
445 writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
446 MDIO_CONTROL_FAULT, &adap_mdio->control)
447 ;
448
449 /* We need to wait for MDIO to start */
450 udelay(1000);
451
452 link = keystone_get_link_status(dev);
453 if (link == 0) {
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300454 ksnav_close(&netcp_pktdma);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400455 qm_close();
456 return -1;
457 }
458 }
459
460 emac_gigabit_enable(dev);
461
462 ethss_start();
463
464 debug("- emac_open\n");
465
466 emac_open = 1;
467
468 return 0;
469}
470
471/* Eth device close */
472void keystone2_eth_close(struct eth_device *dev)
473{
474 debug("+ emac_close\n");
475
476 if (!emac_open)
477 return;
478
479 ethss_stop();
480
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300481 ksnav_close(&netcp_pktdma);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400482 qm_close();
483
484 emac_open = 0;
485
486 debug("- emac_close\n");
487}
488
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400489/*
490 * This function sends a single packet on the network and returns
491 * positive number (number of bytes transmitted) or negative for error
492 */
493static int keystone2_eth_send_packet(struct eth_device *dev,
494 void *packet, int length)
495{
496 int ret_status = -1;
497 struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
498
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400499 if (keystone_get_link_status(dev) == 0)
500 return -1;
501
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400502 if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
503 return ret_status;
504
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400505 return length;
506}
507
508/*
509 * This function handles receipt of a packet from the network
510 */
511static int keystone2_eth_rcv_packet(struct eth_device *dev)
512{
513 void *hd;
514 int pkt_size;
515 u32 *pkt;
516
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300517 hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400518 if (hd == NULL)
519 return 0;
520
521 NetReceive((uchar *)pkt, pkt_size);
522
Khoronzhuk, Ivan9ea90212014-09-05 19:02:48 +0300523 ksnav_release_rxhd(&netcp_pktdma, hd);
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400524
525 return pkt_size;
526}
527
528/*
529 * This function initializes the EMAC hardware.
530 */
531int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
532{
533 struct eth_device *dev;
534
535 dev = malloc(sizeof(struct eth_device));
536 if (dev == NULL)
537 return -1;
538
539 memset(dev, 0, sizeof(struct eth_device));
540
541 strcpy(dev->name, eth_priv->int_name);
542 dev->priv = eth_priv;
543
544 keystone2_eth_read_mac_addr(dev);
545
546 dev->iobase = 0;
547 dev->init = keystone2_eth_open;
548 dev->halt = keystone2_eth_close;
549 dev->send = keystone2_eth_send_packet;
550 dev->recv = keystone2_eth_rcv_packet;
551
552 eth_register(dev);
553
554 return 0;
555}
556
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +0300557static void keystone2_net_serdes_setup(void)
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400558{
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +0300559 ks2_serdes_sgmii_156p25mhz_setup();
Karicheri, Muralidharanfc9a8e82014-04-01 15:01:13 -0400560}