kernel: 5.10: backport qca8k feature additions
authorMatthew Hagan <mnhagan88@gmail.com>
Thu, 9 Sep 2021 19:40:21 +0000 (19:40 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 24 Oct 2021 14:56:17 +0000 (16:56 +0200)
Backport Ansuel Smith's various qca8k feature additions:
- mac-power-sel support
- SGMII PLL explicit enable
- tx/rx clock phase to falling edge
- power-on-sel and LED open drain mode
- cpu port 6
- qca8328 support
- sgmii internal delay
- move port config to dedicated struct
- convert to yaml schema

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
16 files changed:
target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch [new file with mode: 0644]

diff --git a/target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch b/target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch
new file mode 100644 (file)
index 0000000..c8d424d
--- /dev/null
@@ -0,0 +1,80 @@
+From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:06 +0200
+Subject: dsa: qca8k: add mac_power_sel support
+
+Add missing mac power sel support needed for ipq8064/5 SoC that require
+1.8v for the internal regulator port instead of the default 1.5v.
+If other device needs this, consider adding a dedicated binding to
+support this.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  5 +++++
+ 2 files changed, 36 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_
+ }
+ static int
++qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
++{
++      u32 mask = 0;
++      int ret = 0;
++
++      /* SoC specific settings for ipq8064.
++       * If more device require this consider adding
++       * a dedicated binding.
++       */
++      if (of_machine_is_compatible("qcom,ipq8064"))
++              mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
++
++      /* SoC specific settings for ipq8065 */
++      if (of_machine_is_compatible("qcom,ipq8065"))
++              mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
++
++      if (mask) {
++              ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
++                              QCA8K_MAC_PWR_RGMII0_1_8V |
++                              QCA8K_MAC_PWR_RGMII1_1_8V,
++                              mask);
++      }
++
++      return ret;
++}
++
++static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
++      ret = qca8k_setup_mac_pwr_sel(priv);
++      if (ret)
++              return ret;
++
+       /* Enable CPU Port */
+       ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
+                           QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -100,6 +100,11 @@
+ #define   QCA8K_SGMII_MODE_CTRL_PHY                   (1 << 22)
+ #define   QCA8K_SGMII_MODE_CTRL_MAC                   (2 << 22)
++/* MAC_PWR_SEL registers */
++#define QCA8K_REG_MAC_PWR_SEL                         0x0e4
++#define   QCA8K_MAC_PWR_RGMII1_1_8V                   BIT(18)
++#define   QCA8K_MAC_PWR_RGMII0_1_8V                   BIT(19)
++
+ /* EEE control registers */
+ #define QCA8K_REG_EEE_CTRL                            0x100
+ #define  QCA8K_REG_EEE_CTRL_LPI_EN(_i)                        ((_i + 1) * 2)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch b/target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch
new file mode 100644 (file)
index 0000000..bd768ec
--- /dev/null
@@ -0,0 +1,30 @@
+From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:07 +0200
+Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
+
+Add names and descriptions of additional PORT0_PAD_CTRL properties.
+qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
+phase to failling edge.
+
+Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -37,6 +37,10 @@ A CPU port node has the following option
+                           managed entity. See
+                           Documentation/devicetree/bindings/net/fixed-link.txt
+                           for details.
++- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
++                                Mostly used in qca8327 with CPU port 0 set to
++                                sgmii.
++- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
+ For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch b/target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch
new file mode 100644 (file)
index 0000000..e464452
--- /dev/null
@@ -0,0 +1,127 @@
+From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:08 +0200
+Subject: net: dsa: qca8k: add support for sgmii falling edge
+
+Add support for this in the qca8k driver. Also add support for SGMII
+rx/tx clock falling edge. This is only present for pad0, pad5 and
+pad6 have these bit reserved from Documentation. Add a comment that this
+is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
+setting falling in port0 applies to both configuration with sgmii used
+for port0 or port6.
+
+Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  4 ++++
+ 2 files changed, 67 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
+ }
+ static int
++qca8k_parse_port_config(struct qca8k_priv *priv)
++{
++      struct device_node *port_dn;
++      phy_interface_t mode;
++      struct dsa_port *dp;
++      int port, ret;
++
++      /* We have 2 CPU port. Check them */
++      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
++              /* Skip every other port */
++              if (port != 0 && port != 6)
++                      continue;
++
++              dp = dsa_to_port(priv->ds, port);
++              port_dn = dp->dn;
++
++              if (!of_device_is_available(port_dn))
++                      continue;
++
++              ret = of_get_phy_mode(port_dn, &mode);
++              if (ret)
++                      continue;
++
++              if (mode == PHY_INTERFACE_MODE_SGMII) {
++                      if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
++                              priv->sgmii_tx_clk_falling_edge = true;
++
++                      if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
++                              priv->sgmii_rx_clk_falling_edge = true;
++              }
++      }
++
++      return 0;
++}
++
++static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds)
+               return -EINVAL;
+       }
++      /* Parse CPU port config to be later used in phy_link mac_config */
++      ret = qca8k_parse_port_config(priv);
++      if (ret)
++              return ret;
++
+       mutex_init(&priv->reg_mutex);
+       /* Start by setting up the register mapping */
+@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit
+               }
+               qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
++
++              /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
++               * falling edge is set writing in the PORT0 PAD reg
++               */
++              if (priv->switch_id == QCA8K_ID_QCA8327 ||
++                  priv->switch_id == QCA8K_ID_QCA8337)
++                      reg = QCA8K_REG_PORT0_PAD_CTRL;
++
++              val = 0;
++
++              /* SGMII Clock phase configuration */
++              if (priv->sgmii_rx_clk_falling_edge)
++                      val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
++
++              if (priv->sgmii_tx_clk_falling_edge)
++                      val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
++
++              if (val)
++                      ret = qca8k_rmw(priv, reg,
++                                      QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
++                                      QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
++                                      val);
+               break;
+       default:
+               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -35,6 +35,8 @@
+ #define   QCA8K_MASK_CTRL_DEVICE_ID_MASK              GENMASK(15, 8)
+ #define   QCA8K_MASK_CTRL_DEVICE_ID(x)                        ((x) >> 8)
+ #define QCA8K_REG_PORT0_PAD_CTRL                      0x004
++#define   QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE    BIT(19)
++#define   QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE    BIT(18)
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+ #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
+@@ -260,6 +262,8 @@ struct qca8k_priv {
+       u8 switch_revision;
+       u8 rgmii_tx_delay;
+       u8 rgmii_rx_delay;
++      bool sgmii_rx_clk_falling_edge;
++      bool sgmii_tx_clk_falling_edge;
+       bool legacy_phy_port_mapping;
+       struct regmap *regmap;
+       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch b/target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch
new file mode 100644 (file)
index 0000000..606ac0a
--- /dev/null
@@ -0,0 +1,29 @@
+From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:09 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6
+
+The switch now support CPU port to be set 6 instead of be hardcoded to
+0. Document support for it and describe logic selection.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -29,7 +29,11 @@ the mdio MASTER is used as communication
+ Don't use mixed external and internal mdio-bus configurations, as this is
+ not supported by the hardware.
+-The CPU port of this switch is always port 0.
++This switch support 2 CPU port. Normally and advised configuration is with
++CPU port set to port 0. It is also possible to set the CPU port to port 6
++if the device requires it. The driver will configure the switch to the defined
++port. With both CPU port declared the first CPU port is selected as primary
++and the secondary CPU ignored.
+ A CPU port node has the following optional node:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch b/target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch
new file mode 100644 (file)
index 0000000..320db8f
--- /dev/null
@@ -0,0 +1,153 @@
+From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:10 +0200
+Subject: net: dsa: qca8k: add support for cpu port 6
+
+Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
+ports. The original intention of this driver seems to be use the
+mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
+where device have connected only the CPU port 6. To skip the
+introduction of a new binding, rework the driver to address the
+secondary CPU port as primary and drop any reference of hardcoded port.
+With configuration of mac06 exchange, just skip the definition of port0
+and define the CPU port as a secondary. The driver will autoconfigure
+the switch to use that as the primary CPU port.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
+ drivers/net/dsa/qca8k.h |  2 --
+ 2 files changed, 36 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
+       return ret;
+ }
++static int qca8k_find_cpu_port(struct dsa_switch *ds)
++{
++      struct qca8k_priv *priv = ds->priv;
++
++      /* Find the connected cpu port. Valid port are 0 or 6 */
++      if (dsa_is_cpu_port(ds, 0))
++              return 0;
++
++      dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
++
++      if (dsa_is_cpu_port(ds, 6))
++              return 6;
++
++      return -EINVAL;
++}
++
+ static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
+@@ -1017,13 +1033,13 @@ static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int ret, i;
++      int cpu_port, ret, i;
+       u32 mask;
+-      /* Make sure that port 0 is the cpu port */
+-      if (!dsa_is_cpu_port(ds, 0)) {
+-              dev_err(priv->dev, "port 0 is not the CPU port");
+-              return -EINVAL;
++      cpu_port = qca8k_find_cpu_port(ds);
++      if (cpu_port < 0) {
++              dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
++              return cpu_port;
+       }
+       /* Parse CPU port config to be later used in phy_link mac_config */
+@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
+               dev_warn(priv->dev, "mib init failed");
+       /* Enable QCA header mode on the cpu port */
+-      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
++      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
+                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
+                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
+       if (ret) {
+@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
+       /* Forward all unknown frames to CPU port for Linux processing */
+       ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
+       if (ret)
+               return ret;
+@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+               /* CPU port gets connected to all user ports of the switch */
+               if (dsa_is_cpu_port(ds, i)) {
+-                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
++                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
+                                       QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
+                       if (ret)
+                               return ret;
+@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
+                       ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+                                       QCA8K_PORT_LOOKUP_MEMBER,
+-                                      BIT(QCA8K_CPU_PORT));
++                                      BIT(cpu_port));
+                       if (ret)
+                               return ret;
+@@ -1616,9 +1632,12 @@ static int
+ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int port_mask = BIT(QCA8K_CPU_PORT);
++      int port_mask, cpu_port;
+       int i, ret;
++      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
++      port_mask = BIT(cpu_port);
++
+       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+                       continue;
+@@ -1645,7 +1664,9 @@ static void
+ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int i;
++      int cpu_port, i;
++
++      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
+        * this port
+        */
+       qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+-                QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
++                QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
+ }
+ static int
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -24,8 +24,6 @@
+ #define QCA8K_NUM_FDB_RECORDS                         2048
+-#define QCA8K_CPU_PORT                                        0
+-
+ #define QCA8K_PORT_VID_DEF                            1
+ /* Global control registers */
diff --git a/target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch b/target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch
new file mode 100644 (file)
index 0000000..de20176
--- /dev/null
@@ -0,0 +1,295 @@
+From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:11 +0200
+Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
+
+Future proof commit. This switch have 2 CPU ports and one valid
+configuration is first CPU port set to sgmii and second CPU port set to
+rgmii-id. The current implementation detects delay only for CPU port
+zero set to rgmii and doesn't count any delay set in a secondary CPU
+port. Drop the current delay scan function and move it to the sgmii
+parser function to generalize and implicitly add support for secondary
+CPU port set to rgmii-id. Introduce new logic where delay is enabled
+also with internal delay binding declared and rgmii set as PHY mode.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------
+ drivers/net/dsa/qca8k.h |  10 ++-
+ 2 files changed, 89 insertions(+), 86 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+ }
+ static int
+-qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
+-{
+-      struct device_node *port_dn;
+-      phy_interface_t mode;
+-      struct dsa_port *dp;
+-      u32 val;
+-
+-      /* CPU port is already checked */
+-      dp = dsa_to_port(priv->ds, 0);
+-
+-      port_dn = dp->dn;
+-
+-      /* Check if port 0 is set to the correct type */
+-      of_get_phy_mode(port_dn, &mode);
+-      if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
+-          mode != PHY_INTERFACE_MODE_RGMII_RXID &&
+-          mode != PHY_INTERFACE_MODE_RGMII_TXID) {
+-              return 0;
+-      }
+-
+-      switch (mode) {
+-      case PHY_INTERFACE_MODE_RGMII_ID:
+-      case PHY_INTERFACE_MODE_RGMII_RXID:
+-              if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
+-                      val = 2;
+-              else
+-                      /* Switch regs accept value in ns, convert ps to ns */
+-                      val = val / 1000;
+-
+-              if (val > QCA8K_MAX_DELAY) {
+-                      dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
+-                      val = 3;
+-              }
+-
+-              priv->rgmii_rx_delay = val;
+-              /* Stop here if we need to check only for rx delay */
+-              if (mode != PHY_INTERFACE_MODE_RGMII_ID)
+-                      break;
+-
+-              fallthrough;
+-      case PHY_INTERFACE_MODE_RGMII_TXID:
+-              if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
+-                      val = 1;
+-              else
+-                      /* Switch regs accept value in ns, convert ps to ns */
+-                      val = val / 1000;
+-
+-              if (val > QCA8K_MAX_DELAY) {
+-                      dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
+-                      val = 3;
+-              }
+-
+-              priv->rgmii_tx_delay = val;
+-              break;
+-      default:
+-              return 0;
+-      }
+-
+-      return 0;
+-}
+-
+-static int
+ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
+ {
+       u32 mask = 0;
+@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds
+ static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
++      int port, cpu_port_index = 0, ret;
+       struct device_node *port_dn;
+       phy_interface_t mode;
+       struct dsa_port *dp;
+-      int port, ret;
++      u32 delay;
+       /* We have 2 CPU port. Check them */
+-      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
++      for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
+               /* Skip every other port */
+               if (port != 0 && port != 6)
+                       continue;
+               dp = dsa_to_port(priv->ds, port);
+               port_dn = dp->dn;
++              cpu_port_index++;
+               if (!of_device_is_available(port_dn))
+                       continue;
+@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri
+               if (ret)
+                       continue;
+-              if (mode == PHY_INTERFACE_MODE_SGMII) {
++              switch (mode) {
++              case PHY_INTERFACE_MODE_RGMII:
++              case PHY_INTERFACE_MODE_RGMII_ID:
++              case PHY_INTERFACE_MODE_RGMII_TXID:
++              case PHY_INTERFACE_MODE_RGMII_RXID:
++                      delay = 0;
++
++                      if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
++                              /* Switch regs accept value in ns, convert ps to ns */
++                              delay = delay / 1000;
++                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                               mode == PHY_INTERFACE_MODE_RGMII_TXID)
++                              delay = 1;
++
++                      if (delay > QCA8K_MAX_DELAY) {
++                              dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
++                              delay = 3;
++                      }
++
++                      priv->rgmii_tx_delay[cpu_port_index] = delay;
++
++                      delay = 0;
++
++                      if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
++                              /* Switch regs accept value in ns, convert ps to ns */
++                              delay = delay / 1000;
++                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                               mode == PHY_INTERFACE_MODE_RGMII_RXID)
++                              delay = 2;
++
++                      if (delay > QCA8K_MAX_DELAY) {
++                              dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
++                              delay = 3;
++                      }
++
++                      priv->rgmii_rx_delay[cpu_port_index] = delay;
++
++                      break;
++              case PHY_INTERFACE_MODE_SGMII:
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+                               priv->sgmii_tx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+                               priv->sgmii_rx_clk_falling_edge = true;
++
++                      break;
++              default:
++                      continue;
+               }
+       }
+@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
+-      ret = qca8k_setup_of_rgmii_delay(priv);
+-      if (ret)
+-              return ret;
+-
+       ret = qca8k_setup_mac_pwr_sel(priv);
+       if (ret)
+               return ret;
+@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit
+                        const struct phylink_link_state *state)
+ {
+       struct qca8k_priv *priv = ds->priv;
+-      u32 reg, val;
+-      int ret;
++      int cpu_port_index, ret;
++      u32 reg, val, delay;
+       switch (port) {
+       case 0: /* 1st CPU port */
+@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+                       return;
+               reg = QCA8K_REG_PORT0_PAD_CTRL;
++              cpu_port_index = QCA8K_CPU_PORT0;
+               break;
+       case 1:
+       case 2:
+@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+                       return;
+               reg = QCA8K_REG_PORT6_PAD_CTRL;
++              cpu_port_index = QCA8K_CPU_PORT6;
+               break;
+       default:
+               dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit
+       switch (state->interface) {
+       case PHY_INTERFACE_MODE_RGMII:
+-              /* RGMII mode means no delay so don't enable the delay */
+-              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+-              break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+-              /* RGMII_ID needs internal delay. This is enabled through
+-               * PORT5_PAD_CTRL for all ports, rather than individual port
+-               * registers
++              val = QCA8K_PORT_PAD_RGMII_EN;
++
++              /* Delay can be declared in 3 different way.
++               * Mode to rgmii and internal-delay standard binding defined
++               * rgmii-id or rgmii-tx/rx phy mode set.
++               * The parse logic set a delay different than 0 only when one
++               * of the 3 different way is used. In all other case delay is
++               * not enabled. With ID or TX/RXID delay is enabled and set
++               * to the default and recommended value.
++               */
++              if (priv->rgmii_tx_delay[cpu_port_index]) {
++                      delay = priv->rgmii_tx_delay[cpu_port_index];
++
++                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
++                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
++              }
++
++              if (priv->rgmii_rx_delay[cpu_port_index]) {
++                      delay = priv->rgmii_rx_delay[cpu_port_index];
++
++                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
++                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
++              }
++
++              /* Set RGMII delay based on the selected values */
++              qca8k_write(priv, reg, val);
++
++              /* QCA8337 requires to set rgmii rx delay for all ports.
++               * This is enabled through PORT5_PAD_CTRL for all ports,
++               * rather than individual port registers.
+                */
+-              qca8k_write(priv, reg,
+-                          QCA8K_PORT_PAD_RGMII_EN |
+-                          QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
+-                          QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+-              /* QCA8337 requires to set rgmii rx delay */
+               if (priv->switch_id == QCA8K_ID_QCA8337)
+                       qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
+                                   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -13,6 +13,7 @@
+ #include <linux/gpio.h>
+ #define QCA8K_NUM_PORTS                                       7
++#define QCA8K_NUM_CPU_PORTS                           2
+ #define QCA8K_MAX_MTU                                 9000
+ #define PHY_ID_QCA8327                                        0x004dd034
+@@ -255,13 +256,18 @@ struct qca8k_match_data {
+       u8 id;
+ };
++enum {
++      QCA8K_CPU_PORT0,
++      QCA8K_CPU_PORT6,
++};
++
+ struct qca8k_priv {
+       u8 switch_id;
+       u8 switch_revision;
+-      u8 rgmii_tx_delay;
+-      u8 rgmii_rx_delay;
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
++      u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
++      u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       bool legacy_phy_port_mapping;
+       struct regmap *regmap;
+       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch b/target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch
new file mode 100644 (file)
index 0000000..8abd264
--- /dev/null
@@ -0,0 +1,33 @@
+From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:12 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
+
+Document qca,sgmii-enable-pll binding used in the CPU nodes to
+enable SGMII PLL on MAC config.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -45,6 +45,16 @@ A CPU port node has the following option
+                                 Mostly used in qca8327 with CPU port 0 set to
+                                 sgmii.
+ - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
++- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
++                          chain along with Signal Detection.
++                          This should NOT be enabled for qca8327. If enabled with
++                          qca8327 the sgmii port won't correctly init and an err
++                          is printed.
++                          This can be required for qca8337 switch with revision 2.
++                          A warning is displayed when used with revision greater
++                          2.
++                          With CPU port set to sgmii and qca8337 it is advised
++                          to set this unless a communication problem is observed.
+ For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch b/target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch
new file mode 100644 (file)
index 0000000..2b5a84a
--- /dev/null
@@ -0,0 +1,65 @@
+From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:13 +0200
+Subject: net: dsa: qca8k: add explicit SGMII PLL enable
+
+Support enabling PLL on the SGMII CPU port. Some device require this
+special configuration or no traffic is transmitted and the switch
+doesn't work at all. A dedicated binding is added to the CPU node
+port to apply the correct reg on mac config.
+Fail to correctly configure sgmii with qca8327 switch and warn if pll is
+used on qca8337 with a revision greater than 1.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
+ drivers/net/dsa/qca8k.h |  1 +
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+                               priv->sgmii_rx_clk_falling_edge = true;
++                      if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
++                              priv->sgmii_enable_pll = true;
++
++                              if (priv->switch_id == QCA8K_ID_QCA8327) {
++                                      dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
++                                      priv->sgmii_enable_pll = false;
++                              }
++
++                              if (priv->switch_revision < 2)
++                                      dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
++                      }
++
+                       break;
+               default:
+                       continue;
+@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit
+               if (ret)
+                       return;
+-              val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+-                      QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
++              val |= QCA8K_SGMII_EN_SD;
++
++              if (priv->sgmii_enable_pll)
++                      val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
++                             QCA8K_SGMII_EN_TX;
+               if (dsa_is_cpu_port(ds, port)) {
+                       /* CPU port, we're talking to the CPU MAC, be a PHY */
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -266,6 +266,7 @@ struct qca8k_priv {
+       u8 switch_revision;
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
++      bool sgmii_enable_pll;
+       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       bool legacy_phy_port_mapping;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch b/target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch
new file mode 100644 (file)
index 0000000..38dc954
--- /dev/null
@@ -0,0 +1,37 @@
+From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:14 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
+
+Document new binding qca,ignore-power-on-sel used to ignore
+power on strapping and use sw regs instead.
+Document qca,led-open.drain to set led to open drain mode, the
+qca,ignore-power-on-sel is mandatory with this enabled or an error will
+be reported.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -13,6 +13,17 @@ Required properties:
+ Optional properties:
+ - reset-gpios: GPIO to be used to reset the whole device
++- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
++                           drain or eeprom presence. This is needed for broken
++                           devices that have wrong configuration or when the oem
++                           decided to not use pin strapping and fallback to sw
++                           regs.
++- qca,led-open-drain: Set leds to open-drain mode. This requires the
++                      qca,ignore-power-on-sel to be set or the driver will fail
++                      to probe. This is needed if the oem doesn't use pin
++                      strapping to set this mode and prefers to set it using sw
++                      regs. The pin strapping related to led open drain mode is
++                      the pin B68 for QCA832x and B49 for QCA833x
+ Subnodes:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch b/target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch
new file mode 100644 (file)
index 0000000..aa5d92a
--- /dev/null
@@ -0,0 +1,92 @@
+From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:15 +0200
+Subject: net: dsa: qca8k: add support for pws config reg
+
+Some qca8327 switch require to force the ignore of power on sel
+strapping. Some switch require to set the led open drain mode in regs
+instead of using strapping. While most of the device implements this
+using the correct way using pin strapping, there are still some broken
+device that require to be set using sw regs.
+Introduce a new binding and support these special configuration.
+As led open drain require to ignore pin strapping to work, the probe
+fails with EINVAL error with incorrect configuration.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  6 ++++++
+ 2 files changed, 45 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds
+ }
+ static int
++qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
++{
++      struct device_node *node = priv->dev->of_node;
++      u32 val = 0;
++      int ret;
++
++      /* QCA8327 require to set to the correct mode.
++       * His bigger brother QCA8328 have the 172 pin layout.
++       * Should be applied by default but we set this just to make sure.
++       */
++      if (priv->switch_id == QCA8K_ID_QCA8327) {
++              ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
++                              QCA8327_PWS_PACKAGE148_EN);
++              if (ret)
++                      return ret;
++      }
++
++      if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
++              val |= QCA8K_PWS_POWER_ON_SEL;
++
++      if (of_property_read_bool(node, "qca,led-open-drain")) {
++              if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
++                      dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
++                      return -EINVAL;
++              }
++
++              val |= QCA8K_PWS_LED_OPEN_EN_CSR;
++      }
++
++      return qca8k_rmw(priv, QCA8K_REG_PWS,
++                      QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
++                      val);
++}
++
++static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
+       int port, cpu_port_index = 0, ret;
+@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
++      ret = qca8k_setup_of_pws_reg(priv);
++      if (ret)
++              return ret;
++
+       ret = qca8k_setup_mac_pwr_sel(priv);
+       if (ret)
+               return ret;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -46,6 +46,12 @@
+ #define   QCA8K_MAX_DELAY                             3
+ #define   QCA8K_PORT_PAD_SGMII_EN                     BIT(7)
+ #define QCA8K_REG_PWS                                 0x010
++#define   QCA8K_PWS_POWER_ON_SEL                      BIT(31)
++/* This reg is only valid for QCA832x and toggle the package
++ * type from 176 pin (by default) to 148 pin used on QCA8327
++ */
++#define   QCA8327_PWS_PACKAGE148_EN                   BIT(30)
++#define   QCA8K_PWS_LED_OPEN_EN_CSR                   BIT(24)
+ #define   QCA8K_PWS_SERDES_AEN_DIS                    BIT(7)
+ #define QCA8K_REG_MODULE_EN                           0x030
+ #define   QCA8K_MODULE_EN_MIB                         BIT(0)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch b/target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch
new file mode 100644 (file)
index 0000000..1bfb00c
--- /dev/null
@@ -0,0 +1,32 @@
+From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:16 +0200
+Subject: dt-bindings: net: dsa: qca8k: document support for qca8328
+
+QCA8328 is the bigger brother of qca8327. Document the new compatible
+binding and add some information to understand the various switch
+compatible.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -3,9 +3,10 @@
+ Required properties:
+ - compatible: should be one of:
+-    "qca,qca8327"
+-    "qca,qca8334"
+-    "qca,qca8337"
++    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
++    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
++    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
++    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
+ - #size-cells: must be 0
+ - #address-cells: must be 1
diff --git a/target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch b/target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch
new file mode 100644 (file)
index 0000000..6e118f5
--- /dev/null
@@ -0,0 +1,78 @@
+From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:17 +0200
+Subject: net: dsa: qca8k: add support for QCA8328
+
+QCA8328 switch is the bigger brother of the qca8327. Same regs different
+chip. Change the function to set the correct pin layout and introduce a
+new match_data to differentiate the 2 switch as they have the same ID
+and their internal PHY have the same ID.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
+ drivers/net/dsa/qca8k.h |  1 +
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -935,6 +935,7 @@ static int
+ qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
+ {
+       struct device_node *node = priv->dev->of_node;
++      const struct qca8k_match_data *data;
+       u32 val = 0;
+       int ret;
+@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
+        * Should be applied by default but we set this just to make sure.
+        */
+       if (priv->switch_id == QCA8K_ID_QCA8327) {
++              data = of_device_get_match_data(priv->dev);
++
++              /* Set the correct package of 148 pin for QCA8327 */
++              if (data->reduced_package)
++                      val |= QCA8327_PWS_PACKAGE148_EN;
++
+               ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
+-                              QCA8327_PWS_PACKAGE148_EN);
++                              val);
+               if (ret)
+                       return ret;
+       }
+@@ -2098,7 +2105,12 @@ static int qca8k_resume(struct device *d
+ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
+                        qca8k_suspend, qca8k_resume);
+-static const struct qca8k_match_data qca832x = {
++static const struct qca8k_match_data qca8327 = {
++      .id = QCA8K_ID_QCA8327,
++      .reduced_package = true,
++};
++
++static const struct qca8k_match_data qca8328 = {
+       .id = QCA8K_ID_QCA8327,
+ };
+@@ -2107,7 +2119,8 @@ static const struct qca8k_match_data qca
+ };
+ static const struct of_device_id qca8k_of_match[] = {
+-      { .compatible = "qca,qca8327", .data = &qca832x },
++      { .compatible = "qca,qca8327", .data = &qca8327 },
++      { .compatible = "qca,qca8328", .data = &qca8328 },
+       { .compatible = "qca,qca8334", .data = &qca833x },
+       { .compatible = "qca,qca8337", .data = &qca833x },
+       { /* sentinel */ },
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -260,6 +260,7 @@ struct ar8xxx_port_status {
+ struct qca8k_match_data {
+       u8 id;
++      bool reduced_package;
+ };
+ enum {
diff --git a/target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch b/target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch
new file mode 100644 (file)
index 0000000..27f94dc
--- /dev/null
@@ -0,0 +1,159 @@
+From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:18 +0200
+Subject: net: dsa: qca8k: set internal delay also for sgmii
+
+QCA original code report port instability and sa that SGMII also require
+to set internal delay. Generalize the rgmii delay function and apply the
+advised value if they are not defined in DT.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
+ drivers/net/dsa/qca8k.h |  2 ++
+ 2 files changed, 62 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
+               case PHY_INTERFACE_MODE_RGMII_ID:
+               case PHY_INTERFACE_MODE_RGMII_TXID:
+               case PHY_INTERFACE_MODE_RGMII_RXID:
++              case PHY_INTERFACE_MODE_SGMII:
+                       delay = 0;
+                       if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
+@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
+                       priv->rgmii_rx_delay[cpu_port_index] = delay;
+-                      break;
+-              case PHY_INTERFACE_MODE_SGMII:
++                      /* Skip sgmii parsing for rgmii* mode */
++                      if (mode == PHY_INTERFACE_MODE_RGMII ||
++                          mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                          mode == PHY_INTERFACE_MODE_RGMII_TXID ||
++                          mode == PHY_INTERFACE_MODE_RGMII_RXID)
++                              break;
++
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+                               priv->sgmii_tx_clk_falling_edge = true;
+@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
+ }
+ static void
++qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
++                                    u32 reg)
++{
++      u32 delay, val = 0;
++      int ret;
++
++      /* Delay can be declared in 3 different way.
++       * Mode to rgmii and internal-delay standard binding defined
++       * rgmii-id or rgmii-tx/rx phy mode set.
++       * The parse logic set a delay different than 0 only when one
++       * of the 3 different way is used. In all other case delay is
++       * not enabled. With ID or TX/RXID delay is enabled and set
++       * to the default and recommended value.
++       */
++      if (priv->rgmii_tx_delay[cpu_port_index]) {
++              delay = priv->rgmii_tx_delay[cpu_port_index];
++
++              val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
++      }
++
++      if (priv->rgmii_rx_delay[cpu_port_index]) {
++              delay = priv->rgmii_rx_delay[cpu_port_index];
++
++              val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
++      }
++
++      /* Set RGMII delay based on the selected values */
++      ret = qca8k_rmw(priv, reg,
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
++                      val);
++      if (ret)
++              dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
++                      cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
++}
++
++static void
+ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+                        const struct phylink_link_state *state)
+ {
+       struct qca8k_priv *priv = ds->priv;
+       int cpu_port_index, ret;
+-      u32 reg, val, delay;
++      u32 reg, val;
+       switch (port) {
+       case 0: /* 1st CPU port */
+@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+-              val = QCA8K_PORT_PAD_RGMII_EN;
+-
+-              /* Delay can be declared in 3 different way.
+-               * Mode to rgmii and internal-delay standard binding defined
+-               * rgmii-id or rgmii-tx/rx phy mode set.
+-               * The parse logic set a delay different than 0 only when one
+-               * of the 3 different way is used. In all other case delay is
+-               * not enabled. With ID or TX/RXID delay is enabled and set
+-               * to the default and recommended value.
+-               */
+-              if (priv->rgmii_tx_delay[cpu_port_index]) {
+-                      delay = priv->rgmii_tx_delay[cpu_port_index];
+-
+-                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
+-                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
+-              }
+-
+-              if (priv->rgmii_rx_delay[cpu_port_index]) {
+-                      delay = priv->rgmii_rx_delay[cpu_port_index];
+-
+-                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
+-                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
+-              }
++              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+-              /* Set RGMII delay based on the selected values */
+-              qca8k_write(priv, reg, val);
++              /* Configure rgmii delay */
++              qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
+               /* QCA8337 requires to set rgmii rx delay for all ports.
+                * This is enabled through PORT5_PAD_CTRL for all ports,
+@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
+                                       QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
+                                       QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
+                                       val);
++
++              /* From original code is reported port instability as SGMII also
++               * require delay set. Apply advised values here or take them from DT.
++               */
++              if (state->interface == PHY_INTERFACE_MODE_SGMII)
++                      qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
++
+               break;
+       default:
+               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -39,7 +39,9 @@
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+ #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
++#define   QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK          GENMASK(23, 22)
+ #define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            ((x) << 22)
++#define   QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK          GENMASK(21, 20)
+ #define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            ((x) << 20)
+ #define         QCA8K_PORT_PAD_RGMII_TX_DELAY_EN              BIT(25)
+ #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN            BIT(24)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch b/target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch
new file mode 100644 (file)
index 0000000..b991798
--- /dev/null
@@ -0,0 +1,124 @@
+From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:19 +0200
+Subject: net: dsa: qca8k: move port config to dedicated struct
+
+Move ports related config to dedicated struct to keep things organized.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 26 +++++++++++++-------------
+ drivers/net/dsa/qca8k.h | 10 +++++++---
+ 2 files changed, 20 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri
+                               delay = 3;
+                       }
+-                      priv->rgmii_tx_delay[cpu_port_index] = delay;
++                      priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
+                       delay = 0;
+@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri
+                               delay = 3;
+                       }
+-                      priv->rgmii_rx_delay[cpu_port_index] = delay;
++                      priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
+                       /* Skip sgmii parsing for rgmii* mode */
+                       if (mode == PHY_INTERFACE_MODE_RGMII ||
+@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri
+                               break;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+-                              priv->sgmii_tx_clk_falling_edge = true;
++                              priv->ports_config.sgmii_tx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+-                              priv->sgmii_rx_clk_falling_edge = true;
++                              priv->ports_config.sgmii_rx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
+-                              priv->sgmii_enable_pll = true;
++                              priv->ports_config.sgmii_enable_pll = true;
+                               if (priv->switch_id == QCA8K_ID_QCA8327) {
+                                       dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
+-                                      priv->sgmii_enable_pll = false;
++                                      priv->ports_config.sgmii_enable_pll = false;
+                               }
+                               if (priv->switch_revision < 2)
+@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st
+        * not enabled. With ID or TX/RXID delay is enabled and set
+        * to the default and recommended value.
+        */
+-      if (priv->rgmii_tx_delay[cpu_port_index]) {
+-              delay = priv->rgmii_tx_delay[cpu_port_index];
++      if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
++              delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
+               val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
+                       QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
+       }
+-      if (priv->rgmii_rx_delay[cpu_port_index]) {
+-              delay = priv->rgmii_rx_delay[cpu_port_index];
++      if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
++              delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
+               val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
+                       QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
+@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+               val |= QCA8K_SGMII_EN_SD;
+-              if (priv->sgmii_enable_pll)
++              if (priv->ports_config.sgmii_enable_pll)
+                       val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+                              QCA8K_SGMII_EN_TX;
+@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit
+               val = 0;
+               /* SGMII Clock phase configuration */
+-              if (priv->sgmii_rx_clk_falling_edge)
++              if (priv->ports_config.sgmii_rx_clk_falling_edge)
+                       val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
+-              if (priv->sgmii_tx_clk_falling_edge)
++              if (priv->ports_config.sgmii_tx_clk_falling_edge)
+                       val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
+               if (val)
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -270,15 +270,19 @@ enum {
+       QCA8K_CPU_PORT6,
+ };
+-struct qca8k_priv {
+-      u8 switch_id;
+-      u8 switch_revision;
++struct qca8k_ports_config {
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
+       bool sgmii_enable_pll;
+       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
++};
++
++struct qca8k_priv {
++      u8 switch_id;
++      u8 switch_revision;
+       bool legacy_phy_port_mapping;
++      struct qca8k_ports_config ports_config;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch b/target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch
new file mode 100644 (file)
index 0000000..f7cb514
--- /dev/null
@@ -0,0 +1,26 @@
+From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:20 +0200
+Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch
+
+Fix warning now that we have qca8k switch Documentation using yaml.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
++++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
+@@ -51,6 +51,9 @@ examples:
+         switch@10 {
+             compatible = "qca,qca8337";
+             reg = <0x10>;
+-            /* ... */
++
++            ports {
++              /* ... */
++            };
+         };
+     };
diff --git a/target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch b/target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch
new file mode 100644 (file)
index 0000000..b9bce97
--- /dev/null
@@ -0,0 +1,631 @@
+From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001
+From: Matthew Hagan <mnhagan88@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:21 +0200
+Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema
+
+Convert the qca8k bindings to YAML format.
+
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../devicetree/bindings/net/dsa/qca8k.txt          | 245 --------------
+ .../devicetree/bindings/net/dsa/qca8k.yaml         | 362 +++++++++++++++++++++
+ 2 files changed, 362 insertions(+), 245 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt
+ create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ /dev/null
+@@ -1,245 +0,0 @@
+-* Qualcomm Atheros QCA8xxx switch family
+-
+-Required properties:
+-
+-- compatible: should be one of:
+-    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
+-    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
+-    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
+-    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
+-
+-- #size-cells: must be 0
+-- #address-cells: must be 1
+-
+-Optional properties:
+-
+-- reset-gpios: GPIO to be used to reset the whole device
+-- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
+-                           drain or eeprom presence. This is needed for broken
+-                           devices that have wrong configuration or when the oem
+-                           decided to not use pin strapping and fallback to sw
+-                           regs.
+-- qca,led-open-drain: Set leds to open-drain mode. This requires the
+-                      qca,ignore-power-on-sel to be set or the driver will fail
+-                      to probe. This is needed if the oem doesn't use pin
+-                      strapping to set this mode and prefers to set it using sw
+-                      regs. The pin strapping related to led open drain mode is
+-                      the pin B68 for QCA832x and B49 for QCA833x
+-
+-Subnodes:
+-
+-The integrated switch subnode should be specified according to the binding
+-described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
+-mdio-bus each subnode describing a port needs to have a valid phandle
+-referencing the internal PHY it is connected to. This is because there's no
+-N:N mapping of port and PHY id.
+-To declare the internal mdio-bus configuration, declare a mdio node in the
+-switch node and declare the phandle for the port referencing the internal
+-PHY is connected to. In this config a internal mdio-bus is registered and
+-the mdio MASTER is used as communication.
+-
+-Don't use mixed external and internal mdio-bus configurations, as this is
+-not supported by the hardware.
+-
+-This switch support 2 CPU port. Normally and advised configuration is with
+-CPU port set to port 0. It is also possible to set the CPU port to port 6
+-if the device requires it. The driver will configure the switch to the defined
+-port. With both CPU port declared the first CPU port is selected as primary
+-and the secondary CPU ignored.
+-
+-A CPU port node has the following optional node:
+-
+-- fixed-link            : Fixed-link subnode describing a link to a non-MDIO
+-                          managed entity. See
+-                          Documentation/devicetree/bindings/net/fixed-link.txt
+-                          for details.
+-- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
+-                                Mostly used in qca8327 with CPU port 0 set to
+-                                sgmii.
+-- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
+-- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
+-                          chain along with Signal Detection.
+-                          This should NOT be enabled for qca8327. If enabled with
+-                          qca8327 the sgmii port won't correctly init and an err
+-                          is printed.
+-                          This can be required for qca8337 switch with revision 2.
+-                          A warning is displayed when used with revision greater
+-                          2.
+-                          With CPU port set to sgmii and qca8337 it is advised
+-                          to set this unless a communication problem is observed.
+-
+-For QCA8K the 'fixed-link' sub-node supports only the following properties:
+-
+-- 'speed' (integer, mandatory), to indicate the link speed. Accepted
+-  values are 10, 100 and 1000
+-- 'full-duplex' (boolean, optional), to indicate that full duplex is
+-  used. When absent, half duplex is assumed.
+-
+-Examples:
+-
+-for the external mdio-bus configuration:
+-
+-      &mdio0 {
+-              phy_port1: phy@0 {
+-                      reg = <0>;
+-              };
+-
+-              phy_port2: phy@1 {
+-                      reg = <1>;
+-              };
+-
+-              phy_port3: phy@2 {
+-                      reg = <2>;
+-              };
+-
+-              phy_port4: phy@3 {
+-                      reg = <3>;
+-              };
+-
+-              phy_port5: phy@4 {
+-                      reg = <4>;
+-              };
+-
+-              switch@10 {
+-                      compatible = "qca,qca8337";
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+-                      reg = <0x10>;
+-
+-                      ports {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-                              port@0 {
+-                                      reg = <0>;
+-                                      label = "cpu";
+-                                      ethernet = <&gmac1>;
+-                                      phy-mode = "rgmii";
+-                                      fixed-link {
+-                                              speed = 1000;
+-                                              full-duplex;
+-                                      };
+-                              };
+-
+-                              port@1 {
+-                                      reg = <1>;
+-                                      label = "lan1";
+-                                      phy-handle = <&phy_port1>;
+-                              };
+-
+-                              port@2 {
+-                                      reg = <2>;
+-                                      label = "lan2";
+-                                      phy-handle = <&phy_port2>;
+-                              };
+-
+-                              port@3 {
+-                                      reg = <3>;
+-                                      label = "lan3";
+-                                      phy-handle = <&phy_port3>;
+-                              };
+-
+-                              port@4 {
+-                                      reg = <4>;
+-                                      label = "lan4";
+-                                      phy-handle = <&phy_port4>;
+-                              };
+-
+-                              port@5 {
+-                                      reg = <5>;
+-                                      label = "wan";
+-                                      phy-handle = <&phy_port5>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-for the internal master mdio-bus configuration:
+-
+-      &mdio0 {
+-              switch@10 {
+-                      compatible = "qca,qca8337";
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+-                      reg = <0x10>;
+-
+-                      ports {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              port@0 {
+-                                      reg = <0>;
+-                                      label = "cpu";
+-                                      ethernet = <&gmac1>;
+-                                      phy-mode = "rgmii";
+-                                      fixed-link {
+-                                              speed = 1000;
+-                                              full-duplex;
+-                                      };
+-                              };
+-
+-                              port@1 {
+-                                      reg = <1>;
+-                                      label = "lan1";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port1>;
+-                              };
+-
+-                              port@2 {
+-                                      reg = <2>;
+-                                      label = "lan2";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port2>;
+-                              };
+-
+-                              port@3 {
+-                                      reg = <3>;
+-                                      label = "lan3";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port3>;
+-                              };
+-
+-                              port@4 {
+-                                      reg = <4>;
+-                                      label = "lan4";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port4>;
+-                              };
+-
+-                              port@5 {
+-                                      reg = <5>;
+-                                      label = "wan";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port5>;
+-                              };
+-                      };
+-
+-                      mdio {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              phy_port1: phy@0 {
+-                                      reg = <0>;
+-                              };
+-
+-                              phy_port2: phy@1 {
+-                                      reg = <1>;
+-                              };
+-
+-                              phy_port3: phy@2 {
+-                                      reg = <2>;
+-                              };
+-
+-                              phy_port4: phy@3 {
+-                                      reg = <3>;
+-                              };
+-
+-                              phy_port5: phy@4 {
+-                                      reg = <4>;
+-                              };
+-                      };
+-              };
+-      };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml
+@@ -0,0 +1,362 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Qualcomm Atheros QCA83xx switch family
++
++maintainers:
++  - John Crispin <john@phrozen.org>
++
++description:
++  If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode
++  describing a port needs to have a valid phandle referencing the internal PHY
++  it is connected to. This is because there is no N:N mapping of port and PHY
++  ID. To declare the internal mdio-bus configuration, declare an MDIO node in
++  the switch node and declare the phandle for the port, referencing the internal
++  PHY it is connected to. In this config, an internal mdio-bus is registered and
++  the MDIO master is used for communication. Mixed external and internal
++  mdio-bus configurations are not supported by the hardware.
++
++properties:
++  compatible:
++    oneOf:
++      - enum:
++          - qca,qca8327
++          - qca,qca8328
++          - qca,qca8334
++          - qca,qca8337
++    description: |
++      qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
++      qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package
++      qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package
++      qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
++
++  reg:
++    maxItems: 1
++
++  reset-gpios:
++    description:
++      GPIO to be used to reset the whole device
++    maxItems: 1
++
++  qca,ignore-power-on-sel:
++    $ref: /schemas/types.yaml#/definitions/flag
++    description:
++      Ignore power-on pin strapping to configure LED open-drain or EEPROM
++      presence. This is needed for devices with incorrect configuration or when
++      the OEM has decided not to use pin strapping and falls back to SW regs.
++
++  qca,led-open-drain:
++    $ref: /schemas/types.yaml#/definitions/flag
++    description:
++      Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to
++      be set, otherwise the driver will fail at probe. This is required if the
++      OEM does not use pin strapping to set this mode and prefers to set it
++      using SW regs. The pin strappings related to LED open-drain mode are
++      B68 on the QCA832x and B49 on the QCA833x.
++
++  mdio:
++    type: object
++    description: Qca8k switch have an internal mdio to access switch port.
++                 If this is not present, the legacy mapping is used and the
++                 internal mdio access is used.
++                 With the legacy mapping the reg corresponding to the internal
++                 mdio is the switch reg with an offset of -1.
++
++    properties:
++      '#address-cells':
++        const: 1
++      '#size-cells':
++        const: 0
++
++    patternProperties:
++      "^(ethernet-)?phy@[0-4]$":
++        type: object
++
++        allOf:
++          - $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
++
++        properties:
++          reg:
++            maxItems: 1
++
++        required:
++          - reg
++
++patternProperties:
++  "^(ethernet-)?ports$":
++    type: object
++    properties:
++      '#address-cells':
++        const: 1
++      '#size-cells':
++        const: 0
++
++    patternProperties:
++      "^(ethernet-)?port@[0-6]$":
++        type: object
++        description: Ethernet switch ports
++
++        properties:
++          reg:
++            description: Port number
++
++          label:
++            description:
++              Describes the label associated with this port, which will become
++              the netdev name
++            $ref: /schemas/types.yaml#/definitions/string
++
++          link:
++            description:
++              Should be a list of phandles to other switch's DSA port. This
++              port is used as the outgoing port towards the phandle ports. The
++              full routing information must be given, not just the one hop
++              routes to neighbouring switches
++            $ref: /schemas/types.yaml#/definitions/phandle-array
++
++          ethernet:
++            description:
++              Should be a phandle to a valid Ethernet device node.  This host
++              device is what the switch port is connected to
++            $ref: /schemas/types.yaml#/definitions/phandle
++
++          phy-handle: true
++
++          phy-mode: true
++
++          fixed-link: true
++
++          mac-address: true
++
++          sfp: true
++
++          qca,sgmii-rxclk-falling-edge:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              Set the receive clock phase to falling edge. Mostly commonly used on
++              the QCA8327 with CPU port 0 set to SGMII.
++
++          qca,sgmii-txclk-falling-edge:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              Set the transmit clock phase to falling edge.
++
++          qca,sgmii-enable-pll:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              For SGMII CPU port, explicitly enable PLL, TX and RX chain along with
++              Signal Detection. On the QCA8327 this should not be enabled, otherwise
++              the SGMII port will not initialize. When used on the QCA8337, revision 3
++              or greater, a warning will be displayed. When the CPU port is set to
++              SGMII on the QCA8337, it is advised to set this unless a communication
++              issue is observed.
++
++        required:
++          - reg
++
++        additionalProperties: false
++
++oneOf:
++  - required:
++      - ports
++  - required:
++      - ethernet-ports
++
++required:
++  - compatible
++  - reg
++
++additionalProperties: true
++
++examples:
++  - |
++    #include <dt-bindings/gpio/gpio.h>
++
++    mdio {
++        #address-cells = <1>;
++        #size-cells = <0>;
++
++        external_phy_port1: ethernet-phy@0 {
++            reg = <0>;
++        };
++
++        external_phy_port2: ethernet-phy@1 {
++            reg = <1>;
++        };
++
++        external_phy_port3: ethernet-phy@2 {
++            reg = <2>;
++        };
++
++        external_phy_port4: ethernet-phy@3 {
++            reg = <3>;
++        };
++
++        external_phy_port5: ethernet-phy@4 {
++            reg = <4>;
++        };
++
++        switch@10 {
++            compatible = "qca,qca8337";
++            #address-cells = <1>;
++            #size-cells = <0>;
++            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
++            reg = <0x10>;
++
++            ports {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                port@0 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "rgmii";
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++
++                port@1 {
++                    reg = <1>;
++                    label = "lan1";
++                    phy-handle = <&external_phy_port1>;
++                };
++
++                port@2 {
++                    reg = <2>;
++                    label = "lan2";
++                    phy-handle = <&external_phy_port2>;
++                };
++
++                port@3 {
++                    reg = <3>;
++                    label = "lan3";
++                    phy-handle = <&external_phy_port3>;
++                };
++
++                port@4 {
++                    reg = <4>;
++                    label = "lan4";
++                    phy-handle = <&external_phy_port4>;
++                };
++
++                port@5 {
++                    reg = <5>;
++                    label = "wan";
++                    phy-handle = <&external_phy_port5>;
++                };
++            };
++        };
++    };
++  - |
++    #include <dt-bindings/gpio/gpio.h>
++
++    mdio {
++        #address-cells = <1>;
++        #size-cells = <0>;
++
++        switch@10 {
++            compatible = "qca,qca8337";
++            #address-cells = <1>;
++            #size-cells = <0>;
++            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
++            reg = <0x10>;
++
++            ports {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                port@0 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "rgmii";
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++
++                port@1 {
++                    reg = <1>;
++                    label = "lan1";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port1>;
++                };
++
++                port@2 {
++                    reg = <2>;
++                    label = "lan2";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port2>;
++                };
++
++                port@3 {
++                    reg = <3>;
++                    label = "lan3";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port3>;
++                };
++
++                port@4 {
++                    reg = <4>;
++                    label = "lan4";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port4>;
++                };
++
++                port@5 {
++                    reg = <5>;
++                    label = "wan";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port5>;
++                };
++
++                port@6 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "sgmii";
++
++                    qca,sgmii-rxclk-falling-edge;
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++            };
++
++            mdio {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                internal_phy_port1: ethernet-phy@0 {
++                    reg = <0>;
++                };
++
++                internal_phy_port2: ethernet-phy@1 {
++                    reg = <1>;
++                };
++
++                internal_phy_port3: ethernet-phy@2 {
++                    reg = <2>;
++                };
++
++                internal_phy_port4: ethernet-phy@3 {
++                    reg = <3>;
++                };
++
++                internal_phy_port5: ethernet-phy@4 {
++                    reg = <4>;
++                };
++            };
++        };
++    };