2 * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer
4 * Copyright (C) 2017 Corentin Labbe <clabbe.montjoie@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/clk.h>
19 #include <linux/iopoll.h>
20 #include <linux/mdio-mux.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/of_mdio.h>
25 #include <linux/of_net.h>
26 #include <linux/phy.h>
27 #include <linux/platform_device.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/regmap.h>
30 #include <linux/stmmac.h>
33 #include "stmmac_platform.h"
35 /* General notes on dwmac-sun8i:
36 * Locking: no locking is necessary in this file because all necessary locking
37 * is done in the "stmmac files"
40 /* struct emac_variant - Descrive dwmac-sun8i hardware variant
41 * @default_syscon_value: The default value of the EMAC register in syscon
42 * This value is used for disabling properly EMAC
43 * and used as a good starting value in case of the
44 * boot process(uboot) leave some stuff.
45 * @soc_has_internal_phy: Does the MAC embed an internal PHY
46 * @support_mii: Does the MAC handle MII
47 * @support_rmii: Does the MAC handle RMII
48 * @support_rgmii: Does the MAC handle RGMII
51 u32 default_syscon_value
;
52 bool soc_has_internal_phy
;
58 /* struct sunxi_priv_data - hold all sunxi private data
59 * @tx_clk: reference to MAC TX clock
60 * @ephy_clk: reference to the optional EPHY clock for the internal PHY
61 * @regulator: reference to the optional regulator
62 * @rst_ephy: reference to the optional EPHY reset for the internal PHY
63 * @variant: reference to the current board variant
64 * @regmap: regmap for using the syscon
65 * @internal_phy_powered: Does the internal PHY is enabled
66 * @mux_handle: Internal pointer used by mdio-mux lib
68 struct sunxi_priv_data
{
71 struct regulator
*regulator
;
72 struct reset_control
*rst_ephy
;
73 const struct emac_variant
*variant
;
74 struct regmap
*regmap
;
75 bool internal_phy_powered
;
79 static const struct emac_variant emac_variant_h3
= {
80 .default_syscon_value
= 0x58000,
81 .soc_has_internal_phy
= true,
87 static const struct emac_variant emac_variant_v3s
= {
88 .default_syscon_value
= 0x38000,
89 .soc_has_internal_phy
= true,
93 static const struct emac_variant emac_variant_a83t
= {
94 .default_syscon_value
= 0,
95 .soc_has_internal_phy
= false,
100 static const struct emac_variant emac_variant_a64
= {
101 .default_syscon_value
= 0,
102 .soc_has_internal_phy
= false,
104 .support_rmii
= true,
105 .support_rgmii
= true
108 #define EMAC_BASIC_CTL0 0x00
109 #define EMAC_BASIC_CTL1 0x04
110 #define EMAC_INT_STA 0x08
111 #define EMAC_INT_EN 0x0C
112 #define EMAC_TX_CTL0 0x10
113 #define EMAC_TX_CTL1 0x14
114 #define EMAC_TX_FLOW_CTL 0x1C
115 #define EMAC_TX_DESC_LIST 0x20
116 #define EMAC_RX_CTL0 0x24
117 #define EMAC_RX_CTL1 0x28
118 #define EMAC_RX_DESC_LIST 0x34
119 #define EMAC_RX_FRM_FLT 0x38
120 #define EMAC_MDIO_CMD 0x48
121 #define EMAC_MDIO_DATA 0x4C
122 #define EMAC_MACADDR_HI(reg) (0x50 + (reg) * 8)
123 #define EMAC_MACADDR_LO(reg) (0x54 + (reg) * 8)
124 #define EMAC_TX_DMA_STA 0xB0
125 #define EMAC_TX_CUR_DESC 0xB4
126 #define EMAC_TX_CUR_BUF 0xB8
127 #define EMAC_RX_DMA_STA 0xC0
128 #define EMAC_RX_CUR_DESC 0xC4
129 #define EMAC_RX_CUR_BUF 0xC8
131 /* Use in EMAC_BASIC_CTL0 */
132 #define EMAC_DUPLEX_FULL BIT(0)
133 #define EMAC_LOOPBACK BIT(1)
134 #define EMAC_SPEED_1000 0
135 #define EMAC_SPEED_100 (0x03 << 2)
136 #define EMAC_SPEED_10 (0x02 << 2)
138 /* Use in EMAC_BASIC_CTL1 */
139 #define EMAC_BURSTLEN_SHIFT 24
141 /* Used in EMAC_RX_FRM_FLT */
142 #define EMAC_FRM_FLT_RXALL BIT(0)
143 #define EMAC_FRM_FLT_CTL BIT(13)
144 #define EMAC_FRM_FLT_MULTICAST BIT(16)
147 #define EMAC_RX_MD BIT(1)
148 #define EMAC_RX_TH_MASK GENMASK(4, 5)
149 #define EMAC_RX_TH_32 0
150 #define EMAC_RX_TH_64 (0x1 << 4)
151 #define EMAC_RX_TH_96 (0x2 << 4)
152 #define EMAC_RX_TH_128 (0x3 << 4)
153 #define EMAC_RX_DMA_EN BIT(30)
154 #define EMAC_RX_DMA_START BIT(31)
157 #define EMAC_TX_MD BIT(1)
158 #define EMAC_TX_NEXT_FRM BIT(2)
159 #define EMAC_TX_TH_MASK GENMASK(8, 10)
160 #define EMAC_TX_TH_64 0
161 #define EMAC_TX_TH_128 (0x1 << 8)
162 #define EMAC_TX_TH_192 (0x2 << 8)
163 #define EMAC_TX_TH_256 (0x3 << 8)
164 #define EMAC_TX_DMA_EN BIT(30)
165 #define EMAC_TX_DMA_START BIT(31)
167 /* Used in RX_CTL0 */
168 #define EMAC_RX_RECEIVER_EN BIT(31)
169 #define EMAC_RX_DO_CRC BIT(27)
170 #define EMAC_RX_FLOW_CTL_EN BIT(16)
172 /* Used in TX_CTL0 */
173 #define EMAC_TX_TRANSMITTER_EN BIT(31)
175 /* Used in EMAC_TX_FLOW_CTL */
176 #define EMAC_TX_FLOW_CTL_EN BIT(0)
178 /* Used in EMAC_INT_STA */
179 #define EMAC_TX_INT BIT(0)
180 #define EMAC_TX_DMA_STOP_INT BIT(1)
181 #define EMAC_TX_BUF_UA_INT BIT(2)
182 #define EMAC_TX_TIMEOUT_INT BIT(3)
183 #define EMAC_TX_UNDERFLOW_INT BIT(4)
184 #define EMAC_TX_EARLY_INT BIT(5)
185 #define EMAC_RX_INT BIT(8)
186 #define EMAC_RX_BUF_UA_INT BIT(9)
187 #define EMAC_RX_DMA_STOP_INT BIT(10)
188 #define EMAC_RX_TIMEOUT_INT BIT(11)
189 #define EMAC_RX_OVERFLOW_INT BIT(12)
190 #define EMAC_RX_EARLY_INT BIT(13)
191 #define EMAC_RGMII_STA_INT BIT(16)
193 #define MAC_ADDR_TYPE_DST BIT(31)
195 /* H3 specific bits for EPHY */
196 #define H3_EPHY_ADDR_SHIFT 20
197 #define H3_EPHY_CLK_SEL BIT(18) /* 1: 24MHz, 0: 25MHz */
198 #define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */
199 #define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */
200 #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */
201 #define H3_EPHY_MUX_MASK (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT)
202 #define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID 1
203 #define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID 2
205 /* H3/A64 specific bits */
206 #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
208 /* Generic system control EMAC_CLK bits */
209 #define SYSCON_ETXDC_MASK GENMASK(2, 0)
210 #define SYSCON_ETXDC_SHIFT 10
211 #define SYSCON_ERXDC_MASK GENMASK(4, 0)
212 #define SYSCON_ERXDC_SHIFT 5
213 /* EMAC PHY Interface Type */
214 #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
215 #define SYSCON_ETCS_MASK GENMASK(1, 0)
216 #define SYSCON_ETCS_MII 0x0
217 #define SYSCON_ETCS_EXT_GMII 0x1
218 #define SYSCON_ETCS_INT_GMII 0x2
219 #define SYSCON_EMAC_REG 0x30
221 /* sun8i_dwmac_dma_reset() - reset the EMAC
222 * Called from stmmac via stmmac_dma_ops->reset
224 static int sun8i_dwmac_dma_reset(void __iomem
*ioaddr
)
226 writel(0, ioaddr
+ EMAC_RX_CTL1
);
227 writel(0, ioaddr
+ EMAC_TX_CTL1
);
228 writel(0, ioaddr
+ EMAC_RX_FRM_FLT
);
229 writel(0, ioaddr
+ EMAC_RX_DESC_LIST
);
230 writel(0, ioaddr
+ EMAC_TX_DESC_LIST
);
231 writel(0, ioaddr
+ EMAC_INT_EN
);
232 writel(0x1FFFFFF, ioaddr
+ EMAC_INT_STA
);
236 /* sun8i_dwmac_dma_init() - initialize the EMAC
237 * Called from stmmac via stmmac_dma_ops->init
239 static void sun8i_dwmac_dma_init(void __iomem
*ioaddr
,
240 struct stmmac_dma_cfg
*dma_cfg
,
241 u32 dma_tx
, u32 dma_rx
, int atds
)
243 /* Write TX and RX descriptors address */
244 writel(dma_rx
, ioaddr
+ EMAC_RX_DESC_LIST
);
245 writel(dma_tx
, ioaddr
+ EMAC_TX_DESC_LIST
);
247 writel(EMAC_RX_INT
| EMAC_TX_INT
, ioaddr
+ EMAC_INT_EN
);
248 writel(0x1FFFFFF, ioaddr
+ EMAC_INT_STA
);
251 /* sun8i_dwmac_dump_regs() - Dump EMAC address space
252 * Called from stmmac_dma_ops->dump_regs
255 static void sun8i_dwmac_dump_regs(void __iomem
*ioaddr
, u32
*reg_space
)
259 for (i
= 0; i
< 0xC8; i
+= 4) {
260 if (i
== 0x32 || i
== 0x3C)
262 reg_space
[i
/ 4] = readl(ioaddr
+ i
);
266 /* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
267 * Called from stmmac_ops->dump_regs
270 static void sun8i_dwmac_dump_mac_regs(struct mac_device_info
*hw
,
274 void __iomem
*ioaddr
= hw
->pcsr
;
276 for (i
= 0; i
< 0xC8; i
+= 4) {
277 if (i
== 0x32 || i
== 0x3C)
279 reg_space
[i
/ 4] = readl(ioaddr
+ i
);
283 static void sun8i_dwmac_enable_dma_irq(void __iomem
*ioaddr
, u32 chan
)
285 writel(EMAC_RX_INT
| EMAC_TX_INT
, ioaddr
+ EMAC_INT_EN
);
288 static void sun8i_dwmac_disable_dma_irq(void __iomem
*ioaddr
, u32 chan
)
290 writel(0, ioaddr
+ EMAC_INT_EN
);
293 static void sun8i_dwmac_dma_start_tx(void __iomem
*ioaddr
, u32 chan
)
297 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
298 v
|= EMAC_TX_DMA_START
;
300 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
303 static void sun8i_dwmac_enable_dma_transmission(void __iomem
*ioaddr
)
307 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
308 v
|= EMAC_TX_DMA_START
;
310 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
313 static void sun8i_dwmac_dma_stop_tx(void __iomem
*ioaddr
, u32 chan
)
317 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
318 v
&= ~EMAC_TX_DMA_EN
;
319 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
322 static void sun8i_dwmac_dma_start_rx(void __iomem
*ioaddr
, u32 chan
)
326 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
327 v
|= EMAC_RX_DMA_START
;
329 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
332 static void sun8i_dwmac_dma_stop_rx(void __iomem
*ioaddr
, u32 chan
)
336 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
337 v
&= ~EMAC_RX_DMA_EN
;
338 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
341 static int sun8i_dwmac_dma_interrupt(void __iomem
*ioaddr
,
342 struct stmmac_extra_stats
*x
, u32 chan
)
347 v
= readl(ioaddr
+ EMAC_INT_STA
);
349 if (v
& EMAC_TX_INT
) {
351 x
->tx_normal_irq_n
++;
354 if (v
& EMAC_TX_DMA_STOP_INT
)
355 x
->tx_process_stopped_irq
++;
357 if (v
& EMAC_TX_BUF_UA_INT
)
358 x
->tx_process_stopped_irq
++;
360 if (v
& EMAC_TX_TIMEOUT_INT
)
361 ret
|= tx_hard_error
;
363 if (v
& EMAC_TX_UNDERFLOW_INT
) {
364 ret
|= tx_hard_error
;
365 x
->tx_undeflow_irq
++;
368 if (v
& EMAC_TX_EARLY_INT
)
371 if (v
& EMAC_RX_INT
) {
373 x
->rx_normal_irq_n
++;
376 if (v
& EMAC_RX_BUF_UA_INT
)
377 x
->rx_buf_unav_irq
++;
379 if (v
& EMAC_RX_DMA_STOP_INT
)
380 x
->rx_process_stopped_irq
++;
382 if (v
& EMAC_RX_TIMEOUT_INT
)
383 ret
|= tx_hard_error
;
385 if (v
& EMAC_RX_OVERFLOW_INT
) {
386 ret
|= tx_hard_error
;
387 x
->rx_overflow_irq
++;
390 if (v
& EMAC_RX_EARLY_INT
)
393 if (v
& EMAC_RGMII_STA_INT
)
396 writel(v
, ioaddr
+ EMAC_INT_STA
);
401 static void sun8i_dwmac_dma_operation_mode(void __iomem
*ioaddr
, int txmode
,
402 int rxmode
, int rxfifosz
)
406 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
407 if (txmode
== SF_DMA_MODE
) {
409 /* Undocumented bit (called TX_NEXT_FRM in BSP), the original
411 * "Operating on second frame increase the performance
412 * especially when transmit store-and-forward is used."
414 v
|= EMAC_TX_NEXT_FRM
;
417 v
&= ~EMAC_TX_TH_MASK
;
420 else if (txmode
< 128)
422 else if (txmode
< 192)
424 else if (txmode
< 256)
427 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
429 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
430 if (rxmode
== SF_DMA_MODE
) {
434 v
&= ~EMAC_RX_TH_MASK
;
437 else if (rxmode
< 64)
439 else if (rxmode
< 96)
441 else if (rxmode
< 128)
444 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
447 static const struct stmmac_dma_ops sun8i_dwmac_dma_ops
= {
448 .reset
= sun8i_dwmac_dma_reset
,
449 .init
= sun8i_dwmac_dma_init
,
450 .dump_regs
= sun8i_dwmac_dump_regs
,
451 .dma_mode
= sun8i_dwmac_dma_operation_mode
,
452 .enable_dma_transmission
= sun8i_dwmac_enable_dma_transmission
,
453 .enable_dma_irq
= sun8i_dwmac_enable_dma_irq
,
454 .disable_dma_irq
= sun8i_dwmac_disable_dma_irq
,
455 .start_tx
= sun8i_dwmac_dma_start_tx
,
456 .stop_tx
= sun8i_dwmac_dma_stop_tx
,
457 .start_rx
= sun8i_dwmac_dma_start_rx
,
458 .stop_rx
= sun8i_dwmac_dma_stop_rx
,
459 .dma_interrupt
= sun8i_dwmac_dma_interrupt
,
462 static int sun8i_dwmac_init(struct platform_device
*pdev
, void *priv
)
464 struct sunxi_priv_data
*gmac
= priv
;
467 if (gmac
->regulator
) {
468 ret
= regulator_enable(gmac
->regulator
);
470 dev_err(&pdev
->dev
, "Fail to enable regulator\n");
475 ret
= clk_prepare_enable(gmac
->tx_clk
);
478 regulator_disable(gmac
->regulator
);
479 dev_err(&pdev
->dev
, "Could not enable AHB clock\n");
486 static void sun8i_dwmac_core_init(struct mac_device_info
*hw
,
487 struct net_device
*dev
)
489 void __iomem
*ioaddr
= hw
->pcsr
;
492 v
= (8 << EMAC_BURSTLEN_SHIFT
); /* burst len */
493 writel(v
, ioaddr
+ EMAC_BASIC_CTL1
);
496 static void sun8i_dwmac_set_mac(void __iomem
*ioaddr
, bool enable
)
500 t
= readl(ioaddr
+ EMAC_TX_CTL0
);
501 r
= readl(ioaddr
+ EMAC_RX_CTL0
);
503 t
|= EMAC_TX_TRANSMITTER_EN
;
504 r
|= EMAC_RX_RECEIVER_EN
;
506 t
&= ~EMAC_TX_TRANSMITTER_EN
;
507 r
&= ~EMAC_RX_RECEIVER_EN
;
509 writel(t
, ioaddr
+ EMAC_TX_CTL0
);
510 writel(r
, ioaddr
+ EMAC_RX_CTL0
);
513 /* Set MAC address at slot reg_n
514 * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST
515 * If addr is NULL, clear the slot
517 static void sun8i_dwmac_set_umac_addr(struct mac_device_info
*hw
,
521 void __iomem
*ioaddr
= hw
->pcsr
;
525 writel(0, ioaddr
+ EMAC_MACADDR_HI(reg_n
));
529 stmmac_set_mac_addr(ioaddr
, addr
, EMAC_MACADDR_HI(reg_n
),
530 EMAC_MACADDR_LO(reg_n
));
532 v
= readl(ioaddr
+ EMAC_MACADDR_HI(reg_n
));
533 v
|= MAC_ADDR_TYPE_DST
;
534 writel(v
, ioaddr
+ EMAC_MACADDR_HI(reg_n
));
538 static void sun8i_dwmac_get_umac_addr(struct mac_device_info
*hw
,
542 void __iomem
*ioaddr
= hw
->pcsr
;
544 stmmac_get_mac_addr(ioaddr
, addr
, EMAC_MACADDR_HI(reg_n
),
545 EMAC_MACADDR_LO(reg_n
));
548 /* caution this function must return non 0 to work */
549 static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info
*hw
)
551 void __iomem
*ioaddr
= hw
->pcsr
;
554 v
= readl(ioaddr
+ EMAC_RX_CTL0
);
556 writel(v
, ioaddr
+ EMAC_RX_CTL0
);
561 static void sun8i_dwmac_set_filter(struct mac_device_info
*hw
,
562 struct net_device
*dev
)
564 void __iomem
*ioaddr
= hw
->pcsr
;
567 struct netdev_hw_addr
*ha
;
568 int macaddrs
= netdev_uc_count(dev
) + netdev_mc_count(dev
) + 1;
570 v
= EMAC_FRM_FLT_CTL
;
572 if (dev
->flags
& IFF_PROMISC
) {
573 v
= EMAC_FRM_FLT_RXALL
;
574 } else if (dev
->flags
& IFF_ALLMULTI
) {
575 v
|= EMAC_FRM_FLT_MULTICAST
;
576 } else if (macaddrs
<= hw
->unicast_filter_entries
) {
577 if (!netdev_mc_empty(dev
)) {
578 netdev_for_each_mc_addr(ha
, dev
) {
579 sun8i_dwmac_set_umac_addr(hw
, ha
->addr
, i
);
583 if (!netdev_uc_empty(dev
)) {
584 netdev_for_each_uc_addr(ha
, dev
) {
585 sun8i_dwmac_set_umac_addr(hw
, ha
->addr
, i
);
590 netdev_info(dev
, "Too many address, switching to promiscuous\n");
591 v
= EMAC_FRM_FLT_RXALL
;
594 /* Disable unused address filter slots */
595 while (i
< hw
->unicast_filter_entries
)
596 sun8i_dwmac_set_umac_addr(hw
, NULL
, i
++);
598 writel(v
, ioaddr
+ EMAC_RX_FRM_FLT
);
601 static void sun8i_dwmac_flow_ctrl(struct mac_device_info
*hw
,
602 unsigned int duplex
, unsigned int fc
,
603 unsigned int pause_time
, u32 tx_cnt
)
605 void __iomem
*ioaddr
= hw
->pcsr
;
608 v
= readl(ioaddr
+ EMAC_RX_CTL0
);
610 v
|= EMAC_RX_FLOW_CTL_EN
;
612 v
&= ~EMAC_RX_FLOW_CTL_EN
;
613 writel(v
, ioaddr
+ EMAC_RX_CTL0
);
615 v
= readl(ioaddr
+ EMAC_TX_FLOW_CTL
);
617 v
|= EMAC_TX_FLOW_CTL_EN
;
619 v
&= ~EMAC_TX_FLOW_CTL_EN
;
620 writel(v
, ioaddr
+ EMAC_TX_FLOW_CTL
);
623 static int sun8i_dwmac_reset(struct stmmac_priv
*priv
)
628 v
= readl(priv
->ioaddr
+ EMAC_BASIC_CTL1
);
629 writel(v
| 0x01, priv
->ioaddr
+ EMAC_BASIC_CTL1
);
631 /* The timeout was previoulsy set to 10ms, but some board (OrangePI0)
632 * need more if no cable plugged. 100ms seems OK
634 err
= readl_poll_timeout(priv
->ioaddr
+ EMAC_BASIC_CTL1
, v
,
635 !(v
& 0x01), 100, 100000);
638 dev_err(priv
->device
, "EMAC reset timeout\n");
644 /* Search in mdio-mux node for internal PHY node and get its clk/reset */
645 static int get_ephy_nodes(struct stmmac_priv
*priv
)
647 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
648 struct device_node
*mdio_mux
, *iphynode
;
649 struct device_node
*mdio_internal
;
652 mdio_mux
= of_get_child_by_name(priv
->device
->of_node
, "mdio-mux");
654 dev_err(priv
->device
, "Cannot get mdio-mux node\n");
658 mdio_internal
= of_find_compatible_node(mdio_mux
, NULL
,
659 "allwinner,sun8i-h3-mdio-internal");
660 if (!mdio_internal
) {
661 dev_err(priv
->device
, "Cannot get internal_mdio node\n");
665 /* Seek for internal PHY */
666 for_each_child_of_node(mdio_internal
, iphynode
) {
667 gmac
->ephy_clk
= of_clk_get(iphynode
, 0);
668 if (IS_ERR(gmac
->ephy_clk
))
670 gmac
->rst_ephy
= of_reset_control_get_exclusive(iphynode
, NULL
);
671 if (IS_ERR(gmac
->rst_ephy
)) {
672 ret
= PTR_ERR(gmac
->rst_ephy
);
673 if (ret
== -EPROBE_DEFER
)
677 dev_info(priv
->device
, "Found internal PHY node\n");
683 static int sun8i_dwmac_power_internal_phy(struct stmmac_priv
*priv
)
685 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
688 if (gmac
->internal_phy_powered
) {
689 dev_warn(priv
->device
, "Internal PHY already powered\n");
693 dev_info(priv
->device
, "Powering internal PHY\n");
694 ret
= clk_prepare_enable(gmac
->ephy_clk
);
696 dev_err(priv
->device
, "Cannot enable internal PHY\n");
700 /* Make sure the EPHY is properly reseted, as U-Boot may leave
701 * it at deasserted state, and thus it may fail to reset EMAC.
703 reset_control_assert(gmac
->rst_ephy
);
705 ret
= reset_control_deassert(gmac
->rst_ephy
);
707 dev_err(priv
->device
, "Cannot deassert internal phy\n");
708 clk_disable_unprepare(gmac
->ephy_clk
);
712 gmac
->internal_phy_powered
= true;
717 static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data
*gmac
)
719 if (!gmac
->internal_phy_powered
)
722 clk_disable_unprepare(gmac
->ephy_clk
);
723 reset_control_assert(gmac
->rst_ephy
);
724 gmac
->internal_phy_powered
= false;
728 /* MDIO multiplexing switch function
729 * This function is called by the mdio-mux layer when it thinks the mdio bus
730 * multiplexer needs to switch.
731 * 'current_child' is the current value of the mux register
732 * 'desired_child' is the value of the 'reg' property of the target child MDIO
734 * The first time this function is called, current_child == -1.
735 * If current_child == desired_child, then the mux is already set to the
738 static int mdio_mux_syscon_switch_fn(int current_child
, int desired_child
,
741 struct stmmac_priv
*priv
= data
;
742 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
745 bool need_power_ephy
= false;
747 if (current_child
^ desired_child
) {
748 regmap_read(gmac
->regmap
, SYSCON_EMAC_REG
, ®
);
749 switch (desired_child
) {
750 case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID
:
751 dev_info(priv
->device
, "Switch mux to internal PHY");
752 val
= (reg
& ~H3_EPHY_MUX_MASK
) | H3_EPHY_SELECT
;
754 need_power_ephy
= true;
756 case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID
:
757 dev_info(priv
->device
, "Switch mux to external PHY");
758 val
= (reg
& ~H3_EPHY_MUX_MASK
) | H3_EPHY_SHUTDOWN
;
759 need_power_ephy
= false;
762 dev_err(priv
->device
, "Invalid child ID %x\n",
766 regmap_write(gmac
->regmap
, SYSCON_EMAC_REG
, val
);
767 if (need_power_ephy
) {
768 ret
= sun8i_dwmac_power_internal_phy(priv
);
772 sun8i_dwmac_unpower_internal_phy(gmac
);
774 /* After changing syscon value, the MAC need reset or it will
775 * use the last value (and so the last PHY set).
777 ret
= sun8i_dwmac_reset(priv
);
782 static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv
*priv
)
785 struct device_node
*mdio_mux
;
786 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
788 mdio_mux
= of_get_child_by_name(priv
->device
->of_node
, "mdio-mux");
792 ret
= mdio_mux_init(priv
->device
, mdio_mux
, mdio_mux_syscon_switch_fn
,
793 &gmac
->mux_handle
, priv
, priv
->mii
);
797 static int sun8i_dwmac_set_syscon(struct stmmac_priv
*priv
)
799 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
800 struct device_node
*node
= priv
->device
->of_node
;
804 regmap_read(gmac
->regmap
, SYSCON_EMAC_REG
, &val
);
805 reg
= gmac
->variant
->default_syscon_value
;
807 dev_warn(priv
->device
,
808 "Current syscon value is not the default %x (expect %x)\n",
811 if (gmac
->variant
->soc_has_internal_phy
) {
812 if (of_property_read_bool(node
, "allwinner,leds-active-low"))
813 reg
|= H3_EPHY_LED_POL
;
815 reg
&= ~H3_EPHY_LED_POL
;
817 /* Force EPHY xtal frequency to 24MHz. */
818 reg
|= H3_EPHY_CLK_SEL
;
820 ret
= of_mdio_parse_addr(priv
->device
, priv
->plat
->phy_node
);
822 dev_err(priv
->device
, "Could not parse MDIO addr\n");
825 /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
826 * address. No need to mask it again.
828 reg
|= 1 << H3_EPHY_ADDR_SHIFT
;
831 if (!of_property_read_u32(node
, "allwinner,tx-delay-ps", &val
)) {
833 dev_err(priv
->device
, "tx-delay must be a multiple of 100\n");
837 dev_dbg(priv
->device
, "set tx-delay to %x\n", val
);
838 if (val
<= SYSCON_ETXDC_MASK
) {
839 reg
&= ~(SYSCON_ETXDC_MASK
<< SYSCON_ETXDC_SHIFT
);
840 reg
|= (val
<< SYSCON_ETXDC_SHIFT
);
842 dev_err(priv
->device
, "Invalid TX clock delay: %d\n",
848 if (!of_property_read_u32(node
, "allwinner,rx-delay-ps", &val
)) {
850 dev_err(priv
->device
, "rx-delay must be a multiple of 100\n");
854 dev_dbg(priv
->device
, "set rx-delay to %x\n", val
);
855 if (val
<= SYSCON_ERXDC_MASK
) {
856 reg
&= ~(SYSCON_ERXDC_MASK
<< SYSCON_ERXDC_SHIFT
);
857 reg
|= (val
<< SYSCON_ERXDC_SHIFT
);
859 dev_err(priv
->device
, "Invalid RX clock delay: %d\n",
865 /* Clear interface mode bits */
866 reg
&= ~(SYSCON_ETCS_MASK
| SYSCON_EPIT
);
867 if (gmac
->variant
->support_rmii
)
868 reg
&= ~SYSCON_RMII_EN
;
870 switch (priv
->plat
->interface
) {
871 case PHY_INTERFACE_MODE_MII
:
874 case PHY_INTERFACE_MODE_RGMII
:
875 reg
|= SYSCON_EPIT
| SYSCON_ETCS_INT_GMII
;
877 case PHY_INTERFACE_MODE_RMII
:
878 reg
|= SYSCON_RMII_EN
| SYSCON_ETCS_EXT_GMII
;
881 dev_err(priv
->device
, "Unsupported interface mode: %s",
882 phy_modes(priv
->plat
->interface
));
886 regmap_write(gmac
->regmap
, SYSCON_EMAC_REG
, reg
);
891 static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data
*gmac
)
893 u32 reg
= gmac
->variant
->default_syscon_value
;
895 regmap_write(gmac
->regmap
, SYSCON_EMAC_REG
, reg
);
898 static void sun8i_dwmac_exit(struct platform_device
*pdev
, void *priv
)
900 struct sunxi_priv_data
*gmac
= priv
;
902 if (gmac
->variant
->soc_has_internal_phy
) {
903 /* sun8i_dwmac_exit could be called with mdiomux uninit */
904 if (gmac
->mux_handle
)
905 mdio_mux_uninit(gmac
->mux_handle
);
906 if (gmac
->internal_phy_powered
)
907 sun8i_dwmac_unpower_internal_phy(gmac
);
910 sun8i_dwmac_unset_syscon(gmac
);
912 reset_control_put(gmac
->rst_ephy
);
914 clk_disable_unprepare(gmac
->tx_clk
);
917 regulator_disable(gmac
->regulator
);
920 static const struct stmmac_ops sun8i_dwmac_ops
= {
921 .core_init
= sun8i_dwmac_core_init
,
922 .set_mac
= sun8i_dwmac_set_mac
,
923 .dump_regs
= sun8i_dwmac_dump_mac_regs
,
924 .rx_ipc
= sun8i_dwmac_rx_ipc_enable
,
925 .set_filter
= sun8i_dwmac_set_filter
,
926 .flow_ctrl
= sun8i_dwmac_flow_ctrl
,
927 .set_umac_addr
= sun8i_dwmac_set_umac_addr
,
928 .get_umac_addr
= sun8i_dwmac_get_umac_addr
,
931 static struct mac_device_info
*sun8i_dwmac_setup(void *ppriv
)
933 struct mac_device_info
*mac
;
934 struct stmmac_priv
*priv
= ppriv
;
937 mac
= devm_kzalloc(priv
->device
, sizeof(*mac
), GFP_KERNEL
);
941 ret
= sun8i_dwmac_set_syscon(priv
);
945 mac
->pcsr
= priv
->ioaddr
;
946 mac
->mac
= &sun8i_dwmac_ops
;
947 mac
->dma
= &sun8i_dwmac_dma_ops
;
949 /* The loopback bit seems to be re-set when link change
950 * Simply mask it each time
951 * Speed 10/100/1000 are set in BIT(2)/BIT(3)
953 mac
->link
.speed_mask
= GENMASK(3, 2) | EMAC_LOOPBACK
;
954 mac
->link
.speed10
= EMAC_SPEED_10
;
955 mac
->link
.speed100
= EMAC_SPEED_100
;
956 mac
->link
.speed1000
= EMAC_SPEED_1000
;
957 mac
->link
.duplex
= EMAC_DUPLEX_FULL
;
958 mac
->mii
.addr
= EMAC_MDIO_CMD
;
959 mac
->mii
.data
= EMAC_MDIO_DATA
;
960 mac
->mii
.reg_shift
= 4;
961 mac
->mii
.reg_mask
= GENMASK(8, 4);
962 mac
->mii
.addr_shift
= 12;
963 mac
->mii
.addr_mask
= GENMASK(16, 12);
964 mac
->mii
.clk_csr_shift
= 20;
965 mac
->mii
.clk_csr_mask
= GENMASK(22, 20);
966 mac
->unicast_filter_entries
= 8;
968 /* Synopsys Id is not available */
969 priv
->synopsys_id
= 0;
974 static int sun8i_dwmac_probe(struct platform_device
*pdev
)
976 struct plat_stmmacenet_data
*plat_dat
;
977 struct stmmac_resources stmmac_res
;
978 struct sunxi_priv_data
*gmac
;
979 struct device
*dev
= &pdev
->dev
;
981 struct stmmac_priv
*priv
;
982 struct net_device
*ndev
;
984 ret
= stmmac_get_platform_resources(pdev
, &stmmac_res
);
988 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
989 if (IS_ERR(plat_dat
))
990 return PTR_ERR(plat_dat
);
992 gmac
= devm_kzalloc(dev
, sizeof(*gmac
), GFP_KERNEL
);
996 gmac
->variant
= of_device_get_match_data(&pdev
->dev
);
997 if (!gmac
->variant
) {
998 dev_err(&pdev
->dev
, "Missing dwmac-sun8i variant\n");
1002 gmac
->tx_clk
= devm_clk_get(dev
, "stmmaceth");
1003 if (IS_ERR(gmac
->tx_clk
)) {
1004 dev_err(dev
, "Could not get TX clock\n");
1005 return PTR_ERR(gmac
->tx_clk
);
1008 /* Optional regulator for PHY */
1009 gmac
->regulator
= devm_regulator_get_optional(dev
, "phy");
1010 if (IS_ERR(gmac
->regulator
)) {
1011 if (PTR_ERR(gmac
->regulator
) == -EPROBE_DEFER
)
1012 return -EPROBE_DEFER
;
1013 dev_info(dev
, "No regulator found\n");
1014 gmac
->regulator
= NULL
;
1017 gmac
->regmap
= syscon_regmap_lookup_by_phandle(pdev
->dev
.of_node
,
1019 if (IS_ERR(gmac
->regmap
)) {
1020 ret
= PTR_ERR(gmac
->regmap
);
1021 dev_err(&pdev
->dev
, "Unable to map syscon: %d\n", ret
);
1025 plat_dat
->interface
= of_get_phy_mode(dev
->of_node
);
1027 /* platform data specifying hardware features and callbacks.
1028 * hardware features were copied from Allwinner drivers.
1030 plat_dat
->rx_coe
= STMMAC_RX_COE_TYPE2
;
1031 plat_dat
->tx_coe
= 1;
1032 plat_dat
->has_sun8i
= true;
1033 plat_dat
->bsp_priv
= gmac
;
1034 plat_dat
->init
= sun8i_dwmac_init
;
1035 plat_dat
->exit
= sun8i_dwmac_exit
;
1036 plat_dat
->setup
= sun8i_dwmac_setup
;
1038 ret
= sun8i_dwmac_init(pdev
, plat_dat
->bsp_priv
);
1042 ret
= stmmac_dvr_probe(&pdev
->dev
, plat_dat
, &stmmac_res
);
1046 ndev
= dev_get_drvdata(&pdev
->dev
);
1047 priv
= netdev_priv(ndev
);
1048 /* The mux must be registered after parent MDIO
1049 * so after stmmac_dvr_probe()
1051 if (gmac
->variant
->soc_has_internal_phy
) {
1052 ret
= get_ephy_nodes(priv
);
1055 ret
= sun8i_dwmac_register_mdio_mux(priv
);
1057 dev_err(&pdev
->dev
, "Failed to register mux\n");
1061 ret
= sun8i_dwmac_reset(priv
);
1068 sun8i_dwmac_unset_syscon(gmac
);
1070 sun8i_dwmac_exit(pdev
, plat_dat
->bsp_priv
);
1074 static const struct of_device_id sun8i_dwmac_match
[] = {
1075 { .compatible
= "allwinner,sun8i-h3-emac",
1076 .data
= &emac_variant_h3
},
1077 { .compatible
= "allwinner,sun8i-v3s-emac",
1078 .data
= &emac_variant_v3s
},
1079 { .compatible
= "allwinner,sun8i-a83t-emac",
1080 .data
= &emac_variant_a83t
},
1081 { .compatible
= "allwinner,sun50i-a64-emac",
1082 .data
= &emac_variant_a64
},
1085 MODULE_DEVICE_TABLE(of
, sun8i_dwmac_match
);
1087 static struct platform_driver sun8i_dwmac_driver
= {
1088 .probe
= sun8i_dwmac_probe
,
1089 .remove
= stmmac_pltfr_remove
,
1091 .name
= "dwmac-sun8i",
1092 .pm
= &stmmac_pltfr_pm_ops
,
1093 .of_match_table
= sun8i_dwmac_match
,
1096 module_platform_driver(sun8i_dwmac_driver
);
1098 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");
1099 MODULE_DESCRIPTION("Allwinner sun8i DWMAC specific glue layer");
1100 MODULE_LICENSE("GPL");