Skip to content

Commit

Permalink
net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII
Browse files Browse the repository at this point in the history
Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
mode for 1G/100M/10M speed.
Added changes to configure serdes phy and mac based on link speed.
Changing serdes phy speed involves multiple register writes for
serdes block. To avoid redundant write operations only update serdes
phy when new speed is different.
For 2500 speed MAC PCS autoneg needs to disabled. Added changes to
disable MAC PCS autoneg if ANE parameter is not set.

Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com>
Tested-by: Abhishek Chauhan <quic_abchauha@quicinc.com> # sa8775p-ride
Reviewed-by: Abhishek Chauhan <quic_abchauha@quicinc.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sneh Shah authored and David S. Miller committed Feb 23, 2024
1 parent a4634aa commit a818bd1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
26 changes: 26 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct qcom_ethqos {
struct clk *link_clk;
struct phy *serdes_phy;
unsigned int speed;
int serdes_speed;
phy_interface_t phy_mode;

const struct ethqos_emac_por *por;
Expand Down Expand Up @@ -606,19 +607,39 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)
*/
static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
{
struct net_device *dev = platform_get_drvdata(ethqos->pdev);
struct stmmac_priv *priv = netdev_priv(dev);
int val;

val = readl(ethqos->mac_base + MAC_CTRL_REG);

switch (ethqos->speed) {
case SPEED_2500:
val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
RGMII_IO_MACRO_CONFIG2);
if (ethqos->serdes_speed != SPEED_2500)
phy_set_speed(ethqos->serdes_phy, SPEED_2500);
ethqos->serdes_speed = SPEED_2500;
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);
break;
case SPEED_1000:
val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
RGMII_IO_MACRO_CONFIG2);
if (ethqos->serdes_speed != SPEED_1000)
phy_set_speed(ethqos->serdes_phy, SPEED_1000);
ethqos->serdes_speed = SPEED_1000;
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
break;
case SPEED_100:
val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
if (ethqos->serdes_speed != SPEED_1000)
phy_set_speed(ethqos->serdes_phy, SPEED_1000);
ethqos->serdes_speed = SPEED_1000;
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
break;
case SPEED_10:
val |= ETHQOS_MAC_CTRL_PORT_SEL;
Expand All @@ -627,6 +648,10 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,
SGMII_10M_RX_CLK_DVDR),
RGMII_IO_MACRO_CONFIG);
if (ethqos->serdes_speed != SPEED_1000)
phy_set_speed(ethqos->serdes_phy, ethqos->speed);
ethqos->serdes_speed = SPEED_1000;
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
break;
}

Expand Down Expand Up @@ -799,6 +824,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
"Failed to get serdes phy\n");

ethqos->speed = SPEED_1000;
ethqos->serdes_speed = SPEED_1000;
ethqos_update_link_clk(ethqos, SPEED_1000);
ethqos_set_func_clk_en(ethqos);

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
/* Enable and restart the Auto-Negotiation */
if (ane)
value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
else
value &= ~GMAC_AN_CTRL_ANE;

/* In case of MAC-2-MAC connection, block is configured to operate
* according to MAC conf register.
Expand Down

0 comments on commit a818bd1

Please sign in to comment.