Commit 8e7e3d97 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-stmmac-cleanup-transmit-clock-setting'

Russell King says:

====================
net: stmmac: cleanup transmit clock setting

A lot of stmmac platform code which sets the transmit clock is very
similar - they decode the speed to the clock rate (125, 25 or 2.5 MHz)
and then set a clock to that rate.

The DWMAC core appears to have a clock input for the transmit section
called clk_tx_i which requires this rate.

This series moves the code which sets this clock into the core stmmac
code.

Patch 1 adds a hook that platforms can use to configure the clock rate.
Patch 2 adds a generic implementation.
The remainder of the patches convert the glue code for various platforms
to use this new infrastructure.
====================

Link: https://patch.msgid.link/Z8AtX-wyPal1auVO@shell.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 56794b58 945db208
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ struct tegra_eqos {

	struct reset_control *rst;
	struct clk *clk_slave;
	struct clk *clk_tx;

	struct gpio_desc *reset;
};
@@ -150,7 +149,6 @@ static void tegra_eqos_fix_speed(void *priv, int speed, unsigned int mode)
{
	struct tegra_eqos *eqos = priv;
	bool needs_calibration = false;
	long rate = 125000000;
	u32 value;
	int err;

@@ -161,7 +159,6 @@ static void tegra_eqos_fix_speed(void *priv, int speed, unsigned int mode)
		fallthrough;

	case SPEED_10:
		rate = rgmii_clock(speed);
		break;

	default:
@@ -208,10 +205,6 @@ static void tegra_eqos_fix_speed(void *priv, int speed, unsigned int mode)
		value &= ~AUTO_CAL_CONFIG_ENABLE;
		writel(value, eqos->regs + AUTO_CAL_CONFIG);
	}

	err = clk_set_rate(eqos->clk_tx, rate);
	if (err < 0)
		dev_err(eqos->dev, "failed to set TX rate: %d\n", err);
}

