net: ravb: Add RZ/G2L Support
authorPaul Barker <paul.barker.ct@bp.renesas.com>
Wed, 19 Mar 2025 12:03:59 +0000 (12:03 +0000)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 4 May 2025 18:25:03 +0000 (20:25 +0200)
The Renesas R9A07G044L (RZ/G2L) SoC includes two Gigabit Ethernet
interfaces which can be supported using the ravb driver. Some RZ/G2L
specific steps need to be taken during initialization due to differences
between this SoC and previously supported SoCs. We also need to ensure
that the module reset is de-asserted after the module clock is enabled
but before any Ethernet register reads/writes take place.

Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
arch/arm/mach-renesas/Kconfig
drivers/net/Kconfig
drivers/net/ravb.c

index aeb55da..d373ab5 100644 (file)
@@ -76,6 +76,7 @@ config RZG2L
        imply MULTI_DTB_FIT
        imply MULTI_DTB_FIT_USER_DEFINED_AREA
        imply PINCTRL_RZG2L
+       imply RENESAS_RAVB
        imply RENESAS_SDHI
        imply RZG2L_GPIO
        imply SCIF_CONSOLE
index 4434d36..950ed0f 100644 (file)
@@ -860,7 +860,7 @@ config RENESAS_RAVB
        select PHY_ETHERNET_ID
        help
          This driver implements support for the Ethernet AVB block in
-         Renesas M3 and H3 SoCs.
+         several Renesas R-Car and RZ SoCs.
 
 config MPC8XX_FEC
        bool "Fast Ethernet Controller on MPC8XX"
index 43e95bc..6852886 100644 (file)
@@ -31,6 +31,7 @@
 #define RAVB_REG_CSR           0x00C
 #define RAVB_REG_APSR          0x08C
 #define RAVB_REG_RCR           0x090
+#define RAVB_REG_RTC           0x0B4
 #define RAVB_REG_TGC           0x300
 #define RAVB_REG_TCCR          0x304
 #define RAVB_REG_RIC0          0x360
@@ -44,6 +45,7 @@
 #define RAVB_REG_GECMR         0x5b0
 #define RAVB_REG_MAHR          0x5c0
 #define RAVB_REG_MALR          0x5c8
+#define RAVB_REG_CSR0          0x800
 
 #define CCC_OPC_CONFIG         BIT(0)
 #define CCC_OPC_OPERATION      BIT(1)
 #define PIR_MDC                        BIT(0)
 
 #define ECMR_TRCCM             BIT(26)
+#define ECMR_RCPT              BIT(25)
 #define ECMR_RZPF              BIT(20)
 #define ECMR_PFR               BIT(18)
 #define ECMR_RXF               BIT(17)
+#define ECMR_TXF               BIT(16)
 #define ECMR_RE                        BIT(6)
 #define ECMR_TE                        BIT(5)
 #define ECMR_DM                        BIT(1)
+#define ECMR_PRM               BIT(0)
 #define ECMR_CHG_DM            (ECMR_TRCCM | ECMR_RZPF | ECMR_PFR | ECMR_RXF)
 
+#define CSR0_RPE               BIT(5)
+#define CSR0_TPE               BIT(4)
+
+#define GECMR_SPEED_10M                (0 << 4)
+#define GECMR_SPEED_100M       (1 << 4)
+#define GECMR_SPEED_1G         (2 << 4)
+
 /* DMA Descriptors */
 #define RAVB_NUM_BASE_DESC             16
 #define RAVB_NUM_TX_DESC               8
@@ -384,6 +396,16 @@ static void ravb_mac_init_rcar(struct udevice *dev)
        writel(0, eth->iobase + RAVB_REG_ECSIPR);
 }
 
+static void ravb_mac_init_rzg2l(struct udevice *dev)
+{
+       struct ravb_priv *eth = dev_get_priv(dev);
+
+       setbits_32(eth->iobase + RAVB_REG_ECMR,
+                  ECMR_PRM | ECMR_RXF | ECMR_TXF | ECMR_RCPT |
+                  ECMR_TE | ECMR_RE | ECMR_RZPF |
+                  (eth->phydev->duplex ? ECMR_DM : 0));
+}
+
 /* AVB-DMAC init function */
 static int ravb_dmac_init(struct udevice *dev)
 {
@@ -458,6 +480,14 @@ static void ravb_dmac_init_rcar(struct udevice *dev)
        writel(mode, eth->iobase + RAVB_REG_APSR);
 }
 
+static void ravb_dmac_init_rzg2l(struct udevice *dev)
+{
+       struct ravb_priv *eth = dev_get_priv(dev);
+
+       /* Set Max Frame Length (RTC) */
+       writel(0x7ffc0000 | RFLR_RFL_MIN, eth->iobase + RAVB_REG_RTC);
+}
+
 static int ravb_config(struct udevice *dev)
 {
        struct ravb_device_ops *device_ops =
@@ -500,6 +530,22 @@ static void ravb_config_rcar(struct udevice *dev)
        writel(mask, eth->iobase + RAVB_REG_ECMR);
 }
 
+static void ravb_config_rzg2l(struct udevice *dev)
+{
+       struct ravb_priv *eth = dev_get_priv(dev);
+       struct phy_device *phy = eth->phydev;
+
+       writel(CSR0_TPE | CSR0_RPE, eth->iobase + RAVB_REG_CSR0);
+
+       /* Set the transfer speed */
+       if (phy->speed == 10)
+               writel(GECMR_SPEED_10M, eth->iobase + RAVB_REG_GECMR);
+       else if (phy->speed == 100)
+               writel(GECMR_SPEED_100M, eth->iobase + RAVB_REG_GECMR);
+       else if (phy->speed == 1000)
+               writel(GECMR_SPEED_1G, eth->iobase + RAVB_REG_GECMR);
+}
+
 static int ravb_start(struct udevice *dev)
 {
        struct ravb_priv *eth = dev_get_priv(dev);
@@ -739,6 +785,13 @@ static const struct ravb_device_ops ravb_device_ops_rcar = {
        .config = ravb_config_rcar,
 };
 
+static const struct ravb_device_ops ravb_device_ops_rzg2l = {
+       .mac_init = ravb_mac_init_rzg2l,
+       .dmac_init = ravb_dmac_init_rzg2l,
+       .config = ravb_config_rzg2l,
+       .has_reset = true,
+};
+
 static const struct udevice_id ravb_ids[] = {
        {
                .compatible = "renesas,etheravb-rcar-gen3",
@@ -748,6 +801,10 @@ static const struct udevice_id ravb_ids[] = {
                .compatible = "renesas,etheravb-rcar-gen4",
                .data = (ulong)&ravb_device_ops_rcar,
        },
+       {
+               .compatible = "renesas,rzg2l-gbeth",
+               .data = (ulong)&ravb_device_ops_rzg2l,
+       },
        { }
 };