[PATCH 3/8] net: dw_eth_qos: add support for Qualcomm SM8150 SoC
Sumit Garg
sumit.garg at linaro.org
Tue Mar 5 07:49:02 CET 2024
On Thu, 29 Feb 2024 at 19:53, Volodymyr Babchuk
<Volodymyr_Babchuk at 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_babchuk at 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
More information about the U-Boot
mailing list