mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 15:31:22 +01:00
lib/utils: reset: Add RPMI System Reset driver
Add RPMI based driver for system reset and enable it in the generic platform defconfig Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
This commit is contained in:
@@ -196,6 +196,7 @@ struct rpmi_message_args {
|
|||||||
enum rpmi_servicegroup_id {
|
enum rpmi_servicegroup_id {
|
||||||
RPMI_SRVGRP_ID_MIN = 0,
|
RPMI_SRVGRP_ID_MIN = 0,
|
||||||
RPMI_SRVGRP_BASE = 0x0001,
|
RPMI_SRVGRP_BASE = 0x0001,
|
||||||
|
RPMI_SRVGRP_SYSTEM_RESET = 0x0002,
|
||||||
RPMI_SRVGRP_ID_MAX_COUNT,
|
RPMI_SRVGRP_ID_MAX_COUNT,
|
||||||
|
|
||||||
/* Reserved range for service groups */
|
/* Reserved range for service groups */
|
||||||
@@ -252,4 +253,30 @@ struct rpmi_base_get_platform_info_resp {
|
|||||||
char plat_info[];
|
char plat_info[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** RPMI System Reset ServiceGroup Service IDs */
|
||||||
|
enum rpmi_system_reset_service_id {
|
||||||
|
RPMI_SYSRST_SRV_ENABLE_NOTIFICATION = 0x01,
|
||||||
|
RPMI_SYSRST_SRV_GET_ATTRIBUTES = 0x02,
|
||||||
|
RPMI_SYSRST_SRV_SYSTEM_RESET = 0x03,
|
||||||
|
RPMI_SYSRST_SRV_ID_MAX_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** RPMI System Reset types */
|
||||||
|
enum rpmi_sysrst_reset_type {
|
||||||
|
RPMI_SYSRST_TYPE_SHUTDOWN = 0x0,
|
||||||
|
RPMI_SYSRST_TYPE_COLD_REBOOT = 0x1,
|
||||||
|
RPMI_SYSRST_TYPE_WARM_REBOOT = 0x2,
|
||||||
|
RPMI_SYSRST_TYPE_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE_POS (1)
|
||||||
|
#define RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE_MASK \
|
||||||
|
(1U << RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE_POS)
|
||||||
|
|
||||||
|
/** Response for system reset attributes */
|
||||||
|
struct rpmi_sysrst_get_reset_attributes_resp {
|
||||||
|
s32 status;
|
||||||
|
u32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* !__RPMI_MSGPROT_H__ */
|
#endif /* !__RPMI_MSGPROT_H__ */
|
||||||
|
@@ -24,6 +24,11 @@ config FDT_RESET_HTIF
|
|||||||
select SYS_HTIF
|
select SYS_HTIF
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config FDT_RESET_RPMI
|
||||||
|
bool "RPMI FDT reset driver"
|
||||||
|
depends on FDT_MAILBOX && RPMI_MAILBOX
|
||||||
|
default n
|
||||||
|
|
||||||
config FDT_RESET_SG2042_HWMON_MCU
|
config FDT_RESET_SG2042_HWMON_MCU
|
||||||
bool "Sophgo SG2042 hwmon MCU FDT reset driver"
|
bool "Sophgo SG2042 hwmon MCU FDT reset driver"
|
||||||
default n
|
default n
|
||||||
|
141
lib/utils/reset/fdt_reset_rpmi.c
Normal file
141
lib/utils/reset/fdt_reset_rpmi.c
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Ventana Micro Systems Inc.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Rahul Pathak <rpathak@ventanamicro.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sbi/sbi_error.h>
|
||||||
|
#include <sbi/sbi_system.h>
|
||||||
|
#include <sbi/sbi_console.h>
|
||||||
|
#include <sbi_utils/fdt/fdt_helper.h>
|
||||||
|
#include <sbi_utils/reset/fdt_reset.h>
|
||||||
|
#include <sbi_utils/mailbox/fdt_mailbox.h>
|
||||||
|
#include <sbi_utils/mailbox/rpmi_msgprot.h>
|
||||||
|
#include <sbi_utils/mailbox/rpmi_mailbox.h>
|
||||||
|
|
||||||
|
/* struct rpmi_sysreset: RPMI System Reset Context */
|
||||||
|
struct rpmi_sysreset {
|
||||||
|
int warm_reset_support;
|
||||||
|
struct mbox_chan *chan;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rpmi_sysreset sysreset_ctx;
|
||||||
|
|
||||||
|
static int rpmi_system_reset_type_check(u32 reset_type)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct rpmi_sysrst_get_reset_attributes_resp resp;
|
||||||
|
|
||||||
|
ret = rpmi_normal_request_with_status(sysreset_ctx.chan,
|
||||||
|
RPMI_SYSRST_SRV_GET_ATTRIBUTES, &reset_type,
|
||||||
|
rpmi_u32_count(reset_type), rpmi_u32_count(reset_type),
|
||||||
|
&resp, rpmi_u32_count(resp), rpmi_u32_count(resp));
|
||||||
|
if (ret) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (resp.flags & RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE_MASK) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rpmi_do_system_reset: Do system reset
|
||||||
|
*
|
||||||
|
* @reset_type: RPMI System Reset Type
|
||||||
|
*/
|
||||||
|
static void rpmi_do_system_reset(u32 reset_type)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = rpmi_posted_request(sysreset_ctx.chan,
|
||||||
|
RPMI_SYSRST_SRV_SYSTEM_RESET,
|
||||||
|
&reset_type, rpmi_u32_count(reset_type),
|
||||||
|
rpmi_u32_count(reset_type));
|
||||||
|
if (ret)
|
||||||
|
sbi_printf("system reset failed [type: %d]: ret: %d\n",
|
||||||
|
reset_type, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rpmi_system_reset_check: Check the support for
|
||||||
|
* various reset types
|
||||||
|
*
|
||||||
|
* @type: SBI System Reset Type
|
||||||
|
* @reason: Reason for system reset
|
||||||
|
*/
|
||||||
|
static int rpmi_system_reset_check(u32 type, u32 reason)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case SBI_SRST_RESET_TYPE_SHUTDOWN:
|
||||||
|
case SBI_SRST_RESET_TYPE_COLD_REBOOT:
|
||||||
|
return 1;
|
||||||
|
case SBI_SRST_RESET_TYPE_WARM_REBOOT:
|
||||||
|
return sysreset_ctx.warm_reset_support;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpmi_system_reset(u32 type, u32 reason)
|
||||||
|
{
|
||||||
|
u32 reset_type;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case SBI_SRST_RESET_TYPE_SHUTDOWN:
|
||||||
|
reset_type = RPMI_SYSRST_TYPE_SHUTDOWN;
|
||||||
|
break;
|
||||||
|
case SBI_SRST_RESET_TYPE_COLD_REBOOT:
|
||||||
|
reset_type = RPMI_SYSRST_TYPE_COLD_REBOOT;
|
||||||
|
break;
|
||||||
|
case SBI_SRST_RESET_TYPE_WARM_REBOOT:
|
||||||
|
reset_type = RPMI_SYSRST_TYPE_WARM_REBOOT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpmi_do_system_reset(reset_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sbi_system_reset_device rpmi_reset_dev = {
|
||||||
|
.name = "rpmi-system-reset",
|
||||||
|
.system_reset_check = rpmi_system_reset_check,
|
||||||
|
.system_reset = rpmi_system_reset,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rpmi_reset_init(const void *fdt, int nodeoff,
|
||||||
|
const struct fdt_match *match)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* If channel already available then do nothing. */
|
||||||
|
if (sysreset_ctx.chan)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If channel request failed then other end does not support
|
||||||
|
* system reset group so do nothing.
|
||||||
|
*/
|
||||||
|
ret = fdt_mailbox_request_chan(fdt, nodeoff, 0, &sysreset_ctx.chan);
|
||||||
|
if (ret)
|
||||||
|
return SBI_ENODEV;
|
||||||
|
|
||||||
|
sysreset_ctx.warm_reset_support =
|
||||||
|
rpmi_system_reset_type_check(RPMI_SYSRST_TYPE_WARM_REBOOT);
|
||||||
|
|
||||||
|
sbi_system_reset_add_device(&rpmi_reset_dev);
|
||||||
|
|
||||||
|
return SBI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct fdt_match rpmi_reset_match[] = {
|
||||||
|
{ .compatible = "riscv,rpmi-system-reset" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fdt_driver fdt_reset_rpmi = {
|
||||||
|
.match_table = rpmi_reset_match,
|
||||||
|
.init = rpmi_reset_init,
|
||||||
|
};
|
@@ -29,3 +29,6 @@ libsbiutils-objs-$(CONFIG_FDT_RESET_SUNXI_WDT) += reset/fdt_reset_sunxi_wdt.o
|
|||||||
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_poweroff
|
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_poweroff
|
||||||
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_reboot
|
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_SYSCON) += fdt_syscon_reboot
|
||||||
libsbiutils-objs-$(CONFIG_FDT_RESET_SYSCON) += reset/fdt_reset_syscon.o
|
libsbiutils-objs-$(CONFIG_FDT_RESET_SYSCON) += reset/fdt_reset_syscon.o
|
||||||
|
|
||||||
|
carray-fdt_reset_drivers-$(CONFIG_FDT_RESET_RPMI) += fdt_reset_rpmi
|
||||||
|
libsbiutils-objs-$(CONFIG_FDT_RESET_RPMI) += reset/fdt_reset_rpmi.o
|
||||||
|
@@ -29,6 +29,7 @@ CONFIG_FDT_RESET=y
|
|||||||
CONFIG_FDT_RESET_ATCWDT200=y
|
CONFIG_FDT_RESET_ATCWDT200=y
|
||||||
CONFIG_FDT_RESET_GPIO=y
|
CONFIG_FDT_RESET_GPIO=y
|
||||||
CONFIG_FDT_RESET_HTIF=y
|
CONFIG_FDT_RESET_HTIF=y
|
||||||
|
CONFIG_FDT_RESET_RPMI=y
|
||||||
CONFIG_FDT_RESET_SUNXI_WDT=y
|
CONFIG_FDT_RESET_SUNXI_WDT=y
|
||||||
CONFIG_FDT_RESET_SG2042_HWMON_MCU=y
|
CONFIG_FDT_RESET_SG2042_HWMON_MCU=y
|
||||||
CONFIG_FDT_RESET_SYSCON=y
|
CONFIG_FDT_RESET_SYSCON=y
|
||||||
|
Reference in New Issue
Block a user