[PATCH 3/8] net: dw_eth_qos: add support for Qualcomm SM8150 SoC
Volodymyr Babchuk
Volodymyr_Babchuk at epam.com
Thu Feb 29 15:21:07 CET 2024
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);
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