]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: rswitch: Add Renesas R-Car X5H Ethernet Switch3 support
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Mon, 27 Oct 2025 16:45:42 +0000 (17:45 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Thu, 6 Nov 2025 19:08:37 +0000 (20:08 +0100)
Add support for the Renesas Ethernet Switch3 (RSW3) controller,
present in R-Car Gen5 SoCs such as R-Car X5H (R8A78000). The
hardware offset differences are handled via driver match data.

The driver newly detects whether the switch prot is connected
to xPCS or not, and if so, turns on MIOC bit 3. This is new on
R-Car X5H. GWCKSC register is also programmed only on X5H. The
rest of the operation is identical to RSwitch2.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Signed-off-by: Tam Nguyen <tam.nguyen.xa@renesas.com>
Signed-off-by: Phong Hoang <phong.hoang.wz@renesas.com>
Signed-off-by: Thanh Quan <thanh.quan.xn@renesas.com>
Signed-off-by: Hai Pham <hai.pham.ud@renesas.com>
drivers/net/Kconfig
drivers/net/rswitch.c

index 913670ce412a059485172e7129d51cb72ea96c28..544e302d600453153fffd09068e585b90a05efb7 100644 (file)
@@ -842,11 +842,12 @@ config GMAC_ROCKCHIP
 
 config RENESAS_ETHER_SWITCH
        bool "Renesas Ethernet Switch support"
-       depends on DM_ETH && R8A779F0
+       depends on DM_ETH && (R8A779F0 || R8A78000)
        select PHYLIB
        help
          This driver implements support for the Renesas Ethernet Switch
-         which is available on R-Car S4 SoC (r8a779f0).
+         which is available on R-Car S4 SoC (R8A779F0) and newer version
+         on R-Car X5H SoC (R8A78000).
 
 config RENESAS_RAVB
        bool "Renesas Ethernet AVB MAC"
index 54ecb95344fdd0909223e1f019156d3a45785e49..801c22bbdc7336bc4c83dfe846f4506c4c0b3b9d 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Driver for Renesas Ethernet RSwitch2 (Ethernet-TSN).
+ * Driver for Renesas Ethernet RSwitch2 and RSwitch3 (Ethernet-TSN).
  *
- * Copyright (C) 2021 Renesas Electronics Corporation
+ * Copyright (C) 2021-2025 Renesas Electronics Corporation
  *
  * Based on the Renesas Ethernet AVB driver.
  */
@@ -47,6 +47,7 @@
 #define GWMS                   0x0004
 #define GWMTIRM                        0x0100
 #define GWVCC                  0x0130
+#define GWCKSC                 0x013c
 #define GWTTFC                 0x0138
 #define GWDCBAC0               0x0194
 #define GWDCBAC1               0x0198
@@ -65,6 +66,7 @@
 /* List of RMAC registers (RMAC) */
 #define MPSM                   0x1000
 #define MPIC                   0x1004
+#define MIOC                   0x1010
 #define MRMAC0                 0x1084
 #define MRMAC1                 0x1088
 #define MRAFC                  0x108c
@@ -78,6 +80,9 @@
 #define MMIS0                  0x1210
 #define MMIS1                  0x1220
 
+/* MIOC */
+#define MIOC_BIT3_SET          BIT(3)
+
 /* COMA */
 #define RRC_RR                 BIT(0)
 #define RCEC_RCE               BIT(16)
@@ -180,6 +185,7 @@ enum rswitch_gwca_mode {
 #define GWDCC(i)               (GWDCCR + (i) * 0x04)
 #define        GWDCC_DQT               BIT(11)
 #define GWDCC_BALR             BIT(24)
+#define GWCKSC_USMFSPE         BIT(31)
 
 struct rswitch_etha_io {
        int                     index;
@@ -192,6 +198,7 @@ struct rswitch_etha {
        struct phy_device       *phydev;
        struct mii_dev          *bus;
        unsigned char           *enetaddr;
+       bool                    xpcs;
 };
 
 struct rswitch_gwca {
@@ -282,6 +289,7 @@ struct rswitch_drv_data {
        u8                      fwpbfcsdc_offset;
        u8                      cabpirm_offset;
        int                     ports;
+       bool                    is_rsw3;
 };
 
 static inline void rswitch_flush_dcache(u32 addr, u32 len)
@@ -764,6 +772,10 @@ static int rswitch_gwca_init(struct rswitch_port_priv *priv)
        writel(GWDCC_DQT | GWDCC_BALR, gwca->addr + GWDCC(RSWITCH_TX_CHAIN_INDEX));
        writel(GWDCC_BALR, gwca->addr + GWDCC(RSWITCH_RX_CHAIN_INDEX));
 
+       /* Enable Under Switch Minimum Frame Size Padding */
+       if (priv->drv_data->is_rsw3)
+               writel(GWCKSC_USMFSPE, gwca->addr + GWCKSC);
+
        ret = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
        if (ret)
                return ret;
@@ -813,6 +825,13 @@ static int rswitch_etha_init(struct rswitch_port_priv *priv)
 
        rswitch_rmac_init(etha);
 
+       if (etha->xpcs) {
+               if (etha_serdes->index >= 5 && etha_serdes->index <= 7)
+                       writel(MIOC_BIT3_SET, etha_serdes->addr + MIOC);
+               else
+                       printf("RSW: Invalid port %d\n", etha_serdes->index);
+       }
+
        ret = rswitch_etha_change_mode(priv, etha_serdes, EAMC_OPC_OPERATION);
        if (ret)
                return ret;
@@ -1037,6 +1056,11 @@ static int rswitch_port_probe(struct udevice *dev)
        if (ret)
                return ret;
 
+       if (priv->drv_data->is_rsw3) {
+               etha->xpcs = device_is_compatible(priv->serdes.dev,
+                                                 "renesas,r8a78000-ether-pcs");
+       }
+
        etha->enetaddr = pdata->enetaddr;
 
        etha->mii.index = dev_read_u32_default(dev, "reg", 0);
@@ -1207,8 +1231,22 @@ static const struct rswitch_drv_data r8a779f0_drv_data = {
        .cabpirm_offset = 0x0,
 };
 
+static const struct rswitch_drv_data r8a78000_drv_data = {
+       .ports          = 13,
+       .coma_offset    = 0x1c000,
+       .etha_offset    = 0x1d000,
+       .gwca_offset    = 0x37000,
+       .mpid_mdc_clk   = 0x060c0000,
+       .etha_incr      = 0x20,
+       .gwdcbac_offset = 0x50,
+       .fwpbfcsdc_offset = 0xfc,
+       .cabpirm_offset = 0x20,
+       .is_rsw3        = true,
+};
+
 static const struct udevice_id rswitch_ids[] = {
        { .compatible = "renesas,r8a779f0-ether-switch", .data = (ulong)&r8a779f0_drv_data },
+       { .compatible = "renesas,r8a78000-ether-switch3", .data = (ulong)&r8a78000_drv_data },
        { }
 };