summaryrefslogtreecommitdiff
path: root/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/cppc/fdt_cppc_rpmi.c44
-rw-r--r--lib/utils/mpxy/fdt_mpxy_rpmi_logging.c2
-rw-r--r--lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c2
-rw-r--r--lib/utils/mpxy/fdt_mpxy_rpmi_mm.c9
-rw-r--r--lib/utils/reset/Kconfig4
-rw-r--r--lib/utils/reset/fdt_reset_metanoia.c72
-rw-r--r--lib/utils/reset/objects.mk3
7 files changed, 128 insertions, 8 deletions
diff --git a/lib/utils/cppc/fdt_cppc_rpmi.c b/lib/utils/cppc/fdt_cppc_rpmi.c
index 7bd3b0f9..15c89351 100644
--- a/lib/utils/cppc/fdt_cppc_rpmi.c
+++ b/lib/utils/cppc/fdt_cppc_rpmi.c
@@ -12,6 +12,7 @@
#include <sbi/sbi_cppc.h>
#include <sbi/sbi_ecall_interface.h>
#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_timer.h>
#include <sbi_utils/fdt/fdt_driver.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/mailbox/fdt_mailbox.h>
@@ -39,6 +40,8 @@ struct rpmi_cppc {
ulong fc_db_addr;
u64 fc_db_setmask;
u64 fc_db_preservemask;
+ u64 prev_time_csr;
+ u64 prev_delivered_counter;
};
static unsigned long rpmi_cppc_offset;
@@ -107,6 +110,7 @@ static void rpmi_cppc_fc_db_trigger(struct rpmi_cppc *cppc)
static int rpmi_cppc_read(unsigned long reg, u64 *val)
{
+ u64 curr_freq, curr_time_csr, time_csr_delta, freq;
int rc = SBI_SUCCESS;
struct rpmi_cppc_read_reg_req req;
struct rpmi_cppc_read_reg_resp resp;
@@ -116,12 +120,38 @@ static int rpmi_cppc_read(unsigned long reg, u64 *val)
req.reg_id = reg;
cppc = rpmi_cppc_get_pointer(req.hart_id);
- rc = rpmi_normal_request_with_status(
- cppc->chan, RPMI_CPPC_SRV_READ_REG,
- &req, rpmi_u32_count(req), rpmi_u32_count(req),
- &resp, rpmi_u32_count(resp), rpmi_u32_count(resp));
- if (rc)
- return rc;
+ if ((reg == SBI_CPPC_DELIVERED_CTR) && cppc->fc_supported) {
+#if __riscv_xlen != 32
+ curr_freq = readq((void *)cppc->fc_perf_feedback_addr);
+#else
+ curr_freq = readl((void *)cppc->fc_perf_feedback_addr + 4);
+ curr_freq <<= 32;
+ curr_freq |= readl((void *)cppc->fc_perf_feedback_addr);
+#endif
+ curr_time_csr = sbi_timer_value();
+ time_csr_delta = curr_time_csr - cppc->prev_time_csr;
+ cppc->prev_time_csr = curr_time_csr;
+
+ freq = sbi_timer_frequency();
+ if (freq)
+ cppc->prev_delivered_counter +=
+ curr_freq * (time_csr_delta / freq) +
+ (curr_freq * (time_csr_delta % freq)) / freq;
+
+ resp.data_lo = cpu_to_le32(cppc->prev_delivered_counter & UINT32_MAX);
+ resp.data_hi = cpu_to_le32(cppc->prev_delivered_counter >> 32);
+ } else if (reg == SBI_CPPC_REFERENCE_CTR) {
+ curr_time_csr = sbi_timer_value();
+ resp.data_lo = cpu_to_le32(curr_time_csr & UINT32_MAX);
+ resp.data_hi = cpu_to_le32(curr_time_csr >> 32);
+ } else {
+ rc = rpmi_normal_request_with_status(
+ cppc->chan, RPMI_CPPC_SRV_READ_REG,
+ &req, rpmi_u32_count(req), rpmi_u32_count(req),
+ &resp, rpmi_u32_count(resp), rpmi_u32_count(resp));
+ if (rc)
+ return rc;
+ }
#if __riscv_xlen == 32
*val = resp.data_lo;
@@ -276,6 +306,8 @@ static int rpmi_cppc_update_hart_scratch(struct mbox_chan *chan)
if (!cppc)
return SBI_ENOSYS;
+ cppc->prev_time_csr = 0;
+ cppc->prev_delivered_counter = 0;
cppc->chan = chan;
cppc->mode = cppc_mode;
cppc->fc_supported = fc_supported;
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_logging.c b/lib/utils/mpxy/fdt_mpxy_rpmi_logging.c
index e8f085eb..1e92053d 100644
--- a/lib/utils/mpxy/fdt_mpxy_rpmi_logging.c
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi_logging.c
@@ -11,7 +11,7 @@
static struct mpxy_rpmi_service_data logging_services[] = {
[0] = {
- .id = RPMI_MM_SRV_ENABLE_NOTIFICATION,
+ .id = RPMI_LOGGING_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),
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
index 84b7a67d..825ac9b3 100644
--- a/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c
@@ -299,6 +299,8 @@ int mpxy_rpmi_mbox_init(const void *fdt, int nodeoff, const struct fdt_match *ma
/* Setup MPXY mbox client */
/* Channel ID*/
rmb->channel.channel_id = channel_id;
+ /* Set the owner domain */
+ rmb->channel.owner_domain = &root;
/* Callback for read RPMI attributes */
rmb->channel.read_attributes = mpxy_mbox_read_attributes;
/* Callback for write RPMI attributes */
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c b/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c
index d7176aca..7185f3f3 100644
--- a/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi_mm.c
@@ -15,13 +15,20 @@ static struct rpmi_mm_get_attributes_rsp rsp;
static struct mpxy_rpmi_service_data mm_srvcdata[] = {
[0] = {
+ .id = RPMI_MM_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),
+ },
+ [1] = {
.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] = {
+ [2] = {
.id = RPMI_MM_SRV_COMMUNICATE,
.min_tx_len = sizeof(struct rpmi_mm_communicate_req),
.max_tx_len = sizeof(struct rpmi_mm_communicate_req),
diff --git a/lib/utils/reset/Kconfig b/lib/utils/reset/Kconfig
index b2ac120e..8988548c 100644
--- a/lib/utils/reset/Kconfig
+++ b/lib/utils/reset/Kconfig
@@ -29,6 +29,10 @@ config FDT_RESET_LITEX
depends on FDT_GPIO
default n
+config FDT_RESET_METANOIA
+ bool "Metanoia FDT reset driver"
+ default n
+
config FDT_RESET_RPMI
bool "RPMI FDT reset driver"
depends on FDT_MAILBOX && RPMI_MAILBOX
diff --git a/lib/utils/reset/fdt_reset_metanoia.c b/lib/utils/reset/fdt_reset_metanoia.c
new file mode 100644
index 00000000..6f75a893
--- /dev/null
+++ b/lib/utils/reset/fdt_reset_metanoia.c
@@ -0,0 +1,72 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Metanoia Communications Inc.
+ *
+ */
+
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_system.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_driver.h>
+
+#define SWRSTREQ_CTRL_REG_OFFSET 0x00
+#define SWRSTREQ_REG_OFFSET 0x04
+
+struct reset_metanoia_data {
+ u8 *reg_base;
+};
+
+static struct reset_metanoia_data reset_data;
+
+static int metanoia_system_reset_check(u32 type, u32 reason)
+{
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ return 1;
+ case SBI_SRST_RESET_TYPE_SHUTDOWN:
+ default:
+ return 0;
+ }
+}
+
+static void metanoia_system_reset(u32 type, u32 reason)
+{
+ writew(0x1, reset_data.reg_base + SWRSTREQ_CTRL_REG_OFFSET);
+ writew(0x1, reset_data.reg_base + SWRSTREQ_REG_OFFSET);
+}
+
+static struct sbi_system_reset_device metanoia_reset = {
+ .name = "metanoia-mt2824-reboot",
+ .system_reset_check = metanoia_system_reset_check,
+ .system_reset = metanoia_system_reset,
+};
+
+static int metanoia_reset_init(const void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ u64 reg_addr;
+ int rc;
+
+ rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &reg_addr, NULL);
+ if (rc < 0 || !reg_addr)
+ return SBI_ENODEV;
+
+ reset_data.reg_base = (u8 *)(ulong)reg_addr;
+
+ sbi_system_reset_add_device(&metanoia_reset);
+
+ return 0;
+}
+
+static const struct fdt_match metanoia_reset_match[] = {
+ { .compatible = "metanoia,mt2824-reboot" },
+ { /* sentinel */ }
+};
+
+const struct fdt_driver fdt_reset_metanoia = {
+ .match_table = metanoia_reset_match,
+ .init = metanoia_reset_init,
+};
diff --git a/lib/utils/reset/objects.mk b/lib/utils/reset/objects.mk
index 38b4e306..a9b6edad 100644
--- a/lib/utils/reset/objects.mk
+++ b/lib/utils/reset/objects.mk
@@ -20,6 +20,9 @@ libsbiutils-objs-$(CONFIG_FDT_RESET_HTIF) += reset/fdt_reset_htif.o
carray-fdt_early_drivers-$(CONFIG_FDT_RESET_LITEX) += fdt_reset_litex
libsbiutils-objs-$(CONFIG_FDT_RESET_LITEX) += reset/fdt_reset_litex.o
+carray-fdt_early_drivers-$(CONFIG_FDT_RESET_METANOIA) += fdt_reset_metanoia
+libsbiutils-objs-$(CONFIG_FDT_RESET_METANOIA) += reset/fdt_reset_metanoia.o
+
carray-fdt_early_drivers-$(CONFIG_FDT_RESET_SG2042_HWMON_MCU) += fdt_reset_sg2042_mcu
libsbiutils-objs-$(CONFIG_FDT_RESET_SG2042_HWMON_MCU) += reset/fdt_reset_sg2042_hwmon_mcu.o