mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 13:34:27 -04:00 
			
		
		
		
	The qca8k patch series brings the numbering to 799. This patch renames 7xx patches to create space for more backports to be added. Signed-off-by: Matthew Hagan <mnhagan88@gmail.com> [rename 729->719] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
		
			
				
	
	
		
			189 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From e4b9977cee1583da38a6e9118078bb728aaccf7b Mon Sep 17 00:00:00 2001
 | |
| From: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| Date: Fri, 14 May 2021 23:00:06 +0200
 | |
| Subject: [PATCH] net: dsa: qca8k: make rgmii delay configurable
 | |
| 
 | |
| The legacy qsdk code used a different delay instead of the max value.
 | |
| Qsdk use 1 ns for rx and 2 ns for tx. Make these values configurable
 | |
| using the standard rx/tx-internal-delay-ps ethernet binding and apply
 | |
| qsdk values by default. The connected gmac doesn't add any delay so no
 | |
| additional delay is added to tx/rx.
 | |
| On this switch the delay is actually in ns so value should be in the
 | |
| 1000 order. Any value converted from ps to ns by dividing it by 1000
 | |
| as the switch max value for delay is 3ns.
 | |
| 
 | |
| Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| ---
 | |
|  drivers/net/dsa/qca8k.c | 82 ++++++++++++++++++++++++++++++++++++++++-
 | |
|  drivers/net/dsa/qca8k.h | 11 +++---
 | |
|  2 files changed, 86 insertions(+), 7 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/dsa/qca8k.c
 | |
| +++ b/drivers/net/dsa/qca8k.c
 | |
| @@ -778,6 +778,68 @@ 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(struct dsa_switch *ds)
 | |
|  {
 | |
|  	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
 | |
| @@ -802,6 +864,10 @@ qca8k_setup(struct dsa_switch *ds)
 | |
|  	if (ret)
 | |
|  		return ret;
 | |
|  
 | |
| +	ret = qca8k_setup_of_rgmii_delay(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);
 | |
| @@ -970,6 +1036,8 @@ qca8k_phylink_mac_config(struct dsa_swit
 | |
|  	case 0: /* 1st CPU port */
 | |
|  		if (state->interface != PHY_INTERFACE_MODE_RGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_SGMII)
 | |
|  			return;
 | |
|  
 | |
| @@ -985,6 +1053,8 @@ qca8k_phylink_mac_config(struct dsa_swit
 | |
|  	case 6: /* 2nd CPU port / external PHY */
 | |
|  		if (state->interface != PHY_INTERFACE_MODE_RGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_SGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_1000BASEX)
 | |
|  			return;
 | |
| @@ -1008,14 +1078,18 @@ qca8k_phylink_mac_config(struct dsa_swit
 | |
|  		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
 | |
|  		 */
 | |
|  		qca8k_write(priv, reg,
 | |
|  			    QCA8K_PORT_PAD_RGMII_EN |
 | |
| -			    QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
 | |
| -			    QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
 | |
| +			    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,
 | |
| @@ -1073,6 +1147,8 @@ qca8k_phylink_validate(struct dsa_switch
 | |
|  		if (state->interface != PHY_INTERFACE_MODE_NA &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_SGMII)
 | |
|  			goto unsupported;
 | |
|  		break;
 | |
| @@ -1090,6 +1166,8 @@ qca8k_phylink_validate(struct dsa_switch
 | |
|  		if (state->interface != PHY_INTERFACE_MODE_NA &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
 | |
| +		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_SGMII &&
 | |
|  		    state->interface != PHY_INTERFACE_MODE_1000BASEX)
 | |
|  			goto unsupported;
 | |
| --- a/drivers/net/dsa/qca8k.h
 | |
| +++ b/drivers/net/dsa/qca8k.h
 | |
| @@ -38,12 +38,11 @@
 | |
|  #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(x)		\
 | |
| -						((0x8 + (x & 0x3)) << 22)
 | |
| -#define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)		\
 | |
| -						((0x10 + (x & 0x3)) << 20)
 | |
| -#define   QCA8K_MAX_DELAY				3
 | |
| +#define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)		((x) << 22)
 | |
| +#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)
 | |
| +#define   QCA8K_MAX_DELAY				3
 | |
|  #define   QCA8K_PORT_PAD_SGMII_EN			BIT(7)
 | |
|  #define QCA8K_REG_PWS					0x010
 | |
|  #define   QCA8K_PWS_SERDES_AEN_DIS			BIT(7)
 | |
| @@ -254,6 +253,8 @@ struct qca8k_match_data {
 | |
|  struct qca8k_priv {
 | |
|  	u8 switch_id;
 | |
|  	u8 switch_revision;
 | |
| +	u8 rgmii_tx_delay;
 | |
| +	u8 rgmii_rx_delay;
 | |
|  	struct regmap *regmap;
 | |
|  	struct mii_bus *bus;
 | |
|  	struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
 |