From: Ansuel Smith <ansuelsmth@gmail.com>
To: Andrew Lunn <andrew@lunn.ch>,
Vivien Didelot <vivien.didelot@gmail.com>,
Florian Fainelli <f.fainelli@gmail.com>,
Vladimir Oltean <olteanv@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Rob Herring <robh+dt@kernel.org>,
Russell King <linux@armlinux.org.uk>,
netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: Ansuel Smith <ansuelsmth@gmail.com>
Subject: [net-next PATCH v5 06/14] net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
Date: Mon, 11 Oct 2021 03:30:16 +0200 [thread overview]
Message-ID: <20211011013024.569-7-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20211011013024.569-1-ansuelsmth@gmail.com>
Future proof commit. This switch have 2 CPU port and one valid
configuration is first CPU port set to sgmii and second CPU port set to
regmii-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 generilize 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>
---
drivers/net/dsa/qca8k.c | 162 ++++++++++++++++++++--------------------
drivers/net/dsa/qca8k.h | 10 ++-
2 files changed, 87 insertions(+), 85 deletions(-)
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index de50116d483e..b1ce625e9324 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -888,68 +888,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv)
return 0;
}
-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)
{
@@ -996,10 +934,11 @@ static int qca8k_find_cpu_port(struct dsa_switch *ds)
static int
qca8k_parse_port_config(struct qca8k_priv *priv)
{
+ int port, cpu_port_index = 0;
struct device_node *port_dn;
phy_interface_t mode;
struct dsa_port *dp;
- int port;
+ u32 delay;
/* We have 2 CPU port. Check them */
for (port = 0; port < QCA8K_NUM_PORTS; port++) {
@@ -1009,14 +948,56 @@ qca8k_parse_port_config(struct qca8k_priv *priv)
dp = dsa_to_port(priv->ds, port);
port_dn = dp->dn;
+ cpu_port_index++;
of_get_phy_mode(port_dn, &mode);
- 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:
}
}
@@ -1054,10 +1035,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;
@@ -1224,8 +1201,8 @@ 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;
- u32 reg, val;
- int ret;
+ int cpu_port_index, ret;
+ u32 reg, val, delay;
switch (port) {
case 0: /* 1st CPU port */
@@ -1237,6 +1214,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
return;
reg = QCA8K_REG_PORT0_PAD_CTRL;
+ cpu_port_index = QCA8K_CPU_PORT0;
break;
case 1:
case 2:
@@ -1255,6 +1233,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
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);
@@ -1269,23 +1248,40 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
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);
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 781521e6a965..5eb0c890dfe4 100644
--- 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;
--
2.32.0
next prev parent reply other threads:[~2021-10-11 1:31 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-11 1:30 [net-next PATCH v5 00/14] Multiple improvement for qca8337 switch Ansuel Smith
2021-10-11 1:30 ` [net-next PATCH v5 01/14] net: dsa: qca8k: add mac_power_sel support Ansuel Smith
2021-10-11 1:47 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 02/14] dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties Ansuel Smith
2021-10-11 1:48 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 03/14] net: dsa: qca8k: add support for sgmii falling edge Ansuel Smith
2021-10-11 1:49 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 04/14] dt-bindings: net: dsa: qca8k: Document support for CPU port 6 Ansuel Smith
2021-10-11 1:50 ` Florian Fainelli
2021-10-11 2:02 ` Ansuel Smith
2021-10-11 1:30 ` [net-next PATCH v5 05/14] drivers: net: dsa: qca8k: add support for cpu " Ansuel Smith
2021-10-11 2:01 ` Florian Fainelli
2021-10-11 4:49 ` DENG Qingfang
2021-10-11 1:30 ` Ansuel Smith [this message]
2021-10-11 2:11 ` [net-next PATCH v5 06/14] net: dsa: qca8k: rework rgmii delay logic and scan " Florian Fainelli
2021-10-11 2:45 ` Florian Fainelli
2021-10-11 5:15 ` kernel test robot
2021-10-11 5:15 ` kernel test robot
2021-10-11 1:30 ` [net-next PATCH v5 07/14] dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll Ansuel Smith
2021-10-11 1:30 ` [net-next PATCH v5 08/14] net: dsa: qca8k: add explicit SGMII PLL enable Ansuel Smith
2021-10-11 2:46 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 09/14] dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding Ansuel Smith
2021-10-11 1:30 ` [net-next PATCH v5 10/14] drivers: net: dsa: qca8k: add support for pws config reg Ansuel Smith
2021-10-11 2:48 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 11/14] dt-bindings: net: dsa: qca8k: document support for qca8328 Ansuel Smith
2021-10-11 1:58 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 12/14] drivers: net: dsa: qca8k: add support for QCA8328 Ansuel Smith
2021-10-11 2:42 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 13/14] drivers: net: dsa: qca8k: set internal delay also for sgmii Ansuel Smith
2021-10-11 2:44 ` Florian Fainelli
2021-10-11 1:30 ` [net-next PATCH v5 14/14] drivers: net: dsa: qca8k: move port config to dedicated struct Ansuel Smith
2021-10-11 2:47 ` Florian Fainelli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211011013024.569-7-ansuelsmth@gmail.com \
--to=ansuelsmth@gmail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=f.fainelli@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=robh+dt@kernel.org \
--cc=vivien.didelot@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.