cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dwmac-sun8i.c (35421B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer
      4 *
      5 * Copyright (C) 2017 Corentin Labbe <clabbe.montjoie@gmail.com>
      6 */
      7
      8#include <linux/clk.h>
      9#include <linux/io.h>
     10#include <linux/iopoll.h>
     11#include <linux/mdio-mux.h>
     12#include <linux/mfd/syscon.h>
     13#include <linux/module.h>
     14#include <linux/of_device.h>
     15#include <linux/of_mdio.h>
     16#include <linux/of_net.h>
     17#include <linux/phy.h>
     18#include <linux/platform_device.h>
     19#include <linux/pm_runtime.h>
     20#include <linux/regulator/consumer.h>
     21#include <linux/regmap.h>
     22#include <linux/stmmac.h>
     23
     24#include "stmmac.h"
     25#include "stmmac_platform.h"
     26
     27/* General notes on dwmac-sun8i:
     28 * Locking: no locking is necessary in this file because all necessary locking
     29 *		is done in the "stmmac files"
     30 */
     31
     32/* struct emac_variant - Describe dwmac-sun8i hardware variant
     33 * @default_syscon_value:	The default value of the EMAC register in syscon
     34 *				This value is used for disabling properly EMAC
     35 *				and used as a good starting value in case of the
     36 *				boot process(uboot) leave some stuff.
     37 * @syscon_field		reg_field for the syscon's gmac register
     38 * @soc_has_internal_phy:	Does the MAC embed an internal PHY
     39 * @support_mii:		Does the MAC handle MII
     40 * @support_rmii:		Does the MAC handle RMII
     41 * @support_rgmii:		Does the MAC handle RGMII
     42 *
     43 * @rx_delay_max:		Maximum raw value for RX delay chain
     44 * @tx_delay_max:		Maximum raw value for TX delay chain
     45 *				These two also indicate the bitmask for
     46 *				the RX and TX delay chain registers. A
     47 *				value of zero indicates this is not supported.
     48 */
     49struct emac_variant {
     50	u32 default_syscon_value;
     51	const struct reg_field *syscon_field;
     52	bool soc_has_internal_phy;
     53	bool support_mii;
     54	bool support_rmii;
     55	bool support_rgmii;
     56	u8 rx_delay_max;
     57	u8 tx_delay_max;
     58};
     59
     60/* struct sunxi_priv_data - hold all sunxi private data
     61 * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
     62 * @regulator:	reference to the optional regulator
     63 * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
     64 * @variant:	reference to the current board variant
     65 * @regmap:	regmap for using the syscon
     66 * @internal_phy_powered: Does the internal PHY is enabled
     67 * @use_internal_phy: Is the internal PHY selected for use
     68 * @mux_handle:	Internal pointer used by mdio-mux lib
     69 */
     70struct sunxi_priv_data {
     71	struct clk *ephy_clk;
     72	struct regulator *regulator;
     73	struct reset_control *rst_ephy;
     74	const struct emac_variant *variant;
     75	struct regmap_field *regmap_field;
     76	bool internal_phy_powered;
     77	bool use_internal_phy;
     78	void *mux_handle;
     79};
     80
     81/* EMAC clock register @ 0x30 in the "system control" address range */
     82static const struct reg_field sun8i_syscon_reg_field = {
     83	.reg = 0x30,
     84	.lsb = 0,
     85	.msb = 31,
     86};
     87
     88/* EMAC clock register @ 0x164 in the CCU address range */
     89static const struct reg_field sun8i_ccu_reg_field = {
     90	.reg = 0x164,
     91	.lsb = 0,
     92	.msb = 31,
     93};
     94
     95static const struct emac_variant emac_variant_h3 = {
     96	.default_syscon_value = 0x58000,
     97	.syscon_field = &sun8i_syscon_reg_field,
     98	.soc_has_internal_phy = true,
     99	.support_mii = true,
    100	.support_rmii = true,
    101	.support_rgmii = true,
    102	.rx_delay_max = 31,
    103	.tx_delay_max = 7,
    104};
    105
    106static const struct emac_variant emac_variant_v3s = {
    107	.default_syscon_value = 0x38000,
    108	.syscon_field = &sun8i_syscon_reg_field,
    109	.soc_has_internal_phy = true,
    110	.support_mii = true
    111};
    112
    113static const struct emac_variant emac_variant_a83t = {
    114	.default_syscon_value = 0,
    115	.syscon_field = &sun8i_syscon_reg_field,
    116	.soc_has_internal_phy = false,
    117	.support_mii = true,
    118	.support_rgmii = true,
    119	.rx_delay_max = 31,
    120	.tx_delay_max = 7,
    121};
    122
    123static const struct emac_variant emac_variant_r40 = {
    124	.default_syscon_value = 0,
    125	.syscon_field = &sun8i_ccu_reg_field,
    126	.support_mii = true,
    127	.support_rgmii = true,
    128	.rx_delay_max = 7,
    129};
    130
    131static const struct emac_variant emac_variant_a64 = {
    132	.default_syscon_value = 0,
    133	.syscon_field = &sun8i_syscon_reg_field,
    134	.soc_has_internal_phy = false,
    135	.support_mii = true,
    136	.support_rmii = true,
    137	.support_rgmii = true,
    138	.rx_delay_max = 31,
    139	.tx_delay_max = 7,
    140};
    141
    142static const struct emac_variant emac_variant_h6 = {
    143	.default_syscon_value = 0x50000,
    144	.syscon_field = &sun8i_syscon_reg_field,
    145	/* The "Internal PHY" of H6 is not on the die. It's on the
    146	 * co-packaged AC200 chip instead.
    147	 */
    148	.soc_has_internal_phy = false,
    149	.support_mii = true,
    150	.support_rmii = true,
    151	.support_rgmii = true,
    152	.rx_delay_max = 31,
    153	.tx_delay_max = 7,
    154};
    155
    156#define EMAC_BASIC_CTL0 0x00
    157#define EMAC_BASIC_CTL1 0x04
    158#define EMAC_INT_STA    0x08
    159#define EMAC_INT_EN     0x0C
    160#define EMAC_TX_CTL0    0x10
    161#define EMAC_TX_CTL1    0x14
    162#define EMAC_TX_FLOW_CTL        0x1C
    163#define EMAC_TX_DESC_LIST 0x20
    164#define EMAC_RX_CTL0    0x24
    165#define EMAC_RX_CTL1    0x28
    166#define EMAC_RX_DESC_LIST 0x34
    167#define EMAC_RX_FRM_FLT 0x38
    168#define EMAC_MDIO_CMD   0x48
    169#define EMAC_MDIO_DATA  0x4C
    170#define EMAC_MACADDR_HI(reg) (0x50 + (reg) * 8)
    171#define EMAC_MACADDR_LO(reg) (0x54 + (reg) * 8)
    172#define EMAC_TX_DMA_STA 0xB0
    173#define EMAC_TX_CUR_DESC        0xB4
    174#define EMAC_TX_CUR_BUF 0xB8
    175#define EMAC_RX_DMA_STA 0xC0
    176#define EMAC_RX_CUR_DESC        0xC4
    177#define EMAC_RX_CUR_BUF 0xC8
    178
    179/* Use in EMAC_BASIC_CTL0 */
    180#define EMAC_DUPLEX_FULL	BIT(0)
    181#define EMAC_LOOPBACK		BIT(1)
    182#define EMAC_SPEED_1000 0
    183#define EMAC_SPEED_100 (0x03 << 2)
    184#define EMAC_SPEED_10 (0x02 << 2)
    185
    186/* Use in EMAC_BASIC_CTL1 */
    187#define EMAC_BURSTLEN_SHIFT		24
    188
    189/* Used in EMAC_RX_FRM_FLT */
    190#define EMAC_FRM_FLT_RXALL              BIT(0)
    191#define EMAC_FRM_FLT_CTL                BIT(13)
    192#define EMAC_FRM_FLT_MULTICAST          BIT(16)
    193
    194/* Used in RX_CTL1*/
    195#define EMAC_RX_MD              BIT(1)
    196#define EMAC_RX_TH_MASK		GENMASK(5, 4)
    197#define EMAC_RX_TH_32		0
    198#define EMAC_RX_TH_64		(0x1 << 4)
    199#define EMAC_RX_TH_96		(0x2 << 4)
    200#define EMAC_RX_TH_128		(0x3 << 4)
    201#define EMAC_RX_DMA_EN  BIT(30)
    202#define EMAC_RX_DMA_START       BIT(31)
    203
    204/* Used in TX_CTL1*/
    205#define EMAC_TX_MD              BIT(1)
    206#define EMAC_TX_NEXT_FRM        BIT(2)
    207#define EMAC_TX_TH_MASK		GENMASK(10, 8)
    208#define EMAC_TX_TH_64		0
    209#define EMAC_TX_TH_128		(0x1 << 8)
    210#define EMAC_TX_TH_192		(0x2 << 8)
    211#define EMAC_TX_TH_256		(0x3 << 8)
    212#define EMAC_TX_DMA_EN  BIT(30)
    213#define EMAC_TX_DMA_START       BIT(31)
    214
    215/* Used in RX_CTL0 */
    216#define EMAC_RX_RECEIVER_EN             BIT(31)
    217#define EMAC_RX_DO_CRC BIT(27)
    218#define EMAC_RX_FLOW_CTL_EN             BIT(16)
    219
    220/* Used in TX_CTL0 */
    221#define EMAC_TX_TRANSMITTER_EN  BIT(31)
    222
    223/* Used in EMAC_TX_FLOW_CTL */
    224#define EMAC_TX_FLOW_CTL_EN             BIT(0)
    225
    226/* Used in EMAC_INT_STA */
    227#define EMAC_TX_INT             BIT(0)
    228#define EMAC_TX_DMA_STOP_INT    BIT(1)
    229#define EMAC_TX_BUF_UA_INT      BIT(2)
    230#define EMAC_TX_TIMEOUT_INT     BIT(3)
    231#define EMAC_TX_UNDERFLOW_INT   BIT(4)
    232#define EMAC_TX_EARLY_INT       BIT(5)
    233#define EMAC_RX_INT             BIT(8)
    234#define EMAC_RX_BUF_UA_INT      BIT(9)
    235#define EMAC_RX_DMA_STOP_INT    BIT(10)
    236#define EMAC_RX_TIMEOUT_INT     BIT(11)
    237#define EMAC_RX_OVERFLOW_INT    BIT(12)
    238#define EMAC_RX_EARLY_INT       BIT(13)
    239#define EMAC_RGMII_STA_INT      BIT(16)
    240
    241#define EMAC_INT_MSK_COMMON	EMAC_RGMII_STA_INT
    242#define EMAC_INT_MSK_TX		(EMAC_TX_INT | \
    243				 EMAC_TX_DMA_STOP_INT | \
    244				 EMAC_TX_BUF_UA_INT | \
    245				 EMAC_TX_TIMEOUT_INT | \
    246				 EMAC_TX_UNDERFLOW_INT | \
    247				 EMAC_TX_EARLY_INT |\
    248				 EMAC_INT_MSK_COMMON)
    249#define EMAC_INT_MSK_RX		(EMAC_RX_INT | \
    250				 EMAC_RX_BUF_UA_INT | \
    251				 EMAC_RX_DMA_STOP_INT | \
    252				 EMAC_RX_TIMEOUT_INT | \
    253				 EMAC_RX_OVERFLOW_INT | \
    254				 EMAC_RX_EARLY_INT | \
    255				 EMAC_INT_MSK_COMMON)
    256
    257#define MAC_ADDR_TYPE_DST BIT(31)
    258
    259/* H3 specific bits for EPHY */
    260#define H3_EPHY_ADDR_SHIFT	20
    261#define H3_EPHY_CLK_SEL		BIT(18) /* 1: 24MHz, 0: 25MHz */
    262#define H3_EPHY_LED_POL		BIT(17) /* 1: active low, 0: active high */
    263#define H3_EPHY_SHUTDOWN	BIT(16) /* 1: shutdown, 0: power up */
    264#define H3_EPHY_SELECT		BIT(15) /* 1: internal PHY, 0: external PHY */
    265#define H3_EPHY_MUX_MASK	(H3_EPHY_SHUTDOWN | H3_EPHY_SELECT)
    266#define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID	1
    267#define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID	2
    268
    269/* H3/A64 specific bits */
    270#define SYSCON_RMII_EN		BIT(13) /* 1: enable RMII (overrides EPIT) */
    271
    272/* Generic system control EMAC_CLK bits */
    273#define SYSCON_ETXDC_SHIFT		10
    274#define SYSCON_ERXDC_SHIFT		5
    275/* EMAC PHY Interface Type */
    276#define SYSCON_EPIT			BIT(2) /* 1: RGMII, 0: MII */
    277#define SYSCON_ETCS_MASK		GENMASK(1, 0)
    278#define SYSCON_ETCS_MII		0x0
    279#define SYSCON_ETCS_EXT_GMII	0x1
    280#define SYSCON_ETCS_INT_GMII	0x2
    281
    282/* sun8i_dwmac_dma_reset() - reset the EMAC
    283 * Called from stmmac via stmmac_dma_ops->reset
    284 */
    285static int sun8i_dwmac_dma_reset(void __iomem *ioaddr)
    286{
    287	writel(0, ioaddr + EMAC_RX_CTL1);
    288	writel(0, ioaddr + EMAC_TX_CTL1);
    289	writel(0, ioaddr + EMAC_RX_FRM_FLT);
    290	writel(0, ioaddr + EMAC_RX_DESC_LIST);
    291	writel(0, ioaddr + EMAC_TX_DESC_LIST);
    292	writel(0, ioaddr + EMAC_INT_EN);
    293	writel(0x1FFFFFF, ioaddr + EMAC_INT_STA);
    294	return 0;
    295}
    296
    297/* sun8i_dwmac_dma_init() - initialize the EMAC
    298 * Called from stmmac via stmmac_dma_ops->init
    299 */
    300static void sun8i_dwmac_dma_init(void __iomem *ioaddr,
    301				 struct stmmac_dma_cfg *dma_cfg, int atds)
    302{
    303	writel(EMAC_RX_INT | EMAC_TX_INT, ioaddr + EMAC_INT_EN);
    304	writel(0x1FFFFFF, ioaddr + EMAC_INT_STA);
    305}
    306
    307static void sun8i_dwmac_dma_init_rx(void __iomem *ioaddr,
    308				    struct stmmac_dma_cfg *dma_cfg,
    309				    dma_addr_t dma_rx_phy, u32 chan)
    310{
    311	/* Write RX descriptors address */
    312	writel(lower_32_bits(dma_rx_phy), ioaddr + EMAC_RX_DESC_LIST);
    313}
    314
    315static void sun8i_dwmac_dma_init_tx(void __iomem *ioaddr,
    316				    struct stmmac_dma_cfg *dma_cfg,
    317				    dma_addr_t dma_tx_phy, u32 chan)
    318{
    319	/* Write TX descriptors address */
    320	writel(lower_32_bits(dma_tx_phy), ioaddr + EMAC_TX_DESC_LIST);
    321}
    322
    323/* sun8i_dwmac_dump_regs() - Dump EMAC address space
    324 * Called from stmmac_dma_ops->dump_regs
    325 * Used for ethtool
    326 */
    327static void sun8i_dwmac_dump_regs(void __iomem *ioaddr, u32 *reg_space)
    328{
    329	int i;
    330
    331	for (i = 0; i < 0xC8; i += 4) {
    332		if (i == 0x32 || i == 0x3C)
    333			continue;
    334		reg_space[i / 4] = readl(ioaddr + i);
    335	}
    336}
    337
    338/* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
    339 * Called from stmmac_ops->dump_regs
    340 * Used for ethtool
    341 */
    342static void sun8i_dwmac_dump_mac_regs(struct mac_device_info *hw,
    343				      u32 *reg_space)
    344{
    345	int i;
    346	void __iomem *ioaddr = hw->pcsr;
    347
    348	for (i = 0; i < 0xC8; i += 4) {
    349		if (i == 0x32 || i == 0x3C)
    350			continue;
    351		reg_space[i / 4] = readl(ioaddr + i);
    352	}
    353}
    354
    355static void sun8i_dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan,
    356				       bool rx, bool tx)
    357{
    358	u32 value = readl(ioaddr + EMAC_INT_EN);
    359
    360	if (rx)
    361		value |= EMAC_RX_INT;
    362	if (tx)
    363		value |= EMAC_TX_INT;
    364
    365	writel(value, ioaddr + EMAC_INT_EN);
    366}
    367
    368static void sun8i_dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan,
    369					bool rx, bool tx)
    370{
    371	u32 value = readl(ioaddr + EMAC_INT_EN);
    372
    373	if (rx)
    374		value &= ~EMAC_RX_INT;
    375	if (tx)
    376		value &= ~EMAC_TX_INT;
    377
    378	writel(value, ioaddr + EMAC_INT_EN);
    379}
    380
    381static void sun8i_dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
    382{
    383	u32 v;
    384
    385	v = readl(ioaddr + EMAC_TX_CTL1);
    386	v |= EMAC_TX_DMA_START;
    387	v |= EMAC_TX_DMA_EN;
    388	writel(v, ioaddr + EMAC_TX_CTL1);
    389}
    390
    391static void sun8i_dwmac_enable_dma_transmission(void __iomem *ioaddr)
    392{
    393	u32 v;
    394
    395	v = readl(ioaddr + EMAC_TX_CTL1);
    396	v |= EMAC_TX_DMA_START;
    397	v |= EMAC_TX_DMA_EN;
    398	writel(v, ioaddr + EMAC_TX_CTL1);
    399}
    400
    401static void sun8i_dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
    402{
    403	u32 v;
    404
    405	v = readl(ioaddr + EMAC_TX_CTL1);
    406	v &= ~EMAC_TX_DMA_EN;
    407	writel(v, ioaddr + EMAC_TX_CTL1);
    408}
    409
    410static void sun8i_dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
    411{
    412	u32 v;
    413
    414	v = readl(ioaddr + EMAC_RX_CTL1);
    415	v |= EMAC_RX_DMA_START;
    416	v |= EMAC_RX_DMA_EN;
    417	writel(v, ioaddr + EMAC_RX_CTL1);
    418}
    419
    420static void sun8i_dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
    421{
    422	u32 v;
    423
    424	v = readl(ioaddr + EMAC_RX_CTL1);
    425	v &= ~EMAC_RX_DMA_EN;
    426	writel(v, ioaddr + EMAC_RX_CTL1);
    427}
    428
    429static int sun8i_dwmac_dma_interrupt(void __iomem *ioaddr,
    430				     struct stmmac_extra_stats *x, u32 chan,
    431				     u32 dir)
    432{
    433	u32 v;
    434	int ret = 0;
    435
    436	v = readl(ioaddr + EMAC_INT_STA);
    437
    438	if (dir == DMA_DIR_RX)
    439		v &= EMAC_INT_MSK_RX;
    440	else if (dir == DMA_DIR_TX)
    441		v &= EMAC_INT_MSK_TX;
    442
    443	if (v & EMAC_TX_INT) {
    444		ret |= handle_tx;
    445		x->tx_normal_irq_n++;
    446	}
    447
    448	if (v & EMAC_TX_DMA_STOP_INT)
    449		x->tx_process_stopped_irq++;
    450
    451	if (v & EMAC_TX_BUF_UA_INT)
    452		x->tx_process_stopped_irq++;
    453
    454	if (v & EMAC_TX_TIMEOUT_INT)
    455		ret |= tx_hard_error;
    456
    457	if (v & EMAC_TX_UNDERFLOW_INT) {
    458		ret |= tx_hard_error;
    459		x->tx_undeflow_irq++;
    460	}
    461
    462	if (v & EMAC_TX_EARLY_INT)
    463		x->tx_early_irq++;
    464
    465	if (v & EMAC_RX_INT) {
    466		ret |= handle_rx;
    467		x->rx_normal_irq_n++;
    468	}
    469
    470	if (v & EMAC_RX_BUF_UA_INT)
    471		x->rx_buf_unav_irq++;
    472
    473	if (v & EMAC_RX_DMA_STOP_INT)
    474		x->rx_process_stopped_irq++;
    475
    476	if (v & EMAC_RX_TIMEOUT_INT)
    477		ret |= tx_hard_error;
    478
    479	if (v & EMAC_RX_OVERFLOW_INT) {
    480		ret |= tx_hard_error;
    481		x->rx_overflow_irq++;
    482	}
    483
    484	if (v & EMAC_RX_EARLY_INT)
    485		x->rx_early_irq++;
    486
    487	if (v & EMAC_RGMII_STA_INT)
    488		x->irq_rgmii_n++;
    489
    490	writel(v, ioaddr + EMAC_INT_STA);
    491
    492	return ret;
    493}
    494
    495static void sun8i_dwmac_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
    496					      u32 channel, int fifosz, u8 qmode)
    497{
    498	u32 v;
    499
    500	v = readl(ioaddr + EMAC_RX_CTL1);
    501	if (mode == SF_DMA_MODE) {
    502		v |= EMAC_RX_MD;
    503	} else {
    504		v &= ~EMAC_RX_MD;
    505		v &= ~EMAC_RX_TH_MASK;
    506		if (mode < 32)
    507			v |= EMAC_RX_TH_32;
    508		else if (mode < 64)
    509			v |= EMAC_RX_TH_64;
    510		else if (mode < 96)
    511			v |= EMAC_RX_TH_96;
    512		else if (mode < 128)
    513			v |= EMAC_RX_TH_128;
    514	}
    515	writel(v, ioaddr + EMAC_RX_CTL1);
    516}
    517
    518static void sun8i_dwmac_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
    519					      u32 channel, int fifosz, u8 qmode)
    520{
    521	u32 v;
    522
    523	v = readl(ioaddr + EMAC_TX_CTL1);
    524	if (mode == SF_DMA_MODE) {
    525		v |= EMAC_TX_MD;
    526		/* Undocumented bit (called TX_NEXT_FRM in BSP), the original
    527		 * comment is
    528		 * "Operating on second frame increase the performance
    529		 * especially when transmit store-and-forward is used."
    530		 */
    531		v |= EMAC_TX_NEXT_FRM;
    532	} else {
    533		v &= ~EMAC_TX_MD;
    534		v &= ~EMAC_TX_TH_MASK;
    535		if (mode < 64)
    536			v |= EMAC_TX_TH_64;
    537		else if (mode < 128)
    538			v |= EMAC_TX_TH_128;
    539		else if (mode < 192)
    540			v |= EMAC_TX_TH_192;
    541		else if (mode < 256)
    542			v |= EMAC_TX_TH_256;
    543	}
    544	writel(v, ioaddr + EMAC_TX_CTL1);
    545}
    546
    547static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
    548	.reset = sun8i_dwmac_dma_reset,
    549	.init = sun8i_dwmac_dma_init,
    550	.init_rx_chan = sun8i_dwmac_dma_init_rx,
    551	.init_tx_chan = sun8i_dwmac_dma_init_tx,
    552	.dump_regs = sun8i_dwmac_dump_regs,
    553	.dma_rx_mode = sun8i_dwmac_dma_operation_mode_rx,
    554	.dma_tx_mode = sun8i_dwmac_dma_operation_mode_tx,
    555	.enable_dma_transmission = sun8i_dwmac_enable_dma_transmission,
    556	.enable_dma_irq = sun8i_dwmac_enable_dma_irq,
    557	.disable_dma_irq = sun8i_dwmac_disable_dma_irq,
    558	.start_tx = sun8i_dwmac_dma_start_tx,
    559	.stop_tx = sun8i_dwmac_dma_stop_tx,
    560	.start_rx = sun8i_dwmac_dma_start_rx,
    561	.stop_rx = sun8i_dwmac_dma_stop_rx,
    562	.dma_interrupt = sun8i_dwmac_dma_interrupt,
    563};
    564
    565static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
    566
    567static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
    568{
    569	struct net_device *ndev = platform_get_drvdata(pdev);
    570	struct sunxi_priv_data *gmac = priv;
    571	int ret;
    572
    573	if (gmac->regulator) {
    574		ret = regulator_enable(gmac->regulator);
    575		if (ret) {
    576			dev_err(&pdev->dev, "Fail to enable regulator\n");
    577			return ret;
    578		}
    579	}
    580
    581	if (gmac->use_internal_phy) {
    582		ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
    583		if (ret)
    584			goto err_disable_regulator;
    585	}
    586
    587	return 0;
    588
    589err_disable_regulator:
    590	if (gmac->regulator)
    591		regulator_disable(gmac->regulator);
    592
    593	return ret;
    594}
    595
    596static void sun8i_dwmac_core_init(struct mac_device_info *hw,
    597				  struct net_device *dev)
    598{
    599	void __iomem *ioaddr = hw->pcsr;
    600	u32 v;
    601
    602	v = (8 << EMAC_BURSTLEN_SHIFT); /* burst len */
    603	writel(v, ioaddr + EMAC_BASIC_CTL1);
    604}
    605
    606static void sun8i_dwmac_set_mac(void __iomem *ioaddr, bool enable)
    607{
    608	u32 t, r;
    609
    610	t = readl(ioaddr + EMAC_TX_CTL0);
    611	r = readl(ioaddr + EMAC_RX_CTL0);
    612	if (enable) {
    613		t |= EMAC_TX_TRANSMITTER_EN;
    614		r |= EMAC_RX_RECEIVER_EN;
    615	} else {
    616		t &= ~EMAC_TX_TRANSMITTER_EN;
    617		r &= ~EMAC_RX_RECEIVER_EN;
    618	}
    619	writel(t, ioaddr + EMAC_TX_CTL0);
    620	writel(r, ioaddr + EMAC_RX_CTL0);
    621}
    622
    623/* Set MAC address at slot reg_n
    624 * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST
    625 * If addr is NULL, clear the slot
    626 */
    627static void sun8i_dwmac_set_umac_addr(struct mac_device_info *hw,
    628				      const unsigned char *addr,
    629				      unsigned int reg_n)
    630{
    631	void __iomem *ioaddr = hw->pcsr;
    632	u32 v;
    633
    634	if (!addr) {
    635		writel(0, ioaddr + EMAC_MACADDR_HI(reg_n));
    636		return;
    637	}
    638
    639	stmmac_set_mac_addr(ioaddr, addr, EMAC_MACADDR_HI(reg_n),
    640			    EMAC_MACADDR_LO(reg_n));
    641	if (reg_n > 0) {
    642		v = readl(ioaddr + EMAC_MACADDR_HI(reg_n));
    643		v |= MAC_ADDR_TYPE_DST;
    644		writel(v, ioaddr + EMAC_MACADDR_HI(reg_n));
    645	}
    646}
    647
    648static void sun8i_dwmac_get_umac_addr(struct mac_device_info *hw,
    649				      unsigned char *addr,
    650				      unsigned int reg_n)
    651{
    652	void __iomem *ioaddr = hw->pcsr;
    653
    654	stmmac_get_mac_addr(ioaddr, addr, EMAC_MACADDR_HI(reg_n),
    655			    EMAC_MACADDR_LO(reg_n));
    656}
    657
    658/* caution this function must return non 0 to work */
    659static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info *hw)
    660{
    661	void __iomem *ioaddr = hw->pcsr;
    662	u32 v;
    663
    664	v = readl(ioaddr + EMAC_RX_CTL0);
    665	v |= EMAC_RX_DO_CRC;
    666	writel(v, ioaddr + EMAC_RX_CTL0);
    667
    668	return 1;
    669}
    670
    671static void sun8i_dwmac_set_filter(struct mac_device_info *hw,
    672				   struct net_device *dev)
    673{
    674	void __iomem *ioaddr = hw->pcsr;
    675	u32 v;
    676	int i = 1;
    677	struct netdev_hw_addr *ha;
    678	int macaddrs = netdev_uc_count(dev) + netdev_mc_count(dev) + 1;
    679
    680	v = EMAC_FRM_FLT_CTL;
    681
    682	if (dev->flags & IFF_PROMISC) {
    683		v = EMAC_FRM_FLT_RXALL;
    684	} else if (dev->flags & IFF_ALLMULTI) {
    685		v |= EMAC_FRM_FLT_MULTICAST;
    686	} else if (macaddrs <= hw->unicast_filter_entries) {
    687		if (!netdev_mc_empty(dev)) {
    688			netdev_for_each_mc_addr(ha, dev) {
    689				sun8i_dwmac_set_umac_addr(hw, ha->addr, i);
    690				i++;
    691			}
    692		}
    693		if (!netdev_uc_empty(dev)) {
    694			netdev_for_each_uc_addr(ha, dev) {
    695				sun8i_dwmac_set_umac_addr(hw, ha->addr, i);
    696				i++;
    697			}
    698		}
    699	} else {
    700		if (!(readl(ioaddr + EMAC_RX_FRM_FLT) & EMAC_FRM_FLT_RXALL))
    701			netdev_info(dev, "Too many address, switching to promiscuous\n");
    702		v = EMAC_FRM_FLT_RXALL;
    703	}
    704
    705	/* Disable unused address filter slots */
    706	while (i < hw->unicast_filter_entries)
    707		sun8i_dwmac_set_umac_addr(hw, NULL, i++);
    708
    709	writel(v, ioaddr + EMAC_RX_FRM_FLT);
    710}
    711
    712static void sun8i_dwmac_flow_ctrl(struct mac_device_info *hw,
    713				  unsigned int duplex, unsigned int fc,
    714				  unsigned int pause_time, u32 tx_cnt)
    715{
    716	void __iomem *ioaddr = hw->pcsr;
    717	u32 v;
    718
    719	v = readl(ioaddr + EMAC_RX_CTL0);
    720	if (fc == FLOW_AUTO)
    721		v |= EMAC_RX_FLOW_CTL_EN;
    722	else
    723		v &= ~EMAC_RX_FLOW_CTL_EN;
    724	writel(v, ioaddr + EMAC_RX_CTL0);
    725
    726	v = readl(ioaddr + EMAC_TX_FLOW_CTL);
    727	if (fc == FLOW_AUTO)
    728		v |= EMAC_TX_FLOW_CTL_EN;
    729	else
    730		v &= ~EMAC_TX_FLOW_CTL_EN;
    731	writel(v, ioaddr + EMAC_TX_FLOW_CTL);
    732}
    733
    734static int sun8i_dwmac_reset(struct stmmac_priv *priv)
    735{
    736	u32 v;
    737	int err;
    738
    739	v = readl(priv->ioaddr + EMAC_BASIC_CTL1);
    740	writel(v | 0x01, priv->ioaddr + EMAC_BASIC_CTL1);
    741
    742	/* The timeout was previoulsy set to 10ms, but some board (OrangePI0)
    743	 * need more if no cable plugged. 100ms seems OK
    744	 */
    745	err = readl_poll_timeout(priv->ioaddr + EMAC_BASIC_CTL1, v,
    746				 !(v & 0x01), 100, 100000);
    747
    748	if (err) {
    749		dev_err(priv->device, "EMAC reset timeout\n");
    750		return err;
    751	}
    752	return 0;
    753}
    754
    755/* Search in mdio-mux node for internal PHY node and get its clk/reset */
    756static int get_ephy_nodes(struct stmmac_priv *priv)
    757{
    758	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
    759	struct device_node *mdio_mux, *iphynode;
    760	struct device_node *mdio_internal;
    761	int ret;
    762
    763	mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux");
    764	if (!mdio_mux) {
    765		dev_err(priv->device, "Cannot get mdio-mux node\n");
    766		return -ENODEV;
    767	}
    768
    769	mdio_internal = of_get_compatible_child(mdio_mux,
    770						"allwinner,sun8i-h3-mdio-internal");
    771	of_node_put(mdio_mux);
    772	if (!mdio_internal) {
    773		dev_err(priv->device, "Cannot get internal_mdio node\n");
    774		return -ENODEV;
    775	}
    776
    777	/* Seek for internal PHY */
    778	for_each_child_of_node(mdio_internal, iphynode) {
    779		gmac->ephy_clk = of_clk_get(iphynode, 0);
    780		if (IS_ERR(gmac->ephy_clk))
    781			continue;
    782		gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL);
    783		if (IS_ERR(gmac->rst_ephy)) {
    784			ret = PTR_ERR(gmac->rst_ephy);
    785			if (ret == -EPROBE_DEFER) {
    786				of_node_put(iphynode);
    787				of_node_put(mdio_internal);
    788				return ret;
    789			}
    790			continue;
    791		}
    792		dev_info(priv->device, "Found internal PHY node\n");
    793		of_node_put(iphynode);
    794		of_node_put(mdio_internal);
    795		return 0;
    796	}
    797
    798	of_node_put(mdio_internal);
    799	return -ENODEV;
    800}
    801
    802static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv)
    803{
    804	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
    805	int ret;
    806
    807	if (gmac->internal_phy_powered) {
    808		dev_warn(priv->device, "Internal PHY already powered\n");
    809		return 0;
    810	}
    811
    812	dev_info(priv->device, "Powering internal PHY\n");
    813	ret = clk_prepare_enable(gmac->ephy_clk);
    814	if (ret) {
    815		dev_err(priv->device, "Cannot enable internal PHY\n");
    816		return ret;
    817	}
    818
    819	/* Make sure the EPHY is properly reseted, as U-Boot may leave
    820	 * it at deasserted state, and thus it may fail to reset EMAC.
    821	 *
    822	 * This assumes the driver has exclusive access to the EPHY reset.
    823	 */
    824	ret = reset_control_reset(gmac->rst_ephy);
    825	if (ret) {
    826		dev_err(priv->device, "Cannot reset internal PHY\n");
    827		clk_disable_unprepare(gmac->ephy_clk);
    828		return ret;
    829	}
    830
    831	gmac->internal_phy_powered = true;
    832
    833	return 0;
    834}
    835
    836static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
    837{
    838	if (!gmac->internal_phy_powered)
    839		return;
    840
    841	clk_disable_unprepare(gmac->ephy_clk);
    842	reset_control_assert(gmac->rst_ephy);
    843	gmac->internal_phy_powered = false;
    844}
    845
    846/* MDIO multiplexing switch function
    847 * This function is called by the mdio-mux layer when it thinks the mdio bus
    848 * multiplexer needs to switch.
    849 * 'current_child' is the current value of the mux register
    850 * 'desired_child' is the value of the 'reg' property of the target child MDIO
    851 * node.
    852 * The first time this function is called, current_child == -1.
    853 * If current_child == desired_child, then the mux is already set to the
    854 * correct bus.
    855 */
    856static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
    857				     void *data)
    858{
    859	struct stmmac_priv *priv = data;
    860	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
    861	u32 reg, val;
    862	int ret = 0;
    863
    864	if (current_child ^ desired_child) {
    865		regmap_field_read(gmac->regmap_field, &reg);
    866		switch (desired_child) {
    867		case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
    868			dev_info(priv->device, "Switch mux to internal PHY");
    869			val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
    870			gmac->use_internal_phy = true;
    871			break;
    872		case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
    873			dev_info(priv->device, "Switch mux to external PHY");
    874			val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
    875			gmac->use_internal_phy = false;
    876			break;
    877		default:
    878			dev_err(priv->device, "Invalid child ID %x\n",
    879				desired_child);
    880			return -EINVAL;
    881		}
    882		regmap_field_write(gmac->regmap_field, val);
    883		if (gmac->use_internal_phy) {
    884			ret = sun8i_dwmac_power_internal_phy(priv);
    885			if (ret)
    886				return ret;
    887		} else {
    888			sun8i_dwmac_unpower_internal_phy(gmac);
    889		}
    890		/* After changing syscon value, the MAC need reset or it will
    891		 * use the last value (and so the last PHY set).
    892		 */
    893		ret = sun8i_dwmac_reset(priv);
    894	}
    895	return ret;
    896}
    897
    898static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv)
    899{
    900	int ret;
    901	struct device_node *mdio_mux;
    902	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
    903
    904	mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux");
    905	if (!mdio_mux)
    906		return -ENODEV;
    907
    908	ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn,
    909			    &gmac->mux_handle, priv, priv->mii);
    910	of_node_put(mdio_mux);
    911	return ret;
    912}
    913
    914static int sun8i_dwmac_set_syscon(struct device *dev,
    915				  struct plat_stmmacenet_data *plat)
    916{
    917	struct sunxi_priv_data *gmac = plat->bsp_priv;
    918	struct device_node *node = dev->of_node;
    919	int ret;
    920	u32 reg, val;
    921
    922	ret = regmap_field_read(gmac->regmap_field, &val);
    923	if (ret) {
    924		dev_err(dev, "Fail to read from regmap field.\n");
    925		return ret;
    926	}
    927
    928	reg = gmac->variant->default_syscon_value;
    929	if (reg != val)
    930		dev_warn(dev,
    931			 "Current syscon value is not the default %x (expect %x)\n",
    932			 val, reg);
    933
    934	if (gmac->variant->soc_has_internal_phy) {
    935		if (of_property_read_bool(node, "allwinner,leds-active-low"))
    936			reg |= H3_EPHY_LED_POL;
    937		else
    938			reg &= ~H3_EPHY_LED_POL;
    939
    940		/* Force EPHY xtal frequency to 24MHz. */
    941		reg |= H3_EPHY_CLK_SEL;
    942
    943		ret = of_mdio_parse_addr(dev, plat->phy_node);
    944		if (ret < 0) {
    945			dev_err(dev, "Could not parse MDIO addr\n");
    946			return ret;
    947		}
    948		/* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
    949		 * address. No need to mask it again.
    950		 */
    951		reg |= 1 << H3_EPHY_ADDR_SHIFT;
    952	} else {
    953		/* For SoCs without internal PHY the PHY selection bit should be
    954		 * set to 0 (external PHY).
    955		 */
    956		reg &= ~H3_EPHY_SELECT;
    957	}
    958
    959	if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) {
    960		if (val % 100) {
    961			dev_err(dev, "tx-delay must be a multiple of 100\n");
    962			return -EINVAL;
    963		}
    964		val /= 100;
    965		dev_dbg(dev, "set tx-delay to %x\n", val);
    966		if (val <= gmac->variant->tx_delay_max) {
    967			reg &= ~(gmac->variant->tx_delay_max <<
    968				 SYSCON_ETXDC_SHIFT);
    969			reg |= (val << SYSCON_ETXDC_SHIFT);
    970		} else {
    971			dev_err(dev, "Invalid TX clock delay: %d\n",
    972				val);
    973			return -EINVAL;
    974		}
    975	}
    976
    977	if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) {
    978		if (val % 100) {
    979			dev_err(dev, "rx-delay must be a multiple of 100\n");
    980			return -EINVAL;
    981		}
    982		val /= 100;
    983		dev_dbg(dev, "set rx-delay to %x\n", val);
    984		if (val <= gmac->variant->rx_delay_max) {
    985			reg &= ~(gmac->variant->rx_delay_max <<
    986				 SYSCON_ERXDC_SHIFT);
    987			reg |= (val << SYSCON_ERXDC_SHIFT);
    988		} else {
    989			dev_err(dev, "Invalid RX clock delay: %d\n",
    990				val);
    991			return -EINVAL;
    992		}
    993	}
    994
    995	/* Clear interface mode bits */
    996	reg &= ~(SYSCON_ETCS_MASK | SYSCON_EPIT);
    997	if (gmac->variant->support_rmii)
    998		reg &= ~SYSCON_RMII_EN;
    999
   1000	switch (plat->interface) {
   1001	case PHY_INTERFACE_MODE_MII:
   1002		/* default */
   1003		break;
   1004	case PHY_INTERFACE_MODE_RGMII:
   1005	case PHY_INTERFACE_MODE_RGMII_ID:
   1006	case PHY_INTERFACE_MODE_RGMII_RXID:
   1007	case PHY_INTERFACE_MODE_RGMII_TXID:
   1008		reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
   1009		break;
   1010	case PHY_INTERFACE_MODE_RMII:
   1011		reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII;
   1012		break;
   1013	default:
   1014		dev_err(dev, "Unsupported interface mode: %s",
   1015			phy_modes(plat->interface));
   1016		return -EINVAL;
   1017	}
   1018
   1019	regmap_field_write(gmac->regmap_field, reg);
   1020
   1021	return 0;
   1022}
   1023
   1024static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
   1025{
   1026	u32 reg = gmac->variant->default_syscon_value;
   1027
   1028	regmap_field_write(gmac->regmap_field, reg);
   1029}
   1030
   1031static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
   1032{
   1033	struct sunxi_priv_data *gmac = priv;
   1034
   1035	if (gmac->variant->soc_has_internal_phy)
   1036		sun8i_dwmac_unpower_internal_phy(gmac);
   1037
   1038	if (gmac->regulator)
   1039		regulator_disable(gmac->regulator);
   1040}
   1041
   1042static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
   1043{
   1044	u32 value = readl(ioaddr + EMAC_BASIC_CTL0);
   1045
   1046	if (enable)
   1047		value |= EMAC_LOOPBACK;
   1048	else
   1049		value &= ~EMAC_LOOPBACK;
   1050
   1051	writel(value, ioaddr + EMAC_BASIC_CTL0);
   1052}
   1053
   1054static const struct stmmac_ops sun8i_dwmac_ops = {
   1055	.core_init = sun8i_dwmac_core_init,
   1056	.set_mac = sun8i_dwmac_set_mac,
   1057	.dump_regs = sun8i_dwmac_dump_mac_regs,
   1058	.rx_ipc = sun8i_dwmac_rx_ipc_enable,
   1059	.set_filter = sun8i_dwmac_set_filter,
   1060	.flow_ctrl = sun8i_dwmac_flow_ctrl,
   1061	.set_umac_addr = sun8i_dwmac_set_umac_addr,
   1062	.get_umac_addr = sun8i_dwmac_get_umac_addr,
   1063	.set_mac_loopback = sun8i_dwmac_set_mac_loopback,
   1064};
   1065
   1066static struct mac_device_info *sun8i_dwmac_setup(void *ppriv)
   1067{
   1068	struct mac_device_info *mac;
   1069	struct stmmac_priv *priv = ppriv;
   1070
   1071	mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
   1072	if (!mac)
   1073		return NULL;
   1074
   1075	mac->pcsr = priv->ioaddr;
   1076	mac->mac = &sun8i_dwmac_ops;
   1077	mac->dma = &sun8i_dwmac_dma_ops;
   1078
   1079	priv->dev->priv_flags |= IFF_UNICAST_FLT;
   1080
   1081	/* The loopback bit seems to be re-set when link change
   1082	 * Simply mask it each time
   1083	 * Speed 10/100/1000 are set in BIT(2)/BIT(3)
   1084	 */
   1085	mac->link.speed_mask = GENMASK(3, 2) | EMAC_LOOPBACK;
   1086	mac->link.speed10 = EMAC_SPEED_10;
   1087	mac->link.speed100 = EMAC_SPEED_100;
   1088	mac->link.speed1000 = EMAC_SPEED_1000;
   1089	mac->link.duplex = EMAC_DUPLEX_FULL;
   1090	mac->mii.addr = EMAC_MDIO_CMD;
   1091	mac->mii.data = EMAC_MDIO_DATA;
   1092	mac->mii.reg_shift = 4;
   1093	mac->mii.reg_mask = GENMASK(8, 4);
   1094	mac->mii.addr_shift = 12;
   1095	mac->mii.addr_mask = GENMASK(16, 12);
   1096	mac->mii.clk_csr_shift = 20;
   1097	mac->mii.clk_csr_mask = GENMASK(22, 20);
   1098	mac->unicast_filter_entries = 8;
   1099
   1100	/* Synopsys Id is not available */
   1101	priv->synopsys_id = 0;
   1102
   1103	return mac;
   1104}
   1105
   1106static struct regmap *sun8i_dwmac_get_syscon_from_dev(struct device_node *node)
   1107{
   1108	struct device_node *syscon_node;
   1109	struct platform_device *syscon_pdev;
   1110	struct regmap *regmap = NULL;
   1111
   1112	syscon_node = of_parse_phandle(node, "syscon", 0);
   1113	if (!syscon_node)
   1114		return ERR_PTR(-ENODEV);
   1115
   1116	syscon_pdev = of_find_device_by_node(syscon_node);
   1117	if (!syscon_pdev) {
   1118		/* platform device might not be probed yet */
   1119		regmap = ERR_PTR(-EPROBE_DEFER);
   1120		goto out_put_node;
   1121	}
   1122
   1123	/* If no regmap is found then the other device driver is at fault */
   1124	regmap = dev_get_regmap(&syscon_pdev->dev, NULL);
   1125	if (!regmap)
   1126		regmap = ERR_PTR(-EINVAL);
   1127
   1128	platform_device_put(syscon_pdev);
   1129out_put_node:
   1130	of_node_put(syscon_node);
   1131	return regmap;
   1132}
   1133
   1134static int sun8i_dwmac_probe(struct platform_device *pdev)
   1135{
   1136	struct plat_stmmacenet_data *plat_dat;
   1137	struct stmmac_resources stmmac_res;
   1138	struct sunxi_priv_data *gmac;
   1139	struct device *dev = &pdev->dev;
   1140	phy_interface_t interface;
   1141	int ret;
   1142	struct stmmac_priv *priv;
   1143	struct net_device *ndev;
   1144	struct regmap *regmap;
   1145
   1146	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
   1147	if (ret)
   1148		return ret;
   1149
   1150	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
   1151	if (!gmac)
   1152		return -ENOMEM;
   1153
   1154	gmac->variant = of_device_get_match_data(&pdev->dev);
   1155	if (!gmac->variant) {
   1156		dev_err(&pdev->dev, "Missing dwmac-sun8i variant\n");
   1157		return -EINVAL;
   1158	}
   1159
   1160	/* Optional regulator for PHY */
   1161	gmac->regulator = devm_regulator_get_optional(dev, "phy");
   1162	if (IS_ERR(gmac->regulator)) {
   1163		if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
   1164			return -EPROBE_DEFER;
   1165		dev_info(dev, "No regulator found\n");
   1166		gmac->regulator = NULL;
   1167	}
   1168
   1169	/* The "GMAC clock control" register might be located in the
   1170	 * CCU address range (on the R40), or the system control address
   1171	 * range (on most other sun8i and later SoCs).
   1172	 *
   1173	 * The former controls most if not all clocks in the SoC. The
   1174	 * latter has an SoC identification register, and on some SoCs,
   1175	 * controls to map device specific SRAM to either the intended
   1176	 * peripheral, or the CPU address space.
   1177	 *
   1178	 * In either case, there should be a coordinated and restricted
   1179	 * method of accessing the register needed here. This is done by
   1180	 * having the device export a custom regmap, instead of a generic
   1181	 * syscon, which grants all access to all registers.
   1182	 *
   1183	 * To support old device trees, we fall back to using the syscon
   1184	 * interface if possible.
   1185	 */
   1186	regmap = sun8i_dwmac_get_syscon_from_dev(pdev->dev.of_node);
   1187	if (IS_ERR(regmap))
   1188		regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
   1189							 "syscon");
   1190	if (IS_ERR(regmap)) {
   1191		ret = PTR_ERR(regmap);
   1192		dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret);
   1193		return ret;
   1194	}
   1195
   1196	gmac->regmap_field = devm_regmap_field_alloc(dev, regmap,
   1197						     *gmac->variant->syscon_field);
   1198	if (IS_ERR(gmac->regmap_field)) {
   1199		ret = PTR_ERR(gmac->regmap_field);
   1200		dev_err(dev, "Unable to map syscon register: %d\n", ret);
   1201		return ret;
   1202	}
   1203
   1204	ret = of_get_phy_mode(dev->of_node, &interface);
   1205	if (ret)
   1206		return -EINVAL;
   1207
   1208	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
   1209	if (IS_ERR(plat_dat))
   1210		return PTR_ERR(plat_dat);
   1211
   1212	/* platform data specifying hardware features and callbacks.
   1213	 * hardware features were copied from Allwinner drivers.
   1214	 */
   1215	plat_dat->interface = interface;
   1216	plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
   1217	plat_dat->tx_coe = 1;
   1218	plat_dat->has_sun8i = true;
   1219	plat_dat->bsp_priv = gmac;
   1220	plat_dat->init = sun8i_dwmac_init;
   1221	plat_dat->exit = sun8i_dwmac_exit;
   1222	plat_dat->setup = sun8i_dwmac_setup;
   1223	plat_dat->tx_fifo_size = 4096;
   1224	plat_dat->rx_fifo_size = 16384;
   1225
   1226	ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat);
   1227	if (ret)
   1228		goto dwmac_deconfig;
   1229
   1230	ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
   1231	if (ret)
   1232		goto dwmac_syscon;
   1233
   1234	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
   1235	if (ret)
   1236		goto dwmac_exit;
   1237
   1238	ndev = dev_get_drvdata(&pdev->dev);
   1239	priv = netdev_priv(ndev);
   1240
   1241	/* the MAC is runtime suspended after stmmac_dvr_probe(), so we
   1242	 * need to ensure the MAC resume back before other operations such
   1243	 * as reset.
   1244	 */
   1245	pm_runtime_get_sync(&pdev->dev);
   1246
   1247	/* The mux must be registered after parent MDIO
   1248	 * so after stmmac_dvr_probe()
   1249	 */
   1250	if (gmac->variant->soc_has_internal_phy) {
   1251		ret = get_ephy_nodes(priv);
   1252		if (ret)
   1253			goto dwmac_remove;
   1254		ret = sun8i_dwmac_register_mdio_mux(priv);
   1255		if (ret) {
   1256			dev_err(&pdev->dev, "Failed to register mux\n");
   1257			goto dwmac_mux;
   1258		}
   1259	} else {
   1260		ret = sun8i_dwmac_reset(priv);
   1261		if (ret)
   1262			goto dwmac_remove;
   1263	}
   1264
   1265	pm_runtime_put(&pdev->dev);
   1266
   1267	return 0;
   1268
   1269dwmac_mux:
   1270	reset_control_put(gmac->rst_ephy);
   1271	clk_put(gmac->ephy_clk);
   1272dwmac_remove:
   1273	pm_runtime_put_noidle(&pdev->dev);
   1274	stmmac_dvr_remove(&pdev->dev);
   1275dwmac_exit:
   1276	sun8i_dwmac_exit(pdev, gmac);
   1277dwmac_syscon:
   1278	sun8i_dwmac_unset_syscon(gmac);
   1279dwmac_deconfig:
   1280	stmmac_remove_config_dt(pdev, plat_dat);
   1281
   1282	return ret;
   1283}
   1284
   1285static int sun8i_dwmac_remove(struct platform_device *pdev)
   1286{
   1287	struct net_device *ndev = platform_get_drvdata(pdev);
   1288	struct stmmac_priv *priv = netdev_priv(ndev);
   1289	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
   1290
   1291	if (gmac->variant->soc_has_internal_phy) {
   1292		mdio_mux_uninit(gmac->mux_handle);
   1293		sun8i_dwmac_unpower_internal_phy(gmac);
   1294		reset_control_put(gmac->rst_ephy);
   1295		clk_put(gmac->ephy_clk);
   1296	}
   1297
   1298	stmmac_pltfr_remove(pdev);
   1299	sun8i_dwmac_unset_syscon(gmac);
   1300
   1301	return 0;
   1302}
   1303
   1304static void sun8i_dwmac_shutdown(struct platform_device *pdev)
   1305{
   1306	struct net_device *ndev = platform_get_drvdata(pdev);
   1307	struct stmmac_priv *priv = netdev_priv(ndev);
   1308	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
   1309
   1310	sun8i_dwmac_exit(pdev, gmac);
   1311}
   1312
   1313static const struct of_device_id sun8i_dwmac_match[] = {
   1314	{ .compatible = "allwinner,sun8i-h3-emac",
   1315		.data = &emac_variant_h3 },
   1316	{ .compatible = "allwinner,sun8i-v3s-emac",
   1317		.data = &emac_variant_v3s },
   1318	{ .compatible = "allwinner,sun8i-a83t-emac",
   1319		.data = &emac_variant_a83t },
   1320	{ .compatible = "allwinner,sun8i-r40-gmac",
   1321		.data = &emac_variant_r40 },
   1322	{ .compatible = "allwinner,sun50i-a64-emac",
   1323		.data = &emac_variant_a64 },
   1324	{ .compatible = "allwinner,sun50i-h6-emac",
   1325		.data = &emac_variant_h6 },
   1326	{ }
   1327};
   1328MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
   1329
   1330static struct platform_driver sun8i_dwmac_driver = {
   1331	.probe  = sun8i_dwmac_probe,
   1332	.remove = sun8i_dwmac_remove,
   1333	.shutdown = sun8i_dwmac_shutdown,
   1334	.driver = {
   1335		.name           = "dwmac-sun8i",
   1336		.pm		= &stmmac_pltfr_pm_ops,
   1337		.of_match_table = sun8i_dwmac_match,
   1338	},
   1339};
   1340module_platform_driver(sun8i_dwmac_driver);
   1341
   1342MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");
   1343MODULE_DESCRIPTION("Allwinner sun8i DWMAC specific glue layer");
   1344MODULE_LICENSE("GPL");