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

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.pl


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 946b6c48 3c466d65
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#define RGMII_IO_MACRO_CONFIG2		0x1C
#define RGMII_IO_MACRO_DEBUG1		0x20
#define EMAC_SYSTEM_LOW_POWER_DEBUG	0x28
#define EMAC_WRAPPER_SGMII_PHY_CNTRL1	0xf4

/* RGMII_IO_MACRO_CONFIG fields */
#define RGMII_CONFIG_FUNC_CLK_EN		BIT(30)
@@ -79,6 +80,9 @@
#define ETHQOS_MAC_CTRL_SPEED_MODE		BIT(14)
#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

struct ethqos_emac_por {
@@ -95,6 +99,7 @@ struct ethqos_emac_driver_data {
	bool has_integrated_pcs;
	u32 dma_addr_width;
	struct dwmac4_addrs dwmac4_addrs;
	bool needs_sgmii_loopback;
};

struct qcom_ethqos {
@@ -114,6 +119,7 @@ struct qcom_ethqos {
	unsigned int num_por;
	bool rgmii_config_loopback_en;
	bool has_emac_ge_3;
	bool needs_sgmii_loopback;
};

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)
	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)
{
	qcom_ethqos_set_sgmii_loopback(ethqos, true);
	rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN,
		      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 = {
	.has_emac_ge_3 = true,
	.link_clk_name = "phyaux",
	.has_integrated_pcs = true,
	.needs_sgmii_loopback = true,
	.dma_addr_width = 36,
	.dwmac4_addrs = {
		.dma_chan = 0x00008100,
@@ -665,6 +686,14 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
	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)
{
	return ethqos->configure_func(ethqos);
@@ -674,6 +703,7 @@ static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mo
{
	struct qcom_ethqos *ethqos = priv;

	qcom_ethqos_set_sgmii_loopback(ethqos, false);
	ethqos->speed = speed;
	ethqos_update_link_clk(ethqos, speed);
	ethqos_configure(ethqos);
@@ -787,6 +817,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
	case PHY_INTERFACE_MODE_RGMII_TXID:
		ethqos->configure_func = ethqos_configure_rgmii;
		break;
	case PHY_INTERFACE_MODE_2500BASEX:
		plat_dat->speed_mode_2500 = qcom_ethqos_speed_mode_2500;
		fallthrough;
	case PHY_INTERFACE_MODE_SGMII:
		ethqos->configure_func = ethqos_configure_sgmii;
		break;
@@ -809,6 +842,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
	ethqos->num_por = data->num_por;
	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
	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");
	if (IS_ERR(ethqos->link_clk))