Hi,
On Wed, Sep 27, 2023 at 11:01:10AM +0800, Kever Yang wrote:
> On 2023/8/7 08:08, Jonas Karlman wrote:
> > Add rk_gmac_ops and other special handling that is needed for GMAC to
> > work on RK3588.
> >
> > rk_gmac_ops was ported from linux commits:
> > 2f2b60a0ec28 ("net: ethernet: stmmac: dwmac-rk: Add gmac support for
> > rk3588")
> > 88619e77b33d ("net: stmmac: rk3588: Allow multiple gmac controller")
> >
> > Signed-off-by: Jonas Karlman <[email protected]>
> Reviewed-by: Kever Yang <[email protected]>FWIW it's also Reviewed-by: <[email protected]> -- Sebastian > > Thanks, > - Kever > > --- > > Cc: David Wu <[email protected]> > > Cc: Sebastian Reichel <[email protected]> > > Cc: Benjamin Gaignard <[email protected]> > > --- > > drivers/net/dwc_eth_qos.c | 4 + > > drivers/net/dwc_eth_qos_rockchip.c | 182 ++++++++++++++++++++++++++++- > > 2 files changed, 182 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c > > index 9fb98a2c3c74..dc04416865dd 100644 > > --- a/drivers/net/dwc_eth_qos.c > > +++ b/drivers/net/dwc_eth_qos.c > > @@ -1712,6 +1712,10 @@ static const struct udevice_id eqos_ids[] = { > > .compatible = "rockchip,rk3568-gmac", > > .data = (ulong)&eqos_rockchip_config > > }, > > + { > > + .compatible = "rockchip,rk3588-gmac", > > + .data = (ulong)&eqos_rockchip_config > > + }, > > #endif > > #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM) > > { > > diff --git a/drivers/net/dwc_eth_qos_rockchip.c > > b/drivers/net/dwc_eth_qos_rockchip.c > > index c8abe351fc3e..34020496bde6 100644 > > --- a/drivers/net/dwc_eth_qos_rockchip.c > > +++ b/drivers/net/dwc_eth_qos_rockchip.c > > @@ -20,6 +20,7 @@ struct rk_gmac_ops { > > int tx_delay, int rx_delay); > > int (*set_to_rmii)(struct udevice *dev); > > int (*set_gmac_speed)(struct udevice *dev); > > + void (*set_clock_selection)(struct udevice *dev, bool enable); > > u32 regs[3]; > > }; > > @@ -27,7 +28,9 @@ struct rockchip_platform_data { > > struct reset_ctl_bulk resets; > > const struct rk_gmac_ops *ops; > > int id; > > + bool clock_input; > > struct regmap *grf; > > + struct regmap *php_grf; > > }; > > #define HIWORD_UPDATE(val, mask, shift) \ > > @@ -121,6 +124,137 @@ static int rk3568_set_gmac_speed(struct udevice *dev) > > return 0; > > } > > +/* sys_grf */ > > +#define RK3588_GRF_GMAC_CON7 0x031c > > +#define RK3588_GRF_GMAC_CON8 0x0320 > > +#define RK3588_GRF_GMAC_CON9 0x0324 > > + > > +#define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3) > > +#define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3) > > +#define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2) > > +#define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2) > > + > > +#define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, > > 0xFF, 8) > > +#define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, > > 0xFF, 0) > > + > > +/* php_grf */ > > +#define RK3588_GRF_GMAC_CON0 0x0008 > > +#define RK3588_GRF_CLK_CON1 0x0070 > > + > > +#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \ > > + (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + > > (id) * 6)) > > +#define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \ > > + (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + > > (id) * 6)) > > + > > +#define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id)) > > +#define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id)) > > + > > +#define RK3588_GMAC_CLK_SELET_CRU(id) GRF_BIT(5 * (id) + 4) > > +#define RK3588_GMAC_CLK_SELET_IO(id) GRF_CLR_BIT(5 * (id) + > > 4) > > + > > +#define RK3588_GMAC_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2) > > +#define RK3588_GMAC_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + > > 2) > > + > > +#define RK3588_GMAC_CLK_RGMII_DIV1(id) \ > > + (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3)) > > +#define RK3588_GMAC_CLK_RGMII_DIV5(id) \ > > + (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) > > +#define RK3588_GMAC_CLK_RGMII_DIV50(id) \ > > + (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) > > + > > +#define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1) > > +#define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + > > 1) > > + > > +static int rk3588_set_to_rgmii(struct udevice *dev, > > + int tx_delay, int rx_delay) > > +{ > > + struct eth_pdata *pdata = dev_get_plat(dev); > > + struct rockchip_platform_data *data = pdata->priv_pdata; > > + u32 offset_con, id = data->id; > > + > > + offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 : > > + RK3588_GRF_GMAC_CON8; > > + > > + regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0, > > + RK3588_GMAC_PHY_INTF_SEL_RGMII(id)); > > + > > + regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, > > + RK3588_GMAC_CLK_RGMII_MODE(id)); > > + > > + regmap_write(data->grf, RK3588_GRF_GMAC_CON7, > > + RK3588_GMAC_RXCLK_DLY_ENABLE(id) | > > + RK3588_GMAC_TXCLK_DLY_ENABLE(id)); > > + > > + regmap_write(data->grf, offset_con, > > + RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) | > > + RK3588_GMAC_CLK_TX_DL_CFG(tx_delay)); > > + > > + return 0; > > +} > > + > > +static int rk3588_set_to_rmii(struct udevice *dev) > > +{ > > + struct eth_pdata *pdata = dev_get_plat(dev); > > + struct rockchip_platform_data *data = pdata->priv_pdata; > > + > > + regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0, > > + RK3588_GMAC_PHY_INTF_SEL_RMII(data->id)); > > + > > + regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, > > + RK3588_GMAC_CLK_RMII_MODE(data->id)); > > + > > + return 0; > > +} > > + > > +static int rk3588_set_gmac_speed(struct udevice *dev) > > +{ > > + struct eqos_priv *eqos = dev_get_priv(dev); > > + struct eth_pdata *pdata = dev_get_plat(dev); > > + struct rockchip_platform_data *data = pdata->priv_pdata; > > + u32 val = 0, id = data->id; > > + > > + switch (eqos->phy->speed) { > > + case SPEED_10: > > + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) > > + val = RK3588_GMAC_CLK_RMII_DIV20(id); > > + else > > + val = RK3588_GMAC_CLK_RGMII_DIV50(id); > > + break; > > + case SPEED_100: > > + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) > > + val = RK3588_GMAC_CLK_RMII_DIV2(id); > > + else > > + val = RK3588_GMAC_CLK_RGMII_DIV5(id); > > + break; > > + case SPEED_1000: > > + if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII) > > + val = RK3588_GMAC_CLK_RGMII_DIV1(id); > > + else > > + return -EINVAL; > > + break; > > + default: > > + return -EINVAL; > > + } > > + > > + regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val); > > + > > + return 0; > > +} > > + > > +static void rk3588_set_clock_selection(struct udevice *dev, bool enable) > > +{ > > + struct eth_pdata *pdata = dev_get_plat(dev); > > + struct rockchip_platform_data *data = pdata->priv_pdata; > > + > > + u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) : > > + RK3588_GMAC_CLK_SELET_CRU(data->id); > > + > > + val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) : > > + RK3588_GMAC_CLK_RMII_GATE(data->id); > > + > > + regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val); > > +} > > + > > static const struct rk_gmac_ops rk_gmac_ops[] = { > > { > > .compatible = "rockchip,rk3568-gmac", > > @@ -133,6 +267,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = { > > 0x0, /* sentinel */ > > }, > > }, > > + { > > + .compatible = "rockchip,rk3588-gmac", > > + .set_to_rgmii = rk3588_set_to_rgmii, > > + .set_to_rmii = rk3588_set_to_rmii, > > + .set_gmac_speed = rk3588_set_gmac_speed, > > + .set_clock_selection = rk3588_set_clock_selection, > > + .regs = { > > + 0xfe1b0000, /* gmac0 */ > > + 0xfe1c0000, /* gmac1 */ > > + 0x0, /* sentinel */ > > + }, > > + }, > > { } > > }; > > @@ -154,6 +300,7 @@ static int eqos_probe_resources_rk(struct udevice *dev) > > struct eqos_priv *eqos = dev_get_priv(dev); > > struct eth_pdata *pdata = dev_get_plat(dev); > > struct rockchip_platform_data *data; > > + const char *clock_in_out; > > int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE; > > int ret; > > @@ -191,6 +338,16 @@ static int eqos_probe_resources_rk(struct udevice *dev) > > goto err_free; > > } > > + if (device_is_compatible(dev, "rockchip,rk3588-gmac")) { > > + data->php_grf = > > + syscon_regmap_lookup_by_phandle(dev, > > "rockchip,php-grf"); > > + if (IS_ERR(data->php_grf)) { > > + dev_err(dev, "Missing rockchip,php-grf property\n"); > > + ret = -EINVAL; > > + goto err_free; > > + } > > + } > > + > > ret = reset_get_bulk(dev, &data->resets); > > if (ret < 0) > > goto err_free; > > @@ -203,12 +360,20 @@ static int eqos_probe_resources_rk(struct udevice > > *dev) > > goto err_release_resets; > > } > > - ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx); > > - if (ret) { > > - dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret); > > - goto err_free_clk_master_bus; > > + if (device_is_compatible(dev, "rockchip,rk3568-gmac")) { > > + ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx); > > + if (ret) { > > + dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: > > %d", ret); > > + goto err_free_clk_master_bus; > > + } > > } > > + clock_in_out = dev_read_string(dev, "clock_in_out"); > > + if (clock_in_out && !strcmp(clock_in_out, "input")) > > + data->clock_input = true; > > + else > > + data->clock_input = false; > > + > > if (dev_read_bool(dev, "snps,reset-active-low")) > > reset_flags |= GPIOD_ACTIVE_LOW; > > @@ -264,6 +429,12 @@ static int eqos_start_resets_rk(struct udevice *dev) > > static int eqos_stop_clks_rk(struct udevice *dev) > > { > > + struct eth_pdata *pdata = dev_get_plat(dev); > > + struct rockchip_platform_data *data = pdata->priv_pdata; > > + > > + if (data->ops->set_clock_selection) > > + data->ops->set_clock_selection(dev, false); > > + > > return 0; > > } > > @@ -284,6 +455,9 @@ static int eqos_start_clks_rk(struct udevice *dev) > > udelay(eqos->reset_delays[2]); > > } > > + if (data->ops->set_clock_selection) > > + data->ops->set_clock_selection(dev, true); > > + > > tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30); > > rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
signature.asc
Description: PGP signature

