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 - Describe 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 * @syscon_field reg_field for the syscon's gmac register
46 * @soc_has_internal_phy: Does the MAC embed an internal PHY
47 * @support_mii: Does the MAC handle MII
48 * @support_rmii: Does the MAC handle RMII
49 * @support_rgmii: Does the MAC handle RGMII
51 * @rx_delay_max: Maximum raw value for RX delay chain
52 * @tx_delay_max: Maximum raw value for TX delay chain
53 * These two also indicate the bitmask for
54 * the RX and TX delay chain registers. A
55 * value of zero indicates this is not supported.
58 u32 default_syscon_value
;
59 const struct reg_field
*syscon_field
;
60 bool soc_has_internal_phy
;
68 /* struct sunxi_priv_data - hold all sunxi private data
69 * @tx_clk: reference to MAC TX clock
70 * @ephy_clk: reference to the optional EPHY clock for the internal PHY
71 * @regulator: reference to the optional regulator
72 * @rst_ephy: reference to the optional EPHY reset for the internal PHY
73 * @variant: reference to the current board variant
74 * @regmap: regmap for using the syscon
75 * @internal_phy_powered: Does the internal PHY is enabled
76 * @mux_handle: Internal pointer used by mdio-mux lib
78 struct sunxi_priv_data
{
81 struct regulator
*regulator
;
82 struct reset_control
*rst_ephy
;
83 const struct emac_variant
*variant
;
84 struct regmap_field
*regmap_field
;
85 bool internal_phy_powered
;
89 /* EMAC clock register @ 0x30 in the "system control" address range */
90 static const struct reg_field sun8i_syscon_reg_field
= {
96 /* EMAC clock register @ 0x164 in the CCU address range */
97 static const struct reg_field sun8i_ccu_reg_field
= {
103 static const struct emac_variant emac_variant_h3
= {
104 .default_syscon_value
= 0x58000,
105 .syscon_field
= &sun8i_syscon_reg_field
,
106 .soc_has_internal_phy
= true,
108 .support_rmii
= true,
109 .support_rgmii
= true,
114 static const struct emac_variant emac_variant_v3s
= {
115 .default_syscon_value
= 0x38000,
116 .syscon_field
= &sun8i_syscon_reg_field
,
117 .soc_has_internal_phy
= true,
121 static const struct emac_variant emac_variant_a83t
= {
122 .default_syscon_value
= 0,
123 .syscon_field
= &sun8i_syscon_reg_field
,
124 .soc_has_internal_phy
= false,
126 .support_rgmii
= true,
131 static const struct emac_variant emac_variant_r40
= {
132 .default_syscon_value
= 0,
133 .syscon_field
= &sun8i_ccu_reg_field
,
135 .support_rgmii
= true,
139 static const struct emac_variant emac_variant_a64
= {
140 .default_syscon_value
= 0,
141 .syscon_field
= &sun8i_syscon_reg_field
,
142 .soc_has_internal_phy
= false,
144 .support_rmii
= true,
145 .support_rgmii
= true,
150 #define EMAC_BASIC_CTL0 0x00
151 #define EMAC_BASIC_CTL1 0x04
152 #define EMAC_INT_STA 0x08
153 #define EMAC_INT_EN 0x0C
154 #define EMAC_TX_CTL0 0x10
155 #define EMAC_TX_CTL1 0x14
156 #define EMAC_TX_FLOW_CTL 0x1C
157 #define EMAC_TX_DESC_LIST 0x20
158 #define EMAC_RX_CTL0 0x24
159 #define EMAC_RX_CTL1 0x28
160 #define EMAC_RX_DESC_LIST 0x34
161 #define EMAC_RX_FRM_FLT 0x38
162 #define EMAC_MDIO_CMD 0x48
163 #define EMAC_MDIO_DATA 0x4C
164 #define EMAC_MACADDR_HI(reg) (0x50 + (reg) * 8)
165 #define EMAC_MACADDR_LO(reg) (0x54 + (reg) * 8)
166 #define EMAC_TX_DMA_STA 0xB0
167 #define EMAC_TX_CUR_DESC 0xB4
168 #define EMAC_TX_CUR_BUF 0xB8
169 #define EMAC_RX_DMA_STA 0xC0
170 #define EMAC_RX_CUR_DESC 0xC4
171 #define EMAC_RX_CUR_BUF 0xC8
173 /* Use in EMAC_BASIC_CTL0 */
174 #define EMAC_DUPLEX_FULL BIT(0)
175 #define EMAC_LOOPBACK BIT(1)
176 #define EMAC_SPEED_1000 0
177 #define EMAC_SPEED_100 (0x03 << 2)
178 #define EMAC_SPEED_10 (0x02 << 2)
180 /* Use in EMAC_BASIC_CTL1 */
181 #define EMAC_BURSTLEN_SHIFT 24
183 /* Used in EMAC_RX_FRM_FLT */
184 #define EMAC_FRM_FLT_RXALL BIT(0)
185 #define EMAC_FRM_FLT_CTL BIT(13)
186 #define EMAC_FRM_FLT_MULTICAST BIT(16)
189 #define EMAC_RX_MD BIT(1)
190 #define EMAC_RX_TH_MASK GENMASK(4, 5)
191 #define EMAC_RX_TH_32 0
192 #define EMAC_RX_TH_64 (0x1 << 4)
193 #define EMAC_RX_TH_96 (0x2 << 4)
194 #define EMAC_RX_TH_128 (0x3 << 4)
195 #define EMAC_RX_DMA_EN BIT(30)
196 #define EMAC_RX_DMA_START BIT(31)
199 #define EMAC_TX_MD BIT(1)
200 #define EMAC_TX_NEXT_FRM BIT(2)
201 #define EMAC_TX_TH_MASK GENMASK(8, 10)
202 #define EMAC_TX_TH_64 0
203 #define EMAC_TX_TH_128 (0x1 << 8)
204 #define EMAC_TX_TH_192 (0x2 << 8)
205 #define EMAC_TX_TH_256 (0x3 << 8)
206 #define EMAC_TX_DMA_EN BIT(30)
207 #define EMAC_TX_DMA_START BIT(31)
209 /* Used in RX_CTL0 */
210 #define EMAC_RX_RECEIVER_EN BIT(31)
211 #define EMAC_RX_DO_CRC BIT(27)
212 #define EMAC_RX_FLOW_CTL_EN BIT(16)
214 /* Used in TX_CTL0 */
215 #define EMAC_TX_TRANSMITTER_EN BIT(31)
217 /* Used in EMAC_TX_FLOW_CTL */
218 #define EMAC_TX_FLOW_CTL_EN BIT(0)
220 /* Used in EMAC_INT_STA */
221 #define EMAC_TX_INT BIT(0)
222 #define EMAC_TX_DMA_STOP_INT BIT(1)
223 #define EMAC_TX_BUF_UA_INT BIT(2)
224 #define EMAC_TX_TIMEOUT_INT BIT(3)
225 #define EMAC_TX_UNDERFLOW_INT BIT(4)
226 #define EMAC_TX_EARLY_INT BIT(5)
227 #define EMAC_RX_INT BIT(8)
228 #define EMAC_RX_BUF_UA_INT BIT(9)
229 #define EMAC_RX_DMA_STOP_INT BIT(10)
230 #define EMAC_RX_TIMEOUT_INT BIT(11)
231 #define EMAC_RX_OVERFLOW_INT BIT(12)
232 #define EMAC_RX_EARLY_INT BIT(13)
233 #define EMAC_RGMII_STA_INT BIT(16)
235 #define MAC_ADDR_TYPE_DST BIT(31)
237 /* H3 specific bits for EPHY */
238 #define H3_EPHY_ADDR_SHIFT 20
239 #define H3_EPHY_CLK_SEL BIT(18) /* 1: 24MHz, 0: 25MHz */
240 #define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */
241 #define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */
242 #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */
243 #define H3_EPHY_MUX_MASK (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT)
244 #define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID 1
245 #define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID 2
247 /* H3/A64 specific bits */
248 #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
250 /* Generic system control EMAC_CLK bits */
251 #define SYSCON_ETXDC_SHIFT 10
252 #define SYSCON_ERXDC_SHIFT 5
253 /* EMAC PHY Interface Type */
254 #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
255 #define SYSCON_ETCS_MASK GENMASK(1, 0)
256 #define SYSCON_ETCS_MII 0x0
257 #define SYSCON_ETCS_EXT_GMII 0x1
258 #define SYSCON_ETCS_INT_GMII 0x2
260 /* sun8i_dwmac_dma_reset() - reset the EMAC
261 * Called from stmmac via stmmac_dma_ops->reset
263 static int sun8i_dwmac_dma_reset(void __iomem
*ioaddr
)
265 writel(0, ioaddr
+ EMAC_RX_CTL1
);
266 writel(0, ioaddr
+ EMAC_TX_CTL1
);
267 writel(0, ioaddr
+ EMAC_RX_FRM_FLT
);
268 writel(0, ioaddr
+ EMAC_RX_DESC_LIST
);
269 writel(0, ioaddr
+ EMAC_TX_DESC_LIST
);
270 writel(0, ioaddr
+ EMAC_INT_EN
);
271 writel(0x1FFFFFF, ioaddr
+ EMAC_INT_STA
);
275 /* sun8i_dwmac_dma_init() - initialize the EMAC
276 * Called from stmmac via stmmac_dma_ops->init
278 static void sun8i_dwmac_dma_init(void __iomem
*ioaddr
,
279 struct stmmac_dma_cfg
*dma_cfg
, int atds
)
281 writel(EMAC_RX_INT
| EMAC_TX_INT
, ioaddr
+ EMAC_INT_EN
);
282 writel(0x1FFFFFF, ioaddr
+ EMAC_INT_STA
);
285 static void sun8i_dwmac_dma_init_rx(void __iomem
*ioaddr
,
286 struct stmmac_dma_cfg
*dma_cfg
,
287 u32 dma_rx_phy
, u32 chan
)
289 /* Write RX descriptors address */
290 writel(dma_rx_phy
, ioaddr
+ EMAC_RX_DESC_LIST
);
293 static void sun8i_dwmac_dma_init_tx(void __iomem
*ioaddr
,
294 struct stmmac_dma_cfg
*dma_cfg
,
295 u32 dma_tx_phy
, u32 chan
)
297 /* Write TX descriptors address */
298 writel(dma_tx_phy
, ioaddr
+ EMAC_TX_DESC_LIST
);
301 /* sun8i_dwmac_dump_regs() - Dump EMAC address space
302 * Called from stmmac_dma_ops->dump_regs
305 static void sun8i_dwmac_dump_regs(void __iomem
*ioaddr
, u32
*reg_space
)
309 for (i
= 0; i
< 0xC8; i
+= 4) {
310 if (i
== 0x32 || i
== 0x3C)
312 reg_space
[i
/ 4] = readl(ioaddr
+ i
);
316 /* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
317 * Called from stmmac_ops->dump_regs
320 static void sun8i_dwmac_dump_mac_regs(struct mac_device_info
*hw
,
324 void __iomem
*ioaddr
= hw
->pcsr
;
326 for (i
= 0; i
< 0xC8; i
+= 4) {
327 if (i
== 0x32 || i
== 0x3C)
329 reg_space
[i
/ 4] = readl(ioaddr
+ i
);
333 static void sun8i_dwmac_enable_dma_irq(void __iomem
*ioaddr
, u32 chan
)
335 writel(EMAC_RX_INT
| EMAC_TX_INT
, ioaddr
+ EMAC_INT_EN
);
338 static void sun8i_dwmac_disable_dma_irq(void __iomem
*ioaddr
, u32 chan
)
340 writel(0, ioaddr
+ EMAC_INT_EN
);
343 static void sun8i_dwmac_dma_start_tx(void __iomem
*ioaddr
, u32 chan
)
347 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
348 v
|= EMAC_TX_DMA_START
;
350 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
353 static void sun8i_dwmac_enable_dma_transmission(void __iomem
*ioaddr
)
357 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
358 v
|= EMAC_TX_DMA_START
;
360 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
363 static void sun8i_dwmac_dma_stop_tx(void __iomem
*ioaddr
, u32 chan
)
367 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
368 v
&= ~EMAC_TX_DMA_EN
;
369 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
372 static void sun8i_dwmac_dma_start_rx(void __iomem
*ioaddr
, u32 chan
)
376 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
377 v
|= EMAC_RX_DMA_START
;
379 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
382 static void sun8i_dwmac_dma_stop_rx(void __iomem
*ioaddr
, u32 chan
)
386 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
387 v
&= ~EMAC_RX_DMA_EN
;
388 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
391 static int sun8i_dwmac_dma_interrupt(void __iomem
*ioaddr
,
392 struct stmmac_extra_stats
*x
, u32 chan
)
397 v
= readl(ioaddr
+ EMAC_INT_STA
);
399 if (v
& EMAC_TX_INT
) {
401 x
->tx_normal_irq_n
++;
404 if (v
& EMAC_TX_DMA_STOP_INT
)
405 x
->tx_process_stopped_irq
++;
407 if (v
& EMAC_TX_BUF_UA_INT
)
408 x
->tx_process_stopped_irq
++;
410 if (v
& EMAC_TX_TIMEOUT_INT
)
411 ret
|= tx_hard_error
;
413 if (v
& EMAC_TX_UNDERFLOW_INT
) {
414 ret
|= tx_hard_error
;
415 x
->tx_undeflow_irq
++;
418 if (v
& EMAC_TX_EARLY_INT
)
421 if (v
& EMAC_RX_INT
) {
423 x
->rx_normal_irq_n
++;
426 if (v
& EMAC_RX_BUF_UA_INT
)
427 x
->rx_buf_unav_irq
++;
429 if (v
& EMAC_RX_DMA_STOP_INT
)
430 x
->rx_process_stopped_irq
++;
432 if (v
& EMAC_RX_TIMEOUT_INT
)
433 ret
|= tx_hard_error
;
435 if (v
& EMAC_RX_OVERFLOW_INT
) {
436 ret
|= tx_hard_error
;
437 x
->rx_overflow_irq
++;
440 if (v
& EMAC_RX_EARLY_INT
)
443 if (v
& EMAC_RGMII_STA_INT
)
446 writel(v
, ioaddr
+ EMAC_INT_STA
);
451 static void sun8i_dwmac_dma_operation_mode_rx(void __iomem
*ioaddr
, int mode
,
452 u32 channel
, int fifosz
, u8 qmode
)
456 v
= readl(ioaddr
+ EMAC_RX_CTL1
);
457 if (mode
== SF_DMA_MODE
) {
461 v
&= ~EMAC_RX_TH_MASK
;
471 writel(v
, ioaddr
+ EMAC_RX_CTL1
);
474 static void sun8i_dwmac_dma_operation_mode_tx(void __iomem
*ioaddr
, int mode
,
475 u32 channel
, int fifosz
, u8 qmode
)
479 v
= readl(ioaddr
+ EMAC_TX_CTL1
);
480 if (mode
== SF_DMA_MODE
) {
482 /* Undocumented bit (called TX_NEXT_FRM in BSP), the original
484 * "Operating on second frame increase the performance
485 * especially when transmit store-and-forward is used."
487 v
|= EMAC_TX_NEXT_FRM
;
490 v
&= ~EMAC_TX_TH_MASK
;
500 writel(v
, ioaddr
+ EMAC_TX_CTL1
);
503 static const struct stmmac_dma_ops sun8i_dwmac_dma_ops
= {
504 .reset
= sun8i_dwmac_dma_reset
,
505 .init
= sun8i_dwmac_dma_init
,
506 .init_rx_chan
= sun8i_dwmac_dma_init_rx
,
507 .init_tx_chan
= sun8i_dwmac_dma_init_tx
,
508 .dump_regs
= sun8i_dwmac_dump_regs
,
509 .dma_rx_mode
= sun8i_dwmac_dma_operation_mode_rx
,
510 .dma_tx_mode
= sun8i_dwmac_dma_operation_mode_tx
,
511 .enable_dma_transmission
= sun8i_dwmac_enable_dma_transmission
,
512 .enable_dma_irq
= sun8i_dwmac_enable_dma_irq
,
513 .disable_dma_irq
= sun8i_dwmac_disable_dma_irq
,
514 .start_tx
= sun8i_dwmac_dma_start_tx
,
515 .stop_tx
= sun8i_dwmac_dma_stop_tx
,
516 .start_rx
= sun8i_dwmac_dma_start_rx
,
517 .stop_rx
= sun8i_dwmac_dma_stop_rx
,
518 .dma_interrupt
= sun8i_dwmac_dma_interrupt
,
521 static int sun8i_dwmac_init(struct platform_device
*pdev
, void *priv
)
523 struct sunxi_priv_data
*gmac
= priv
;
526 if (gmac
->regulator
) {
527 ret
= regulator_enable(gmac
->regulator
);
529 dev_err(&pdev
->dev
, "Fail to enable regulator\n");
534 ret
= clk_prepare_enable(gmac
->tx_clk
);
537 regulator_disable(gmac
->regulator
);
538 dev_err(&pdev
->dev
, "Could not enable AHB clock\n");
545 static void sun8i_dwmac_core_init(struct mac_device_info
*hw
,
546 struct net_device
*dev
)
548 void __iomem
*ioaddr
= hw
->pcsr
;
551 v
= (8 << EMAC_BURSTLEN_SHIFT
); /* burst len */
552 writel(v
, ioaddr
+ EMAC_BASIC_CTL1
);
555 static void sun8i_dwmac_set_mac(void __iomem
*ioaddr
, bool enable
)
559 t
= readl(ioaddr
+ EMAC_TX_CTL0
);
560 r
= readl(ioaddr
+ EMAC_RX_CTL0
);
562 t
|= EMAC_TX_TRANSMITTER_EN
;
563 r
|= EMAC_RX_RECEIVER_EN
;
565 t
&= ~EMAC_TX_TRANSMITTER_EN
;
566 r
&= ~EMAC_RX_RECEIVER_EN
;
568 writel(t
, ioaddr
+ EMAC_TX_CTL0
);
569 writel(r
, ioaddr
+ EMAC_RX_CTL0
);
572 /* Set MAC address at slot reg_n
573 * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST
574 * If addr is NULL, clear the slot
576 static void sun8i_dwmac_set_umac_addr(struct mac_device_info
*hw
,
580 void __iomem
*ioaddr
= hw
->pcsr
;
584 writel(0, ioaddr
+ EMAC_MACADDR_HI(reg_n
));
588 stmmac_set_mac_addr(ioaddr
, addr
, EMAC_MACADDR_HI(reg_n
),
589 EMAC_MACADDR_LO(reg_n
));
591 v
= readl(ioaddr
+ EMAC_MACADDR_HI(reg_n
));
592 v
|= MAC_ADDR_TYPE_DST
;
593 writel(v
, ioaddr
+ EMAC_MACADDR_HI(reg_n
));
597 static void sun8i_dwmac_get_umac_addr(struct mac_device_info
*hw
,
601 void __iomem
*ioaddr
= hw
->pcsr
;
603 stmmac_get_mac_addr(ioaddr
, addr
, EMAC_MACADDR_HI(reg_n
),
604 EMAC_MACADDR_LO(reg_n
));
607 /* caution this function must return non 0 to work */
608 static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info
*hw
)
610 void __iomem
*ioaddr
= hw
->pcsr
;
613 v
= readl(ioaddr
+ EMAC_RX_CTL0
);
615 writel(v
, ioaddr
+ EMAC_RX_CTL0
);
620 static void sun8i_dwmac_set_filter(struct mac_device_info
*hw
,
621 struct net_device
*dev
)
623 void __iomem
*ioaddr
= hw
->pcsr
;
626 struct netdev_hw_addr
*ha
;
627 int macaddrs
= netdev_uc_count(dev
) + netdev_mc_count(dev
) + 1;
629 v
= EMAC_FRM_FLT_CTL
;
631 if (dev
->flags
& IFF_PROMISC
) {
632 v
= EMAC_FRM_FLT_RXALL
;
633 } else if (dev
->flags
& IFF_ALLMULTI
) {
634 v
|= EMAC_FRM_FLT_MULTICAST
;
635 } else if (macaddrs
<= hw
->unicast_filter_entries
) {
636 if (!netdev_mc_empty(dev
)) {
637 netdev_for_each_mc_addr(ha
, dev
) {
638 sun8i_dwmac_set_umac_addr(hw
, ha
->addr
, i
);
642 if (!netdev_uc_empty(dev
)) {
643 netdev_for_each_uc_addr(ha
, dev
) {
644 sun8i_dwmac_set_umac_addr(hw
, ha
->addr
, i
);
649 netdev_info(dev
, "Too many address, switching to promiscuous\n");
650 v
= EMAC_FRM_FLT_RXALL
;
653 /* Disable unused address filter slots */
654 while (i
< hw
->unicast_filter_entries
)
655 sun8i_dwmac_set_umac_addr(hw
, NULL
, i
++);
657 writel(v
, ioaddr
+ EMAC_RX_FRM_FLT
);
660 static void sun8i_dwmac_flow_ctrl(struct mac_device_info
*hw
,
661 unsigned int duplex
, unsigned int fc
,
662 unsigned int pause_time
, u32 tx_cnt
)
664 void __iomem
*ioaddr
= hw
->pcsr
;
667 v
= readl(ioaddr
+ EMAC_RX_CTL0
);
669 v
|= EMAC_RX_FLOW_CTL_EN
;
671 v
&= ~EMAC_RX_FLOW_CTL_EN
;
672 writel(v
, ioaddr
+ EMAC_RX_CTL0
);
674 v
= readl(ioaddr
+ EMAC_TX_FLOW_CTL
);
676 v
|= EMAC_TX_FLOW_CTL_EN
;
678 v
&= ~EMAC_TX_FLOW_CTL_EN
;
679 writel(v
, ioaddr
+ EMAC_TX_FLOW_CTL
);
682 static int sun8i_dwmac_reset(struct stmmac_priv
*priv
)
687 v
= readl(priv
->ioaddr
+ EMAC_BASIC_CTL1
);
688 writel(v
| 0x01, priv
->ioaddr
+ EMAC_BASIC_CTL1
);
690 /* The timeout was previoulsy set to 10ms, but some board (OrangePI0)
691 * need more if no cable plugged. 100ms seems OK
693 err
= readl_poll_timeout(priv
->ioaddr
+ EMAC_BASIC_CTL1
, v
,
694 !(v
& 0x01), 100, 100000);
697 dev_err(priv
->device
, "EMAC reset timeout\n");
703 /* Search in mdio-mux node for internal PHY node and get its clk/reset */
704 static int get_ephy_nodes(struct stmmac_priv
*priv
)
706 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
707 struct device_node
*mdio_mux
, *iphynode
;
708 struct device_node
*mdio_internal
;
711 mdio_mux
= of_get_child_by_name(priv
->device
->of_node
, "mdio-mux");
713 dev_err(priv
->device
, "Cannot get mdio-mux node\n");
717 mdio_internal
= of_get_compatible_child(mdio_mux
,
718 "allwinner,sun8i-h3-mdio-internal");
719 of_node_put(mdio_mux
);
720 if (!mdio_internal
) {
721 dev_err(priv
->device
, "Cannot get internal_mdio node\n");
725 /* Seek for internal PHY */
726 for_each_child_of_node(mdio_internal
, iphynode
) {
727 gmac
->ephy_clk
= of_clk_get(iphynode
, 0);
728 if (IS_ERR(gmac
->ephy_clk
))
730 gmac
->rst_ephy
= of_reset_control_get_exclusive(iphynode
, NULL
);
731 if (IS_ERR(gmac
->rst_ephy
)) {
732 ret
= PTR_ERR(gmac
->rst_ephy
);
733 if (ret
== -EPROBE_DEFER
) {
734 of_node_put(iphynode
);
735 of_node_put(mdio_internal
);
740 dev_info(priv
->device
, "Found internal PHY node\n");
741 of_node_put(iphynode
);
742 of_node_put(mdio_internal
);
746 of_node_put(mdio_internal
);
750 static int sun8i_dwmac_power_internal_phy(struct stmmac_priv
*priv
)
752 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
755 if (gmac
->internal_phy_powered
) {
756 dev_warn(priv
->device
, "Internal PHY already powered\n");
760 dev_info(priv
->device
, "Powering internal PHY\n");
761 ret
= clk_prepare_enable(gmac
->ephy_clk
);
763 dev_err(priv
->device
, "Cannot enable internal PHY\n");
767 /* Make sure the EPHY is properly reseted, as U-Boot may leave
768 * it at deasserted state, and thus it may fail to reset EMAC.
770 reset_control_assert(gmac
->rst_ephy
);
772 ret
= reset_control_deassert(gmac
->rst_ephy
);
774 dev_err(priv
->device
, "Cannot deassert internal phy\n");
775 clk_disable_unprepare(gmac
->ephy_clk
);
779 gmac
->internal_phy_powered
= true;
784 static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data
*gmac
)
786 if (!gmac
->internal_phy_powered
)
789 clk_disable_unprepare(gmac
->ephy_clk
);
790 reset_control_assert(gmac
->rst_ephy
);
791 gmac
->internal_phy_powered
= false;
795 /* MDIO multiplexing switch function
796 * This function is called by the mdio-mux layer when it thinks the mdio bus
797 * multiplexer needs to switch.
798 * 'current_child' is the current value of the mux register
799 * 'desired_child' is the value of the 'reg' property of the target child MDIO
801 * The first time this function is called, current_child == -1.
802 * If current_child == desired_child, then the mux is already set to the
805 static int mdio_mux_syscon_switch_fn(int current_child
, int desired_child
,
808 struct stmmac_priv
*priv
= data
;
809 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
812 bool need_power_ephy
= false;
814 if (current_child
^ desired_child
) {
815 regmap_field_read(gmac
->regmap_field
, ®
);
816 switch (desired_child
) {
817 case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID
:
818 dev_info(priv
->device
, "Switch mux to internal PHY");
819 val
= (reg
& ~H3_EPHY_MUX_MASK
) | H3_EPHY_SELECT
;
821 need_power_ephy
= true;
823 case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID
:
824 dev_info(priv
->device
, "Switch mux to external PHY");
825 val
= (reg
& ~H3_EPHY_MUX_MASK
) | H3_EPHY_SHUTDOWN
;
826 need_power_ephy
= false;
829 dev_err(priv
->device
, "Invalid child ID %x\n",
833 regmap_field_write(gmac
->regmap_field
, val
);
834 if (need_power_ephy
) {
835 ret
= sun8i_dwmac_power_internal_phy(priv
);
839 sun8i_dwmac_unpower_internal_phy(gmac
);
841 /* After changing syscon value, the MAC need reset or it will
842 * use the last value (and so the last PHY set).
844 ret
= sun8i_dwmac_reset(priv
);
849 static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv
*priv
)
852 struct device_node
*mdio_mux
;
853 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
855 mdio_mux
= of_get_child_by_name(priv
->device
->of_node
, "mdio-mux");
859 ret
= mdio_mux_init(priv
->device
, mdio_mux
, mdio_mux_syscon_switch_fn
,
860 &gmac
->mux_handle
, priv
, priv
->mii
);
864 static int sun8i_dwmac_set_syscon(struct stmmac_priv
*priv
)
866 struct sunxi_priv_data
*gmac
= priv
->plat
->bsp_priv
;
867 struct device_node
*node
= priv
->device
->of_node
;
871 regmap_field_read(gmac
->regmap_field
, &val
);
872 reg
= gmac
->variant
->default_syscon_value
;
874 dev_warn(priv
->device
,
875 "Current syscon value is not the default %x (expect %x)\n",
878 if (gmac
->variant
->soc_has_internal_phy
) {
879 if (of_property_read_bool(node
, "allwinner,leds-active-low"))
880 reg
|= H3_EPHY_LED_POL
;
882 reg
&= ~H3_EPHY_LED_POL
;
884 /* Force EPHY xtal frequency to 24MHz. */
885 reg
|= H3_EPHY_CLK_SEL
;
887 ret
= of_mdio_parse_addr(priv
->device
, priv
->plat
->phy_node
);
889 dev_err(priv
->device
, "Could not parse MDIO addr\n");
892 /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
893 * address. No need to mask it again.
895 reg
|= 1 << H3_EPHY_ADDR_SHIFT
;
898 if (!of_property_read_u32(node
, "allwinner,tx-delay-ps", &val
)) {
900 dev_err(priv
->device
, "tx-delay must be a multiple of 100\n");
904 dev_dbg(priv
->device
, "set tx-delay to %x\n", val
);
905 if (val
<= gmac
->variant
->tx_delay_max
) {
906 reg
&= ~(gmac
->variant
->tx_delay_max
<<
908 reg
|= (val
<< SYSCON_ETXDC_SHIFT
);
910 dev_err(priv
->device
, "Invalid TX clock delay: %d\n",
916 if (!of_property_read_u32(node
, "allwinner,rx-delay-ps", &val
)) {
918 dev_err(priv
->device
, "rx-delay must be a multiple of 100\n");
922 dev_dbg(priv
->device
, "set rx-delay to %x\n", val
);
923 if (val
<= gmac
->variant
->rx_delay_max
) {
924 reg
&= ~(gmac
->variant
->rx_delay_max
<<
926 reg
|= (val
<< SYSCON_ERXDC_SHIFT
);
928 dev_err(priv
->device
, "Invalid RX clock delay: %d\n",
934 /* Clear interface mode bits */
935 reg
&= ~(SYSCON_ETCS_MASK
| SYSCON_EPIT
);
936 if (gmac
->variant
->support_rmii
)
937 reg
&= ~SYSCON_RMII_EN
;
939 switch (priv
->plat
->interface
) {
940 case PHY_INTERFACE_MODE_MII
:
943 case PHY_INTERFACE_MODE_RGMII
:
944 reg
|= SYSCON_EPIT
| SYSCON_ETCS_INT_GMII
;
946 case PHY_INTERFACE_MODE_RMII
:
947 reg
|= SYSCON_RMII_EN
| SYSCON_ETCS_EXT_GMII
;
950 dev_err(priv
->device
, "Unsupported interface mode: %s",
951 phy_modes(priv
->plat
->interface
));
955 regmap_field_write(gmac
->regmap_field
, reg
);
960 static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data
*gmac
)
962 u32 reg
= gmac
->variant
->default_syscon_value
;
964 regmap_field_write(gmac
->regmap_field
, reg
);
967 static void sun8i_dwmac_exit(struct platform_device
*pdev
, void *priv
)
969 struct sunxi_priv_data
*gmac
= priv
;
971 if (gmac
->variant
->soc_has_internal_phy
) {
972 /* sun8i_dwmac_exit could be called with mdiomux uninit */
973 if (gmac
->mux_handle
)
974 mdio_mux_uninit(gmac
->mux_handle
);
975 if (gmac
->internal_phy_powered
)
976 sun8i_dwmac_unpower_internal_phy(gmac
);
979 sun8i_dwmac_unset_syscon(gmac
);
981 reset_control_put(gmac
->rst_ephy
);
983 clk_disable_unprepare(gmac
->tx_clk
);
986 regulator_disable(gmac
->regulator
);
989 static const struct stmmac_ops sun8i_dwmac_ops
= {
990 .core_init
= sun8i_dwmac_core_init
,
991 .set_mac
= sun8i_dwmac_set_mac
,
992 .dump_regs
= sun8i_dwmac_dump_mac_regs
,
993 .rx_ipc
= sun8i_dwmac_rx_ipc_enable
,
994 .set_filter
= sun8i_dwmac_set_filter
,
995 .flow_ctrl
= sun8i_dwmac_flow_ctrl
,
996 .set_umac_addr
= sun8i_dwmac_set_umac_addr
,
997 .get_umac_addr
= sun8i_dwmac_get_umac_addr
,
1000 static struct mac_device_info
*sun8i_dwmac_setup(void *ppriv
)
1002 struct mac_device_info
*mac
;
1003 struct stmmac_priv
*priv
= ppriv
;
1006 mac
= devm_kzalloc(priv
->device
, sizeof(*mac
), GFP_KERNEL
);
1010 ret
= sun8i_dwmac_set_syscon(priv
);
1014 mac
->pcsr
= priv
->ioaddr
;
1015 mac
->mac
= &sun8i_dwmac_ops
;
1016 mac
->dma
= &sun8i_dwmac_dma_ops
;
1018 priv
->dev
->priv_flags
|= IFF_UNICAST_FLT
;
1020 /* The loopback bit seems to be re-set when link change
1021 * Simply mask it each time
1022 * Speed 10/100/1000 are set in BIT(2)/BIT(3)
1024 mac
->link
.speed_mask
= GENMASK(3, 2) | EMAC_LOOPBACK
;
1025 mac
->link
.speed10
= EMAC_SPEED_10
;
1026 mac
->link
.speed100
= EMAC_SPEED_100
;
1027 mac
->link
.speed1000
= EMAC_SPEED_1000
;
1028 mac
->link
.duplex
= EMAC_DUPLEX_FULL
;
1029 mac
->mii
.addr
= EMAC_MDIO_CMD
;
1030 mac
->mii
.data
= EMAC_MDIO_DATA
;
1031 mac
->mii
.reg_shift
= 4;
1032 mac
->mii
.reg_mask
= GENMASK(8, 4);
1033 mac
->mii
.addr_shift
= 12;
1034 mac
->mii
.addr_mask
= GENMASK(16, 12);
1035 mac
->mii
.clk_csr_shift
= 20;
1036 mac
->mii
.clk_csr_mask
= GENMASK(22, 20);
1037 mac
->unicast_filter_entries
= 8;
1039 /* Synopsys Id is not available */
1040 priv
->synopsys_id
= 0;
1045 static struct regmap
*sun8i_dwmac_get_syscon_from_dev(struct device_node
*node
)
1047 struct device_node
*syscon_node
;
1048 struct platform_device
*syscon_pdev
;
1049 struct regmap
*regmap
= NULL
;
1051 syscon_node
= of_parse_phandle(node
, "syscon", 0);
1053 return ERR_PTR(-ENODEV
);
1055 syscon_pdev
= of_find_device_by_node(syscon_node
);
1057 /* platform device might not be probed yet */
1058 regmap
= ERR_PTR(-EPROBE_DEFER
);
1062 /* If no regmap is found then the other device driver is at fault */
1063 regmap
= dev_get_regmap(&syscon_pdev
->dev
, NULL
);
1065 regmap
= ERR_PTR(-EINVAL
);
1067 platform_device_put(syscon_pdev
);
1069 of_node_put(syscon_node
);
1073 static int sun8i_dwmac_probe(struct platform_device
*pdev
)
1075 struct plat_stmmacenet_data
*plat_dat
;
1076 struct stmmac_resources stmmac_res
;
1077 struct sunxi_priv_data
*gmac
;
1078 struct device
*dev
= &pdev
->dev
;
1080 struct stmmac_priv
*priv
;
1081 struct net_device
*ndev
;
1082 struct regmap
*regmap
;
1084 ret
= stmmac_get_platform_resources(pdev
, &stmmac_res
);
1088 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
1089 if (IS_ERR(plat_dat
))
1090 return PTR_ERR(plat_dat
);
1092 gmac
= devm_kzalloc(dev
, sizeof(*gmac
), GFP_KERNEL
);
1096 gmac
->variant
= of_device_get_match_data(&pdev
->dev
);
1097 if (!gmac
->variant
) {
1098 dev_err(&pdev
->dev
, "Missing dwmac-sun8i variant\n");
1102 gmac
->tx_clk
= devm_clk_get(dev
, "stmmaceth");
1103 if (IS_ERR(gmac
->tx_clk
)) {
1104 dev_err(dev
, "Could not get TX clock\n");
1105 return PTR_ERR(gmac
->tx_clk
);
1108 /* Optional regulator for PHY */
1109 gmac
->regulator
= devm_regulator_get_optional(dev
, "phy");
1110 if (IS_ERR(gmac
->regulator
)) {
1111 if (PTR_ERR(gmac
->regulator
) == -EPROBE_DEFER
)
1112 return -EPROBE_DEFER
;
1113 dev_info(dev
, "No regulator found\n");
1114 gmac
->regulator
= NULL
;
1117 /* The "GMAC clock control" register might be located in the
1118 * CCU address range (on the R40), or the system control address
1119 * range (on most other sun8i and later SoCs).
1121 * The former controls most if not all clocks in the SoC. The
1122 * latter has an SoC identification register, and on some SoCs,
1123 * controls to map device specific SRAM to either the intended
1124 * peripheral, or the CPU address space.
1126 * In either case, there should be a coordinated and restricted
1127 * method of accessing the register needed here. This is done by
1128 * having the device export a custom regmap, instead of a generic
1129 * syscon, which grants all access to all registers.
1131 * To support old device trees, we fall back to using the syscon
1132 * interface if possible.
1134 regmap
= sun8i_dwmac_get_syscon_from_dev(pdev
->dev
.of_node
);
1136 regmap
= syscon_regmap_lookup_by_phandle(pdev
->dev
.of_node
,
1138 if (IS_ERR(regmap
)) {
1139 ret
= PTR_ERR(regmap
);
1140 dev_err(&pdev
->dev
, "Unable to map syscon: %d\n", ret
);
1144 gmac
->regmap_field
= devm_regmap_field_alloc(dev
, regmap
,
1145 *gmac
->variant
->syscon_field
);
1146 if (IS_ERR(gmac
->regmap_field
)) {
1147 ret
= PTR_ERR(gmac
->regmap_field
);
1148 dev_err(dev
, "Unable to map syscon register: %d\n", ret
);
1152 ret
= of_get_phy_mode(dev
->of_node
);
1155 plat_dat
->interface
= ret
;
1157 /* platform data specifying hardware features and callbacks.
1158 * hardware features were copied from Allwinner drivers.
1160 plat_dat
->rx_coe
= STMMAC_RX_COE_TYPE2
;
1161 plat_dat
->tx_coe
= 1;
1162 plat_dat
->has_sun8i
= true;
1163 plat_dat
->bsp_priv
= gmac
;
1164 plat_dat
->init
= sun8i_dwmac_init
;
1165 plat_dat
->exit
= sun8i_dwmac_exit
;
1166 plat_dat
->setup
= sun8i_dwmac_setup
;
1168 ret
= sun8i_dwmac_init(pdev
, plat_dat
->bsp_priv
);
1172 ret
= stmmac_dvr_probe(&pdev
->dev
, plat_dat
, &stmmac_res
);
1176 ndev
= dev_get_drvdata(&pdev
->dev
);
1177 priv
= netdev_priv(ndev
);
1178 /* The mux must be registered after parent MDIO
1179 * so after stmmac_dvr_probe()
1181 if (gmac
->variant
->soc_has_internal_phy
) {
1182 ret
= get_ephy_nodes(priv
);
1185 ret
= sun8i_dwmac_register_mdio_mux(priv
);
1187 dev_err(&pdev
->dev
, "Failed to register mux\n");
1191 ret
= sun8i_dwmac_reset(priv
);
1198 sun8i_dwmac_unset_syscon(gmac
);
1200 sun8i_dwmac_exit(pdev
, plat_dat
->bsp_priv
);
1204 static const struct of_device_id sun8i_dwmac_match
[] = {
1205 { .compatible
= "allwinner,sun8i-h3-emac",
1206 .data
= &emac_variant_h3
},
1207 { .compatible
= "allwinner,sun8i-v3s-emac",
1208 .data
= &emac_variant_v3s
},
1209 { .compatible
= "allwinner,sun8i-a83t-emac",
1210 .data
= &emac_variant_a83t
},
1211 { .compatible
= "allwinner,sun8i-r40-gmac",
1212 .data
= &emac_variant_r40
},
1213 { .compatible
= "allwinner,sun50i-a64-emac",
1214 .data
= &emac_variant_a64
},
1217 MODULE_DEVICE_TABLE(of
, sun8i_dwmac_match
);
1219 static struct platform_driver sun8i_dwmac_driver
= {
1220 .probe
= sun8i_dwmac_probe
,
1221 .remove
= stmmac_pltfr_remove
,
1223 .name
= "dwmac-sun8i",
1224 .pm
= &stmmac_pltfr_pm_ops
,
1225 .of_match_table
= sun8i_dwmac_match
,
1228 module_platform_driver(sun8i_dwmac_driver
);
1230 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");
1231 MODULE_DESCRIPTION("Allwinner sun8i DWMAC specific glue layer");
1232 MODULE_LICENSE("GPL");