wdt: imx8qxp: add option to control external PMIC wdt via IMX8 SCU

Driver for a PMIC watchdog timer controlled via Siemens SCU firmware
extensions. Only useful on some Siemens i.MX8-based platforms as
special SCFW is needed which provides the needed SCU API.

Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
Signed-off-by: Heiko Schocher <hs@denx.de>
Reviewed-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Heiko Schocher 2024-11-23 17:52:45 +01:00 committed by Fabio Estevam
parent 48380f9b2a
commit a1766d55e5
6 changed files with 91 additions and 0 deletions

View file

@ -951,6 +951,26 @@ int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window)
return ret; return ret;
} }
int sc_timer_control_siemens_pmic_wdog(sc_ipc_t ipc, u8 cmd)
{
struct udevice *dev = gd->arch.scu_dev;
struct sc_rpc_msg_s msg;
int size = sizeof(struct sc_rpc_msg_s);
int ret;
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SVC(&msg) = (u8)SC_RPC_SVC_TIMER;
RPC_FUNC(&msg) = (u8)TIMER_FUNC_CTRL_SIEMENS_PMIC_WDOG;
RPC_U8(&msg, 0U) = (u8)cmd;
RPC_SIZE(&msg) = 2U;
ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
if (ret)
printf("%s: res:%d\n", __func__, RPC_R8(&msg));
return ret;
}
int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd, int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
sc_faddr_t addr) sc_faddr_t addr)
{ {

View file

@ -351,6 +351,13 @@ config WDT_SBSA
In the single stage mode, when the timeout is reached, your system In the single stage mode, when the timeout is reached, your system
will be reset by WS1. The first signal (WS0) is ignored. will be reset by WS1. The first signal (WS0) is ignored.
config WDT_SIEMENS_PMIC
bool "Enable PMIC Watchdog Timer support for Siemens platforms"
depends on ARCH_IMX8 && WDT
help
Select this to enable the PMIC watchdog driver controlled via
IMX8 SCU API found on Siemens platforms.
config WDT_SL28CPLD config WDT_SL28CPLD
bool "sl28cpld watchdog timer support" bool "sl28cpld watchdog timer support"
depends on WDT && SL28CPLD depends on WDT && SL28CPLD

View file

@ -45,6 +45,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
obj-$(CONFIG_WDT_SIEMENS_PMIC) += siemens_pmic_wdt.o
obj-$(CONFIG_WDT_SL28CPLD) += sl28cpld-wdt.o obj-$(CONFIG_WDT_SL28CPLD) += sl28cpld-wdt.o
obj-$(CONFIG_WDT_SP805) += sp805_wdt.o obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
obj-$(CONFIG_WDT_STARFIVE) += starfive_wdt.o obj-$(CONFIG_WDT_STARFIVE) += starfive_wdt.o

View file

@ -0,0 +1,59 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for a PMIC watchdog timer controlled via Siemens SCU firmware
* extensions. Only useful on some Siemens i.MX8-based platforms as
* special NXP SCFW is needed which provides the needed SCU API.
*
* Copyright (C) 2024 Siemens AG
*/
#include <dm.h>
#include <wdt.h>
#include <firmware/imx/sci/sci.h>
/* watchdog commands */
#define CMD_START_WDT 0x55
#define CMD_STOP_WDT 0x45
#define CMD_PING_WDT 0x35
static int scu_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
/* start external watchdog via Timer API */
return sc_timer_control_siemens_pmic_wdog(-1, CMD_START_WDT);
}
static int scu_wdt_stop(struct udevice *dev)
{
/* stop external watchdog via Timer API */
return sc_timer_control_siemens_pmic_wdog(-1, CMD_STOP_WDT);
}
static int scu_wdt_reset(struct udevice *dev)
{
return sc_timer_control_siemens_pmic_wdog(-1, CMD_PING_WDT);
}
static int scu_wdt_probe(struct udevice *dev)
{
debug("%s(dev=%p)\n", __func__, dev);
return 0;
}
static const struct wdt_ops scu_wdt_ops = {
.reset = scu_wdt_reset,
.start = scu_wdt_start,
.stop = scu_wdt_stop,
};
static const struct udevice_id scu_wdt_ids[] = {
{ .compatible = "siemens,scu-wdt" },
{ }
};
U_BOOT_DRIVER(scu_wdt) = {
.name = "scu_wdt",
.id = UCLASS_WDT,
.of_match = scu_wdt_ids,
.probe = scu_wdt_probe,
.ops = &scu_wdt_ops,
};

View file

@ -231,4 +231,7 @@ struct sc_rpc_msg_s {
#define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U /* Index for sc_timer_set_sysctr_periodic_alarm() RPC call */ #define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U /* Index for sc_timer_set_sysctr_periodic_alarm() RPC call */
#define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U /* Index for sc_timer_cancel_sysctr_alarm() RPC call */ #define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U /* Index for sc_timer_cancel_sysctr_alarm() RPC call */
/* Siemens specific API extension */
#define TIMER_FUNC_CTRL_SIEMENS_PMIC_WDOG 20U /*!< Index for sc_timer_ctrl_pmic_wdog() RPC call */
#endif /* SC_RPC_H */ #endif /* SC_RPC_H */

View file

@ -123,6 +123,7 @@ int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid);
/* Timer API */ /* Timer API */
int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window); int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window);
int sc_timer_control_siemens_pmic_wdog(sc_ipc_t ipc, u8 cmd);
/* SECO API */ /* SECO API */
int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd, int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,