diff options
| author | Ranbir Singh <ranbir.singh@oss.qualcomm.com> | 2026-02-25 11:43:47 +0530 |
|---|---|---|
| committer | Anup Patel <anup@brainfault.org> | 2026-04-06 18:23:25 +0530 |
| commit | 0b041e58c0787f76325da5081e41a13bf304d328 (patch) | |
| tree | f760e8ec16deb744945120e1cc53a2c58efaa6a6 /lib/utils | |
| parent | 2bf0de88c8897ff4be5b89c04115c17421ad5687 (diff) | |
| download | opensbi-0b041e58c0787f76325da5081e41a13bf304d328.tar.gz opensbi-0b041e58c0787f76325da5081e41a13bf304d328.tar.bz2 opensbi-0b041e58c0787f76325da5081e41a13bf304d328.zip | |
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 <sunilvl@oss.qualcomm.com>
Signed-off-by: Ranbir Singh <ranbir.singh@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260225061347.1396504-1-ranbir.singh@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'lib/utils')
| -rw-r--r-- | lib/utils/mpxy/Kconfig | 4 | ||||
| -rw-r--r-- | lib/utils/mpxy/fdt_mpxy_rpmi_mm.c | 116 | ||||
| -rw-r--r-- | lib/utils/mpxy/objects.mk | 3 |
3 files changed, 123 insertions, 0 deletions
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 <ranbir.singh@oss.qualcomm.com> + * Sunil V L <sunilvl@oss.qualcomm.com> + */ + +#include <sbi_utils/mpxy/fdt_mpxy_rpmi_mbox.h> +#include <sbi_utils/mailbox/rpmi_mailbox.h> + +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 |
