From 0b041e58c0787f76325da5081e41a13bf304d328 Mon Sep 17 00:00:00 2001 From: Ranbir Singh Date: Wed, 25 Feb 2026 11:43:47 +0530 Subject: [PATCH] lib: utils: Add MPXY client driver for RPMI MM service group Add necessary infra for implementing RPMI Management Mode service group on platform microcontroller. Co-authored-by: Sunil V L Signed-off-by: Ranbir Singh Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260225061347.1396504-1-ranbir.singh@oss.qualcomm.com Signed-off-by: Anup Patel --- include/sbi_utils/mailbox/rpmi_msgprot.h | 37 ++++++++ lib/utils/mpxy/Kconfig | 4 + lib/utils/mpxy/fdt_mpxy_rpmi_mm.c | 116 +++++++++++++++++++++++ lib/utils/mpxy/objects.mk | 3 + platform/generic/configs/defconfig | 1 + 5 files changed, 161 insertions(+) create mode 100644 lib/utils/mpxy/fdt_mpxy_rpmi_mm.c diff --git a/include/sbi_utils/mailbox/rpmi_msgprot.h b/include/sbi_utils/mailbox/rpmi_msgprot.h index f8b16753..c35788f0 100644 --- a/include/sbi_utils/mailbox/rpmi_msgprot.h +++ b/include/sbi_utils/mailbox/rpmi_msgprot.h @@ -220,6 +220,7 @@ enum rpmi_servicegroup_id { RPMI_SRVGRP_CLOCK = 0x0008, RPMI_SRVGRP_DEVICE_POWER = 0x0009, RPMI_SRVGRP_PERFORMANCE = 0x0000A, + RPMI_SRVGRP_MANAGEMENT_MODE = 0x000B, RPMI_SRVGRP_ID_MAX_COUNT, /* Reserved range for service groups */ @@ -947,4 +948,40 @@ struct rpmi_perf_get_fast_chn_attr_resp { u32 db_perserved_high; }; +/** RPMI MM ServiceGroup Service IDs */ +enum rpmi_mm_service_id { + RPMI_MM_SRV_ENABLE_NOTIFICATION = 0x01, + RPMI_MM_SRV_GET_ATTRIBUTES = 0x02, + RPMI_MM_SRV_COMMUNICATE = 0x03, + RPMI_MM_SRV_MAX_COUNT, +}; + +/** RPMI MM ServiceGroup Get Attributes main struct */ +struct rpmi_mm_attributes { + u32 mm_version; + u32 shmem_addr_lo; + u32 shmem_addr_hi; + u32 shmem_size; +}; + +/** RPMI MM ServiceGroup Get Attributes response struct */ +struct rpmi_mm_get_attributes_rsp { + s32 status; + struct rpmi_mm_attributes mma; +}; + +/** RPMI MM ServiceGroup Communicate request struct */ +struct rpmi_mm_communicate_req { + u32 mm_comm_ipdata_off; + u32 mm_comm_ipdata_size; + u32 mm_comm_opdata_off; + u32 mm_comm_opdata_size; +}; + +/** RPMI MM ServiceGroup Communicate response struct */ +struct rpmi_mm_communicate_rsp { + s32 status; + u32 mm_comm_retdata_size; +}; + #endif /* !__RPMI_MSGPROT_H__ */ diff --git a/lib/utils/mpxy/Kconfig b/lib/utils/mpxy/Kconfig index 507b8371..1a38b792 100644 --- a/lib/utils/mpxy/Kconfig +++ b/lib/utils/mpxy/Kconfig @@ -34,6 +34,10 @@ config FDT_MPXY_RPMI_PERFORMANCE bool "MPXY driver for RPMI performance service group" default n +config FDT_MPXY_RPMI_MM + bool "MPXY driver for RPMI MM service group" + default n + endif endmenu diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c b/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c new file mode 100644 index 00000000..0163d0d2 --- /dev/null +++ b/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c @@ -0,0 +1,116 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * + * Authors: + * Ranbir Singh + * Sunil V L + */ + +#include +#include + +static struct rpmi_mm_get_attributes_rsp rsp; + +static struct mpxy_rpmi_service_data mm_srvcdata[] = { + [0] { + .id = RPMI_MM_SRV_GET_ATTRIBUTES, + .min_tx_len = 0, + .max_tx_len = 0, + .min_rx_len = sizeof(struct rpmi_mm_get_attributes_rsp), + .max_rx_len = sizeof(struct rpmi_mm_get_attributes_rsp), + }, + [1] { + .id = RPMI_MM_SRV_COMMUNICATE, + .min_tx_len = sizeof(struct rpmi_mm_communicate_req), + .max_tx_len = sizeof(struct rpmi_mm_communicate_req), + .min_rx_len = sizeof(struct rpmi_mm_communicate_rsp), + .max_rx_len = sizeof(struct rpmi_mm_communicate_rsp), + }, +}; + +static int mpxy_rpmi_mm_setup(void **context, struct mbox_chan *chan, + const struct mpxy_rpmi_mbox_data *data) +{ + unsigned long mm_region_addr = 0; + unsigned long mm_region_size = 0; + unsigned long mm_region_flags; + int rc = 0; + + rc = rpmi_normal_request_with_status(chan, RPMI_MM_SRV_GET_ATTRIBUTES, + NULL, 0, 0, &rsp, + rpmi_u32_count(rsp), + rpmi_u32_count(rsp)); + if (rc) + return rc; + +#if __riscv_xlen == 32 + mm_region_addr = rsp.mma.shmem_addr_lo; +#else + mm_region_addr = ((unsigned long)(rsp.mma.shmem_addr_hi) << 32) | + rsp.mma.shmem_addr_lo; +#endif + + mm_region_size = rsp.mma.shmem_size; + mm_region_flags = SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW; + + rc = sbi_domain_root_add_memrange(mm_region_addr, mm_region_size, + PAGE_SIZE, mm_region_flags); + return rc; +} + +static int mpxy_rpmi_mm_xfer(void *context, struct mbox_chan *chan, + struct mbox_xfer *xfer) +{ + struct rpmi_message_args *args = xfer->args; + int rc = 0; + + if (!xfer->rx || (args->type != RPMI_MSG_NORMAL_REQUEST)) + return 0; + + switch (args->service_id) { + case RPMI_MM_SRV_GET_ATTRIBUTES: + ((u32 *)xfer->rx)[0] = cpu_to_le32(RPMI_SUCCESS); + ((u32 *)xfer->rx)[1] = cpu_to_le32(rsp.mma.mm_version); + ((u32 *)xfer->rx)[2] = cpu_to_le32(rsp.mma.shmem_addr_lo); + ((u32 *)xfer->rx)[3] = cpu_to_le32(rsp.mma.shmem_addr_hi); + ((u32 *)xfer->rx)[4] = cpu_to_le32(rsp.mma.shmem_size); + args->rx_data_len = 5 * sizeof(u32); + break; + + case RPMI_MM_SRV_COMMUNICATE: + rc = mbox_chan_xfer(chan, xfer); + break; + + default: + ((u32 *)xfer->rx)[0] = cpu_to_le32(RPMI_ERR_NOTSUPP); + args->rx_data_len = sizeof(u32); + break; + }; + + return rc; +} + +static const struct mpxy_rpmi_mbox_data mm_data = { + .servicegrp_id = RPMI_SRVGRP_MANAGEMENT_MODE, + .num_services = RPMI_MM_SRV_MAX_COUNT, + .service_data = mm_srvcdata, + .setup_group = mpxy_rpmi_mm_setup, + .xfer_group = mpxy_rpmi_mm_xfer, +}; + +/* one extra blank entry for loop termination while matching */ +static const struct fdt_match mm_match[] = { + { + .compatible = "riscv,rpmi-mpxy-mm", + .data = &mm_data, + }, + {}, +}; + +const struct fdt_driver fdt_mpxy_rpmi_mm = { + .experimental = true, + .match_table = mm_match, + .init = mpxy_rpmi_mbox_init, +}; diff --git a/lib/utils/mpxy/objects.mk b/lib/utils/mpxy/objects.mk index bbc998af..9cfd86bc 100644 --- a/lib/utils/mpxy/objects.mk +++ b/lib/utils/mpxy/objects.mk @@ -26,3 +26,6 @@ libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_VOLTAGE) += mpxy/fdt_mpxy_rpmi_voltage.o carray-fdt_mpxy_drivers-$(CONFIG_FDT_MPXY_RPMI_DEVICE_POWER) += fdt_mpxy_rpmi_device_power libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_DEVICE_POWER) += mpxy/fdt_mpxy_rpmi_device_power.o + +carray-fdt_mpxy_drivers-$(CONFIG_FDT_MPXY_RPMI_MM) += fdt_mpxy_rpmi_mm +libsbiutils-objs-$(CONFIG_FDT_MPXY_RPMI_MM) += mpxy/fdt_mpxy_rpmi_mm.o diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig index debc5f86..1d3431e7 100644 --- a/platform/generic/configs/defconfig +++ b/platform/generic/configs/defconfig @@ -78,3 +78,4 @@ CONFIG_FDT_MPXY_RPMI_VOLTAGE=y CONFIG_FDT_MPXY_RPMI_DEVICE_POWER=y CONFIG_FDT_MPXY_RPMI_PERFORMANCE=y CONFIG_FDT_MPXY_RPMI_SYSMSI=y +CONFIG_FDT_MPXY_RPMI_MM=y