Merge branch 'add-gbeth-glue-layer-driver-for-renesas-rz-v2h-p-soc'

Lad Prabhakar says:

====================
Add GBETH glue layer driver for Renesas RZ/V2H(P) SoC

This patch series adds support for the GBETH (Gigabit Ethernet) glue layer
driver for the Renesas RZ/V2H(P) SoC. The GBETH IP is integrated with
the Synopsys DesignWare MAC (version 5.20). The changes include updating
the device tree bindings, documenting the GBETH bindings, and adding the
DWMAC glue layer for the Renesas GBETH.

v1: https://lore.kernel.org/20250302181808.728734-1-prabhakar.mahadev-lad.rj@bp.renesas.com
====================

Link: https://patch.msgid.link/20250417084015.74154-1-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-04-22 18:49:26 -07:00
commit eff59eb102
6 changed files with 383 additions and 9 deletions

View File

@ -0,0 +1,201 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/renesas,r9a09g057-gbeth.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GBETH glue layer for Renesas RZ/V2H(P) (and similar SoCs)
maintainers:
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
select:
properties:
compatible:
contains:
enum:
- renesas,r9a09g057-gbeth
- renesas,rzv2h-gbeth
required:
- compatible
properties:
compatible:
items:
- enum:
- renesas,r9a09g057-gbeth # RZ/V2H(P)
- const: renesas,rzv2h-gbeth
- const: snps,dwmac-5.20
reg:
maxItems: 1
clocks:
items:
- description: CSR clock
- description: AXI system clock
- description: PTP clock
- description: TX clock
- description: RX clock
- description: TX clock phase-shifted by 180 degrees
- description: RX clock phase-shifted by 180 degrees
clock-names:
items:
- const: stmmaceth
- const: pclk
- const: ptp_ref
- const: tx
- const: rx
- const: tx-180
- const: rx-180
interrupts:
minItems: 11
interrupt-names:
items:
- const: macirq
- const: eth_wake_irq
- const: eth_lpi
- const: rx-queue-0
- const: rx-queue-1
- const: rx-queue-2
- const: rx-queue-3
- const: tx-queue-0
- const: tx-queue-1
- const: tx-queue-2
- const: tx-queue-3
resets:
items:
- description: AXI power-on system reset
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
- interrupt-names
- resets
allOf:
- $ref: snps,dwmac.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/renesas-cpg-mssr.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
ethernet@15c30000 {
compatible = "renesas,r9a09g057-gbeth", "renesas,rzv2h-gbeth", "snps,dwmac-5.20";
reg = <0x15c30000 0x10000>;
clocks = <&cpg CPG_MOD 0xbd>, <&cpg CPG_MOD 0xbc>,
<&ptp_clock>, <&cpg CPG_MOD 0xb8>,
<&cpg CPG_MOD 0xb9>, <&cpg CPG_MOD 0xba>,
<&cpg CPG_MOD 0xbb>;
clock-names = "stmmaceth", "pclk", "ptp_ref",
"tx", "rx", "tx-180", "rx-180";
resets = <&cpg 0xb0>;
interrupts = <GIC_SPI 765 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 767 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 766 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 772 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 773 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 774 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 745 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 768 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 769 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 770 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 771 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi",
"rx-queue-0", "rx-queue-1", "rx-queue-2",
"rx-queue-3", "tx-queue-0", "tx-queue-1",
"tx-queue-2", "tx-queue-3";
phy-mode = "rgmii-id";
snps,multicast-filter-bins = <256>;
snps,perfect-filter-entries = <128>;
rx-fifo-depth = <8192>;
tx-fifo-depth = <8192>;
snps,fixed-burst;
snps,force_thresh_dma_mode;
snps,axi-config = <&stmmac_axi_setup>;
snps,mtl-rx-config = <&mtl_rx_setup>;
snps,mtl-tx-config = <&mtl_tx_setup>;
snps,txpbl = <32>;
snps,rxpbl = <32>;
phy-handle = <&phy0>;
stmmac_axi_setup: stmmac-axi-config {
snps,lpi_en;
snps,wr_osr_lmt = <0xf>;
snps,rd_osr_lmt = <0xf>;
snps,blen = <16 8 4 0 0 0 0>;
};
mtl_rx_setup: rx-queues-config {
snps,rx-queues-to-use = <4>;
snps,rx-sched-sp;
queue0 {
snps,dcb-algorithm;
snps,priority = <0x1>;
snps,map-to-dma-channel = <0>;
};
queue1 {
snps,dcb-algorithm;
snps,priority = <0x2>;
snps,map-to-dma-channel = <1>;
};
queue2 {
snps,dcb-algorithm;
snps,priority = <0x4>;
snps,map-to-dma-channel = <2>;
};
queue3 {
snps,dcb-algorithm;
snps,priority = <0x8>;
snps,map-to-dma-channel = <3>;
};
};
mtl_tx_setup: tx-queues-config {
snps,tx-queues-to-use = <4>;
queue0 {
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,dcb-algorithm;
snps,priority = <0x1>;
};
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy0: ethernet-phy@0 {
reg = <0>;
};
};
};

