generic: 6.1: replace ipq40xx MDIO patch with upstream version
authorChristian Marangi <ansuelsmth@gmail.com>
Sat, 3 Feb 2024 20:26:32 +0000 (21:26 +0100)
committerChristian Marangi <ansuelsmth@gmail.com>
Sat, 3 Feb 2024 20:29:25 +0000 (21:29 +0100)
Replace ipq40xx MDIO patch with upstream version now that the driver
part got merged upstream.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch [new file with mode: 0644]
target/linux/generic/pending-6.1/713-01-dt-bindings-net-ipq4019-mdio-document-now-supported-.patch [deleted file]
target/linux/generic/pending-6.1/713-02-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch [deleted file]

diff --git a/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch b/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch
new file mode 100644 (file)
index 0000000..e6a240d
--- /dev/null
@@ -0,0 +1,205 @@
+From bdce82e960d1205d118662f575cec39379984e34 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 31 Jan 2024 03:26:04 +0100
+Subject: [PATCH] net: mdio: ipq4019: add support for clock-frequency property
+
+The IPQ4019 MDIO internally divide the clock feed by AHB based on the
+MDIO_MODE reg. On reset or power up, the default value for the
+divider is 0xff that reflect the divider set to /256.
+
+This makes the MDC run at a very low rate, that is, considering AHB is
+always fixed to 100Mhz, a value of 390KHz.
+
+This hasn't have been a problem as MDIO wasn't used for time sensitive
+operation, it is now that on IPQ807x is usually mounted with PHY that
+requires MDIO to load their firmware (example Aquantia PHY).
+
+To handle this problem and permit to set the correct designed MDC
+frequency for the SoC add support for the standard "clock-frequency"
+property for the MDIO node.
+
+The divider supports value from /1 to /256 and the common value are to
+set it to /16 to reflect 6.25Mhz or to /8 on newer platform to reflect
+12.5Mhz.
+
+To scan if the requested rate is supported by the divider, loop with
+each supported divider and stop when the requested rate match the final
+rate with the current divider. An error is returned if the rate doesn't
+match any value.
+
+On MDIO reset, the divider is restored to the requested value to prevent
+any kind of downclocking caused by the divider reverting to a default
+value.
+
+To follow 802.3 spec of 2.5MHz of default value, if divider is set at
+/256 and "clock-frequency" is not set in DT, assume nobody set the
+divider and try to find the closest MDC rate to 2.5MHz. (in the case of
+AHB set to 100MHz, it's 1.5625MHz)
+
+While at is also document other bits of the MDIO_MODE reg to have a
+clear idea of what is actually applied there.
+
+Documentation of some BITs is skipped as they are marked as reserved and
+their usage is not clear (RES 11:9 GENPHY 16:13 RES1 19:17)
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/mdio/mdio-ipq4019.c | 109 ++++++++++++++++++++++++++++++--
+ 1 file changed, 103 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/mdio/mdio-ipq4019.c
++++ b/drivers/net/mdio/mdio-ipq4019.c
+@@ -14,6 +14,20 @@
+ #include <linux/clk.h>
+ #define MDIO_MODE_REG                         0x40
++#define   MDIO_MODE_MDC_MODE                  BIT(12)
++/* 0 = Clause 22, 1 = Clause 45 */
++#define   MDIO_MODE_C45                               BIT(8)
++#define   MDIO_MODE_DIV_MASK                  GENMASK(7, 0)
++#define     MDIO_MODE_DIV(x)                  FIELD_PREP(MDIO_MODE_DIV_MASK, (x) - 1)
++#define     MDIO_MODE_DIV_1                   0x0
++#define     MDIO_MODE_DIV_2                   0x1
++#define     MDIO_MODE_DIV_4                   0x3
++#define     MDIO_MODE_DIV_8                   0x7
++#define     MDIO_MODE_DIV_16                  0xf
++#define     MDIO_MODE_DIV_32                  0x1f
++#define     MDIO_MODE_DIV_64                  0x3f
++#define     MDIO_MODE_DIV_128                 0x7f
++#define     MDIO_MODE_DIV_256                 0xff
+ #define MDIO_ADDR_REG                         0x44
+ #define MDIO_DATA_WRITE_REG                   0x48
+ #define MDIO_DATA_READ_REG                    0x4c
+@@ -26,9 +40,6 @@
+ #define MDIO_CMD_ACCESS_CODE_C45_WRITE        1
+ #define MDIO_CMD_ACCESS_CODE_C45_READ 2
+-/* 0 = Clause 22, 1 = Clause 45 */
+-#define MDIO_MODE_C45                         BIT(8)
+-
+ #define IPQ4019_MDIO_TIMEOUT  10000
+ #define IPQ4019_MDIO_SLEEP            10
+@@ -41,6 +52,7 @@ struct ipq4019_mdio_data {
+       void __iomem    *membase;
+       void __iomem *eth_ldo_rdy;
+       struct clk *mdio_clk;
++      unsigned int mdc_rate;
+ };
+ static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
+@@ -179,6 +191,38 @@ static int ipq4019_mdio_write(struct mii
+       return 0;
+ }
++static int ipq4019_mdio_set_div(struct ipq4019_mdio_data *priv)
++{
++      unsigned long ahb_rate;
++      int div;
++      u32 val;
++
++      /* If we don't have a clock for AHB use the fixed value */
++      ahb_rate = IPQ_MDIO_CLK_RATE;
++      if (priv->mdio_clk)
++              ahb_rate = clk_get_rate(priv->mdio_clk);
++
++      /* MDC rate is ahb_rate/(MDIO_MODE_DIV + 1)
++       * While supported, internal documentation doesn't
++       * assure correct functionality of the MDIO bus
++       * with divider of 1, 2 or 4.
++       */
++      for (div = 8; div <= 256; div *= 2) {
++              /* The requested rate is supported by the div */
++              if (priv->mdc_rate == DIV_ROUND_UP(ahb_rate, div)) {
++                      val = readl(priv->membase + MDIO_MODE_REG);
++                      val &= ~MDIO_MODE_DIV_MASK;
++                      val |= MDIO_MODE_DIV(div);
++                      writel(val, priv->membase + MDIO_MODE_REG);
++
++                      return 0;
++              }
++      }
++
++      /* The requested rate is not supported */
++      return -EINVAL;
++}
++
+ static int ipq_mdio_reset(struct mii_bus *bus)
+ {
+       struct ipq4019_mdio_data *priv = bus->priv;
+@@ -201,10 +245,58 @@ static int ipq_mdio_reset(struct mii_bus
+               return ret;
+       ret = clk_prepare_enable(priv->mdio_clk);
+-      if (ret == 0)
+-              mdelay(10);
++      if (ret)
++              return ret;
++
++      mdelay(10);
+-      return ret;
++      /* Restore MDC rate */
++      return ipq4019_mdio_set_div(priv);
++}
++
++static void ipq4019_mdio_select_mdc_rate(struct platform_device *pdev,
++                                       struct ipq4019_mdio_data *priv)
++{
++      unsigned long ahb_rate;
++      int div;
++      u32 val;
++
++      /* MDC rate defined in DT, we don't have to decide a default value */
++      if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
++                                &priv->mdc_rate))
++              return;
++
++      /* If we don't have a clock for AHB use the fixed value */
++      ahb_rate = IPQ_MDIO_CLK_RATE;
++      if (priv->mdio_clk)
++              ahb_rate = clk_get_rate(priv->mdio_clk);
++
++      /* Check what is the current div set */
++      val = readl(priv->membase + MDIO_MODE_REG);
++      div = FIELD_GET(MDIO_MODE_DIV_MASK, val);
++
++      /* div is not set to the default value of /256
++       * Probably someone changed that (bootloader, other drivers)
++       * Keep this and don't overwrite it.
++       */
++      if (div != MDIO_MODE_DIV_256) {
++              priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div + 1);
++              return;
++      }
++
++      /* If div is /256 assume nobody have set this value and
++       * try to find one MDC rate that is close the 802.3 spec of
++       * 2.5MHz
++       */
++      for (div = 256; div >= 8; div /= 2) {
++              /* Stop as soon as we found a divider that
++               * reached the closest value to 2.5MHz
++               */
++              if (DIV_ROUND_UP(ahb_rate, div) > 2500000)
++                      break;
++
++              priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div);
++      }
+ }
+ static int ipq4019_mdio_probe(struct platform_device *pdev)
+@@ -228,6 +320,11 @@ static int ipq4019_mdio_probe(struct pla
+       if (IS_ERR(priv->mdio_clk))
+               return PTR_ERR(priv->mdio_clk);
++      ipq4019_mdio_select_mdc_rate(pdev, priv);
++      ret = ipq4019_mdio_set_div(priv);
++      if (ret)
++              return ret;
++
+       /* The platform resource is provided on the chipset IPQ5018 */
+       /* This resource is optional */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
diff --git a/target/linux/generic/pending-6.1/713-01-dt-bindings-net-ipq4019-mdio-document-now-supported-.patch b/target/linux/generic/pending-6.1/713-01-dt-bindings-net-ipq4019-mdio-document-now-supported-.patch
deleted file mode 100644 (file)
index 35258d8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 85e2038891989e41bc62f6a4625fd5865da8a1a2 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 24 Jan 2024 19:17:02 +0100
-Subject: [PATCH 1/3] dt-bindings: net: ipq4019-mdio: document now supported
- clock-frequency
-
-Document support for clock-frequency and add details on why this
-property is needed and what values are supported.
-
-From internal documentation, while other values are supported, the
-correct function of the MDIO bus is not assured hence add only the
-suggested supported values to the property enum.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- .../bindings/net/qcom,ipq4019-mdio.yaml           | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/qcom,ipq4019-mdio.yaml
-+++ b/Documentation/devicetree/bindings/net/qcom,ipq4019-mdio.yaml
-@@ -38,6 +38,21 @@ properties:
-       MDIO clock source frequency fixed to 100MHZ, this clock should be specified
-       by the platform IPQ807x, IPQ60xx and IPQ50xx.
-+  clock-frequency:
-+    description:
-+      The MDIO bus clock that must be output by the MDIO bus hardware, if
-+      absent, the default hardware values are used.
-+
-+      MDC rate is feed by an external clock (fixed 100MHz) and is divider
-+      internally. The default divider is /256 resulting in the default rate
-+      applied of 390KHz.
-+
-+      To follow 802.3 standard that instruct up to 2.5MHz by default, if
-+      this property is not declared and the divider is set to /256, by
-+      default 1.5625Mhz is select.
-+    enum: [ 390625, 781250, 1562500, 3125000, 6250000, 12500000 ]
-+    default: 1562500
-+
- required:
-   - compatible
-   - reg
diff --git a/target/linux/generic/pending-6.1/713-02-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch b/target/linux/generic/pending-6.1/713-02-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch
deleted file mode 100644 (file)
index 809d7a0..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-From eacf1d2505dfecd3599d558cdade1a2da47fe06d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 24 Jan 2024 18:52:33 +0100
-Subject: [PATCH 2/3] net: mdio: ipq4019: add support for clock-frequency
- property
-
-The IPQ4019 MDIO internally divide the clock feed by AHB based on the
-MDIO_MODE reg. On reset or power up, the default value for the
-divider is 0xff that reflect the divider set to /256.
-
-This makes the MDC run at a very low rate, that is, considering AHB is
-always fixed to 100Mhz, a value of 390KHz.
-
-This hasn't have been a problem as MDIO wasn't used for time sensitive
-operation, it is now that on IPQ807x is usually mounted with PHY that
-requires MDIO to load their firmware (example Aquantia PHY).
-
-To handle this problem and permit to set the correct designed MDC
-frequency for the SoC add support for the standard "clock-frequency"
-property for the MDIO node.
-
-The divider supports value from /1 to /256 and the common value are to
-set it to /16 to reflect 6.25Mhz or to /8 on newer platform to reflect
-12.5Mhz.
-
-To scan if the requested rate is supported by the divider, loop with
-each supported divider and stop when the requested rate match the final
-rate with the current divider. An error is returned if the rate doesn't
-match any value.
-
-On MDIO reset, the divider is restored to the requested value to prevent
-any kind of downclocking caused by the divider reverting to a default
-value.
-
-To follow 802.3 spec of 2.5MHz of default value, if divider is set at
-/256 and "clock-frequency" is not set in DT, assume nobody set the
-divider and try to find the closest MDC rate to 2.5MHz. (in the case of
-AHB set to 100MHz, it's 1.5625MHz)
-
-While at is also document other bits of the MDIO_MODE reg to have a
-clear idea of what is actually applied there.
-
-Documentation of some BITs is skipped as they are marked as reserved and
-their usage is not clear (RES 11:9 GENPHY 16:13 RES1 19:17)
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/mdio/mdio-ipq4019.c | 109 ++++++++++++++++++++++++++++++--
- 1 file changed, 103 insertions(+), 6 deletions(-)
-
---- a/drivers/net/mdio/mdio-ipq4019.c
-+++ b/drivers/net/mdio/mdio-ipq4019.c
-@@ -14,6 +14,20 @@
- #include <linux/clk.h>
- #define MDIO_MODE_REG                         0x40
-+#define   MDIO_MODE_MDC_MODE                  BIT(12)
-+/* 0 = Clause 22, 1 = Clause 45 */
-+#define   MDIO_MODE_C45                               BIT(8)
-+#define   MDIO_MODE_DIV_MASK                  GENMASK(7, 0)
-+#define     MDIO_MODE_DIV(x)                  FIELD_PREP(MDIO_MODE_DIV_MASK, (x) - 1)
-+#define     MDIO_MODE_DIV_1                   0x0
-+#define     MDIO_MODE_DIV_2                   0x1
-+#define     MDIO_MODE_DIV_4                   0x3
-+#define     MDIO_MODE_DIV_8                   0x7
-+#define     MDIO_MODE_DIV_16                  0xf
-+#define     MDIO_MODE_DIV_32                  0x1f
-+#define     MDIO_MODE_DIV_64                  0x3f
-+#define     MDIO_MODE_DIV_128                 0x7f
-+#define     MDIO_MODE_DIV_256                 0xff
- #define MDIO_ADDR_REG                         0x44
- #define MDIO_DATA_WRITE_REG                   0x48
- #define MDIO_DATA_READ_REG                    0x4c
-@@ -26,9 +40,6 @@
- #define MDIO_CMD_ACCESS_CODE_C45_WRITE        1
- #define MDIO_CMD_ACCESS_CODE_C45_READ 2
--/* 0 = Clause 22, 1 = Clause 45 */
--#define MDIO_MODE_C45                         BIT(8)
--
- #define IPQ4019_MDIO_TIMEOUT  10000
- #define IPQ4019_MDIO_SLEEP            10
-@@ -41,6 +52,7 @@ struct ipq4019_mdio_data {
-       void __iomem    *membase;
-       void __iomem *eth_ldo_rdy;
-       struct clk *mdio_clk;
-+      unsigned int mdc_rate;
- };
- static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
-@@ -179,6 +191,38 @@ static int ipq4019_mdio_write(struct mii
-       return 0;
- }
-+static int ipq4019_mdio_set_div(struct ipq4019_mdio_data *priv)
-+{
-+      unsigned long ahb_rate;
-+      int div;
-+      u32 val;
-+
-+      /* If we don't have a clock for AHB use the fixed value */
-+      ahb_rate = IPQ_MDIO_CLK_RATE;
-+      if (priv->mdio_clk)
-+              ahb_rate = clk_get_rate(priv->mdio_clk);
-+
-+      /* MDC rate is ahb_rate/(MDIO_MODE_DIV + 1)
-+       * While supported, internal documentation doesn't
-+       * assure correct functionality of the MDIO bus
-+       * with divider of 1, 2 or 4.
-+       */
-+      for (div = 8; div <= 256; div *= 2) {
-+              /* The requested rate is supported by the div */
-+              if (priv->mdc_rate == DIV_ROUND_UP(ahb_rate, div)) {
-+                      val = readl(priv->membase + MDIO_MODE_REG);
-+                      val &= ~MDIO_MODE_DIV_MASK;
-+                      val |= MDIO_MODE_DIV(div);
-+                      writel(val, priv->membase + MDIO_MODE_REG);
-+
-+                      return 0;
-+              }
-+      }
-+
-+      /* The requested rate is not supported */
-+      return -EINVAL;
-+}
-+
- static int ipq_mdio_reset(struct mii_bus *bus)
- {
-       struct ipq4019_mdio_data *priv = bus->priv;
-@@ -201,10 +245,58 @@ static int ipq_mdio_reset(struct mii_bus
-               return ret;
-       ret = clk_prepare_enable(priv->mdio_clk);
--      if (ret == 0)
--              mdelay(10);
-+      if (ret)
-+              return ret;
-+
-+      mdelay(10);
--      return ret;
-+      /* Restore MDC rate */
-+      return ipq4019_mdio_set_div(priv);
-+}
-+
-+static void ipq4019_mdio_select_mdc_rate(struct platform_device *pdev,
-+                                       struct ipq4019_mdio_data *priv)
-+{
-+      unsigned long ahb_rate;
-+      int div;
-+      u32 val;
-+
-+      /* MDC rate defined in DT, we don't have to decide a default value */
-+      if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
-+                                &priv->mdc_rate))
-+              return;
-+
-+      /* If we don't have a clock for AHB use the fixed value */
-+      ahb_rate = IPQ_MDIO_CLK_RATE;
-+      if (priv->mdio_clk)
-+              ahb_rate = clk_get_rate(priv->mdio_clk);
-+
-+      /* Check what is the current div set */
-+      val = readl(priv->membase + MDIO_MODE_REG);
-+      div = FIELD_GET(MDIO_MODE_DIV_MASK, val);
-+
-+      /* div is not set to the default value of /256
-+       * Probably someone changed that (bootloader, other drivers)
-+       * Keep this and doesn't overwrite it.
-+       */
-+      if (div != MDIO_MODE_DIV_256) {
-+              priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div + 1);
-+              return;
-+      }
-+
-+      /* If div is /256 assume nobody have set this value and
-+       * try to find one MDC rate that is close the 802.3 spec of
-+       * 2.5MHz
-+       */
-+      for (div = 256; div >= 8; div /= 2) {
-+              /* Stop as soon as we found a divider that
-+               * reached the closest value to 2.5MHz
-+               */
-+              if (DIV_ROUND_UP(ahb_rate, div) > 2500000)
-+                      break;
-+
-+              priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div);
-+      }
- }
- static int ipq4019_mdio_probe(struct platform_device *pdev)
-@@ -228,6 +320,11 @@ static int ipq4019_mdio_probe(struct pla
-       if (IS_ERR(priv->mdio_clk))
-               return PTR_ERR(priv->mdio_clk);
-+      ipq4019_mdio_select_mdc_rate(pdev, priv);
-+      ret = ipq4019_mdio_set_div(priv);
-+      if (ret)
-+              return ret;
-+
-       /* The platform resource is provided on the chipset IPQ5018 */
-       /* This resource is optional */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);