On Thu, 29 Feb 2024 at 19:53, Volodymyr Babchuk <volodymyr_babc...@epam.com> wrote: > > Add support for Qualcomm SM8150 SoC to the EQOS driver. SM8150 has two > main differences from already supported QCS404: it has another RGMII > configuration registers set and it does require RGMII loopback to > be disabled. > > To support different variants of QCOM SoC we had to add two new fields > to the eqos_priv struct: eqos_qcom_rgmii_regs and > qcom_enable_loopback. > > Signed-off-by: Volodymyr Babchuk <volodymyr_babc...@epam.com> > --- > > drivers/net/dwc_eth_qos.c | 4 +++ > drivers/net/dwc_eth_qos.h | 2 ++ > drivers/net/dwc_eth_qos_qcom.c | 47 +++++++++++++++++++++++++++------- > 3 files changed, 44 insertions(+), 9 deletions(-) > > diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c > index 9b3bce1dc8..882b854697 100644 > --- a/drivers/net/dwc_eth_qos.c > +++ b/drivers/net/dwc_eth_qos.c > @@ -1700,6 +1700,10 @@ static const struct udevice_id eqos_ids[] = { > .compatible = "qcom,qcs404-ethqos", > .data = (ulong)&eqos_qcom_config > }, > + { > + .compatible = "qcom,sm8150-ethqos", > + .data = (ulong)&eqos_qcom_config > + }, > #endif > #if IS_ENABLED(CONFIG_DWC_ETH_QOS_STARFIVE) > { > diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h > index e3222e1e17..216e1afe53 100644 > --- a/drivers/net/dwc_eth_qos.h > +++ b/drivers/net/dwc_eth_qos.h > @@ -255,6 +255,7 @@ struct eqos_priv { > struct eqos_dma_regs *dma_regs; > struct eqos_tegra186_regs *tegra186_regs; > void *eqos_qcom_rgmii_regs; > + struct dwmac_rgmii_regs *eqos_qcom_por; > struct reset_ctl reset_ctl; > struct gpio_desc phy_reset_gpio; > struct clk clk_master_bus; > @@ -277,6 +278,7 @@ struct eqos_priv { > bool started; > bool reg_access_ok; > bool clk_ck_enabled; > + bool qcom_enable_loopback; > unsigned int tx_fifo_sz, rx_fifo_sz; > u32 reset_delays[3]; > }; > diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c > index 8178138fc6..e9592ff686 100644 > --- a/drivers/net/dwc_eth_qos_qcom.c > +++ b/drivers/net/dwc_eth_qos_qcom.c > @@ -95,6 +95,15 @@ static struct dwmac_rgmii_regs emac_v2_3_0_por = { > .io_macro_config2 = 0x00002060 > }; > > +static struct dwmac_rgmii_regs emac_v2_1_0_por = { > + .io_macro_config = 0x40C01343, > + .sdcc_hc_dll_config = 0x2004642C, > + .sdcc_hc_ddr_config = 0x00000000, > + .sdcc_hc_dll_config2 = 0x00200000, > + .sdcc_usr_ctl = 0x00010800, > + .io_macro_config2 = 0x00002060 > +}; > + > static void ethqos_set_func_clk_en(struct dwmac_rgmii_regs *regs) > { > setbits_le32(®s->io_macro_config, RGMII_CONFIG_FUNC_CLK_EN); > @@ -172,6 +181,8 @@ static int ethqos_rgmii_macro_init(struct udevice *dev, > struct dwmac_rgmii_regs *regs, > unsigned long speed) > { > + struct eqos_priv *eqos = dev_get_priv(dev); > + > /* Disable loopback mode */ > clrbits_le32(®s->io_macro_config2, > RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN); > @@ -202,7 +213,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev, > SDCC_DDR_CONFIG_PRG_RCLK_DLY, 57); > setbits_le32(®s->sdcc_hc_ddr_config, > SDCC_DDR_CONFIG_PRG_DLY_EN); > > - setbits_le32(®s->io_macro_config, > RGMII_CONFIG_LOOPBACK_EN); > + if (eqos->qcom_enable_loopback) > + setbits_le32(®s->io_macro_config, > + RGMII_CONFIG_LOOPBACK_EN);
We should explicitly clear the loopback bit for the else part too. I suppose it can be written cleanly as below here and other places too: loopback = eqos->qcom_enable_loopback ? RGMII_CONFIG_LOOPBACK_EN : 0; clrsetbits_le32(®s->io_macro_config, RGMII_CONFIG_LOOPBACK_EN, loopback); -Sumit > break; > > case SPEED_100: > @@ -233,7 +246,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev, > setbits_le32(®s->sdcc_hc_ddr_config, > SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN); > > - setbits_le32(®s->io_macro_config, > RGMII_CONFIG_LOOPBACK_EN); > + if (eqos->qcom_enable_loopback) > + setbits_le32(®s->io_macro_config, > + RGMII_CONFIG_LOOPBACK_EN); > break; > > case SPEED_10: > @@ -265,7 +280,9 @@ static int ethqos_rgmii_macro_init(struct udevice *dev, > setbits_le32(®s->sdcc_hc_ddr_config, > SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN); > > - setbits_le32(®s->io_macro_config, > RGMII_CONFIG_LOOPBACK_EN); > + if (eqos->qcom_enable_loopback) > + setbits_le32(®s->io_macro_config, > + RGMII_CONFIG_LOOPBACK_EN); > break; > > default: > @@ -281,14 +298,15 @@ static int ethqos_configure(struct udevice *dev, > unsigned long speed) > { > unsigned int retry = 1000; > + struct eqos_priv *eqos = dev_get_priv(dev); > > /* Reset to POR values and enable clk */ > - writel(emac_v2_3_0_por.io_macro_config, ®s->io_macro_config); > - writel(emac_v2_3_0_por.sdcc_hc_dll_config, ®s->sdcc_hc_dll_config); > - writel(emac_v2_3_0_por.sdcc_hc_ddr_config, ®s->sdcc_hc_ddr_config); > - writel(emac_v2_3_0_por.sdcc_hc_dll_config2, > ®s->sdcc_hc_dll_config2); > - writel(emac_v2_3_0_por.sdcc_usr_ctl, ®s->sdcc_usr_ctl); > - writel(emac_v2_3_0_por.io_macro_config2, ®s->io_macro_config2); > + writel(eqos->eqos_qcom_por->io_macro_config, ®s->io_macro_config); > + writel(eqos->eqos_qcom_por->sdcc_hc_dll_config, > ®s->sdcc_hc_dll_config); > + writel(eqos->eqos_qcom_por->sdcc_hc_ddr_config, > ®s->sdcc_hc_ddr_config); > + writel(eqos->eqos_qcom_por->sdcc_hc_dll_config2, > ®s->sdcc_hc_dll_config2); > + writel(eqos->eqos_qcom_por->sdcc_usr_ctl, ®s->sdcc_usr_ctl); > + writel(eqos->eqos_qcom_por->io_macro_config2, > ®s->io_macro_config2); > > ethqos_set_func_clk_en(regs); > > @@ -565,6 +583,17 @@ static int eqos_probe_resources_qcom(struct udevice *dev) > return -EINVAL; > } > > + if (device_is_compatible(dev, "qcom,qcs404-ethqos")) { > + eqos->eqos_qcom_por = &emac_v2_3_0_por; > + eqos->qcom_enable_loopback = true; > + } else if (device_is_compatible(dev, "qcom,sm8150-ethqos")) { > + eqos->eqos_qcom_por = &emac_v2_1_0_por; > + eqos->qcom_enable_loopback = false; > + } else { > + pr_err("Unknown QCOM ethernet device\n"); > + return -EINVAL; > + } > + > debug("%s: OK\n", __func__); > return 0; > } > -- > 2.43.0