Commit 06cd3d4b authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-stmmac-qcom-ethqos-enable-2-5g-ethernet-on-sa8775p-ride'

Bartosz Golaszewski says:

====================
net: stmmac: qcom-ethqos: enable 2.5G ethernet on sa8775p-ride

Here are the changes required to enable 2.5G ethernet on sa8775p-ride.
As advised by Andrew Lunn and Russell King, I am reusing the existing
stmmac infrastructure to enable the SGMII loopback and so I dropped the
patches adding new callbacks to the driver core. I also added more
details to the commit message and made sure the workaround is only
enabled on Rev 3 of the board (with AQR115C PHY). Also: dropped any
mentions of the OCSGMII mode.

v2: https://lore.kernel.org/20240627113948.25358-1-brgl@bgdev.pl
v1: https://lore.kernel.org/20240619184550.34524-1-brgl@bgdev.pl
====================

Link: https://patch.msgid.link/20240703181500.28491-1-brgl@bgdev.plSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 946b6c48 3c466d65
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define RGMII_IO_MACRO_CONFIG2 0x1C #define RGMII_IO_MACRO_CONFIG2 0x1C
#define RGMII_IO_MACRO_DEBUG1 0x20 #define RGMII_IO_MACRO_DEBUG1 0x20
#define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28
#define EMAC_WRAPPER_SGMII_PHY_CNTRL1 0xf4
/* RGMII_IO_MACRO_CONFIG fields */ /* RGMII_IO_MACRO_CONFIG fields */
#define RGMII_CONFIG_FUNC_CLK_EN BIT(30) #define RGMII_CONFIG_FUNC_CLK_EN BIT(30)
...@@ -79,6 +80,9 @@ ...@@ -79,6 +80,9 @@
#define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14)
#define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15)
/* EMAC_WRAPPER_SGMII_PHY_CNTRL1 bits */
#define SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN BIT(3)
#define SGMII_10M_RX_CLK_DVDR 0x31 #define SGMII_10M_RX_CLK_DVDR 0x31
struct ethqos_emac_por { struct ethqos_emac_por {
...@@ -95,6 +99,7 @@ struct ethqos_emac_driver_data { ...@@ -95,6 +99,7 @@ struct ethqos_emac_driver_data {
bool has_integrated_pcs; bool has_integrated_pcs;
u32 dma_addr_width; u32 dma_addr_width;
struct dwmac4_addrs dwmac4_addrs; struct dwmac4_addrs dwmac4_addrs;
bool needs_sgmii_loopback;
}; };
struct qcom_ethqos { struct qcom_ethqos {
...@@ -114,6 +119,7 @@ struct qcom_ethqos { ...@@ -114,6 +119,7 @@ struct qcom_ethqos {
unsigned int num_por; unsigned int num_por;
bool rgmii_config_loopback_en; bool rgmii_config_loopback_en;
bool has_emac_ge_3; bool has_emac_ge_3;
bool needs_sgmii_loopback;
}; };
static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
...@@ -191,8 +197,22 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed) ...@@ -191,8 +197,22 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed)
clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate); clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
} }
static void
qcom_ethqos_set_sgmii_loopback(struct qcom_ethqos *ethqos, bool enable)
{
if (!ethqos->needs_sgmii_loopback ||
ethqos->phy_mode != PHY_INTERFACE_MODE_2500BASEX)
return;
rgmii_updatel(ethqos,
SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN,
enable ? SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN : 0,
EMAC_WRAPPER_SGMII_PHY_CNTRL1);
}
static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos) static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos)
{ {
qcom_ethqos_set_sgmii_loopback(ethqos, true);
rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN, rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN,
RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG); RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG);
} }
...@@ -277,6 +297,7 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = { ...@@ -277,6 +297,7 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
.has_emac_ge_3 = true, .has_emac_ge_3 = true,
.link_clk_name = "phyaux", .link_clk_name = "phyaux",
.has_integrated_pcs = true, .has_integrated_pcs = true,
.needs_sgmii_loopback = true,
.dma_addr_width = 36, .dma_addr_width = 36,
.dwmac4_addrs = { .dwmac4_addrs = {
.dma_chan = 0x00008100, .dma_chan = 0x00008100,
...@@ -665,6 +686,14 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) ...@@ -665,6 +686,14 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
return val; return val;
} }
static void qcom_ethqos_speed_mode_2500(struct net_device *ndev, void *data)
{
struct stmmac_priv *priv = netdev_priv(ndev);
priv->plat->max_speed = 2500;
priv->plat->phy_interface = PHY_INTERFACE_MODE_2500BASEX;
}
static int ethqos_configure(struct qcom_ethqos *ethqos) static int ethqos_configure(struct qcom_ethqos *ethqos)
{ {
return ethqos->configure_func(ethqos); return ethqos->configure_func(ethqos);
...@@ -674,6 +703,7 @@ static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mo ...@@ -674,6 +703,7 @@ static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mo
{ {
struct qcom_ethqos *ethqos = priv; struct qcom_ethqos *ethqos = priv;
qcom_ethqos_set_sgmii_loopback(ethqos, false);
ethqos->speed = speed; ethqos->speed = speed;
ethqos_update_link_clk(ethqos, speed); ethqos_update_link_clk(ethqos, speed);
ethqos_configure(ethqos); ethqos_configure(ethqos);
...@@ -787,6 +817,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev) ...@@ -787,6 +817,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_TXID:
ethqos->configure_func = ethqos_configure_rgmii; ethqos->configure_func = ethqos_configure_rgmii;
break; break;
case PHY_INTERFACE_MODE_2500BASEX:
plat_dat->speed_mode_2500 = qcom_ethqos_speed_mode_2500;
fallthrough;
case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_SGMII:
ethqos->configure_func = ethqos_configure_sgmii; ethqos->configure_func = ethqos_configure_sgmii;
break; break;
...@@ -809,6 +842,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) ...@@ -809,6 +842,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->num_por = data->num_por; ethqos->num_por = data->num_por;
ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en; ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
ethqos->has_emac_ge_3 = data->has_emac_ge_3; ethqos->has_emac_ge_3 = data->has_emac_ge_3;
ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;
ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii"); ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
if (IS_ERR(ethqos->link_clk)) if (IS_ERR(ethqos->link_clk))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment