1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019, Linaro Limited
11 #include <linux/bug.h>
12 #include <linux/mii.h>
18 #define STATION_ADDR_LOW 0x0000
19 #define STATION_ADDR_HIGH 0x0004
20 #define MAC_DUPLEX_HALF_CTRL 0x0008
21 #define PORT_MODE 0x0040
22 #define PORT_EN 0x0044
23 #define BIT_TX_EN BIT(2)
24 #define BIT_RX_EN BIT(1)
25 #define MODE_CHANGE_EN 0x01b4
26 #define BIT_MODE_CHANGE_EN BIT(0)
27 #define MDIO_SINGLE_CMD 0x03c0
28 #define BIT_MDIO_BUSY BIT(20)
29 #define MDIO_READ (BIT(17) | BIT_MDIO_BUSY)
30 #define MDIO_WRITE (BIT(16) | BIT_MDIO_BUSY)
31 #define MDIO_SINGLE_DATA 0x03c4
32 #define MDIO_RDATA_STATUS 0x03d0
33 #define BIT_MDIO_RDATA_INVALID BIT(0)
34 #define RX_FQ_START_ADDR 0x0500
35 #define RX_FQ_DEPTH 0x0504
36 #define RX_FQ_WR_ADDR 0x0508
37 #define RX_FQ_RD_ADDR 0x050c
38 #define RX_FQ_REG_EN 0x0518
39 #define RX_BQ_START_ADDR 0x0520
40 #define RX_BQ_DEPTH 0x0524
41 #define RX_BQ_WR_ADDR 0x0528
42 #define RX_BQ_RD_ADDR 0x052c
43 #define RX_BQ_REG_EN 0x0538
44 #define TX_BQ_START_ADDR 0x0580
45 #define TX_BQ_DEPTH 0x0584
46 #define TX_BQ_WR_ADDR 0x0588
47 #define TX_BQ_RD_ADDR 0x058c
48 #define TX_BQ_REG_EN 0x0598
49 #define TX_RQ_START_ADDR 0x05a0
50 #define TX_RQ_DEPTH 0x05a4
51 #define TX_RQ_WR_ADDR 0x05a8
52 #define TX_RQ_RD_ADDR 0x05ac
53 #define TX_RQ_REG_EN 0x05b8
54 #define BIT_START_ADDR_EN BIT(2)
55 #define BIT_DEPTH_EN BIT(1)
56 #define DESC_WR_RD_ENA 0x05cc
57 #define BIT_RX_OUTCFF_WR BIT(3)
58 #define BIT_RX_CFF_RD BIT(2)
59 #define BIT_TX_OUTCFF_WR BIT(1)
60 #define BIT_TX_CFF_RD BIT(0)
61 #define BITS_DESC_ENA (BIT_RX_OUTCFF_WR | BIT_RX_CFF_RD | \
62 BIT_TX_OUTCFF_WR | BIT_TX_CFF_RD)
65 #define RGMII_SPEED_1000 0x2c
66 #define RGMII_SPEED_100 0x2f
67 #define RGMII_SPEED_10 0x2d
68 #define MII_SPEED_100 0x0f
69 #define MII_SPEED_10 0x0d
70 #define GMAC_SPEED_1000 0x05
71 #define GMAC_SPEED_100 0x01
72 #define GMAC_SPEED_10 0x00
73 #define GMAC_FULL_DUPLEX BIT(4)
75 #define RX_DESC_NUM 64
78 #define DESC_WORD_SHIFT 3
79 #define DESC_BYTE_SHIFT 5
80 #define DESC_CNT(n) ((n) >> DESC_BYTE_SHIFT)
81 #define DESC_BYTE(n) ((n) << DESC_BYTE_SHIFT)
82 #define DESC_VLD_FREE 0
83 #define DESC_VLD_BUSY 1
85 #define MAC_MAX_FRAME_SIZE 1600
95 unsigned int buf_addr
;
96 unsigned int buf_len
:11;
97 unsigned int reserve0
:5;
98 unsigned int data_len
:11;
99 unsigned int reserve1
:2;
101 unsigned int descvid
:1;
102 unsigned int reserve2
[6];
107 void __iomem
*macif_ctrl
;
108 struct reset_ctl rst_phy
;
109 struct higmac_desc
*rxfq
;
110 struct higmac_desc
*rxbq
;
111 struct higmac_desc
*txbq
;
112 struct higmac_desc
*txrq
;
115 struct phy_device
*phydev
;
120 #define flush_desc(d) flush_cache((unsigned long)(d), sizeof(*(d)))
121 #define invalidate_desc(d) \
122 invalidate_dcache_range((unsigned long)(d), \
123 (unsigned long)(d) + sizeof(*(d)))
125 static int higmac_write_hwaddr(struct udevice
*dev
)
127 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
128 struct higmac_priv
*priv
= dev_get_priv(dev
);
129 unsigned char *mac
= pdata
->enetaddr
;
132 val
= mac
[1] | (mac
[0] << 8);
133 writel(val
, priv
->base
+ STATION_ADDR_HIGH
);
135 val
= mac
[5] | (mac
[4] << 8) | (mac
[3] << 16) | (mac
[2] << 24);
136 writel(val
, priv
->base
+ STATION_ADDR_LOW
);
141 static int higmac_free_pkt(struct udevice
*dev
, uchar
*packet
, int length
)
143 struct higmac_priv
*priv
= dev_get_priv(dev
);
145 /* Inform GMAC that the RX descriptor is no longer in use */
146 writel(DESC_BYTE(priv
->rxdesc_in_use
), priv
->base
+ RX_BQ_RD_ADDR
);
151 static int higmac_recv(struct udevice
*dev
, int flags
, uchar
**packetp
)
153 struct higmac_priv
*priv
= dev_get_priv(dev
);
154 struct higmac_desc
*fqd
= priv
->rxfq
;
155 struct higmac_desc
*bqd
= priv
->rxbq
;
156 int fqw_pos
, fqr_pos
, bqw_pos
, bqr_pos
;
157 int timeout
= 100000;
162 fqw_pos
= DESC_CNT(readl(priv
->base
+ RX_FQ_WR_ADDR
));
163 fqr_pos
= DESC_CNT(readl(priv
->base
+ RX_FQ_RD_ADDR
));
165 if (fqw_pos
>= fqr_pos
)
166 space
= RX_DESC_NUM
- (fqw_pos
- fqr_pos
);
168 space
= fqr_pos
- fqw_pos
;
170 /* Leave one free to distinguish full filled from empty buffer */
171 for (i
= 0; i
< space
- 1; i
++) {
172 fqd
= priv
->rxfq
+ fqw_pos
;
173 invalidate_dcache_range(fqd
->buf_addr
,
174 fqd
->buf_addr
+ MAC_MAX_FRAME_SIZE
);
176 if (++fqw_pos
>= RX_DESC_NUM
)
179 writel(DESC_BYTE(fqw_pos
), priv
->base
+ RX_FQ_WR_ADDR
);
182 bqr_pos
= DESC_CNT(readl(priv
->base
+ RX_BQ_RD_ADDR
));
184 /* BQ is only ever written by GMAC */
185 invalidate_desc(bqd
);
188 bqw_pos
= DESC_CNT(readl(priv
->base
+ RX_BQ_WR_ADDR
));
190 } while (--timeout
&& bqw_pos
== bqr_pos
);
195 if (++bqr_pos
>= RX_DESC_NUM
)
200 /* CPU should not have touched this buffer since we added it to FQ */
201 invalidate_dcache_range(bqd
->buf_addr
, bqd
->buf_addr
+ len
);
202 *packetp
= (void *)(unsigned long)bqd
->buf_addr
;
204 /* Record the RX_BQ descriptor that is holding RX data */
205 priv
->rxdesc_in_use
= bqr_pos
;
210 static int higmac_send(struct udevice
*dev
, void *packet
, int length
)
212 struct higmac_priv
*priv
= dev_get_priv(dev
);
213 struct higmac_desc
*bqd
= priv
->txbq
;
214 int bqw_pos
, rqw_pos
, rqr_pos
;
217 flush_cache((unsigned long)packet
, length
);
219 bqw_pos
= DESC_CNT(readl(priv
->base
+ TX_BQ_WR_ADDR
));
221 bqd
->buf_addr
= (unsigned long)packet
;
222 bqd
->descvid
= DESC_VLD_BUSY
;
223 bqd
->data_len
= length
;
226 if (++bqw_pos
>= TX_DESC_NUM
)
229 writel(DESC_BYTE(bqw_pos
), priv
->base
+ TX_BQ_WR_ADDR
);
231 rqr_pos
= DESC_CNT(readl(priv
->base
+ TX_RQ_RD_ADDR
));
232 if (++rqr_pos
>= TX_DESC_NUM
)
236 rqw_pos
= DESC_CNT(readl(priv
->base
+ TX_RQ_WR_ADDR
));
238 } while (--timeout
&& rqr_pos
!= rqw_pos
);
243 writel(DESC_BYTE(rqr_pos
), priv
->base
+ TX_RQ_RD_ADDR
);
248 static int higmac_adjust_link(struct higmac_priv
*priv
)
250 struct phy_device
*phydev
= priv
->phydev
;
251 int interface
= priv
->phyintf
;
255 case PHY_INTERFACE_MODE_RGMII
:
256 if (phydev
->speed
== SPEED_1000
)
257 val
= RGMII_SPEED_1000
;
258 else if (phydev
->speed
== SPEED_100
)
259 val
= RGMII_SPEED_100
;
261 val
= RGMII_SPEED_10
;
263 case PHY_INTERFACE_MODE_MII
:
264 if (phydev
->speed
== SPEED_100
)
270 debug("unsupported mode: %d\n", interface
);
275 val
|= GMAC_FULL_DUPLEX
;
277 writel(val
, priv
->macif_ctrl
);
279 if (phydev
->speed
== SPEED_1000
)
280 val
= GMAC_SPEED_1000
;
281 else if (phydev
->speed
== SPEED_100
)
282 val
= GMAC_SPEED_100
;
286 writel(BIT_MODE_CHANGE_EN
, priv
->base
+ MODE_CHANGE_EN
);
287 writel(val
, priv
->base
+ PORT_MODE
);
288 writel(0, priv
->base
+ MODE_CHANGE_EN
);
289 writel(phydev
->duplex
, priv
->base
+ MAC_DUPLEX_HALF_CTRL
);
294 static int higmac_start(struct udevice
*dev
)
296 struct higmac_priv
*priv
= dev_get_priv(dev
);
297 struct phy_device
*phydev
= priv
->phydev
;
300 ret
= phy_startup(phydev
);
305 debug("%s: link down\n", phydev
->dev
->name
);
309 ret
= higmac_adjust_link(priv
);
314 writel(BITS_DESC_ENA
, priv
->base
+ DESC_WR_RD_ENA
);
315 writel(BIT_TX_EN
| BIT_RX_EN
, priv
->base
+ PORT_EN
);
320 static void higmac_stop(struct udevice
*dev
)
322 struct higmac_priv
*priv
= dev_get_priv(dev
);
325 writel(0, priv
->base
+ PORT_EN
);
326 writel(0, priv
->base
+ DESC_WR_RD_ENA
);
329 static const struct eth_ops higmac_ops
= {
330 .start
= higmac_start
,
333 .free_pkt
= higmac_free_pkt
,
335 .write_hwaddr
= higmac_write_hwaddr
,
338 static int higmac_mdio_read(struct mii_dev
*bus
, int addr
, int devad
, int reg
)
340 struct higmac_priv
*priv
= bus
->priv
;
343 ret
= wait_for_bit_le32(priv
->base
+ MDIO_SINGLE_CMD
, BIT_MDIO_BUSY
,
348 writel(MDIO_READ
| addr
<< 8 | reg
, priv
->base
+ MDIO_SINGLE_CMD
);
350 ret
= wait_for_bit_le32(priv
->base
+ MDIO_SINGLE_CMD
, BIT_MDIO_BUSY
,
355 if (readl(priv
->base
+ MDIO_RDATA_STATUS
) & BIT_MDIO_RDATA_INVALID
)
358 return readl(priv
->base
+ MDIO_SINGLE_DATA
) >> 16;
361 static int higmac_mdio_write(struct mii_dev
*bus
, int addr
, int devad
,
364 struct higmac_priv
*priv
= bus
->priv
;
367 ret
= wait_for_bit_le32(priv
->base
+ MDIO_SINGLE_CMD
, BIT_MDIO_BUSY
,
372 writel(value
, priv
->base
+ MDIO_SINGLE_DATA
);
373 writel(MDIO_WRITE
| addr
<< 8 | reg
, priv
->base
+ MDIO_SINGLE_CMD
);
378 static int higmac_init_rx_descs(struct higmac_desc
*descs
, int num
)
382 for (i
= 0; i
< num
; i
++) {
383 struct higmac_desc
*desc
= &descs
[i
];
385 desc
->buf_addr
= (unsigned long)memalign(ARCH_DMA_MINALIGN
,
390 desc
->descvid
= DESC_VLD_FREE
;
391 desc
->buf_len
= MAC_MAX_FRAME_SIZE
- 1;
399 free((void *)(unsigned long)descs
[i
].buf_addr
);
403 static int higmac_init_hw_queue(struct higmac_priv
*priv
,
404 enum higmac_queue queue
)
406 struct higmac_desc
*desc
, **pdesc
;
407 u32 regaddr
, regen
, regdep
;
413 regaddr
= RX_FQ_START_ADDR
;
414 regen
= RX_FQ_REG_EN
;
415 regdep
= RX_FQ_DEPTH
;
420 regaddr
= RX_BQ_START_ADDR
;
421 regen
= RX_BQ_REG_EN
;
422 regdep
= RX_BQ_DEPTH
;
427 regaddr
= TX_BQ_START_ADDR
;
428 regen
= TX_BQ_REG_EN
;
429 regdep
= TX_BQ_DEPTH
;
434 regaddr
= TX_RQ_START_ADDR
;
435 regen
= TX_RQ_REG_EN
;
436 regdep
= TX_RQ_DEPTH
;
443 writel(BIT_DEPTH_EN
, priv
->base
+ regen
);
444 writel(depth
<< DESC_WORD_SHIFT
, priv
->base
+ regdep
);
445 writel(0, priv
->base
+ regen
);
447 len
= depth
* sizeof(*desc
);
448 desc
= memalign(ARCH_DMA_MINALIGN
, len
);
451 memset(desc
, 0, len
);
452 flush_cache((unsigned long)desc
, len
);
455 /* Set up RX_FQ descriptors */
457 higmac_init_rx_descs(desc
, depth
);
459 /* Enable start address */
460 writel(BIT_START_ADDR_EN
, priv
->base
+ regen
);
461 writel((unsigned long)desc
, priv
->base
+ regaddr
);
462 writel(0, priv
->base
+ regen
);
467 static int higmac_hw_init(struct higmac_priv
*priv
)
471 /* Initialize hardware queues */
472 ret
= higmac_init_hw_queue(priv
, RX_FQ
);
476 ret
= higmac_init_hw_queue(priv
, RX_BQ
);
480 ret
= higmac_init_hw_queue(priv
, TX_BQ
);
484 ret
= higmac_init_hw_queue(priv
, TX_RQ
);
489 reset_deassert(&priv
->rst_phy
);
491 reset_assert(&priv
->rst_phy
);
493 reset_deassert(&priv
->rst_phy
);
507 static int higmac_probe(struct udevice
*dev
)
509 struct higmac_priv
*priv
= dev_get_priv(dev
);
510 struct phy_device
*phydev
;
514 ret
= higmac_hw_init(priv
);
522 bus
->read
= higmac_mdio_read
;
523 bus
->write
= higmac_mdio_write
;
527 ret
= mdio_register_seq(bus
, dev
->seq
);
531 phydev
= phy_connect(bus
, priv
->phyaddr
, dev
, priv
->phyintf
);
535 phydev
->supported
&= PHY_GBIT_FEATURES
;
536 phydev
->advertising
= phydev
->supported
;
537 priv
->phydev
= phydev
;
539 return phy_config(phydev
);
542 static int higmac_remove(struct udevice
*dev
)
544 struct higmac_priv
*priv
= dev_get_priv(dev
);
547 mdio_unregister(priv
->bus
);
548 mdio_free(priv
->bus
);
550 /* Free RX packet buffers */
551 for (i
= 0; i
< RX_DESC_NUM
; i
++)
552 free((void *)(unsigned long)priv
->rxfq
[i
].buf_addr
);
557 static int higmac_ofdata_to_platdata(struct udevice
*dev
)
559 struct higmac_priv
*priv
= dev_get_priv(dev
);
560 int phyintf
= PHY_INTERFACE_MODE_NONE
;
561 const char *phy_mode
;
564 priv
->base
= dev_remap_addr_index(dev
, 0);
565 priv
->macif_ctrl
= dev_remap_addr_index(dev
, 1);
567 phy_mode
= dev_read_string(dev
, "phy-mode");
569 phyintf
= phy_get_interface_by_name(phy_mode
);
570 if (phyintf
== PHY_INTERFACE_MODE_NONE
)
572 priv
->phyintf
= phyintf
;
574 phy_node
= dev_read_subnode(dev
, "phy");
575 if (!ofnode_valid(phy_node
)) {
576 debug("failed to find phy node\n");
579 priv
->phyaddr
= ofnode_read_u32_default(phy_node
, "reg", 0);
581 return reset_get_by_name(dev
, "phy", &priv
->rst_phy
);
584 static const struct udevice_id higmac_ids
[] = {
585 { .compatible
= "hisilicon,hi3798cv200-gmac" },
589 U_BOOT_DRIVER(eth_higmac
) = {
590 .name
= "eth_higmac",
592 .of_match
= higmac_ids
,
593 .ofdata_to_platdata
= higmac_ofdata_to_platdata
,
594 .probe
= higmac_probe
,
595 .remove
= higmac_remove
,
597 .priv_auto_alloc_size
= sizeof(struct higmac_priv
),
598 .platdata_auto_alloc_size
= sizeof(struct eth_pdata
),