[PATCH 01/12] lib: utils: Split the FDT MPXY RPMI mailbox client into two parts
Anup Patel
apatel at ventanamicro.com
Thu Jan 16 07:56:40 PST 2025
Instead of having one common FDT MPXY RPMI mailbox client drivers
for various RPMI service groups, split this driver into two parts:
1) Common MPXY RPMI mailbox client library
2) MPXY driver for RPMI clock service group
The above split enables having a separate MPXY driver for each
RPMI clock service group and #1 (above) will allow code sharing
between various MPXY RPMI drivers.
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
include/sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h | 70 ++++++++
lib/utils/mpxy/Kconfig | 12 +-
lib/utils/mpxy/fdt_mpxy_rpmi_clock.c | 88 ++++++++++
lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c | 169 +++-----------------
lib/utils/mpxy/objects.mk | 4 +-
platform/generic/configs/defconfig | 1 +
6 files changed, 190 insertions(+), 154 deletions(-)
create mode 100644 include/sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h
create mode 100644 lib/utils/mpxy/fdt_mpxy_rpmi_clock.c
diff --git a/include/sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h b/include/sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h
new file mode 100644
index 00000000..e4ca0151
--- /dev/null
+++ b/include/sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h
@@ -0,0 +1,70 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ * Anup Patel <apatel at ventanamicro.com>
+ */
+
+#ifndef __FDT_MPXY_RPMI_MBOX_H__
+#define __FDT_MPXY_RPMI_MBOX_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_mpxy.h>
+#include <sbi_utils/mailbox/rpmi_msgprot.h>
+#include <sbi_utils/mpxy/fdt_mpxy.h>
+
+#define MPXY_RPMI_MAJOR_VER (1)
+#define MPXY_RPMI_MINOR_VER (0)
+
+/** Convert the mpxy attribute ID to attribute array index */
+#define attr_id2index(attr_id) (attr_id - SBI_MPXY_ATTR_MSGPROTO_ATTR_START)
+
+enum mpxy_msgprot_rpmi_attr_id {
+ MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_ID = SBI_MPXY_ATTR_MSGPROTO_ATTR_START,
+ MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_VERSION,
+ MPXY_MSGPROT_RPMI_ATTR_MAX_ID,
+};
+
+/**
+ * MPXY message protocol attributes for RPMI
+ * Order of attribute fields must follow the
+ * attribute IDs in `enum mpxy_msgprot_rpmi_attr_id`
+ */
+struct mpxy_rpmi_channel_attrs {
+ u32 servicegrp_id;
+ u32 servicegrp_ver;
+};
+
+/** Make sure all attributes are packed for direct memcpy */
+#define assert_field_offset(field, attr_offset) \
+ _Static_assert( \
+ ((offsetof(struct mpxy_rpmi_channel_attrs, field)) / \
+ sizeof(u32)) == (attr_offset - SBI_MPXY_ATTR_MSGPROTO_ATTR_START),\
+ "field " #field \
+ " from struct mpxy_rpmi_channel_attrs invalid offset, expected " #attr_offset)
+
+assert_field_offset(servicegrp_id, MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_ID);
+
+/** MPXY RPMI service data for each service group */
+struct mpxy_rpmi_service_data {
+ u8 id;
+ u32 min_tx_len;
+ u32 max_tx_len;
+ u32 min_rx_len;
+ u32 max_rx_len;
+};
+
+/** MPXY RPMI mbox data for each service group */
+struct mpxy_rpmi_mbox_data {
+ u32 servicegrp_id;
+ u32 num_services;
+ u32 notifications_support;
+ struct mpxy_rpmi_service_data *service_data;
+};
+
+/** Common probe function for MPXY RPMI drivers */
+int mpxy_rpmi_mbox_init(const void *fdt, int nodeoff, const struct fdt_match *match);
+
+#endif
diff --git a/lib/utils/mpxy/Kconfig b/lib/utils/mpxy/Kconfig
index 131fb91a..ff88f24f 100644
--- a/lib/utils/mpxy/Kconfig
+++ b/lib/utils/mpxy/Kconfig
@@ -7,11 +7,15 @@ config FDT_MPXY
depends on FDT
default n
-if FDT_MPXY
-
config FDT_MPXY_RPMI_MBOX
- bool "FDT MPXY mailbox client driver"
- depends on FDT_MAILBOX
+ bool "MPXY drivers as RPMI mailbox client"
+ depends on FDT_MAILBOX && FDT_MPXY
+ default n
+
+if FDT_MPXY_RPMI_MBOX
+
+config FDT_MPXY_RPMI_CLOCK
+ bool "MPXY driver for RPMI clock service group"
default n
endif
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_clock.c b/lib/utils/mpxy/fdt_mpxy_rpmi_clock.c
new file mode 100644
index 00000000..1f5c6e75
--- /dev/null
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi_clock.c
@@ -0,0 +1,88 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ * Rahul Pathak <rpathak at ventanamicro.com>
+ * Anup Patel <apatel at ventanamicro.com>
+ */
+
+#include <sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h>
+
+static struct mpxy_rpmi_service_data clock_services[] = {
+{
+ .id = RPMI_CLOCK_SRV_ENABLE_NOTIFICATION,
+ .min_tx_len = sizeof(struct rpmi_enable_notification_req),
+ .max_tx_len = sizeof(struct rpmi_enable_notification_req),
+ .min_rx_len = sizeof(struct rpmi_enable_notification_resp),
+ .max_rx_len = sizeof(struct rpmi_enable_notification_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_GET_NUM_CLOCKS,
+ .min_tx_len = 0,
+ .max_tx_len = 0,
+ .min_rx_len = sizeof(struct rpmi_clock_get_num_clocks_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_get_num_clocks_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_GET_ATTRIBUTES,
+ .min_tx_len = sizeof(struct rpmi_clock_get_attributes_req),
+ .max_tx_len = sizeof(struct rpmi_clock_get_attributes_req),
+ .min_rx_len = sizeof(struct rpmi_clock_get_attributes_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_get_attributes_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_GET_SUPPORTED_RATES,
+ .min_tx_len = sizeof(struct rpmi_clock_get_supported_rates_req),
+ .max_tx_len = sizeof(struct rpmi_clock_get_supported_rates_req),
+ .min_rx_len = sizeof(struct rpmi_clock_get_supported_rates_resp),
+ .max_rx_len = -1U,
+},
+{
+ .id = RPMI_CLOCK_SRV_SET_CONFIG,
+ .min_tx_len = sizeof(struct rpmi_clock_set_config_req),
+ .max_tx_len = sizeof(struct rpmi_clock_set_config_req),
+ .min_rx_len = sizeof(struct rpmi_clock_set_config_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_set_config_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_GET_CONFIG,
+ .min_tx_len = sizeof(struct rpmi_clock_get_config_req),
+ .max_tx_len = sizeof(struct rpmi_clock_get_config_req),
+ .min_rx_len = sizeof(struct rpmi_clock_get_config_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_get_config_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_SET_RATE,
+ .min_tx_len = sizeof(struct rpmi_clock_set_rate_req),
+ .max_tx_len = sizeof(struct rpmi_clock_set_rate_req),
+ .min_rx_len = sizeof(struct rpmi_clock_set_rate_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_set_rate_resp),
+},
+{
+ .id = RPMI_CLOCK_SRV_GET_RATE,
+ .min_tx_len = sizeof(struct rpmi_clock_get_rate_req),
+ .max_tx_len = sizeof(struct rpmi_clock_get_rate_req),
+ .min_rx_len = sizeof(struct rpmi_clock_get_rate_resp),
+ .max_rx_len = sizeof(struct rpmi_clock_get_rate_resp),
+},
+};
+
+static struct mpxy_rpmi_mbox_data clock_data = {
+ .servicegrp_id = RPMI_SRVGRP_CLOCK,
+ .num_services = RPMI_CLOCK_SRV_MAX_COUNT,
+ .notifications_support = 1,
+ .service_data = clock_services,
+};
+
+static const struct fdt_match clock_match[] = {
+ { .compatible = "riscv,rpmi-mpxy-clock", .data = &clock_data },
+ { },
+};
+
+struct fdt_driver fdt_mpxy_rpmi_clock = {
+ .match_table = clock_match,
+ .init = mpxy_rpmi_mbox_init,
+ .experimental = true,
+};
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
index 78020eae..0d4fd1fe 100644
--- a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
@@ -11,82 +11,32 @@
#include <libfdt.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_heap.h>
-#include <sbi/sbi_mpxy.h>
#include <sbi_utils/fdt/fdt_helper.h>
-#include <sbi_utils/mpxy/fdt_mpxy.h>
+#include <sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h>
#include <sbi_utils/mailbox/fdt_mailbox.h>
-#include <sbi_utils/mailbox/rpmi_msgprot.h>
#include <sbi/sbi_console.h>
-#define RPMI_MAJOR_VER (1)
-#define RPMI_MINOR_VER (0)
-
-/** Convert the mpxy attribute ID to attribute array index */
-#define attr_id2index(attr_id) (attr_id - SBI_MPXY_ATTR_MSGPROTO_ATTR_START)
-
-enum mpxy_msgprot_rpmi_attr_id {
- MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_ID = SBI_MPXY_ATTR_MSGPROTO_ATTR_START,
- MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_VERSION,
- MPXY_MSGPROT_RPMI_ATTR_MAX_ID,
-};
-
-/**
- * MPXY message protocol attributes for RPMI
- * Order of attribute fields must follow the
- * attribute IDs in `enum mpxy_msgprot_rpmi_attr_id`
- */
-struct mpxy_rpmi_channel_attrs {
- u32 servicegrp_id;
- u32 servicegrp_ver;
-};
-
-/* RPMI mbox data per service group */
-struct mpxy_mbox_data {
- u32 servicegrp_id;
- u32 num_services;
- u32 notifications_support;
- void *priv_data;
-};
-
-/* RPMI service data per service group */
-struct rpmi_service_data {
- u8 id;
- u32 min_tx_len;
- u32 max_tx_len;
- u32 min_rx_len;
- u32 max_rx_len;
-};
-
/**
* MPXY mbox instance per MPXY channel. This ties
* an MPXY channel with an RPMI Service group.
*/
-struct mpxy_mbox {
+struct mpxy_rpmi_mbox {
struct mbox_chan *chan;
- struct mpxy_mbox_data *mbox_data;
+ struct mpxy_rpmi_mbox_data *mbox_data;
struct mpxy_rpmi_channel_attrs msgprot_attrs;
struct sbi_mpxy_channel channel;
};
-/** Make sure all attributes are packed for direct memcpy */
-#define assert_field_offset(field, attr_offset) \
- _Static_assert( \
- ((offsetof(struct mpxy_rpmi_channel_attrs, field)) / \
- sizeof(u32)) == (attr_offset - SBI_MPXY_ATTR_MSGPROTO_ATTR_START),\
- "field " #field \
- " from struct mpxy_rpmi_channel_attrs invalid offset, expected " #attr_offset)
-
-assert_field_offset(servicegrp_id, MPXY_MSGPROT_RPMI_ATTR_SERVICEGROUP_ID);
-
/**
* Discover the RPMI service data using message_id
* MPXY message_id == RPMI service_id
*/
-static struct rpmi_service_data *mpxy_find_rpmi_srvid(u32 message_id,
- struct mpxy_mbox_data *mbox_data)
+static struct mpxy_rpmi_service_data *mpxy_find_rpmi_srvid(u32 message_id,
+ struct mpxy_rpmi_mbox_data *mbox_data)
{
int mid = 0;
- struct rpmi_service_data *srv = mbox_data->priv_data;
+ struct mpxy_rpmi_service_data *srv = mbox_data->service_data;
+
for (mid = 0; srv[mid].id < mbox_data->num_services; mid++) {
if (srv[mid].id == (u8)message_id)
return &srv[mid];
@@ -108,9 +58,8 @@ static int mpxy_mbox_read_attributes(struct sbi_mpxy_channel *channel,
u32 attr_count)
{
u32 end_id;
- struct mpxy_mbox *rmb =
- container_of(channel, struct mpxy_mbox, channel);
-
+ struct mpxy_rpmi_mbox *rmb =
+ container_of(channel, struct mpxy_rpmi_mbox, channel);
u32 *attr_array = (u32 *)&rmb->msgprot_attrs;
end_id = base_attr_id + attr_count - 1;
@@ -161,8 +110,8 @@ static int mpxy_mbox_write_attributes(struct sbi_mpxy_channel *channel,
{
int ret, mem_idx;
u32 end_id, attr_val, idx;
- struct mpxy_mbox *rmb =
- container_of(channel, struct mpxy_mbox, channel);
+ struct mpxy_rpmi_mbox *rmb =
+ container_of(channel, struct mpxy_rpmi_mbox, channel);
end_id = base_attr_id + attr_count - 1;
@@ -195,9 +144,9 @@ static int __mpxy_mbox_send_message(struct sbi_mpxy_channel *channel,
u32 rx_len = 0;
struct mbox_xfer xfer;
struct rpmi_message_args args = {0};
- struct mpxy_mbox *rmb =
- container_of(channel, struct mpxy_mbox, channel);
- struct rpmi_service_data *srv =
+ struct mpxy_rpmi_mbox *rmb =
+ container_of(channel, struct mpxy_rpmi_mbox, channel);
+ struct mpxy_rpmi_service_data *srv =
mpxy_find_rpmi_srvid(message_id, rmb->mbox_data);
if (!srv)
return SBI_ENOTSUPP;
@@ -266,15 +215,14 @@ static int mpxy_mbox_get_notifications(struct sbi_mpxy_channel *channel,
return SBI_ENOTSUPP;
}
-static int mpxy_mbox_init(const void *fdt, int nodeoff,
- const struct fdt_match *match)
+int mpxy_rpmi_mbox_init(const void *fdt, int nodeoff, const struct fdt_match *match)
{
int rc, len;
const fdt32_t *val;
u32 channel_id;
- struct mpxy_mbox *rmb;
struct mbox_chan *chan;
- const struct mpxy_mbox_data *data = match->data;
+ struct mpxy_rpmi_mbox *rmb;
+ const struct mpxy_rpmi_mbox_data *data = match->data;
/* Allocate context for RPXY mbox client */
rmb = sbi_zalloc(sizeof(*rmb));
@@ -334,7 +282,7 @@ static int mpxy_mbox_init(const void *fdt, int nodeoff,
rmb->channel.attrs.msg_proto_id = SBI_MPXY_MSGPROTO_RPMI_ID;
/* RPMI Message Protocol Version */
rmb->channel.attrs.msg_proto_version =
- SBI_MPXY_MSGPROTO_VERSION(RPMI_MAJOR_VER, RPMI_MINOR_VER);
+ SBI_MPXY_MSGPROTO_VERSION(MPXY_RPMI_MAJOR_VER, MPXY_RPMI_MINOR_VER);
/* RPMI supported max message data length(bytes), same for
* all service groups */
@@ -349,9 +297,9 @@ static int mpxy_mbox_init(const void *fdt, int nodeoff,
/* RPMI message protocol attributes */
rmb->msgprot_attrs.servicegrp_id = data->servicegrp_id;
rmb->msgprot_attrs.servicegrp_ver =
- SBI_MPXY_MSGPROTO_VERSION(RPMI_MAJOR_VER, RPMI_MINOR_VER);
+ SBI_MPXY_MSGPROTO_VERSION(MPXY_RPMI_MAJOR_VER, MPXY_RPMI_MINOR_VER);
- rmb->mbox_data = (struct mpxy_mbox_data *)data;
+ rmb->mbox_data = (struct mpxy_rpmi_mbox_data *)data;
rmb->chan = chan;
/* Register RPXY service group */
@@ -364,80 +312,3 @@ static int mpxy_mbox_init(const void *fdt, int nodeoff,
return SBI_OK;
}
-
-static struct rpmi_service_data clock_services[] = {
-{
- .id = RPMI_CLOCK_SRV_ENABLE_NOTIFICATION,
- .min_tx_len = sizeof(struct rpmi_enable_notification_req),
- .max_tx_len = sizeof(struct rpmi_enable_notification_req),
- .min_rx_len = sizeof(struct rpmi_enable_notification_resp),
- .max_rx_len = sizeof(struct rpmi_enable_notification_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_GET_NUM_CLOCKS,
- .min_tx_len = 0,
- .max_tx_len = 0,
- .min_rx_len = sizeof(struct rpmi_clock_get_num_clocks_resp),
- .max_rx_len = sizeof(struct rpmi_clock_get_num_clocks_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_GET_ATTRIBUTES,
- .min_tx_len = sizeof(struct rpmi_clock_get_attributes_req),
- .max_tx_len = sizeof(struct rpmi_clock_get_attributes_req),
- .min_rx_len = sizeof(struct rpmi_clock_get_attributes_resp),
- .max_rx_len = sizeof(struct rpmi_clock_get_attributes_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_GET_SUPPORTED_RATES,
- .min_tx_len = sizeof(struct rpmi_clock_get_supported_rates_req),
- .max_tx_len = sizeof(struct rpmi_clock_get_supported_rates_req),
- .min_rx_len = sizeof(struct rpmi_clock_get_supported_rates_resp),
- .max_rx_len = -1U,
-},
-{
- .id = RPMI_CLOCK_SRV_SET_CONFIG,
- .min_tx_len = sizeof(struct rpmi_clock_set_config_req),
- .max_tx_len = sizeof(struct rpmi_clock_set_config_req),
- .min_rx_len = sizeof(struct rpmi_clock_set_config_resp),
- .max_rx_len = sizeof(struct rpmi_clock_set_config_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_GET_CONFIG,
- .min_tx_len = sizeof(struct rpmi_clock_get_config_req),
- .max_tx_len = sizeof(struct rpmi_clock_get_config_req),
- .min_rx_len = sizeof(struct rpmi_clock_get_config_resp),
- .max_rx_len = sizeof(struct rpmi_clock_get_config_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_SET_RATE,
- .min_tx_len = sizeof(struct rpmi_clock_set_rate_req),
- .max_tx_len = sizeof(struct rpmi_clock_set_rate_req),
- .min_rx_len = sizeof(struct rpmi_clock_set_rate_resp),
- .max_rx_len = sizeof(struct rpmi_clock_set_rate_resp),
-},
-{
- .id = RPMI_CLOCK_SRV_GET_RATE,
- .min_tx_len = sizeof(struct rpmi_clock_get_rate_req),
- .max_tx_len = sizeof(struct rpmi_clock_get_rate_req),
- .min_rx_len = sizeof(struct rpmi_clock_get_rate_resp),
- .max_rx_len = sizeof(struct rpmi_clock_get_rate_resp),
-},
-};
-
-static struct mpxy_mbox_data clock_data = {
- .servicegrp_id = RPMI_SRVGRP_CLOCK,
- .num_services = RPMI_CLOCK_SRV_MAX_COUNT,
- .notifications_support = 1,
- .priv_data = clock_services,
-};
-
-static const struct fdt_match mpxy_mbox_match[] = {
- { .compatible = "riscv,rpmi-mpxy-clock", .data = &clock_data },
- { },
-};
-
-struct fdt_driver fdt_mpxy_rpmi_mbox = {
- .match_table = mpxy_mbox_match,
- .init = mpxy_mbox_init,
- .experimental = true,
-};
diff --git a/lib/utils/mpxy/objects.mk b/lib/utils/mpxy/objects.mk
index ccb28b55..1c9afed9 100644
--- a/lib/utils/mpxy/objects.mk
+++ b/lib/utils/mpxy/objects.mk
@@ -10,5 +10,7 @@
libsbiutils-objs-$(CONFIG_FDT_MPXY) += mpxy/fdt_mpxy.o
libsbiutils-objs-$(CONFIG_FDT_MPXY) += mpxy/fdt_mpxy_drivers.carray.o
-carray-fdt_mpxy_drivers-$(CONFIG_FDT_MPXY_RPMI_MBOX) += fdt_mpxy_rpmi_mbox
libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_MBOX) += mpxy/fdt_mpxy_rpmi_mbox.o
+
+carray-fdt_mpxy_drivers-$(CONFIG_FDT_MPXY_RPMI_CLOCK) += fdt_mpxy_rpmi_clock
+libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_CLOCK) += mpxy/fdt_mpxy_rpmi_clock.o
diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig
index e23b38b2..55607a28 100644
--- a/platform/generic/configs/defconfig
+++ b/platform/generic/configs/defconfig
@@ -55,3 +55,4 @@ CONFIG_FDT_TIMER_MTIMER=y
CONFIG_FDT_TIMER_PLMT=y
CONFIG_FDT_MPXY=y
CONFIG_FDT_MPXY_RPMI_MBOX=y
+CONFIG_FDT_MPXY_RPMI_CLOCK=y
--
2.43.0
More information about the opensbi
mailing list