View File

@ -75,6 +75,7 @@ properties:
- qcom,sm8150-ethqos
- renesas,r9a06g032-gmac
- renesas,rzn1-gmac
- renesas,rzv2h-gbeth
- rockchip,px30-gmac
- rockchip,rk3128-gmac
- rockchip,rk3228-gmac
@ -114,19 +115,25 @@ properties:
interrupts:
minItems: 1
items:
- description: Combined signal for various interrupt events
- description: The interrupt to manage the remote wake-up packet detection
- description: The interrupt that occurs when Rx exits the LPI state
- description: The interrupt that occurs when HW safety error triggered
maxItems: 11
interrupt-names:
minItems: 1
maxItems: 11
items:
- const: macirq
- enum: [eth_wake_irq, eth_lpi, sfty]
- enum: [eth_wake_irq, eth_lpi, sfty]
- enum: [eth_wake_irq, eth_lpi, sfty]
oneOf:
- description: Combined signal for various interrupt events
const: macirq
- description: The interrupt to manage the remote wake-up packet detection
const: eth_wake_irq
- description: The interrupt that occurs when Rx exits the LPI state
const: eth_lpi
- description: The interrupt that occurs when HW safety error triggered
const: sfty
- description: Per channel receive completion interrupt
pattern: '^rx-queue-[0-3]$'
- description: Per channel transmit completion interrupt
pattern: '^tx-queue-[0-3]$'
clocks:
minItems: 1

View File

@ -20626,6 +20626,14 @@ S: Maintained
F: Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
F: drivers/usb/gadget/udc/renesas_usbf.c
RENESAS RZ/V2H(P) DWMAC GBETH GLUE LAYER DRIVER
M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
L: netdev@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/net/renesas,r9a09g057-gbeth.yaml
F: drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
RENESAS RZ/V2M I2C DRIVER
M: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
L: linux-i2c@vger.kernel.org

View File

@ -131,6 +131,17 @@ config DWMAC_QCOM_ETHQOS
This selects the Qualcomm ETHQOS glue layer support for the
stmmac device driver.
config DWMAC_RENESAS_GBETH
tristate "Renesas RZ/V2H(P) GBETH support"
default ARCH_RENESAS
depends on OF && (ARCH_RENESAS || COMPILE_TEST)
help
Support for Gigabit Ethernet Interface (GBETH) on Renesas
RZ/V2H(P) SoCs.
This selects the Renesas RZ/V2H(P) Soc specific glue layer support
for the stmmac device driver.
config DWMAC_ROCKCHIP
tristate "Rockchip dwmac support"
default ARCH_ROCKCHIP

View File

@ -20,6 +20,7 @@ obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
obj-$(CONFIG_DWMAC_RENESAS_GBETH) += dwmac-renesas-gbeth.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
obj-$(CONFIG_DWMAC_RZN1) += dwmac-rzn1.o
obj-$(CONFIG_DWMAC_S32) += dwmac-s32.o

View File

