diff options
Diffstat (limited to 'lib/utils')
| -rw-r--r-- | lib/utils/cppc/fdt_cppc_rpmi.c | 44 | ||||
| -rw-r--r-- | lib/utils/mpxy/fdt_mpxy_rpmi_logging.c | 2 | ||||
| -rw-r--r-- | lib/utils/mpxy/fdt_mpxy_rpmi_mbox.c | 2 | ||||
| -rw-r--r-- | lib/utils/mpxy/fdt_mpxy_rpmi_mm.c | 9 | ||||
| -rw-r--r-- | lib/utils/reset/Kconfig | 4 | ||||
| -rw-r--r-- | lib/utils/reset/fdt_reset_metanoia.c | 72 | ||||
| -rw-r--r-- | lib/utils/reset/objects.mk | 3 |
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, ®_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 |
