[PATCH v5-S3 13/14] drivers: bus/fslmc provide shared DPRTC RTC services
Prashant Gupta
prashant.gupta_3 at nxp.com
Fri Oct 30 06:20:15 CET 2026
From: Jun Yang <jun.yang at nxp.com>
Introduce shared DPRTC RTC services in the fslmc bus layer.
Move the DPRTC MC driver and object management code from the
DPAA2 Ethernet PMD into bus/fslmc. Add bus-level APIs for DPRTC
allocation, release, time read and time update operations.
The fslmc bus acquires a DPRTC handle during initialization and
exposes it through rte_fslmc_bus_info. DPAA2 PTP operations are
updated to use these bus services instead of managing a private
DPRTC instance.
This centralizes DPRTC ownership and enables RTC functionality
to be shared by FSLMC-based drivers.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
drivers/bus/fslmc/bus_fslmc_driver.h | 1 +
drivers/bus/fslmc/fslmc_bus.c | 7 +
drivers/bus/fslmc/fslmc_vfio.c | 10 ++
drivers/{net/dpaa2 => bus/fslmc}/mc/dprtc.c | 0
.../{net/dpaa2 => bus/fslmc}/mc/fsl_dprtc.h | 0
.../dpaa2 => bus/fslmc}/mc/fsl_dprtc_cmd.h | 0
drivers/bus/fslmc/meson.build | 2 +
drivers/bus/fslmc/portal/dpaa2_hw_dprtc.c | 131 ++++++++++++++++++
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 18 +++
drivers/bus/fslmc/private.h | 5 +-
drivers/net/dpaa2/dpaa2_ethdev.c | 1 +
drivers/net/dpaa2/dpaa2_ethdev.h | 1 +
drivers/net/dpaa2/dpaa2_ptp.c | 96 +++----------
drivers/net/dpaa2/meson.build | 1 -
14 files changed, 192 insertions(+), 81 deletions(-)
rename drivers/{net/dpaa2 => bus/fslmc}/mc/dprtc.c (100%)
rename drivers/{net/dpaa2 => bus/fslmc}/mc/fsl_dprtc.h (100%)
rename drivers/{net/dpaa2 => bus/fslmc}/mc/fsl_dprtc_cmd.h (100%)
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dprtc.c
diff --git a/drivers/bus/fslmc/bus_fslmc_driver.h b/drivers/bus/fslmc/bus_fslmc_driver.h
index 1cef0d7b4b..73d7f9abf1 100644
--- a/drivers/bus/fslmc/bus_fslmc_driver.h
+++ b/drivers/bus/fslmc/bus_fslmc_driver.h
@@ -90,6 +90,7 @@ enum rte_dpaa2_dev_type {
};
struct rte_fslmc_bus_info {
+ void *rtc_handle;
int sp_protocol;
uint64_t mc_rev;
uint32_t svr;
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index cb88333c68..477f765a67 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -640,6 +640,9 @@ fslmc_bus_process_iodevices(void)
}
}
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ fslmc_bus_info.rtc_handle = fslmc_vfio_get_rtc_handle();
+
return 0;
}
@@ -710,6 +713,10 @@ fslmc_bus_close_group(void)
{
struct rte_dpaa2_device *dev;
+ if (fslmc_bus_info.rtc_handle)
+ fslmc_vfio_put_rtc_handle(fslmc_bus_info.rtc_handle);
+ fslmc_bus_info.rtc_handle = NULL;
+
RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus) {
if (dev->device.devargs &&
dev->device.devargs->policy == RTE_DEV_BLOCKED) {
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 58e33c6866..40bcd51153 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -1783,3 +1783,13 @@ fslmc_vfio_setup_group(void)
return 0;
}
+
+void *fslmc_vfio_get_rtc_handle(void)
+{
+ return rte_dpaa2_alloc_dprtc_dev();
+}
+
+void fslmc_vfio_put_rtc_handle(void *rtc_handle)
+{
+ rte_dpaa2_free_dprtc_dev(rtc_handle);
+}
diff --git a/drivers/net/dpaa2/mc/dprtc.c b/drivers/bus/fslmc/mc/dprtc.c
similarity index 100%
rename from drivers/net/dpaa2/mc/dprtc.c
rename to drivers/bus/fslmc/mc/dprtc.c
diff --git a/drivers/net/dpaa2/mc/fsl_dprtc.h b/drivers/bus/fslmc/mc/fsl_dprtc.h
similarity index 100%
rename from drivers/net/dpaa2/mc/fsl_dprtc.h
rename to drivers/bus/fslmc/mc/fsl_dprtc.h
diff --git a/drivers/net/dpaa2/mc/fsl_dprtc_cmd.h b/drivers/bus/fslmc/mc/fsl_dprtc_cmd.h
similarity index 100%
rename from drivers/net/dpaa2/mc/fsl_dprtc_cmd.h
rename to drivers/bus/fslmc/mc/fsl_dprtc_cmd.h
diff --git a/drivers/bus/fslmc/meson.build b/drivers/bus/fslmc/meson.build
index 50d9e91a37..67379432a0 100644
--- a/drivers/bus/fslmc/meson.build
+++ b/drivers/bus/fslmc/meson.build
@@ -19,12 +19,14 @@ sources = files(
'mc/dpio.c',
'mc/dpmng.c',
'mc/dprc.c',
+ 'mc/dprtc.c',
'mc/mc_sys.c',
'portal/dpaa2_hw_dpbp.c',
'portal/dpaa2_hw_dpci.c',
'portal/dpaa2_hw_dpcon.c',
'portal/dpaa2_hw_dpio.c',
'portal/dpaa2_hw_dprc.c',
+ 'portal/dpaa2_hw_dprtc.c',
'qbman/qbman_portal.c',
'qbman/qbman_debug.c',
)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dprtc.c b/drivers/bus/fslmc/portal/dpaa2_hw_dprtc.c
new file mode 100644
index 0000000000..13c9385e45
--- /dev/null
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dprtc.c
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright 2026 NXP
+ *
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <eal_export.h>
+#include <rte_malloc.h>
+#include <dev_driver.h>
+
+#include "private.h"
+#include <fslmc_logs.h>
+#include <mc/fsl_dprtc.h>
+#include "portal/dpaa2_hw_pvt.h"
+
+TAILQ_HEAD(dprtc_dev_list, dpaa2_dprtc_dev);
+static struct dprtc_dev_list dprtc_dev_list
+ = TAILQ_HEAD_INITIALIZER(dprtc_dev_list); /*!< DPRTC device list */
+
+RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_alloc_dprtc_dev)
+struct dpaa2_dprtc_dev *rte_dpaa2_alloc_dprtc_dev(void)
+{
+ struct dpaa2_dprtc_dev *dprtc_dev = NULL;
+ uint16_t expected;
+
+ /* Get DPCI dev handle from list using index */
+ TAILQ_FOREACH(dprtc_dev, &dprtc_dev_list, next) {
+ expected = 0;
+ if (rte_atomic_compare_exchange_strong_explicit(&dprtc_dev->in_use,
+ &expected, 1, rte_memory_order_acquire,
+ rte_memory_order_relaxed))
+ break;
+ }
+
+ return dprtc_dev;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_dprtc_set_time)
+int rte_dpaa2_dprtc_set_time(struct dpaa2_dprtc_dev *dprtc, uint64_t ns)
+{
+ int ret;
+
+ ret = dprtc_set_time(&dprtc->dprtc, CMD_PRI_LOW, dprtc->token, ns);
+ if (ret)
+ DPAA2_BUS_ERR("dprtc_set_time failed ret: %d", ret);
+
+ return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_dprtc_get_time)
+int rte_dpaa2_dprtc_get_time(struct dpaa2_dprtc_dev *dprtc, uint64_t *ns)
+{
+ int ret;
+
+ ret = dprtc_get_time(&dprtc->dprtc, CMD_PRI_LOW, dprtc->token, ns);
+ if (ret)
+ DPAA2_BUS_ERR("dprtc_get_time failed ret: %d", ret);
+
+ return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_free_dprtc_dev)
+void rte_dpaa2_free_dprtc_dev(struct dpaa2_dprtc_dev *dprtc)
+{
+ struct dpaa2_dprtc_dev *dprtc_dev = NULL;
+
+ /* Match DPCI handle and mark it free */
+ TAILQ_FOREACH(dprtc_dev, &dprtc_dev_list, next) {
+ if (dprtc_dev == dprtc) {
+ rte_atomic_store_explicit(&dprtc_dev->in_use, 0,
+ rte_memory_order_release);
+ return;
+ }
+ }
+}
+
+static int
+dpaa2_create_dprtc_device(int vdev_fd __rte_unused,
+ struct vfio_device_info *obj_info __rte_unused,
+ struct rte_dpaa2_device *obj)
+{
+ struct dpaa2_dprtc_dev *dprtc_dev;
+ struct dprtc_attr attr;
+ int ret = 0, dprtc_id = obj->object_id;
+
+ /* Allocate DPAA2 dprtc handle */
+ dprtc_dev = rte_zmalloc(NULL, sizeof(struct dpaa2_dprtc_dev), 0);
+ if (!dprtc_dev) {
+ DPAA2_BUS_ERR("Memory allocation failed for DPRTC Device");
+ return -ENOMEM;
+ }
+
+ /* Open the dprtc object */
+ dprtc_dev->dprtc.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
+ ret = dprtc_open(&dprtc_dev->dprtc, CMD_PRI_LOW, dprtc_id,
+ &dprtc_dev->token);
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to open dprtc object: err(%d)", ret);
+ goto init_err;
+ }
+
+ ret = dprtc_get_attributes(&dprtc_dev->dprtc, CMD_PRI_LOW,
+ dprtc_dev->token, &attr);
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to get dprtc attr: err(%d)", ret);
+ goto init_err;
+ }
+
+ dprtc_dev->dprtc_id = dprtc_id;
+
+ TAILQ_INSERT_TAIL(&dprtc_dev_list, dprtc_dev, next);
+
+ return 0;
+
+init_err:
+ rte_free(dprtc_dev);
+
+ return ret;
+}
+
+static struct rte_dpaa2_object rte_dpaa2_dprtc_obj = {
+ .dev_type = DPAA2_DPRTC,
+ .create = dpaa2_create_dprtc_device,
+};
+
+RTE_PMD_REGISTER_DPAA2_OBJECT(dprtc, rte_dpaa2_dprtc_obj);
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index 2250c8db6e..502cf5eeb5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -284,6 +284,15 @@ struct dpaa2_dpcon_dev {
uint8_t channel_index;
};
+struct dpaa2_dprtc_dev {
+ TAILQ_ENTRY(dpaa2_dprtc_dev) next;
+ struct fsl_mc_io dprtc;
+ uint16_t token;
+ uint32_t dprtc_id;
+
+ RTE_ATOMIC(uint16_t) in_use;
+};
+
/* DPCON channel pool, shared by the net rx-interrupt path and the event PMD */
__rte_internal
struct dpaa2_dpcon_dev *rte_dpaa2_alloc_dpcon_dev(void);
@@ -568,6 +577,15 @@ void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp);
__rte_internal
int dpaa2_dpbp_supported(void);
+__rte_internal
+struct dpaa2_dprtc_dev *rte_dpaa2_alloc_dprtc_dev(void);
+__rte_internal
+void rte_dpaa2_free_dprtc_dev(struct dpaa2_dprtc_dev *dprtc);
+__rte_internal
+int rte_dpaa2_dprtc_get_time(struct dpaa2_dprtc_dev *dprtc, uint64_t *ns);
+__rte_internal
+int rte_dpaa2_dprtc_set_time(struct dpaa2_dprtc_dev *dprtc, uint64_t ns);
+
__rte_internal
struct dpaa2_dpci_dev *rte_dpaa2_alloc_dpci_dev(void);
diff --git a/drivers/bus/fslmc/private.h b/drivers/bus/fslmc/private.h
index 3586092529..44d1c1453a 100644
--- a/drivers/bus/fslmc/private.h
+++ b/drivers/bus/fslmc/private.h
@@ -18,8 +18,9 @@ void fslmc_vfio_close_iodevices(struct rte_dpaa2_device *dev);
int fslmc_vfio_setup_group(void);
void fslmc_vfio_clear_group(void);
+void *fslmc_vfio_get_rtc_handle(void);
+void fslmc_vfio_put_rtc_handle(void *rtc_handle);
+
int fslmc_vfio_get_container_group(const char *group_name, int *gropuid);
int fslmc_vfio_dmamap(void);
-
-
#endif /* BUS_FSLMC_PRIVATE_H */
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index c842f1546d..68e70cdb45 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -3601,6 +3601,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
}
priv->mc_rev = dpaa2_dev->bus_info->mc_rev;
+ priv->rtc_handle = dpaa2_dev->bus_info->rtc_handle;
priv->num_rx_tc = attr.num_rx_tcs;
priv->num_tx_tc = attr.num_tx_tcs;
priv->qos_entries = attr.qos_entries;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index 7a58833ba1..573a23d00f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -499,6 +499,7 @@ struct dpaa2_dev_priv {
uint64_t *cnt_values_dma_mem;
uint64_t cnt_idx_iova, cnt_values_iova;
uint64_t mc_rev;
+ void *rtc_handle;
struct dpaa2_dev_flow *curr;
LIST_HEAD(, dpaa2_dev_flow) flows;
diff --git a/drivers/net/dpaa2/dpaa2_ptp.c b/drivers/net/dpaa2/dpaa2_ptp.c
index 2863cad4dd..774fe58d77 100644
--- a/drivers/net/dpaa2/dpaa2_ptp.c
+++ b/drivers/net/dpaa2/dpaa2_ptp.c
@@ -17,19 +17,10 @@
#include <rte_time.h>
#include <bus_fslmc_driver.h>
-#include <fsl_dprtc.h>
-#include <fsl_dpkg.h>
#include <dpaa2_ethdev.h>
#include <dpaa2_pmd_logs.h>
-struct dpaa2_dprtc_dev {
- struct fsl_mc_io dprtc; /** handle to DPRTC portal object */
- uint16_t token;
- uint32_t dprtc_id; /*HW ID for DPRTC object */
-};
-static struct dpaa2_dprtc_dev *dprtc_dev;
-
int dpaa2_timesync_enable(struct rte_eth_dev *dev __rte_unused)
{
return 0;
@@ -41,15 +32,16 @@ int dpaa2_timesync_disable(struct rte_eth_dev *dev __rte_unused)
}
int dpaa2_timesync_read_time(struct rte_eth_dev *dev,
- struct timespec *timestamp)
+ struct timespec *timestamp)
{
uint64_t ns;
int ret = 0;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
- RTE_SET_USED(dev);
+ if (!priv->rtc_handle)
+ return -ENODEV;
- ret = dprtc_get_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
- dprtc_dev->token, &ns);
+ ret = rte_dpaa2_dprtc_get_time(priv->rtc_handle, &ns);
if (ret) {
DPAA2_PMD_ERR("dprtc_get_time failed ret: %d", ret);
return ret;
@@ -61,19 +53,19 @@ int dpaa2_timesync_read_time(struct rte_eth_dev *dev,
}
int dpaa2_timesync_write_time(struct rte_eth_dev *dev,
- const struct timespec *ts)
+ const struct timespec *ts)
{
uint64_t ns;
int ret = 0;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
- RTE_SET_USED(dev);
+ if (!priv->rtc_handle)
+ return -ENODEV;
ns = rte_timespec_to_ns(ts);
-
- ret = dprtc_set_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
- dprtc_dev->token, ns);
+ ret = rte_dpaa2_dprtc_set_time(priv->rtc_handle, ns);
if (ret) {
- DPAA2_PMD_ERR("dprtc_set_time failed ret: %d", ret);
+ DPAA2_PMD_ERR("Failed(%d) to set rtc", ret);
return ret;
}
@@ -84,22 +76,22 @@ int dpaa2_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
{
uint64_t ns;
int ret = 0;
+ struct dpaa2_dev_priv *priv = dev->data->dev_private;
- RTE_SET_USED(dev);
+ if (!priv->rtc_handle)
+ return -ENODEV;
- ret = dprtc_get_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
- dprtc_dev->token, &ns);
+ ret = rte_dpaa2_dprtc_get_time(priv->rtc_handle, &ns);
if (ret) {
- DPAA2_PMD_ERR("dprtc_get_time failed ret: %d", ret);
+ DPAA2_PMD_ERR("Failed(%d) to get rtc", ret);
return ret;
}
ns += delta;
- ret = dprtc_set_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
- dprtc_dev->token, ns);
+ ret = rte_dpaa2_dprtc_set_time(priv->rtc_handle, ns);
if (ret) {
- DPAA2_PMD_ERR("dprtc_set_time failed ret: %d", ret);
+ DPAA2_PMD_ERR("Failed(%d) to set rtc", ret);
return ret;
}
@@ -130,55 +122,3 @@ int dpaa2_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
*timestamp = rte_ns_to_timespec(priv->rx_timestamp);
return 0;
}
-
-#if defined(RTE_LIBRTE_IEEE1588)
-static int
-dpaa2_create_dprtc_device(int vdev_fd __rte_unused,
- struct vfio_device_info *obj_info __rte_unused,
- struct rte_dpaa2_device *obj)
-{
- struct dprtc_attr attr;
- int ret, dprtc_id = obj->object_id;
-
- PMD_INIT_FUNC_TRACE();
-
- /* Allocate DPAA2 dprtc handle */
- dprtc_dev = rte_malloc(NULL, sizeof(struct dpaa2_dprtc_dev), 0);
- if (!dprtc_dev) {
- DPAA2_PMD_ERR("Memory allocation failed for DPRTC Device");
- return -1;
- }
-
- /* Open the dprtc object */
- dprtc_dev->dprtc.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
- ret = dprtc_open(&dprtc_dev->dprtc, CMD_PRI_LOW, dprtc_id,
- &dprtc_dev->token);
- if (ret) {
- DPAA2_PMD_ERR("Unable to open dprtc object: err(%d)", ret);
- goto init_err;
- }
-
- ret = dprtc_get_attributes(&dprtc_dev->dprtc, CMD_PRI_LOW,
- dprtc_dev->token, &attr);
- if (ret) {
- DPAA2_PMD_ERR("Unable to get dprtc attr: err(%d)", ret);
- goto init_err;
- }
-
- dprtc_dev->dprtc_id = dprtc_id;
-
- return 0;
-
-init_err:
- rte_free(dprtc_dev);
-
- return -1;
-}
-
-static struct rte_dpaa2_object rte_dpaa2_dprtc_obj = {
- .dev_type = DPAA2_DPRTC,
- .create = dpaa2_create_dprtc_device,
-};
-
-RTE_PMD_REGISTER_DPAA2_OBJECT(dprtc, rte_dpaa2_dprtc_obj);
-#endif
diff --git a/drivers/net/dpaa2/meson.build b/drivers/net/dpaa2/meson.build
index b821f7bfad..61f68f6fec 100644
--- a/drivers/net/dpaa2/meson.build
+++ b/drivers/net/dpaa2/meson.build
@@ -17,7 +17,6 @@ sources = files(
'dpaa2_recycle.c',
'dpaa2_rxtx.c',
'dpaa2_ptp.c',
- 'mc/dprtc.c',
'mc/dpkg.c',
'mc/dpdmux.c',
'mc/dpni.c',
--
2.43.0
More information about the dev
mailing list