static int tegra_eqos_init(struct platform_device *pdev, void *priv)
@@ -247,7 +240,7 @@ static int tegra_eqos_probe(struct platform_device *pdev,
	if (!is_of_node(dev->fwnode))
		goto bypass_clk_reset_gpio;

	eqos->clk_tx = dwc_eth_find_clk(plat_dat, "tx");
	plat_dat->clk_tx_i = dwc_eth_find_clk(plat_dat, "tx");

	eqos->reset = devm_gpiod_get(&pdev->dev, "phy-reset", GPIOD_OUT_HIGH);
	if (IS_ERR(eqos->reset)) {
@@ -281,6 +274,7 @@ static int tegra_eqos_probe(struct platform_device *pdev,

bypass_clk_reset_gpio:
	plat_dat->fix_mac_speed = tegra_eqos_fix_speed;
	plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate;
	plat_dat->init = tegra_eqos_init;
	plat_dat->bsp_priv = eqos;
	plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
+19 −2
Original line number Diff line number Diff line
@@ -192,6 +192,19 @@ static void imx_dwmac_exit(struct platform_device *pdev, void *priv)
	/* nothing to do now */
}

static int imx_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
				     phy_interface_t interface, int speed)
{
	struct imx_priv_data *dwmac = bsp_priv;

	interface = dwmac->plat_dat->mac_interface;
	if (interface == PHY_INTERFACE_MODE_RMII ||
	    interface == PHY_INTERFACE_MODE_MII)
		return 0;

	return stmmac_set_clk_tx_rate(bsp_priv, clk_tx_i, interface, speed);
}

static void imx_dwmac_fix_speed(void *priv, int speed, unsigned int mode)
{
	struct plat_stmmacenet_data *plat_dat;
@@ -358,7 +371,6 @@ static int imx_dwmac_probe(struct platform_device *pdev)
	plat_dat->init = imx_dwmac_init;
	plat_dat->exit = imx_dwmac_exit;
	plat_dat->clks_config = imx_dwmac_clks_config;
	plat_dat->fix_mac_speed = imx_dwmac_fix_speed;
	plat_dat->bsp_priv = dwmac;
	dwmac->plat_dat = plat_dat;
	dwmac->base_addr = stmmac_res.addr;
@@ -371,8 +383,13 @@ static int imx_dwmac_probe(struct platform_device *pdev)
	if (ret)
		goto err_dwmac_init;

	if (dwmac->ops->fix_mac_speed)
	if (dwmac->ops->fix_mac_speed) {
		plat_dat->fix_mac_speed = dwmac->ops->fix_mac_speed;
	} else if (!dwmac->ops->mac_rgmii_txclk_auto_adj) {
		plat_dat->clk_tx_i = dwmac->clk_tx;
		plat_dat->set_clk_tx_rate = imx_dwmac_set_clk_tx_rate;
	}

	dwmac->plat_dat->fix_soc_reset = dwmac->ops->fix_soc_reset;

	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+3 −21
Original line number Diff line number Diff line
@@ -22,31 +22,12 @@ struct intel_dwmac {
};

struct intel_dwmac_data {
	void (*fix_mac_speed)(void *priv, int speed, unsigned int mode);
	unsigned long ptp_ref_clk_rate;
	unsigned long tx_clk_rate;
	bool tx_clk_en;
};

static void kmb_eth_fix_mac_speed(void *priv, int speed, unsigned int mode)
{
	struct intel_dwmac *dwmac = priv;
	long rate;
	int ret;

	rate = rgmii_clock(speed);
	if (rate < 0) {
		dev_err(dwmac->dev, "Invalid speed\n");
		return;
	}

	ret = clk_set_rate(dwmac->tx_clk, rate);
	if (ret)
		dev_err(dwmac->dev, "Failed to configure tx clock rate\n");
}

static const struct intel_dwmac_data kmb_data = {
	.fix_mac_speed = kmb_eth_fix_mac_speed,
	.ptp_ref_clk_rate = 200000000,
	.tx_clk_rate = 125000000,
	.tx_clk_en = true,
@@ -89,8 +70,6 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
	 * platform_match().
	 */
	dwmac->data = device_get_match_data(&pdev->dev);
	if (dwmac->data->fix_mac_speed)
		plat_dat->fix_mac_speed = dwmac->data->fix_mac_speed;

	/* Enable TX clock */
	if (dwmac->data->tx_clk_en) {
@@ -132,6 +111,9 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
		}
	}

	plat_dat->clk_tx_i = dwmac->tx_clk;
	plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate;

	plat_dat->bsp_priv = dwmac;
	plat_dat->eee_usecs_rate = plat_dat->clk_ptp_rate;

+5 −4
Original line number Diff line number Diff line
@@ -260,11 +260,12 @@ static int ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
	return PTR_ERR_OR_ZERO(gmac->qsgmii_csr);
}

static void ipq806x_gmac_fix_mac_speed(void *priv, int speed, unsigned int mode)
static int ipq806x_gmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
					phy_interface_t interface, int speed)
{
	struct ipq806x_gmac *gmac = priv;
	struct ipq806x_gmac *gmac = bsp_priv;

	ipq806x_gmac_set_speed(gmac, speed);
	return ipq806x_gmac_set_speed(gmac, speed);
}

static int
@@ -478,7 +479,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)

	plat_dat->has_gmac = true;
	plat_dat->bsp_priv = gmac;
	plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
	plat_dat->set_clk_tx_rate = ipq806x_gmac_set_clk_tx_rate;
	plat_dat->multicast_filter_bins = 0;
	plat_dat->tx_fifo_size = 8192;
	plat_dat->rx_fifo_size = 8192;
+6 −3
Original line number Diff line number Diff line
@@ -22,9 +22,10 @@ struct meson_dwmac {
	void __iomem	*reg;
};

static void meson6_dwmac_fix_mac_speed(void *priv, int speed, unsigned int mode)
static int meson6_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
					phy_interface_t interface, int speed)
{
	struct meson_dwmac *dwmac = priv;
	struct meson_dwmac *dwmac = bsp_priv;
	unsigned int val;

	val = readl(dwmac->reg);
@@ -39,6 +40,8 @@ static void meson6_dwmac_fix_mac_speed(void *priv, int speed, unsigned int mode)
	}

	writel(val, dwmac->reg);

	return 0;
}

static int meson6_dwmac_probe(struct platform_device *pdev)
@@ -65,7 +68,7 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
		return PTR_ERR(dwmac->reg);

	plat_dat->bsp_priv = dwmac;
	plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
	plat_dat->set_clk_tx_rate = meson6_dwmac_set_clk_tx_rate;

	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}
Loading