From: Jie Gan <jie.gan@oss.qualcomm.com>
To: Luo Jie <quic_luoj@quicinc.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Lei Wei <quic_leiwei@quicinc.com>,
Suruchi Agarwal <quic_suruchia@quicinc.com>,
Pavithra R <quic_pavir@quicinc.com>,
Simon Horman <horms@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
Kees Cook <kees@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>
Cc: linux-arm-msm@vger.kernel.org, netdev@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, linux-hardening@vger.kernel.org,
quic_kkumarcs@quicinc.com, quic_linchen@quicinc.com,
srinivas.kandagatla@linaro.org, bartosz.golaszewski@linaro.org,
john@phrozen.org
Subject: Re: [PATCH net-next v3 03/14] net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC
Date: Mon, 10 Feb 2025 10:12:37 +0800 [thread overview]
Message-ID: <58e05149-abc2-4cf4-a6e8-35380823d94a@oss.qualcomm.com> (raw)
In-Reply-To: <20250209-qcom_ipq_ppe-v3-3-453ea18d3271@quicinc.com>
On 2/9/2025 10:29 PM, Luo Jie wrote:
> The PPE (Packet Process Engine) hardware block is available
> on Qualcomm IPQ SoC that support PPE architecture, such as
> IPQ9574.
>
> The PPE in IPQ9574 includes six integrated ethernet MAC
> (for 6 PPE ports), buffer management, queue management and
> scheduler functions. The MACs can connect with the external
> PHY or switch devices using the UNIPHY PCS block available
> in the SoC.
>
> The PPE also includes various packet processing offload
> capabilities such as L3 routing and L2 bridging, VLAN and
> tunnel processing offload. It also includes Ethernet DMA
> function for transferring packets between ARM cores and
> PPE ethernet ports.
>
> This patch adds the base source files and Makefiles for
> the PPE driver such as platform driver registration,
> clock initialization, and PPE reset routines.
>
> Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
> ---
> drivers/net/ethernet/qualcomm/Kconfig | 15 ++
> drivers/net/ethernet/qualcomm/Makefile | 1 +
> drivers/net/ethernet/qualcomm/ppe/Makefile | 7 +
> drivers/net/ethernet/qualcomm/ppe/ppe.c | 218 +++++++++++++++++++++++++++++
> drivers/net/ethernet/qualcomm/ppe/ppe.h | 36 +++++
> 5 files changed, 277 insertions(+)
>
> diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
> index 9210ff360fdc..59931c4edbeb 100644
> --- a/drivers/net/ethernet/qualcomm/Kconfig
> +++ b/drivers/net/ethernet/qualcomm/Kconfig
> @@ -61,6 +61,21 @@ config QCOM_EMAC
> low power, Receive-Side Scaling (RSS), and IEEE 1588-2008
> Precision Clock Synchronization Protocol.
>
> +config QCOM_PPE
> + tristate "Qualcomm Technologies, Inc. PPE Ethernet support"
> + depends on HAS_IOMEM && OF
> + depends on COMMON_CLK
> + select REGMAP_MMIO
> + help
> + This driver supports the Qualcomm Technologies, Inc. packet
> + process engine (PPE) available with IPQ SoC. The PPE includes
> + the ethernet MACs, Ethernet DMA (EDMA) and switch core that
> + supports L3 flow offload, L2 switch function, RSS and tunnel
> + offload.
> +
> + To compile this driver as a module, choose M here. The module
> + will be called qcom-ppe.
> +
> source "drivers/net/ethernet/qualcomm/rmnet/Kconfig"
>
> endif # NET_VENDOR_QUALCOMM
> diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
> index 9250976dd884..166a59aea363 100644
> --- a/drivers/net/ethernet/qualcomm/Makefile
> +++ b/drivers/net/ethernet/qualcomm/Makefile
> @@ -11,4 +11,5 @@ qcauart-objs := qca_uart.o
>
> obj-y += emac/
>
> +obj-$(CONFIG_QCOM_PPE) += ppe/
> obj-$(CONFIG_RMNET) += rmnet/
> diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
> new file mode 100644
> index 000000000000..63d50d3b4f2e
> --- /dev/null
> +++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Makefile for the device driver of PPE (Packet Process Engine) in IPQ SoC
> +#
> +
> +obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
> +qcom-ppe-objs := ppe.o
> diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
> new file mode 100644
> index 000000000000..40da7d240594
> --- /dev/null
> +++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
> @@ -0,0 +1,218 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +/* PPE platform device probe, DTSI parser and PPE clock initializations. */
> +
> +#include <linux/clk.h>
> +#include <linux/interconnect.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include "ppe.h"
> +
> +#define PPE_PORT_MAX 8
> +#define PPE_CLK_RATE 353000000
> +
> +/* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0
> + * will be updated by the clock rate of PPE.
> + */
> +static const struct icc_bulk_data ppe_icc_data[] = {
> + {
> + .name = "ppe",
> + .avg_bw = 0,
> + .peak_bw = 0,
> + },
> + {
> + .name = "ppe_cfg",
> + .avg_bw = 0,
> + .peak_bw = 0,
> + },
> + {
> + .name = "qos_gen",
> + .avg_bw = 6000,
> + .peak_bw = 6000,
> + },
> + {
> + .name = "timeout_ref",
> + .avg_bw = 6000,
> + .peak_bw = 6000,
> + },
> + {
> + .name = "nssnoc_memnoc",
> + .avg_bw = 533333,
> + .peak_bw = 533333,
> + },
> + {
> + .name = "memnoc_nssnoc",
> + .avg_bw = 533333,
> + .peak_bw = 533333,
> + },
> + {
> + .name = "memnoc_nssnoc_1",
> + .avg_bw = 533333,
> + .peak_bw = 533333,
> + },
> +};
> +
> +static const struct regmap_range ppe_readable_ranges[] = {
> + regmap_reg_range(0x0, 0x1ff), /* Global */
> + regmap_reg_range(0x400, 0x5ff), /* LPI CSR */
> + regmap_reg_range(0x1000, 0x11ff), /* GMAC0 */
> + regmap_reg_range(0x1200, 0x13ff), /* GMAC1 */
> + regmap_reg_range(0x1400, 0x15ff), /* GMAC2 */
> + regmap_reg_range(0x1600, 0x17ff), /* GMAC3 */
> + regmap_reg_range(0x1800, 0x19ff), /* GMAC4 */
> + regmap_reg_range(0x1a00, 0x1bff), /* GMAC5 */
> + regmap_reg_range(0xb000, 0xefff), /* PRX CSR */
> + regmap_reg_range(0xf000, 0x1efff), /* IPE */
> + regmap_reg_range(0x20000, 0x5ffff), /* PTX CSR */
> + regmap_reg_range(0x60000, 0x9ffff), /* IPE L2 CSR */
> + regmap_reg_range(0xb0000, 0xeffff), /* IPO CSR */
> + regmap_reg_range(0x100000, 0x17ffff), /* IPE PC */
> + regmap_reg_range(0x180000, 0x1bffff), /* PRE IPO CSR */
> + regmap_reg_range(0x1d0000, 0x1dffff), /* Tunnel parser */
> + regmap_reg_range(0x1e0000, 0x1effff), /* Ingress parse */
> + regmap_reg_range(0x200000, 0x2fffff), /* IPE L3 */
> + regmap_reg_range(0x300000, 0x3fffff), /* IPE tunnel */
> + regmap_reg_range(0x400000, 0x4fffff), /* Scheduler */
> + regmap_reg_range(0x500000, 0x503fff), /* XGMAC0 */
> + regmap_reg_range(0x504000, 0x507fff), /* XGMAC1 */
> + regmap_reg_range(0x508000, 0x50bfff), /* XGMAC2 */
> + regmap_reg_range(0x50c000, 0x50ffff), /* XGMAC3 */
> + regmap_reg_range(0x510000, 0x513fff), /* XGMAC4 */
> + regmap_reg_range(0x514000, 0x517fff), /* XGMAC5 */
> + regmap_reg_range(0x600000, 0x6fffff), /* BM */
> + regmap_reg_range(0x800000, 0x9fffff), /* QM */
> + regmap_reg_range(0xb00000, 0xbef800), /* EDMA */
> +};
> +
> +static const struct regmap_access_table ppe_reg_table = {
> + .yes_ranges = ppe_readable_ranges,
> + .n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),
> +};
> +
> +static const struct regmap_config regmap_config_ipq9574 = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .rd_table = &ppe_reg_table,
> + .wr_table = &ppe_reg_table,
> + .max_register = 0xbef800,
> + .fast_io = true,
> +};
> +
> +static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
> +{
> + unsigned long ppe_rate = ppe_dev->clk_rate;
> + struct device *dev = ppe_dev->dev;
> + struct reset_control *rstc;
> + struct clk_bulk_data *clks;
> + struct clk *clk;
> + int ret, i;
> +
> + for (i = 0; i < ppe_dev->num_icc_paths; i++) {
> + ppe_dev->icc_paths[i].name = ppe_icc_data[i].name;
> + ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ? :
> + Bps_to_icc(ppe_rate);
it's ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ?
ppe_icc_data[i].avg_bw : Bps_to_icc(ppe_rate); ?
> + ppe_dev->icc_paths[i].peak_bw = ppe_icc_data[i].peak_bw ? :
> + Bps_to_icc(ppe_rate);
Same with previous one?
> + }
> +
> + ret = devm_of_icc_bulk_get(dev, ppe_dev->num_icc_paths,
> + ppe_dev->icc_paths);
> + if (ret)
> + return ret;
> +
> + ret = icc_bulk_set_bw(ppe_dev->num_icc_paths, ppe_dev->icc_paths);
> + if (ret)
> + return ret;
> +
> + /* The PPE clocks have a common parent clock. Setting the clock
Should be:
/*
* The PPE clocks have a common parent clock. Setting the clock
* rate of "ppe" ensures the clock rate of all PPE clocks is
* configured to the same rate.
*/
BTW, it's better wrapped with ~75 characters per line.
> + * rate of "ppe" ensures the clock rate of all PPE clocks is
> + * configured to the same rate.
> + */
> + clk = devm_clk_get(dev, "ppe");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + ret = clk_set_rate(clk, ppe_rate);
> + if (ret)
> + return ret;
> +
> + ret = devm_clk_bulk_get_all_enabled(dev, &clks);
> + if (ret < 0)
> + return ret;
> +
> + /* Reset the PPE. */
> + rstc = devm_reset_control_get_exclusive(dev, NULL);
> + if (IS_ERR(rstc))
> + return PTR_ERR(rstc);
> +
> + ret = reset_control_assert(rstc);
> + if (ret)
> + return ret;
> +
> + /* The delay 10 ms of assert is necessary for resetting PPE. */
> + usleep_range(10000, 11000);
> +
> + return reset_control_deassert(rstc);
> +}
> +
> +static int qcom_ppe_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct ppe_device *ppe_dev;
> + void __iomem *base;
> + int ret, num_icc;
I think it's better with:
int num_icc = ARRAY_SIZE(ppe_icc_data);
> +
> + num_icc = ARRAY_SIZE(ppe_icc_data);
> + ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc),
> + GFP_KERNEL);
> + if (!ppe_dev)
> + return -ENOMEM;
> +
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap failed\n");
> +
> + ppe_dev->regmap = devm_regmap_init_mmio(dev, base, ®map_config_ipq9574);
> + if (IS_ERR(ppe_dev->regmap))
> + return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap),
> + "PPE initialize regmap failed\n");
> + ppe_dev->dev = dev;
> + ppe_dev->clk_rate = PPE_CLK_RATE;
> + ppe_dev->num_ports = PPE_PORT_MAX;
> + ppe_dev->num_icc_paths = num_icc;
> +
> + ret = ppe_clock_init_and_reset(ppe_dev);
> + if (ret)
> + return dev_err_probe(dev, ret, "PPE clock config failed\n");
> +
> + platform_set_drvdata(pdev, ppe_dev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id qcom_ppe_of_match[] = {
> + { .compatible = "qcom,ipq9574-ppe" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);
> +
> +static struct platform_driver qcom_ppe_driver = {
> + .driver = {
> + .name = "qcom_ppe",
> + .of_match_table = qcom_ppe_of_match,
> + },
> + .probe = qcom_ppe_probe,
> +};
> +module_platform_driver(qcom_ppe_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ PPE driver");
> diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h
> new file mode 100644
> index 000000000000..cc6767b7c2b8
> --- /dev/null
> +++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: GPL-2.0-only
> + *
> + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef __PPE_H__
> +#define __PPE_H__
> +
> +#include <linux/compiler.h>
> +#include <linux/interconnect.h>
> +
> +struct device;
#include <linux/device.h> ?
> +struct regmap;
Same with previous one, include it's header file?
> +
> +/**
> + * struct ppe_device - PPE device private data.
> + * @dev: PPE device structure.
> + * @regmap: PPE register map.
> + * @clk_rate: PPE clock rate.
> + * @num_ports: Number of PPE ports.
> + * @num_icc_paths: Number of interconnect paths.
> + * @icc_paths: Interconnect path array.
> + *
> + * PPE device is the instance of PPE hardware, which is used to
> + * configure PPE packet process modules such as BM (buffer management),
> + * QM (queue management), and scheduler.
> + */
> +struct ppe_device {
> + struct device *dev;
> + struct regmap *regmap;
> + unsigned long clk_rate;
> + unsigned int num_ports;
> + unsigned int num_icc_paths;
> + struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
> +};
> +#endif
>
Thanks,
Jie
next prev parent reply other threads:[~2025-02-10 2:23 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-09 14:29 [PATCH net-next v3 00/14] Add PPE driver for Qualcomm IPQ9574 SoC Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 01/14] dt-bindings: net: Add PPE " Luo Jie
2025-02-10 2:47 ` Jie Gan
2025-02-11 14:02 ` Jie Luo
2025-02-09 14:29 ` [PATCH net-next v3 02/14] docs: networking: Add PPE driver documentation " Luo Jie
2025-02-10 2:15 ` Bagas Sanjaya
2025-02-11 12:36 ` Lei Wei
2025-02-09 14:29 ` [PATCH net-next v3 03/14] net: ethernet: qualcomm: Add PPE driver for " Luo Jie
2025-02-10 2:12 ` Jie Gan [this message]
2025-02-11 13:04 ` Andrew Lunn
2025-02-12 1:49 ` Jie Gan
2025-02-11 13:58 ` Jie Luo
2025-02-12 1:58 ` Jie Gan
2025-02-14 6:09 ` Jie Luo
2025-02-09 14:29 ` [PATCH net-next v3 04/14] net: ethernet: qualcomm: Initialize PPE buffer management for IPQ9574 Luo Jie
2025-02-11 13:14 ` Andrew Lunn
2025-02-19 13:00 ` Jie Luo
2025-02-11 13:22 ` Andrew Lunn
2025-02-20 14:38 ` Jie Luo
2025-02-20 15:09 ` Andrew Lunn
2025-03-06 10:01 ` Jie Luo
2025-03-06 15:29 ` Andrew Lunn
2025-03-11 10:44 ` Jie Luo
2025-02-09 14:29 ` [PATCH net-next v3 05/14] net: ethernet: qualcomm: Initialize PPE queue " Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 06/14] net: ethernet: qualcomm: Initialize the PPE scheduler settings Luo Jie
2025-02-11 13:32 ` Andrew Lunn
2025-02-20 14:50 ` Jie Luo
2025-02-20 15:12 ` Andrew Lunn
2025-02-28 15:24 ` Jie Luo
2025-02-09 14:29 ` [PATCH net-next v3 07/14] net: ethernet: qualcomm: Initialize PPE queue settings Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 08/14] net: ethernet: qualcomm: Initialize PPE service code settings Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 09/14] net: ethernet: qualcomm: Initialize PPE port control settings Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 10/14] net: ethernet: qualcomm: Initialize PPE RSS hash settings Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 11/14] net: ethernet: qualcomm: Initialize PPE queue to Ethernet DMA ring mapping Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 12/14] net: ethernet: qualcomm: Initialize PPE L2 bridge settings Luo Jie
2025-02-09 14:29 ` [PATCH net-next v3 13/14] net: ethernet: qualcomm: Add PPE debugfs support for PPE counters Luo Jie
2025-02-11 13:55 ` Andrew Lunn
2025-02-14 7:53 ` Jie Luo
2025-02-14 14:02 ` Andrew Lunn
2025-02-18 11:16 ` Jie Luo
2025-02-09 14:29 ` [PATCH net-next v3 14/14] MAINTAINERS: Add maintainer for Qualcomm PPE driver Luo Jie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=58e05149-abc2-4cf4-a6e8-35380823d94a@oss.qualcomm.com \
--to=jie.gan@oss.qualcomm.com \
--cc=andrew+netdev@lunn.ch \
--cc=bartosz.golaszewski@linaro.org \
--cc=conor+dt@kernel.org \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=gustavoars@kernel.org \
--cc=horms@kernel.org \
--cc=john@phrozen.org \
--cc=kees@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=pabeni@redhat.com \
--cc=quic_kkumarcs@quicinc.com \
--cc=quic_leiwei@quicinc.com \
--cc=quic_linchen@quicinc.com \
--cc=quic_luoj@quicinc.com \
--cc=quic_pavir@quicinc.com \
--cc=quic_suruchia@quicinc.com \
--cc=robh@kernel.org \
--cc=srinivas.kandagatla@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox