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...@bp.renesas.com>
---
 arch/arm/mach-renesas/Kconfig |  1 +
 drivers/net/Kconfig           |  2 +-
 drivers/net/ravb.c            | 57 +++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-renesas/Kconfig b/arch/arm/mach-renesas/Kconfig
index aeb55da609bd..d373ab56ce91 100644
--- a/arch/arm/mach-renesas/Kconfig
+++ b/arch/arm/mach-renesas/Kconfig
@@ -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
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3db784faedd3..157d330a9cce 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -864,7 +864,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"
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index ecf6e05f47eb..86aa5cd5835c 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -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)
@@ -65,14 +67,24 @@
 #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
@@ -385,6 +397,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)
 {
@@ -459,6 +481,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 =
@@ -501,6 +531,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);
@@ -740,6 +786,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",
@@ -749,6 +802,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,
+       },
        { }
 };
 
-- 
2.43.0

Reply via email to