From a4a78a97ee4bccb865006015340905c90b38cd8f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:18 +0800 Subject: [PATCH 1/8] dt-bindings: net: dwmac-sun8i: Clean up clock delay chain descriptions The clock delay chains found in the glue layer for dwmac-sun8i are only used with RGMII PHYs. They are not intended for non-RGMII PHYs, such as MII external PHYs or the internal PHY. Also, a recent SoC has a smaller range of possible values for the delay chain. This patch reformats the delay chain section of the device tree binding to make it clear that the delay chains only apply to RGMII PHYs, and make it easier to add the R40-specific bits later. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dwmac-sun8i.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt index 3d6d5fa0c4d5..e04ce75e24a3 100644 --- a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt +++ b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt @@ -28,10 +28,13 @@ Required properties: - allwinner,sun8i-a83t-system-controller Optional properties: -- allwinner,tx-delay-ps: TX clock delay chain value in ps. Range value is 0-700. Default is 0) -- allwinner,rx-delay-ps: RX clock delay chain value in ps. Range value is 0-3100. Default is 0) -Both delay properties need to be a multiple of 100. They control the delay for -external PHY. +- allwinner,tx-delay-ps: TX clock delay chain value in ps. + Range is 0-700. Default is 0. +- allwinner,rx-delay-ps: RX clock delay chain value in ps. + Range is 0-3100. Default is 0. +Both delay properties need to be a multiple of 100. They control the +clock delay for external RGMII PHY. They do not apply to the internal +PHY or external non-RGMII PHYs. Optional properties for the following compatibles: - "allwinner,sun8i-h3-emac", From 9ed3fec3c336b71d532aaeda8d3239246aa43d61 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:19 +0800 Subject: [PATCH 2/8] dt-bindings: net: dwmac-sun8i: Sort syscon compatibles by alphabetical order The A83T syscon compatible was appended to the syscon compatibles list, instead of inserted in to preserve the ordering. Move it to the proper place to keep the list sorted. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dwmac-sun8i.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt index e04ce75e24a3..1b8e33e71651 100644 --- a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt +++ b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt @@ -22,10 +22,10 @@ Required properties: - #size-cells: shall be 0 - syscon: A phandle to the syscon of the SoC with one of the following compatible string: + - allwinner,sun8i-a83t-system-controller - allwinner,sun8i-h3-system-controller - allwinner,sun8i-v3s-system-controller - allwinner,sun50i-a64-system-controller - - allwinner,sun8i-a83t-system-controller Optional properties: - allwinner,tx-delay-ps: TX clock delay chain value in ps. From a6fe692e6eb554eb6f9e097142c7b7099edd203f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:20 +0800 Subject: [PATCH 3/8] dt-bindings: net: dwmac-sun8i: simplify description of syscon property The syscon property is used to point to the device that holds the glue layer control register known as the "EMAC (or GMAC) clock register". We do not need to explicitly list what compatible strings are needed, as this information is readily available in the user manuals. Also the "syscon" device type is more of an implementation detail. There are many ways to access a register not in a device's address range, the syscon interface being the most generic and unrestricted one. Simplify the description so that it says what it is supposed to describe. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dwmac-sun8i.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt index 1b8e33e71651..1c0906a5c02b 100644 --- a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt +++ b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt @@ -20,12 +20,7 @@ Required properties: - phy-handle: See ethernet.txt - #address-cells: shall be 1 - #size-cells: shall be 0 -- syscon: A phandle to the syscon of the SoC with one of the following - compatible string: - - allwinner,sun8i-a83t-system-controller - - allwinner,sun8i-h3-system-controller - - allwinner,sun8i-v3s-system-controller - - allwinner,sun50i-a64-system-controller +- syscon: A phandle to the device containing the EMAC or GMAC clock register Optional properties: - allwinner,tx-delay-ps: TX clock delay chain value in ps. From eef8811d9219d197d158cda9233ce2f78ea0a790 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:21 +0800 Subject: [PATCH 4/8] dt-bindings: net: dwmac-sun8i: Add binding for GMAC on Allwinner R40 SoC The Allwinner R40 SoC has the EMAC controller supported by dwmac-sun8i. It is named "GMAC", while EMAC refers to the 10/100 Mbps Ethernet controller supported by sun4i-emac. The controller is the same, but the R40 has the glue layer controls in the clock control unit (CCU), with a reduced RX delay chain, and no TX delay chain. This patch adds the R40 specific bits to the dwmac-sun8i binding. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dwmac-sun8i.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt index 1c0906a5c02b..cfe724398a12 100644 --- a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt +++ b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt @@ -7,6 +7,7 @@ Required properties: - compatible: must be one of the following string: "allwinner,sun8i-a83t-emac" "allwinner,sun8i-h3-emac" + "allwinner,sun8i-r40-gmac" "allwinner,sun8i-v3s-emac" "allwinner,sun50i-a64-emac" - reg: address and length of the register for the device. @@ -25,8 +26,10 @@ Required properties: Optional properties: - allwinner,tx-delay-ps: TX clock delay chain value in ps. Range is 0-700. Default is 0. + Unavailable for allwinner,sun8i-r40-gmac - allwinner,rx-delay-ps: RX clock delay chain value in ps. Range is 0-3100. Default is 0. + Range is 0-700 for allwinner,sun8i-r40-gmac Both delay properties need to be a multiple of 100. They control the clock delay for external RGMII PHY. They do not apply to the internal PHY or external non-RGMII PHYs. From 25ae15fb0ecda594306937ebf9ea65b7d0c4f592 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:22 +0800 Subject: [PATCH 5/8] net: stmmac: dwmac-sun8i: Use regmap_field for syscon register access On the Allwinner R40, the "GMAC clock" register is located in the CCU block, at a different register address than the other SoCs that have it in the "system control" block. This patch converts the use of regmap to regmap_field for mapping and accessing the syscon register, so we can have the register address in the variants data, and not in the actual register manipulation code. This patch only converts regmap_read() and regmap_write() calls to regmap_field_read() and regmap_field_write() calls. There are some places where it might make sense to switch to regmap_field_update_bits(), but this is not done here to keep the patch simple. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index a3fa65b1ca8e..bbc051474806 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -42,6 +42,7 @@ * This value is used for disabling properly EMAC * and used as a good starting value in case of the * boot process(uboot) leave some stuff. + * @syscon_field reg_field for the syscon's gmac register * @soc_has_internal_phy: Does the MAC embed an internal PHY * @support_mii: Does the MAC handle MII * @support_rmii: Does the MAC handle RMII @@ -49,6 +50,7 @@ */ struct emac_variant { u32 default_syscon_value; + const struct reg_field *syscon_field; bool soc_has_internal_phy; bool support_mii; bool support_rmii; @@ -71,13 +73,21 @@ struct sunxi_priv_data { struct regulator *regulator; struct reset_control *rst_ephy; const struct emac_variant *variant; - struct regmap *regmap; + struct regmap_field *regmap_field; bool internal_phy_powered; void *mux_handle; }; +/* EMAC clock register @ 0x30 in the "system control" address range */ +static const struct reg_field sun8i_syscon_reg_field = { + .reg = 0x30, + .lsb = 0, + .msb = 31, +}; + static const struct emac_variant emac_variant_h3 = { .default_syscon_value = 0x58000, + .syscon_field = &sun8i_syscon_reg_field, .soc_has_internal_phy = true, .support_mii = true, .support_rmii = true, @@ -86,12 +96,14 @@ static const struct emac_variant emac_variant_h3 = { static const struct emac_variant emac_variant_v3s = { .default_syscon_value = 0x38000, + .syscon_field = &sun8i_syscon_reg_field, .soc_has_internal_phy = true, .support_mii = true }; static const struct emac_variant emac_variant_a83t = { .default_syscon_value = 0, + .syscon_field = &sun8i_syscon_reg_field, .soc_has_internal_phy = false, .support_mii = true, .support_rgmii = true @@ -99,6 +111,7 @@ static const struct emac_variant emac_variant_a83t = { static const struct emac_variant emac_variant_a64 = { .default_syscon_value = 0, + .syscon_field = &sun8i_syscon_reg_field, .soc_has_internal_phy = false, .support_mii = true, .support_rmii = true, @@ -216,7 +229,6 @@ static const struct emac_variant emac_variant_a64 = { #define SYSCON_ETCS_MII 0x0 #define SYSCON_ETCS_EXT_GMII 0x1 #define SYSCON_ETCS_INT_GMII 0x2 -#define SYSCON_EMAC_REG 0x30 /* sun8i_dwmac_dma_reset() - reset the EMAC * Called from stmmac via stmmac_dma_ops->reset @@ -745,7 +757,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, bool need_power_ephy = false; if (current_child ^ desired_child) { - regmap_read(gmac->regmap, SYSCON_EMAC_REG, ®); + regmap_field_read(gmac->regmap_field, ®); switch (desired_child) { case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: dev_info(priv->device, "Switch mux to internal PHY"); @@ -763,7 +775,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, desired_child); return -EINVAL; } - regmap_write(gmac->regmap, SYSCON_EMAC_REG, val); + regmap_field_write(gmac->regmap_field, val); if (need_power_ephy) { ret = sun8i_dwmac_power_internal_phy(priv); if (ret) @@ -801,7 +813,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) int ret; u32 reg, val; - regmap_read(gmac->regmap, SYSCON_EMAC_REG, &val); + regmap_field_read(gmac->regmap_field, &val); reg = gmac->variant->default_syscon_value; if (reg != val) dev_warn(priv->device, @@ -883,7 +895,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) return -EINVAL; } - regmap_write(gmac->regmap, SYSCON_EMAC_REG, reg); + regmap_field_write(gmac->regmap_field, reg); return 0; } @@ -892,7 +904,7 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac) { u32 reg = gmac->variant->default_syscon_value; - regmap_write(gmac->regmap, SYSCON_EMAC_REG, reg); + regmap_field_write(gmac->regmap_field, reg); } static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) @@ -980,6 +992,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) int ret; struct stmmac_priv *priv; struct net_device *ndev; + struct regmap *regmap; ret = stmmac_get_platform_resources(pdev, &stmmac_res); if (ret) @@ -1014,14 +1027,21 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) gmac->regulator = NULL; } - gmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "syscon"); - if (IS_ERR(gmac->regmap)) { - ret = PTR_ERR(gmac->regmap); + regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "syscon"); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret); return ret; } + gmac->regmap_field = devm_regmap_field_alloc(dev, regmap, + *gmac->variant->syscon_field); + if (IS_ERR(gmac->regmap_field)) { + ret = PTR_ERR(gmac->regmap_field); + dev_err(dev, "Unable to map syscon register: %d\n", ret); + return ret; + } + plat_dat->interface = of_get_phy_mode(dev->of_node); /* platform data specifying hardware features and callbacks. From 49a06cae6e7ceb77f17914c4617309e038c24c4d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:23 +0800 Subject: [PATCH 6/8] net: stmmac: dwmac-sun8i: Allow getting syscon regmap from external device On the Allwinner R40 SoC, the "GMAC clock" register is in the CCU address space. Using a standard syscon to access it provides no coordination with the CCU driver for register access. Neither does it prevent this and other drivers from accessing other, maybe critical, clock control registers. On other SoCs, the register is in the "system control" address space, which might also contain controls for mapping SRAM to devices or the CPU. This hardware has the same issues. Instead, for these types of setups, we let the device containing the control register create a regmap tied to it. We can then get the device from the existing syscon phandle, and retrieve the regmap with dev_get_regmap(). Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index bbc051474806..79e104a20e20 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -983,6 +983,34 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) return mac; } +static struct regmap *sun8i_dwmac_get_syscon_from_dev(struct device_node *node) +{ + struct device_node *syscon_node; + struct platform_device *syscon_pdev; + struct regmap *regmap = NULL; + + syscon_node = of_parse_phandle(node, "syscon", 0); + if (!syscon_node) + return ERR_PTR(-ENODEV); + + syscon_pdev = of_find_device_by_node(syscon_node); + if (!syscon_pdev) { + /* platform device might not be probed yet */ + regmap = ERR_PTR(-EPROBE_DEFER); + goto out_put_node; + } + + /* If no regmap is found then the other device driver is at fault */ + regmap = dev_get_regmap(&syscon_pdev->dev, NULL); + if (!regmap) + regmap = ERR_PTR(-EINVAL); + + platform_device_put(syscon_pdev); +out_put_node: + of_node_put(syscon_node); + return regmap; +} + static int sun8i_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; @@ -1027,7 +1055,27 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) gmac->regulator = NULL; } - regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "syscon"); + /* The "GMAC clock control" register might be located in the + * CCU address range (on the R40), or the system control address + * range (on most other sun8i and later SoCs). + * + * The former controls most if not all clocks in the SoC. The + * latter has an SoC identification register, and on some SoCs, + * controls to map device specific SRAM to either the intended + * peripheral, or the CPU address space. + * + * In either case, there should be a coordinated and restricted + * method of accessing the register needed here. This is done by + * having the device export a custom regmap, instead of a generic + * syscon, which grants all access to all registers. + * + * To support old device trees, we fall back to using the syscon + * interface if possible. + */ + regmap = sun8i_dwmac_get_syscon_from_dev(pdev->dev.of_node); + if (IS_ERR(regmap)) + regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "syscon"); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret); From 7b270b725a867587957676a8dae862caad558011 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:24 +0800 Subject: [PATCH 7/8] net: stmmac: dwmac-sun8i: Support different ranges for TX/RX delay chains On the R40 SoC, the RX delay chain only has a range of 0~7 (hundred picoseconds), instead of 0~31. Also the TX delay chain is completely absent. This patch adds support for different ranges by adding per-compatible maximum values in the variant data. A maximum of 0 indicates that the delay chain is not supported or absent. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index 79e104a20e20..4f5612a3c855 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -47,6 +47,12 @@ * @support_mii: Does the MAC handle MII * @support_rmii: Does the MAC handle RMII * @support_rgmii: Does the MAC handle RGMII + * + * @rx_delay_max: Maximum raw value for RX delay chain + * @tx_delay_max: Maximum raw value for TX delay chain + * These two also indicate the bitmask for + * the RX and TX delay chain registers. A + * value of zero indicates this is not supported. */ struct emac_variant { u32 default_syscon_value; @@ -55,6 +61,8 @@ struct emac_variant { bool support_mii; bool support_rmii; bool support_rgmii; + u8 rx_delay_max; + u8 tx_delay_max; }; /* struct sunxi_priv_data - hold all sunxi private data @@ -91,7 +99,9 @@ static const struct emac_variant emac_variant_h3 = { .soc_has_internal_phy = true, .support_mii = true, .support_rmii = true, - .support_rgmii = true + .support_rgmii = true, + .rx_delay_max = 31, + .tx_delay_max = 7, }; static const struct emac_variant emac_variant_v3s = { @@ -106,7 +116,9 @@ static const struct emac_variant emac_variant_a83t = { .syscon_field = &sun8i_syscon_reg_field, .soc_has_internal_phy = false, .support_mii = true, - .support_rgmii = true + .support_rgmii = true, + .rx_delay_max = 31, + .tx_delay_max = 7, }; static const struct emac_variant emac_variant_a64 = { @@ -115,7 +127,9 @@ static const struct emac_variant emac_variant_a64 = { .soc_has_internal_phy = false, .support_mii = true, .support_rmii = true, - .support_rgmii = true + .support_rgmii = true, + .rx_delay_max = 31, + .tx_delay_max = 7, }; #define EMAC_BASIC_CTL0 0x00 @@ -219,9 +233,7 @@ static const struct emac_variant emac_variant_a64 = { #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */ /* Generic system control EMAC_CLK bits */ -#define SYSCON_ETXDC_MASK GENMASK(2, 0) #define SYSCON_ETXDC_SHIFT 10 -#define SYSCON_ERXDC_MASK GENMASK(4, 0) #define SYSCON_ERXDC_SHIFT 5 /* EMAC PHY Interface Type */ #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */ @@ -847,8 +859,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) } val /= 100; dev_dbg(priv->device, "set tx-delay to %x\n", val); - if (val <= SYSCON_ETXDC_MASK) { - reg &= ~(SYSCON_ETXDC_MASK << SYSCON_ETXDC_SHIFT); + if (val <= gmac->variant->tx_delay_max) { + reg &= ~(gmac->variant->tx_delay_max << + SYSCON_ETXDC_SHIFT); reg |= (val << SYSCON_ETXDC_SHIFT); } else { dev_err(priv->device, "Invalid TX clock delay: %d\n", @@ -864,8 +877,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) } val /= 100; dev_dbg(priv->device, "set rx-delay to %x\n", val); - if (val <= SYSCON_ERXDC_MASK) { - reg &= ~(SYSCON_ERXDC_MASK << SYSCON_ERXDC_SHIFT); + if (val <= gmac->variant->rx_delay_max) { + reg &= ~(gmac->variant->rx_delay_max << + SYSCON_ERXDC_SHIFT); reg |= (val << SYSCON_ERXDC_SHIFT); } else { dev_err(priv->device, "Invalid RX clock delay: %d\n", From 9bf5085aaaadd6488a0ea6121e0cb7dadaf0652a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 14 May 2018 03:14:25 +0800 Subject: [PATCH 8/8] net: stmmac: dwmac-sun8i: Add support for GMAC on Allwinner R40 SoC The Allwinner R40 SoC has the EMAC controller supported by dwmac-sun8i. It is named "GMAC", while EMAC refers to the 10/100 Mbps Ethernet controller supported by sun4i-emac. The controller is the same, but the R40 has the glue layer controls in the clock control unit (CCU), with a reduced RX delay chain, and no TX delay chain. This patch adds support for it using the framework laid out by previous patches to map the differences. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index 4f5612a3c855..2f7f0915f071 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -93,6 +93,13 @@ static const struct reg_field sun8i_syscon_reg_field = { .msb = 31, }; +/* EMAC clock register @ 0x164 in the CCU address range */ +static const struct reg_field sun8i_ccu_reg_field = { + .reg = 0x164, + .lsb = 0, + .msb = 31, +}; + static const struct emac_variant emac_variant_h3 = { .default_syscon_value = 0x58000, .syscon_field = &sun8i_syscon_reg_field, @@ -121,6 +128,14 @@ static const struct emac_variant emac_variant_a83t = { .tx_delay_max = 7, }; +static const struct emac_variant emac_variant_r40 = { + .default_syscon_value = 0, + .syscon_field = &sun8i_ccu_reg_field, + .support_mii = true, + .support_rgmii = true, + .rx_delay_max = 7, +}; + static const struct emac_variant emac_variant_a64 = { .default_syscon_value = 0, .syscon_field = &sun8i_syscon_reg_field, @@ -1160,6 +1175,8 @@ static const struct of_device_id sun8i_dwmac_match[] = { .data = &emac_variant_v3s }, { .compatible = "allwinner,sun8i-a83t-emac", .data = &emac_variant_a83t }, + { .compatible = "allwinner,sun8i-r40-gmac", + .data = &emac_variant_r40 }, { .compatible = "allwinner,sun50i-a64-emac", .data = &emac_variant_a64 }, { }