1 From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
2 From: Ansuel Smith <ansuelsmth@gmail.com>
3 Date: Thu, 14 Oct 2021 00:39:18 +0200
4 Subject: net: dsa: qca8k: set internal delay also for sgmii
6 QCA original code report port instability and sa that SGMII also require
7 to set internal delay. Generalize the rgmii delay function and apply the
8 advised value if they are not defined in DT.
10 Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
11 Signed-off-by: David S. Miller <davem@davemloft.net>
13 drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
14 drivers/net/dsa/qca8k.h | 2 ++
15 2 files changed, 62 insertions(+), 28 deletions(-)
17 --- a/drivers/net/dsa/qca8k.c
18 +++ b/drivers/net/dsa/qca8k.c
19 @@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
20 case PHY_INTERFACE_MODE_RGMII_ID:
21 case PHY_INTERFACE_MODE_RGMII_TXID:
22 case PHY_INTERFACE_MODE_RGMII_RXID:
23 + case PHY_INTERFACE_MODE_SGMII:
26 if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
27 @@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
29 priv->rgmii_rx_delay[cpu_port_index] = delay;
32 - case PHY_INTERFACE_MODE_SGMII:
33 + /* Skip sgmii parsing for rgmii* mode */
34 + if (mode == PHY_INTERFACE_MODE_RGMII ||
35 + mode == PHY_INTERFACE_MODE_RGMII_ID ||
36 + mode == PHY_INTERFACE_MODE_RGMII_TXID ||
37 + mode == PHY_INTERFACE_MODE_RGMII_RXID)
40 if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
41 priv->sgmii_tx_clk_falling_edge = true;
43 @@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
47 +qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
53 + /* Delay can be declared in 3 different way.
54 + * Mode to rgmii and internal-delay standard binding defined
55 + * rgmii-id or rgmii-tx/rx phy mode set.
56 + * The parse logic set a delay different than 0 only when one
57 + * of the 3 different way is used. In all other case delay is
58 + * not enabled. With ID or TX/RXID delay is enabled and set
59 + * to the default and recommended value.
61 + if (priv->rgmii_tx_delay[cpu_port_index]) {
62 + delay = priv->rgmii_tx_delay[cpu_port_index];
64 + val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
65 + QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
68 + if (priv->rgmii_rx_delay[cpu_port_index]) {
69 + delay = priv->rgmii_rx_delay[cpu_port_index];
71 + val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
72 + QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
75 + /* Set RGMII delay based on the selected values */
76 + ret = qca8k_rmw(priv, reg,
77 + QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
78 + QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
79 + QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
80 + QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
83 + dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
84 + cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
88 qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
89 const struct phylink_link_state *state)
91 struct qca8k_priv *priv = ds->priv;
92 int cpu_port_index, ret;
93 - u32 reg, val, delay;
97 case 0: /* 1st CPU port */
98 @@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
99 case PHY_INTERFACE_MODE_RGMII_ID:
100 case PHY_INTERFACE_MODE_RGMII_TXID:
101 case PHY_INTERFACE_MODE_RGMII_RXID:
102 - val = QCA8K_PORT_PAD_RGMII_EN;
104 - /* Delay can be declared in 3 different way.
105 - * Mode to rgmii and internal-delay standard binding defined
106 - * rgmii-id or rgmii-tx/rx phy mode set.
107 - * The parse logic set a delay different than 0 only when one
108 - * of the 3 different way is used. In all other case delay is
109 - * not enabled. With ID or TX/RXID delay is enabled and set
110 - * to the default and recommended value.
112 - if (priv->rgmii_tx_delay[cpu_port_index]) {
113 - delay = priv->rgmii_tx_delay[cpu_port_index];
115 - val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
116 - QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
119 - if (priv->rgmii_rx_delay[cpu_port_index]) {
120 - delay = priv->rgmii_rx_delay[cpu_port_index];
122 - val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
123 - QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
125 + qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
127 - /* Set RGMII delay based on the selected values */
128 - qca8k_write(priv, reg, val);
129 + /* Configure rgmii delay */
130 + qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
132 /* QCA8337 requires to set rgmii rx delay for all ports.
133 * This is enabled through PORT5_PAD_CTRL for all ports,
134 @@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
135 QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
136 QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
139 + /* From original code is reported port instability as SGMII also
140 + * require delay set. Apply advised values here or take them from DT.
142 + if (state->interface == PHY_INTERFACE_MODE_SGMII)
143 + qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
147 dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
148 --- a/drivers/net/dsa/qca8k.h
149 +++ b/drivers/net/dsa/qca8k.h
151 #define QCA8K_REG_PORT5_PAD_CTRL 0x008
152 #define QCA8K_REG_PORT6_PAD_CTRL 0x00c
153 #define QCA8K_PORT_PAD_RGMII_EN BIT(26)
154 +#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
155 #define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22)
156 +#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
157 #define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20)
158 #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
159 #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)