mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-17 02:15:02 +00:00
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:
parent
48380f9b2a
commit
a1766d55e5
6 changed files with 91 additions and 0 deletions
|
@ -951,6 +951,26 @@ int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window)
|
|||
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,
|
||||
sc_faddr_t addr)
|
||||
{
|
||||
|
|
|
@ -351,6 +351,13 @@ config WDT_SBSA
|
|||
In the single stage mode, when the timeout is reached, your system
|
||||
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
|
||||
bool "sl28cpld watchdog timer support"
|
||||
depends on WDT && SL28CPLD
|
||||
|
|
|
@ -45,6 +45,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
|
|||
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
|
||||
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.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_SP805) += sp805_wdt.o
|
||||
obj-$(CONFIG_WDT_STARFIVE) += starfive_wdt.o
|
||||
|
|
59
drivers/watchdog/siemens_pmic_wdt.c
Normal file
59
drivers/watchdog/siemens_pmic_wdt.c
Normal 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,
|
||||
};
|
|
@ -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_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 */
|
||||
|
|
|
@ -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 */
|
||||
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 */
|
||||
int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
|
||||
|
|
Loading…
Add table
Reference in a new issue