@ -0,0 +1,146 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* dwmac-renesas-gbeth.c - DWMAC Specific Glue layer for Renesas GBETH
*
* The Rx and Tx clocks are supplied as follows for the GBETH IP.
*
* Rx / Tx
* -------+------------- on / off -------
* |
* | Rx-180 / Tx-180
* +---- not ---- on / off -------
*
* Copyright (C) 2025 Renesas Electronics Corporation
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include "stmmac_platform.h"
struct renesas_gbeth {
struct plat_stmmacenet_data *plat_dat;
struct reset_control *rstc;
struct device *dev;
};
static const char *const renesas_gbeth_clks[] = {
"tx", "tx-180", "rx", "rx-180",
};
static int renesas_gbeth_init(struct platform_device *pdev, void *priv)
{
struct plat_stmmacenet_data *plat_dat;
struct renesas_gbeth *gbeth = priv;
int ret;
plat_dat = gbeth->plat_dat;
ret = reset_control_deassert(gbeth->rstc);
if (ret) {
dev_err(gbeth->dev, "Reset deassert failed\n");
return ret;
}
ret = clk_bulk_prepare_enable(plat_dat->num_clks,
plat_dat->clks);
if (ret)
reset_control_assert(gbeth->rstc);
return ret;
}
static void renesas_gbeth_exit(struct platform_device *pdev, void *priv)
{
struct plat_stmmacenet_data *plat_dat;
struct renesas_gbeth *gbeth = priv;
int ret;
plat_dat = gbeth->plat_dat;
clk_bulk_disable_unprepare(plat_dat->num_clks, plat_dat->clks);
ret = reset_control_assert(gbeth->rstc);
if (ret)
dev_err(gbeth->dev, "Reset assert failed\n");
}
static int renesas_gbeth_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
struct device *dev = &pdev->dev;
struct renesas_gbeth *gbeth;
unsigned int i;
int err;
err = stmmac_get_platform_resources(pdev, &stmmac_res);
if (err)
return dev_err_probe(dev, err,
"failed to get resources\n");
plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
if (IS_ERR(plat_dat))
return dev_err_probe(dev, PTR_ERR(plat_dat),
"dt configuration failed\n");
gbeth = devm_kzalloc(dev, sizeof(*gbeth), GFP_KERNEL);
if (!gbeth)
return -ENOMEM;
plat_dat->num_clks = ARRAY_SIZE(renesas_gbeth_clks);
plat_dat->clks = devm_kcalloc(dev, plat_dat->num_clks,
sizeof(*plat_dat->clks), GFP_KERNEL);
if (!plat_dat->clks)
return -ENOMEM;
for (i = 0; i < plat_dat->num_clks; i++)
plat_dat->clks[i].id = renesas_gbeth_clks[i];
err = devm_clk_bulk_get(dev, plat_dat->num_clks, plat_dat->clks);
if (err < 0)
return err;
plat_dat->clk_tx_i = stmmac_pltfr_find_clk(plat_dat, "tx");
if (!plat_dat->clk_tx_i)
return dev_err_probe(dev, -EINVAL,
"error finding tx clock\n");
gbeth->rstc = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(gbeth->rstc))
return PTR_ERR(gbeth->rstc);
gbeth->dev = dev;
gbeth->plat_dat = plat_dat;
plat_dat->bsp_priv = gbeth;
plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate;
plat_dat->init = renesas_gbeth_init;
plat_dat->exit = renesas_gbeth_exit;
plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY |
STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP |
STMMAC_FLAG_SPH_DISABLE;
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
}
static const struct of_device_id renesas_gbeth_match[] = {
{ .compatible = "renesas,rzv2h-gbeth", },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, renesas_gbeth_match);
static struct platform_driver renesas_gbeth_driver = {
.probe = renesas_gbeth_probe,
.driver = {
.name = "renesas-gbeth",
.of_match_table = renesas_gbeth_match,
},
};
module_platform_driver(renesas_gbeth_driver);
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("Renesas GBETH DWMAC Specific Glue layer");
MODULE_LICENSE("GPL");