net: stmmac: starfive: Add jhb100 SGMII interface

Add jhb100 compatible and SGMII support. jhb100 soc contains
2 SGMII interfaces and integrated with serdes PHY. SGMII with
split TX/RX MAC clock and need to set 2.5M/25M/125M TX/RX clock
rate in 10M/100M/1000M speed mode.

Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Sai Krishna <saikrishnag@marvell.com>
Link: https://patch.msgid.link/20260527084108.121416-4-minda.chen@starfivetech.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Minda Chen 2026-05-27 16:41:07 +08:00 committed by Jakub Kicinski
parent 64772e4d06
commit 98182c7481

View File

@ -26,6 +26,7 @@ struct starfive_dwmac_data {
struct starfive_dwmac {
struct device *dev;
const struct starfive_dwmac_data *data;
struct clk *sgmii_rx;
};
static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
@ -68,6 +69,25 @@ static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
return 0;
}
static int stmmac_starfive_sgmii_set_clk_rate(void *bsp_priv, struct clk *clk_tx_i,
phy_interface_t __maybe_unused interface,
int speed)
{
struct starfive_dwmac *dwmac = bsp_priv;
long rate = rgmii_clock(speed);
int ret;
/* MAC clock rate the same as RGMII */
if (rate < 0)
return -EINVAL;
ret = clk_set_rate(clk_tx_i, rate);
if (ret)
return ret;
return clk_set_rate(dwmac->sgmii_rx, rate);
}
static int starfive_dwmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
@ -102,23 +122,34 @@ static int starfive_dwmac_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
"error getting gtx clock\n");
/* Generally, the rgmii_tx clock is provided by the internal clock,
* which needs to match the corresponding clock frequency according
* to different speeds. If the rgmii_tx clock is provided by the
* external rgmii_rxin, there is no need to configure the clock
* internally, because rgmii_rxin will be adaptively adjusted.
*/
if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate;
dwmac->dev = &pdev->dev;
plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP;
plat_dat->bsp_priv = dwmac;
plat_dat->dma_cfg->dche = true;
/* generic sgmii, 1000_BASEX not support yet */
if (plat_dat->phy_interface == PHY_INTERFACE_MODE_SGMII) {
dwmac->sgmii_rx = devm_clk_get_enabled(&pdev->dev, "sgmii_rx");
if (IS_ERR(dwmac->sgmii_rx))
return dev_err_probe(&pdev->dev,
PTR_ERR(dwmac->sgmii_rx),
"error getting sgmii rx clock\n");
plat_dat->set_clk_tx_rate = stmmac_starfive_sgmii_set_clk_rate;
} else {
/*
* Generally, the rgmii_tx clock is provided by the internal clock,
* which needs to match the corresponding clock frequency according
* to different speeds. If the rgmii_tx clock is provided by the
* external rgmii_rxin, there is no need to configure the clock
* internally, because rgmii_rxin will be adaptively adjusted.
*/
if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate;
err = starfive_dwmac_set_mode(plat_dat);
if (err)
return err;
err = starfive_dwmac_set_mode(plat_dat);
if (err)
return err;
}
plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP;
plat_dat->dma_cfg->dche = true;
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}