From 15ca0518c1b36b86c832de54417b9b61b5f6a4c9 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 26 Jan 2022 17:05:39 +0100 Subject: [PATCH 1/5] dt-bindings: net: xgmac_mdio: Remove unsupported "bus-frequency" This property has never been supported by the driver. The kernel has settled on "clock-frequency" as the standard name for this binding, so once that is supported we will document that instead. Fixes: 7f93c9d90f4d ("power/fsl: add MDIO dt binding for FMan") Signed-off-by: Tobias Waldekranz Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/fsl-fman.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt index 020337f3c05f..cd5288fb4318 100644 --- a/Documentation/devicetree/bindings/net/fsl-fman.txt +++ b/Documentation/devicetree/bindings/net/fsl-fman.txt @@ -388,15 +388,6 @@ PROPERTIES Value type: Definition: A standard property. -- bus-frequency - Usage: optional - Value type: - Definition: Specifies the external MDIO bus clock speed to - be used, if different from the standard 2.5 MHz. - This may be due to the standard speed being unsupported (e.g. - due to a hardware problem), or to advertise that all relevant - components in the system support a faster speed. - - interrupts Usage: required for external MDIO Value type: From 1d14eb15dc2c3961ffe88d20df17fb2e2eaf1504 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 26 Jan 2022 17:05:40 +0100 Subject: [PATCH 2/5] net/fsl: xgmac_mdio: Use managed device resources All of the resources used by this driver has managed interfaces, so use them. Heed the warning in the comment before platform_get_resource and use a bare devm_ioremap to allow for non-exclusive access to the IO memory. Signed-off-by: Tobias Waldekranz Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/xgmac_mdio.c | 35 ++++----------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c index 266e562bd67a..40442d64a247 100644 --- a/drivers/net/ethernet/freescale/xgmac_mdio.c +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c @@ -273,7 +273,7 @@ static int xgmac_mdio_probe(struct platform_device *pdev) return -EINVAL; } - bus = mdiobus_alloc_size(sizeof(struct mdio_fsl_priv)); + bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(struct mdio_fsl_priv)); if (!bus) return -ENOMEM; @@ -284,13 +284,11 @@ static int xgmac_mdio_probe(struct platform_device *pdev) bus->probe_capabilities = MDIOBUS_C22_C45; snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start); - /* Set the PHY base address */ priv = bus->priv; - priv->mdio_base = ioremap(res->start, resource_size(res)); - if (!priv->mdio_base) { - ret = -ENOMEM; - goto err_ioremap; - } + priv->mdio_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (IS_ERR(priv->mdio_base)) + return PTR_ERR(priv->mdio_base); /* For both ACPI and DT cases, endianness of MDIO controller * needs to be specified using "little-endian" property. @@ -312,31 +310,11 @@ static int xgmac_mdio_probe(struct platform_device *pdev) ret = -EINVAL; if (ret) { dev_err(&pdev->dev, "cannot register MDIO bus\n"); - goto err_registration; + return ret; } platform_set_drvdata(pdev, bus); - return 0; - -err_registration: - iounmap(priv->mdio_base); - -err_ioremap: - mdiobus_free(bus); - - return ret; -} - -static int xgmac_mdio_remove(struct platform_device *pdev) -{ - struct mii_bus *bus = platform_get_drvdata(pdev); - struct mdio_fsl_priv *priv = bus->priv; - - mdiobus_unregister(bus); - iounmap(priv->mdio_base); - mdiobus_free(bus); - return 0; } @@ -364,7 +342,6 @@ static struct platform_driver xgmac_mdio_driver = { .acpi_match_table = xgmac_acpi_match, }, .probe = xgmac_mdio_probe, - .remove = xgmac_mdio_remove, }; module_platform_driver(xgmac_mdio_driver); From 909bea73485fab5e99e222e727e82b259d667880 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 26 Jan 2022 17:05:41 +0100 Subject: [PATCH 3/5] net/fsl: xgmac_mdio: Support preamble suppression Support the standard "suppress-preamble" attribute to disable preamble generation. Signed-off-by: Tobias Waldekranz Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/xgmac_mdio.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c index 40442d64a247..18bf2370d45a 100644 --- a/drivers/net/ethernet/freescale/xgmac_mdio.c +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c @@ -39,6 +39,7 @@ struct tgec_mdio_controller { #define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) #define MDIO_STAT_BSY BIT(0) #define MDIO_STAT_RD_ER BIT(1) +#define MDIO_STAT_PRE_DIS BIT(5) #define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) #define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) #define MDIO_CTL_PRE_DIS BIT(10) @@ -254,6 +255,21 @@ irq_restore: return ret; } +static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus) +{ + struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; + struct tgec_mdio_controller __iomem *regs = priv->mdio_base; + struct device *dev = bus->parent; + u32 mdio_stat; + + if (!device_property_read_bool(dev, "suppress-preamble")) + return; + + mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian); + mdio_stat |= MDIO_STAT_PRE_DIS; + xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian); +} + static int xgmac_mdio_probe(struct platform_device *pdev) { struct fwnode_handle *fwnode; @@ -301,6 +317,8 @@ static int xgmac_mdio_probe(struct platform_device *pdev) priv->has_a011043 = device_property_read_bool(&pdev->dev, "fsl,erratum-a011043"); + xgmac_mdio_set_suppress_preamble(bus); + fwnode = pdev->dev.fwnode; if (is_of_node(fwnode)) ret = of_mdiobus_register(bus, to_of_node(fwnode)); From dd8f467eda72cdaff50e4636c382709124956da3 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 26 Jan 2022 17:05:42 +0100 Subject: [PATCH 4/5] net/fsl: xgmac_mdio: Support setting the MDC frequency Support the standard "clock-frequency" attribute to set the generated MDC frequency. If not specified, the driver will leave the divisor bits untouched. Signed-off-by: Tobias Waldekranz Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/xgmac_mdio.c | 38 ++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c index 18bf2370d45a..d38d0c372585 100644 --- a/drivers/net/ethernet/freescale/xgmac_mdio.c +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -36,7 +37,7 @@ struct tgec_mdio_controller { } __packed; #define MDIO_STAT_ENC BIT(6) -#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) +#define MDIO_STAT_CLKDIV(x) (((x) & 0x1ff) << 7) #define MDIO_STAT_BSY BIT(0) #define MDIO_STAT_RD_ER BIT(1) #define MDIO_STAT_PRE_DIS BIT(5) @@ -51,6 +52,8 @@ struct tgec_mdio_controller { struct mdio_fsl_priv { struct tgec_mdio_controller __iomem *mdio_base; + struct clk *enet_clk; + u32 mdc_freq; bool is_little_endian; bool has_a009885; bool has_a011043; @@ -255,6 +258,35 @@ irq_restore: return ret; } +static int xgmac_mdio_set_mdc_freq(struct mii_bus *bus) +{ + struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; + struct tgec_mdio_controller __iomem *regs = priv->mdio_base; + struct device *dev = bus->parent; + u32 mdio_stat, div; + + if (device_property_read_u32(dev, "clock-frequency", &priv->mdc_freq)) + return 0; + + priv->enet_clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->enet_clk)) { + dev_err(dev, "Input clock unknown, not changing MDC frequency"); + return PTR_ERR(priv->enet_clk); + } + + div = ((clk_get_rate(priv->enet_clk) / priv->mdc_freq) - 1) / 2; + if (div < 5 || div > 0x1ff) { + dev_err(dev, "Requested MDC frequecy is out of range, ignoring"); + return -EINVAL; + } + + mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian); + mdio_stat &= ~MDIO_STAT_CLKDIV(0x1ff); + mdio_stat |= MDIO_STAT_CLKDIV(div); + xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian); + return 0; +} + static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus) { struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; @@ -319,6 +351,10 @@ static int xgmac_mdio_probe(struct platform_device *pdev) xgmac_mdio_set_suppress_preamble(bus); + ret = xgmac_mdio_set_mdc_freq(bus); + if (ret) + return ret; + fwnode = pdev->dev.fwnode; if (is_of_node(fwnode)) ret = of_mdiobus_register(bus, to_of_node(fwnode)); From f7af8fe85aacfeff5f3f61fd98889119a110ef18 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 26 Jan 2022 17:05:43 +0100 Subject: [PATCH 5/5] dt-bindings: net: xgmac_mdio: Add "clock-frequency" and "suppress-preamble" The driver now supports the standard "clock-frequency" and "suppress-preamble" properties, do document them in the binding description. Signed-off-by: Tobias Waldekranz Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- .../devicetree/bindings/net/fsl-fman.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt index cd5288fb4318..801efc7d6818 100644 --- a/Documentation/devicetree/bindings/net/fsl-fman.txt +++ b/Documentation/devicetree/bindings/net/fsl-fman.txt @@ -388,6 +388,25 @@ PROPERTIES Value type: Definition: A standard property. +- clocks + Usage: optional + Value type: + Definition: A reference to the input clock of the controller + from which the MDC frequency is derived. + +- clock-frequency + Usage: optional + Value type: + Definition: Specifies the external MDC frequency, in Hertz, to + be used. Requires that the input clock is specified in the + "clocks" property. See also: mdio.yaml. + +- suppress-preamble + Usage: optional + Value type: + Definition: Disable generation of preamble bits. See also: + mdio.yaml. + - interrupts Usage: required for external MDIO Value type: