drivers: watchdog: support NXP FS26 watchdog
Introduce support for NXP FS26 SBC watchdog. Both Challenger and Simple watchdog types are supported. Only watchdog functionalities of the device are supported and any other monitoring feature is either not supported or disabled. Signed-off-by: Manuel Argüelles <manuel.arguelles@nxp.com>
This commit is contained in:
parent
565e582b8d
commit
3d36af15fa
|
@ -42,5 +42,6 @@ zephyr_library_sources_ifdef(CONFIG_WDT_OPENTITAN wdt_opentitan.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c wdt_dw_common.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_WDT_ANDES_ATCWDT200 wdt_andes_atcwdt200.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_WDT_NXP_FS26 wdt_nxp_fs26.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE wdt_handlers.c)
|
||||
|
|
|
@ -114,4 +114,6 @@ source "drivers/watchdog/Kconfig.opentitan"
|
|||
|
||||
source "drivers/watchdog/Kconfig.andes_atcwdt200"
|
||||
|
||||
source "drivers/watchdog/Kconfig.nxp_fs26"
|
||||
|
||||
endif # WATCHDOG
|
||||
|
|
76
drivers/watchdog/Kconfig.nxp_fs26
Normal file
76
drivers/watchdog/Kconfig.nxp_fs26
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Copyright 2023 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig WDT_NXP_FS26
|
||||
bool "NXP FS26 SBC watchdog driver"
|
||||
default y
|
||||
depends on DT_HAS_NXP_FS26_WDOG_ENABLED
|
||||
select SPI
|
||||
select GPIO
|
||||
help
|
||||
Enable the NXP FS26 SBC watchdog driver.
|
||||
|
||||
if WDT_NXP_FS26
|
||||
|
||||
config WDT_NXP_FS26_INIT_PRIORITY
|
||||
int
|
||||
default 80
|
||||
help
|
||||
Device driver initialization priority. Device is connected to SPI bus,
|
||||
so it has to be initialized after SPI driver.
|
||||
|
||||
config WDT_NXP_FS26_ERROR_COUNTER_LIMIT
|
||||
int "Watchdog error counter limit"
|
||||
default 6
|
||||
help
|
||||
Sets the maximum value of the watchdog error counter. Each time a
|
||||
watchdog failure occurs, the device increments this counter by 2. The
|
||||
watchdog error counter is decremented by 1 each time the watchdog is
|
||||
properly refreshed.
|
||||
|
||||
Possible values are 2, 4, 6, 8.
|
||||
|
||||
config WDT_NXP_FS26_REFRESH_COUNTER_LIMIT
|
||||
int "Watchdog refresh counter limit"
|
||||
default 6
|
||||
help
|
||||
Sets the maximum value of the watchdog refresh counter. Each time the
|
||||
watchdog is properly refreshed, this counter is incremented by 1. Each
|
||||
time this counter reaches its maximum value and if the next refresh is
|
||||
also good, the fault error counter is decremented by 1. Each time
|
||||
there is a bad watchdog refresh, this counter is reset to 0.
|
||||
|
||||
Possible values are 1, 2, 4, 6.
|
||||
|
||||
config WDT_NXP_FS26_SEED
|
||||
hex "Watchdog seed"
|
||||
default 0x5ab2
|
||||
range 0x0 0xffff
|
||||
help
|
||||
Seed to pass to the device. This property can be used with both simple
|
||||
and challenger watchdog configurations. In simple watchdog
|
||||
configuration, values 0xffff and 0x0000 are not allowed. In challenger
|
||||
watchdog configuration, value 0x0000 is not allowed.
|
||||
|
||||
config WDT_NXP_FS26_EXIT_DEBUG_MODE
|
||||
bool "Exit DEBUG mode"
|
||||
help
|
||||
If the device is started in DEBUG mode, the driver will exit this mode
|
||||
so that the watchdog is enabled. Otherwise, if the device is in DEBUG
|
||||
mode and this driver is enabled, it will fail to initialize.
|
||||
|
||||
config WDT_NXP_FS26_INT_THREAD_STACK_SIZE
|
||||
int "Stack size for internal interrupt handler"
|
||||
default 1024
|
||||
help
|
||||
Size of the stack used for internal thread which is ran for
|
||||
interrupt processing.
|
||||
|
||||
config WDT_NXP_FS26_INT_THREAD_PRIO
|
||||
int "Priority for internal incoming packet handler"
|
||||
default 2
|
||||
help
|
||||
Priority level for internal cooperative thread which is ran for
|
||||
interrupt processing.
|
||||
|
||||
endif # WDT_NXP_FS26
|
838
drivers/watchdog/wdt_nxp_fs26.c
Normal file
838
drivers/watchdog/wdt_nxp_fs26.c
Normal file
|
@ -0,0 +1,838 @@
|
|||
/*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT nxp_fs26_wdog
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/watchdog.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(wdt_nxp_fs26);
|
||||
|
||||
#include "wdt_nxp_fs26.h"
|
||||
|
||||
#if defined(CONFIG_BIG_ENDIAN)
|
||||
#define SWAP_ENDIANNESS
|
||||
#endif
|
||||
|
||||
#define FS26_CRC_TABLE_SIZE 256U
|
||||
#define FS26_CRC_INIT 0xff
|
||||
#define FS26_FS_WD_TOKEN_DEFAULT 0x5ab2
|
||||
#define FS26_INIT_FS_TIMEOUT_MS 1000U
|
||||
|
||||
/* Helper macros to set register values from Kconfig options */
|
||||
#define WD_ERR_LIMIT(x) CONCAT(WD_ERR_LIMIT_, x)
|
||||
#define WD_RFR_LIMIT(x) CONCAT(WD_RFR_LIMIT_, x)
|
||||
#define WDW_PERIOD(x) CONCAT(CONCAT(WDW_PERIOD_, x), MS)
|
||||
|
||||
#define BAD_WD_REFRESH_ERROR_STRING(x) \
|
||||
((((x) & BAD_WD_DATA) ? "error in the data" : \
|
||||
(((x) & BAD_WD_TIMING) ? "error in the timing (window)" \
|
||||
: "unknown error")))
|
||||
|
||||
enum fs26_wd_type {
|
||||
FS26_WD_SIMPLE,
|
||||
FS26_WD_CHALLENGER
|
||||
};
|
||||
|
||||
struct fs26_spi_rx_frame {
|
||||
union {
|
||||
struct {
|
||||
uint8_t m_aval : 1;
|
||||
uint8_t fs_en : 1;
|
||||
uint8_t fs_g : 1;
|
||||
uint8_t com_g : 1;
|
||||
uint8_t wio_g : 1;
|
||||
uint8_t vsup_g : 1;
|
||||
uint8_t reg_g : 1;
|
||||
uint8_t tsd_g : 1;
|
||||
};
|
||||
uint8_t raw;
|
||||
} status;
|
||||
uint16_t data;
|
||||
};
|
||||
|
||||
struct fs26_spi_tx_frame {
|
||||
bool write;
|
||||
uint8_t addr;
|
||||
uint16_t data;
|
||||
};
|
||||
|
||||
struct wdt_nxp_fs26_config {
|
||||
struct spi_dt_spec spi;
|
||||
enum fs26_wd_type wd_type;
|
||||
struct gpio_dt_spec int_gpio;
|
||||
};
|
||||
|
||||
struct wdt_nxp_fs26_data {
|
||||
wdt_callback_t callback;
|
||||
uint16_t token; /* local copy of the watchdog token */
|
||||
bool timeout_installed;
|
||||
uint8_t window_period;
|
||||
uint8_t window_duty_cycle;
|
||||
uint8_t fs_reaction;
|
||||
struct gpio_callback int_gpio_cb;
|
||||
struct k_sem int_sem;
|
||||
struct k_thread int_thread;
|
||||
|
||||
K_KERNEL_STACK_MEMBER(int_thread_stack, CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE);
|
||||
};
|
||||
|
||||
/*
|
||||
* Allowed values for watchdog period and duty cycle (CLOSED window).
|
||||
* The index is the value to write to the register. Keep values in ascending order.
|
||||
*/
|
||||
static const uint32_t fs26_period_values[] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 64, 128, 256, 512, 1024
|
||||
};
|
||||
|
||||
static const double fs26_dc_closed_values[] = {
|
||||
0.3125, 0.375, 0.5, 0.625, 0.6875, 0.75, 0.8125
|
||||
};
|
||||
|
||||
/* CRC lookup table */
|
||||
static const uint8_t FS26_CRC_TABLE[FS26_CRC_TABLE_SIZE] = {
|
||||
0x00u, 0x1du, 0x3au, 0x27u, 0x74u, 0x69u, 0x4eu, 0x53u, 0xe8u,
|
||||
0xf5u, 0xd2u, 0xcfu, 0x9cu, 0x81u, 0xa6u, 0xbbu, 0xcdu, 0xd0u,
|
||||
0xf7u, 0xeau, 0xb9u, 0xa4u, 0x83u, 0x9eu, 0x25u, 0x38u, 0x1fu,
|
||||
0x02u, 0x51u, 0x4cu, 0x6bu, 0x76u, 0x87u, 0x9au, 0xbdu, 0xa0u,
|
||||
0xf3u, 0xeeu, 0xc9u, 0xd4u, 0x6fu, 0x72u, 0x55u, 0x48u, 0x1bu,
|
||||
0x06u, 0x21u, 0x3cu, 0x4au, 0x57u, 0x70u, 0x6du, 0x3eu, 0x23u,
|
||||
0x04u, 0x19u, 0xa2u, 0xbfu, 0x98u, 0x85u, 0xd6u, 0xcbu, 0xecu,
|
||||
0xf1u, 0x13u, 0x0eu, 0x29u, 0x34u, 0x67u, 0x7au, 0x5du, 0x40u,
|
||||
0xfbu, 0xe6u, 0xc1u, 0xdcu, 0x8fu, 0x92u, 0xb5u, 0xa8u, 0xdeu,
|
||||
0xc3u, 0xe4u, 0xf9u, 0xaau, 0xb7u, 0x90u, 0x8du, 0x36u, 0x2bu,
|
||||
0x0cu, 0x11u, 0x42u, 0x5fu, 0x78u, 0x65u, 0x94u, 0x89u, 0xaeu,
|
||||
0xb3u, 0xe0u, 0xfdu, 0xdau, 0xc7u, 0x7cu, 0x61u, 0x46u, 0x5bu,
|
||||
0x08u, 0x15u, 0x32u, 0x2fu, 0x59u, 0x44u, 0x63u, 0x7eu, 0x2du,
|
||||
0x30u, 0x17u, 0x0au, 0xb1u, 0xacu, 0x8bu, 0x96u, 0xc5u, 0xd8u,
|
||||
0xffu, 0xe2u, 0x26u, 0x3bu, 0x1cu, 0x01u, 0x52u, 0x4fu, 0x68u,
|
||||
0x75u, 0xceu, 0xd3u, 0xf4u, 0xe9u, 0xbau, 0xa7u, 0x80u, 0x9du,
|
||||
0xebu, 0xf6u, 0xd1u, 0xccu, 0x9fu, 0x82u, 0xa5u, 0xb8u, 0x03u,
|
||||
0x1eu, 0x39u, 0x24u, 0x77u, 0x6au, 0x4du, 0x50u, 0xa1u, 0xbcu,
|
||||
0x9bu, 0x86u, 0xd5u, 0xc8u, 0xefu, 0xf2u, 0x49u, 0x54u, 0x73u,
|
||||
0x6eu, 0x3du, 0x20u, 0x07u, 0x1au, 0x6cu, 0x71u, 0x56u, 0x4bu,
|
||||
0x18u, 0x05u, 0x22u, 0x3fu, 0x84u, 0x99u, 0xbeu, 0xa3u, 0xf0u,
|
||||
0xedu, 0xcau, 0xd7u, 0x35u, 0x28u, 0x0fu, 0x12u, 0x41u, 0x5cu,
|
||||
0x7bu, 0x66u, 0xddu, 0xc0u, 0xe7u, 0xfau, 0xa9u, 0xb4u, 0x93u,
|
||||
0x8eu, 0xf8u, 0xe5u, 0xc2u, 0xdfu, 0x8cu, 0x91u, 0xb6u, 0xabu,
|
||||
0x10u, 0x0du, 0x2au, 0x37u, 0x64u, 0x79u, 0x5eu, 0x43u, 0xb2u,
|
||||
0xafu, 0x88u, 0x95u, 0xc6u, 0xdbu, 0xfcu, 0xe1u, 0x5au, 0x47u,
|
||||
0x60u, 0x7du, 0x2eu, 0x33u, 0x14u, 0x09u, 0x7fu, 0x62u, 0x45u,
|
||||
0x58u, 0x0bu, 0x16u, 0x31u, 0x2cu, 0x97u, 0x8au, 0xadu, 0xb0u,
|
||||
0xe3u, 0xfeu, 0xd9u, 0xc4u
|
||||
};
|
||||
|
||||
static uint8_t fs26_calcrc(const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t crc;
|
||||
uint8_t tableidx;
|
||||
uint8_t i;
|
||||
|
||||
/* Set CRC token value */
|
||||
crc = FS26_CRC_INIT;
|
||||
|
||||
for (i = size; i > 0; i--) {
|
||||
tableidx = crc ^ data[i];
|
||||
crc = FS26_CRC_TABLE[tableidx];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
static int fs26_spi_transceive(const struct spi_dt_spec *spi,
|
||||
struct fs26_spi_tx_frame *tx_frame,
|
||||
struct fs26_spi_rx_frame *rx_frame)
|
||||
{
|
||||
uint32_t tx_buf;
|
||||
uint32_t rx_buf;
|
||||
uint8_t crc;
|
||||
int retval;
|
||||
|
||||
struct spi_buf spi_tx_buf = {
|
||||
.buf = &tx_buf,
|
||||
.len = sizeof(tx_buf)
|
||||
};
|
||||
struct spi_buf spi_rx_buf = {
|
||||
.buf = &rx_buf,
|
||||
.len = sizeof(rx_buf)
|
||||
};
|
||||
struct spi_buf_set spi_tx_set = {
|
||||
.buffers = &spi_tx_buf,
|
||||
.count = 1U
|
||||
};
|
||||
struct spi_buf_set spi_rx_set = {
|
||||
.buffers = &spi_rx_buf,
|
||||
.count = 1U
|
||||
};
|
||||
|
||||
/* Create frame to Tx, always for Fail Safe */
|
||||
tx_buf = (uint32_t)(FS26_SET_REG_ADDR(tx_frame->addr)
|
||||
| FS26_SET_DATA(tx_frame->data)
|
||||
| (tx_frame->write ? FS26_RW : 0));
|
||||
|
||||
crc = fs26_calcrc((uint8_t *)&tx_buf, sizeof(tx_buf) - 1);
|
||||
tx_buf |= (uint32_t)FS26_SET_CRC(crc);
|
||||
|
||||
#if defined(SWAP_ENDIANNESS)
|
||||
tx_buf = __builtin_bswap32(tx_buf);
|
||||
#endif
|
||||
|
||||
retval = spi_transceive_dt(spi, &spi_tx_set, &spi_rx_set);
|
||||
if (retval) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if defined(SWAP_ENDIANNESS)
|
||||
rx_buf = __builtin_bswap32(rx_buf);
|
||||
#endif
|
||||
|
||||
/* Verify CRC of Rx frame */
|
||||
crc = fs26_calcrc((uint8_t *)&rx_buf, sizeof(rx_buf) - 1);
|
||||
if (crc != ((uint8_t)FS26_GET_CRC(rx_buf))) {
|
||||
LOG_ERR("Rx invalid CRC");
|
||||
retval = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rx_frame) {
|
||||
rx_frame->status.raw = (uint8_t)FS26_GET_DEV_STATUS(rx_buf);
|
||||
rx_frame->data = (uint16_t)FS26_GET_DATA(rx_buf);
|
||||
}
|
||||
|
||||
error:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get value of register with address @p addr
|
||||
*
|
||||
* @param spi SPI specs for interacting with the device
|
||||
* @param addr Register address
|
||||
* @param rx_frame SPI frame containing read data and device status flags
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static int fs26_getreg(const struct spi_dt_spec *spi, uint8_t addr,
|
||||
struct fs26_spi_rx_frame *rx_frame)
|
||||
{
|
||||
struct fs26_spi_tx_frame tx_frame = {
|
||||
.addr = addr,
|
||||
.write = 0,
|
||||
.data = 0
|
||||
};
|
||||
|
||||
return fs26_spi_transceive(spi, &tx_frame, rx_frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set @p regval value in register with address @p addr
|
||||
*
|
||||
* @param spi SPI specs for interacting with the device
|
||||
* @param addr Register address
|
||||
* @param regval Register value to set
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static int fs26_setreg(const struct spi_dt_spec *spi, uint8_t addr, uint16_t regval)
|
||||
{
|
||||
struct fs26_spi_tx_frame tx_frame = {
|
||||
.addr = addr,
|
||||
.write = true,
|
||||
.data = regval
|
||||
};
|
||||
|
||||
return fs26_spi_transceive(spi, &tx_frame, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate watchdog answer based on received token
|
||||
*
|
||||
* @return answer value to write to FS_WD_ANSWER
|
||||
*/
|
||||
static inline uint16_t fs26_wd_compute_answer(uint16_t token)
|
||||
{
|
||||
uint32_t tmp = token;
|
||||
|
||||
tmp *= 4U;
|
||||
tmp += 6U;
|
||||
tmp -= 4U;
|
||||
tmp = ~tmp;
|
||||
tmp /= 4U;
|
||||
|
||||
return (uint16_t)tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Refresh the watchdog and verify the refresh was good.
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static int fs26_wd_refresh(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
int retval = 0;
|
||||
int key;
|
||||
uint16_t answer;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
|
||||
if (config->wd_type == FS26_WD_SIMPLE) {
|
||||
if (fs26_setreg(&config->spi, FS26_FS_WD_ANSWER, data->token) == 0) {
|
||||
LOG_ERR("Failed to write answer");
|
||||
retval = -EIO;
|
||||
}
|
||||
} else if (config->wd_type == FS26_WD_CHALLENGER) {
|
||||
key = irq_lock();
|
||||
|
||||
/* Read challenge token generated by the device */
|
||||
if (fs26_getreg(&config->spi, FS26_FS_WD_TOKEN, &rx_frame)) {
|
||||
LOG_ERR("Failed to obtain watchdog token");
|
||||
retval = -EIO;
|
||||
} else {
|
||||
data->token = rx_frame.data;
|
||||
LOG_DBG("Watchdog token is %x", data->token);
|
||||
|
||||
answer = fs26_wd_compute_answer(data->token);
|
||||
if (fs26_setreg(&config->spi, FS26_FS_WD_ANSWER, answer)) {
|
||||
LOG_ERR("Failed to write answer");
|
||||
retval = -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
} else {
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if watchdog refresh was successful */
|
||||
if (!retval) {
|
||||
if (!fs26_getreg(&config->spi, FS26_FS_GRL_FLAGS, &rx_frame)) {
|
||||
if ((rx_frame.data & FS_WD_G_MASK) == FS_WD_G) {
|
||||
if (!fs26_getreg(&config->spi, FS26_FS_DIAG_SAFETY1, &rx_frame)) {
|
||||
LOG_ERR("Bad watchdog refresh, %s",
|
||||
BAD_WD_REFRESH_ERROR_STRING(rx_frame.data));
|
||||
}
|
||||
retval = -EIO;
|
||||
} else {
|
||||
LOG_DBG("Refreshed the watchdog");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for state machine to be at in INIT_FS state
|
||||
*
|
||||
* @return 0 on success, -ETIMEDOUT if timedout
|
||||
*/
|
||||
static int fs26_poll_for_init_fs_state(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
uint32_t regval = 0;
|
||||
int64_t timeout;
|
||||
int64_t now;
|
||||
|
||||
timeout = k_uptime_get() + FS26_INIT_FS_TIMEOUT_MS;
|
||||
|
||||
do {
|
||||
if (!fs26_getreg(&config->spi, FS26_FS_STATES, &rx_frame)) {
|
||||
regval = rx_frame.data;
|
||||
}
|
||||
k_sleep(K_MSEC(1));
|
||||
now = k_uptime_get();
|
||||
} while ((now < timeout) && (regval & FS_STATES_MASK) != FS_STATES_INIT_FS);
|
||||
|
||||
if (now >= timeout) {
|
||||
LOG_ERR("Timedout waiting for INIT_FS state");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Go to INIT_FS state from any FS state after INIT_FS
|
||||
*
|
||||
* After INIT_FS closure, it is possible to come back to INIT_FS with the
|
||||
* GOTO_INIT bit in FS_SAFE_IOS_1 register from any FS state after INIT_FS.
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static int fs26_goto_init_fs_state(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
uint32_t current_state;
|
||||
int retval = -EIO;
|
||||
|
||||
if (!fs26_getreg(&config->spi, FS26_FS_STATES, &rx_frame)) {
|
||||
current_state = rx_frame.data & FS_STATES_MASK;
|
||||
if (current_state < FS_STATES_INIT_FS) {
|
||||
LOG_ERR("Cannot go to INIT_FS from current state %x", current_state);
|
||||
retval = -EIO;
|
||||
} else if (current_state == FS_STATES_INIT_FS) {
|
||||
retval = 0;
|
||||
} else {
|
||||
fs26_setreg(&config->spi, FS26_FS_SAFE_IOS_1, (uint32_t)FS_GOTO_INIT);
|
||||
retval = fs26_poll_for_init_fs_state(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close INIT_FS phase with a (good) watchdog refresh.
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static inline int fs26_exit_init_fs_state(const struct device *dev)
|
||||
{
|
||||
return fs26_wd_refresh(dev);
|
||||
}
|
||||
|
||||
static int wdt_nxp_fs26_feed(const struct device *dev, int channel_id)
|
||||
{
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
|
||||
if (channel_id != 0) {
|
||||
LOG_ERR("Invalid channel ID");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!data->timeout_installed) {
|
||||
LOG_ERR("No timeout installed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return fs26_wd_refresh(dev);
|
||||
}
|
||||
|
||||
static int wdt_nxp_fs26_setup(const struct device *dev, uint8_t options)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
uint32_t regval;
|
||||
|
||||
if (!data->timeout_installed) {
|
||||
LOG_ERR("No timeout installed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((options & WDT_OPT_PAUSE_IN_SLEEP) || (options & WDT_OPT_PAUSE_HALTED_BY_DBG)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply fail-safe reaction configuration on RSTB and/or the safety output(s),
|
||||
* configurable during the initialization phase.
|
||||
*/
|
||||
if (fs26_goto_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to go to INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
regval = WD_ERR_LIMIT(CONFIG_WDT_NXP_FS26_ERROR_COUNTER_LIMIT)
|
||||
| WD_RFR_LIMIT(CONFIG_WDT_NXP_FS26_REFRESH_COUNTER_LIMIT)
|
||||
| ((data->fs_reaction << WD_FS_REACTION_SHIFT) & WD_FS_REACTION_MASK);
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_WD_CFG, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_WD_CFG, ~regval);
|
||||
|
||||
/* Apply watchdog window configuration, configurable during any FS state */
|
||||
regval = ((data->window_period << WDW_PERIOD_SHIFT) & WDW_PERIOD_MASK)
|
||||
| ((data->window_duty_cycle << WDW_DC_SHIFT) & WDW_DC_MASK)
|
||||
| WDW_RECOVERY_DISABLE;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_WDW_DURATION, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_NOT_WDW_DURATION, ~regval);
|
||||
|
||||
/*
|
||||
* The new watchdog window is effective after the next watchdog refresh,
|
||||
* so feed the watchdog once to make it effective after exiting this
|
||||
* function. Also it's required to close init phase.
|
||||
*/
|
||||
if (fs26_exit_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to close INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_nxp_fs26_install_timeout(const struct device *dev,
|
||||
const struct wdt_timeout_cfg *cfg)
|
||||
{
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
uint32_t window_min;
|
||||
uint8_t i;
|
||||
|
||||
if (data->timeout_installed) {
|
||||
LOG_ERR("No more timeouts can be installed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if ((cfg->window.max == 0) || (cfg->window.max > 1024)
|
||||
|| (cfg->window.max <= cfg->window.min)) {
|
||||
LOG_ERR("Invalid timeout value");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Find nearest period value (rounded up) */
|
||||
for (i = 0; i < ARRAY_SIZE(fs26_period_values); i++) {
|
||||
if (fs26_period_values[i] >= cfg->window.max) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
data->window_period = i;
|
||||
LOG_DBG("window.max requested %d ms, using %d ms",
|
||||
cfg->window.max, fs26_period_values[data->window_period]);
|
||||
|
||||
/*
|
||||
* Find nearest duty cycle value based on new period, that results in a
|
||||
* window's minimum near the requested (rounded up)
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(fs26_dc_closed_values); i++) {
|
||||
window_min = (uint32_t)(fs26_dc_closed_values[i]
|
||||
* fs26_period_values[data->window_period]);
|
||||
if (window_min >= cfg->window.min) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= ARRAY_SIZE(fs26_dc_closed_values)) {
|
||||
LOG_ERR("Watchdog opened window too small");
|
||||
return -EINVAL;
|
||||
}
|
||||
data->window_duty_cycle = i;
|
||||
|
||||
LOG_DBG("window.min requested %d ms, using %d ms (%.2f%%)",
|
||||
cfg->window.min, window_min,
|
||||
fs26_dc_closed_values[data->window_duty_cycle] * 100);
|
||||
|
||||
/* Fail-safe reaction configuration */
|
||||
switch (cfg->flags) {
|
||||
case WDT_FLAG_RESET_SOC:
|
||||
__fallthrough;
|
||||
case WDT_FLAG_RESET_CPU_CORE:
|
||||
data->fs_reaction = WD_FS_REACTION_RSTB_FS0B >> WD_FS_REACTION_SHIFT;
|
||||
LOG_DBG("Configuring reset mode");
|
||||
break;
|
||||
case WDT_FLAG_RESET_NONE:
|
||||
data->fs_reaction = WD_FS_REACTION_NO_ACTION >> WD_FS_REACTION_SHIFT;
|
||||
LOG_DBG("Configuring non-reset mode");
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unsupported watchdog configuration flag");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->callback = cfg->callback;
|
||||
data->timeout_installed = true;
|
||||
|
||||
/* Always return channel ID equal to 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_nxp_fs26_disable(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
uint32_t regval;
|
||||
|
||||
if (fs26_getreg(&config->spi, FS26_FS_WDW_DURATION, &rx_frame)) {
|
||||
return -EIO;
|
||||
}
|
||||
if ((rx_frame.data & WDW_PERIOD_MASK) == WDW_PERIOD_DISABLE) {
|
||||
LOG_ERR("Watchdog already disabled");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* The watchdog window can be disabled only during the initialization phase */
|
||||
if (fs26_goto_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to go to INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
regval = WDW_PERIOD_DISABLE | WDW_RECOVERY_DISABLE;
|
||||
fs26_setreg(&config->spi, FS26_FS_WDW_DURATION, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_NOT_WDW_DURATION, ~regval);
|
||||
|
||||
/* The watchdog disabling is effective when the initialization phase is closed */
|
||||
if (fs26_exit_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to close INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
LOG_DBG("Watchdog disabled");
|
||||
data->timeout_installed = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wdt_nxp_fs26_int_thread(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
uint32_t regval;
|
||||
|
||||
while (1) {
|
||||
k_sem_take(&data->int_sem, K_FOREVER);
|
||||
|
||||
if ((!fs26_getreg(&config->spi, FS26_FS_GRL_FLAGS, &rx_frame))
|
||||
&& ((rx_frame.data & FS_WD_G_MASK) == FS_WD_G)) {
|
||||
|
||||
if ((!fs26_getreg(&config->spi, FS26_FS_DIAG_SAFETY1, &rx_frame))
|
||||
&& (rx_frame.data & BAD_WD_TIMING)) {
|
||||
|
||||
/* Clear flag */
|
||||
regval = BAD_WD_TIMING;
|
||||
fs26_setreg(&config->spi, FS26_FS_DIAG_SAFETY1, regval);
|
||||
|
||||
/* Invoke user callback */
|
||||
if (data->callback && data->timeout_installed) {
|
||||
data->callback(dev, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wdt_nxp_fs26_int_callback(const struct device *dev,
|
||||
struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
struct wdt_nxp_fs26_data *data = CONTAINER_OF(cb, struct wdt_nxp_fs26_data,
|
||||
int_gpio_cb);
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
k_sem_give(&data->int_sem);
|
||||
}
|
||||
|
||||
static int wdt_nxp_fs26_init(const struct device *dev)
|
||||
{
|
||||
const struct wdt_nxp_fs26_config *config = dev->config;
|
||||
struct wdt_nxp_fs26_data *data = dev->data;
|
||||
struct fs26_spi_rx_frame rx_frame;
|
||||
uint32_t regval;
|
||||
|
||||
/* Validate bus is ready */
|
||||
if (!spi_is_ready_dt(&config->spi)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
k_sem_init(&data->int_sem, 0, 1);
|
||||
|
||||
/* Configure GPIO used for INTB signal */
|
||||
if (!gpio_is_ready_dt(&config->int_gpio)) {
|
||||
LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT)) {
|
||||
LOG_ERR("Unable to configure GPIO pin %u", config->int_gpio.pin);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
gpio_init_callback(&(data->int_gpio_cb), wdt_nxp_fs26_int_callback,
|
||||
BIT(config->int_gpio.pin));
|
||||
|
||||
if (gpio_add_callback(config->int_gpio.port, &(data->int_gpio_cb))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gpio_pin_interrupt_configure_dt(&config->int_gpio,
|
||||
GPIO_INT_EDGE_FALLING)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_thread_create(&data->int_thread, data->int_thread_stack,
|
||||
CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)wdt_nxp_fs26_int_thread,
|
||||
(void *)dev, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO),
|
||||
0, K_NO_WAIT);
|
||||
|
||||
/* Verify FS BIST before proceeding */
|
||||
if (fs26_getreg(&config->spi, FS26_FS_DIAG_SAFETY1, &rx_frame)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if ((rx_frame.data & (ABIST1_PASS_MASK | LBIST_STATUS_MASK))
|
||||
!= (ABIST1_PASS | LBIST_STATUS_OK)) {
|
||||
|
||||
LOG_ERR("BIST failed 0x%x", rx_frame.data);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Get FS state machine state */
|
||||
if (fs26_getreg(&config->spi, FS26_FS_STATES, &rx_frame)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Verify if in DEBUG mode */
|
||||
if ((rx_frame.data & DBG_MODE_MASK) == DBG_MODE) {
|
||||
if (IS_ENABLED(CONFIG_WDT_NXP_FS26_EXIT_DEBUG_MODE)) {
|
||||
LOG_DBG("Exiting DEBUG mode");
|
||||
regval = rx_frame.data | EXIT_DBG_MODE;
|
||||
fs26_setreg(&config->spi, FS26_FS_STATES, regval);
|
||||
} else {
|
||||
LOG_ERR("In DEBUG mode, watchdog is disabled");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to INIT_FS state, if not already there */
|
||||
if (fs26_goto_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to go to INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Clear pending FS diagnostic flags before initializing */
|
||||
regval = BAD_WD_DATA | BAD_WD_TIMING | ABIST2_PASS | ABIST2_DONE
|
||||
| SPI_FS_CLK | SPI_FS_REQ | SPI_FS_CRC | FS_OSC_DRIFT;
|
||||
fs26_setreg(&config->spi, FS26_FS_DIAG_SAFETY1, regval);
|
||||
|
||||
/*
|
||||
* Perform the following sequence for all INIT_FS registers (FS_I_xxxx)
|
||||
* - Write the desired data in the FS_I_Register_A (data)
|
||||
* - Write the opposite in the FS_I_NOT_Register_A (~data)
|
||||
*/
|
||||
|
||||
/* OVUV_SAFE_REACTION1 */
|
||||
regval = VMON_PRE_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_PRE_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_CORE_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_CORE_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_LDO1_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_LDO1_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_LDO2_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_LDO2_UV_FS_REACTION_NO_EFFECT;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_OVUV_SAFE_REACTION1, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_OVUV_SAFE_REACTION1, ~regval);
|
||||
|
||||
/* OVUV_SAFE_REACTION2 */
|
||||
regval = VMON_EXT_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_EXT_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_REF_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_REF_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_TRK2_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_TRK2_UV_FS_REACTION_NO_EFFECT |
|
||||
VMON_TRK1_OV_FS_REACTION_NO_EFFECT |
|
||||
VMON_TRK1_UV_FS_REACTION_NO_EFFECT;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_OVUV_SAFE_REACTION2, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_OVUV_SAFE_REACTION2, ~regval);
|
||||
|
||||
/* FS_I_SAFE_INPUTS */
|
||||
regval = FCCU_CFG_NO_MONITORING | ERRMON_ACK_TIME_32MS;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_SAFE_INPUTS, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_SAFE_INPUTS, ~regval);
|
||||
|
||||
/* FS_I_FSSM */
|
||||
regval = FLT_ERR_REACTION_NO_EFFECT | CLK_MON_DIS | DIS8S;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_FSSM, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_FSSM, ~regval);
|
||||
|
||||
/* FS_I_WD_CFG */
|
||||
regval = WD_ERR_LIMIT(CONFIG_WDT_NXP_FS26_ERROR_COUNTER_LIMIT)
|
||||
| WD_RFR_LIMIT(CONFIG_WDT_NXP_FS26_REFRESH_COUNTER_LIMIT)
|
||||
| WD_FS_REACTION_NO_ACTION;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_I_WD_CFG, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_I_NOT_WD_CFG, ~regval);
|
||||
|
||||
/* FS_WDW_DURATION */
|
||||
/* Watchdog always disabled at boot */
|
||||
regval = WDW_PERIOD_DISABLE | WDW_RECOVERY_DISABLE;
|
||||
|
||||
fs26_setreg(&config->spi, FS26_FS_WDW_DURATION, regval);
|
||||
fs26_setreg(&config->spi, FS26_FS_NOT_WDW_DURATION, ~regval);
|
||||
|
||||
/* Set watchdog seed if not using the default */
|
||||
if (data->token != FS26_FS_WD_TOKEN_DEFAULT) {
|
||||
LOG_DBG("Set seed to %x", data->token);
|
||||
fs26_setreg(&config->spi, FS26_FS_WD_TOKEN, data->token);
|
||||
}
|
||||
|
||||
/* Mask all Fail-Safe interrupt sources except for watchdog bad refresh */
|
||||
regval = ~BAD_WD_M;
|
||||
fs26_setreg(&config->spi, FS26_FS_INTB_MASK, regval);
|
||||
|
||||
/* Mask all main interrupt souces */
|
||||
regval = 0xffff;
|
||||
fs26_setreg(&config->spi, FS26_M_TSD_MSK, regval);
|
||||
fs26_setreg(&config->spi, FS26_M_REG_MSK, regval);
|
||||
fs26_setreg(&config->spi, FS26_M_VSUP_MSK, regval);
|
||||
fs26_setreg(&config->spi, FS26_M_WIO_MSK, regval);
|
||||
fs26_setreg(&config->spi, FS26_M_COM_MSK, regval);
|
||||
|
||||
/* INIT_FS must be closed before the 256 ms timeout */
|
||||
if (fs26_exit_init_fs_state(dev)) {
|
||||
LOG_ERR("Failed to close INIT_FS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* After INIT_FS is completed, check for data corruption in init registers */
|
||||
if (!fs26_getreg(&config->spi, FS26_FS_STATES, &rx_frame)) {
|
||||
if ((rx_frame.data & REG_CORRUPT_MASK) == REG_CORRUPT) {
|
||||
LOG_ERR("Data content corruption detected in init registers");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct wdt_driver_api wdt_nxp_fs26_api = {
|
||||
.setup = wdt_nxp_fs26_setup,
|
||||
.disable = wdt_nxp_fs26_disable,
|
||||
.install_timeout = wdt_nxp_fs26_install_timeout,
|
||||
.feed = wdt_nxp_fs26_feed,
|
||||
};
|
||||
|
||||
#define FS26_WDT_DEVICE_INIT(n) \
|
||||
COND_CODE_1(DT_INST_ENUM_IDX(n, type), \
|
||||
(BUILD_ASSERT(CONFIG_WDT_NXP_FS26_SEED != 0x0, \
|
||||
"Seed value 0x0000 is not allowed");), \
|
||||
(BUILD_ASSERT((CONFIG_WDT_NXP_FS26_SEED != 0x0) \
|
||||
&& (CONFIG_WDT_NXP_FS26_SEED != 0xffff), \
|
||||
"Seed values 0x0000 and 0xffff are not allowed");)) \
|
||||
\
|
||||
static struct wdt_nxp_fs26_data wdt_nxp_fs26_data_##n = { \
|
||||
.token = CONFIG_WDT_NXP_FS26_SEED, \
|
||||
}; \
|
||||
\
|
||||
static const struct wdt_nxp_fs26_config wdt_nxp_fs26_config_##n = { \
|
||||
.spi = SPI_DT_SPEC_INST_GET(n, \
|
||||
SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(32), 0), \
|
||||
.wd_type = CONCAT(FS26_WD_, DT_INST_STRING_UPPER_TOKEN(n, type)), \
|
||||
.int_gpio = GPIO_DT_SPEC_INST_GET(n, int_gpios), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
wdt_nxp_fs26_init, \
|
||||
NULL, \
|
||||
&wdt_nxp_fs26_data_##n, \
|
||||
&wdt_nxp_fs26_config_##n, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_WDT_NXP_FS26_INIT_PRIORITY, \
|
||||
&wdt_nxp_fs26_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(FS26_WDT_DEVICE_INIT)
|
580
drivers/watchdog/wdt_nxp_fs26.h
Normal file
580
drivers/watchdog/wdt_nxp_fs26.h
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_WATCHDOG_WDT_NXP_FS26_H_
|
||||
#define ZEPHYR_DRIVERS_WATCHDOG_WDT_NXP_FS26_H_
|
||||
|
||||
/* FS26 SPI Tx frame fields */
|
||||
|
||||
/* Main or Fail-safe register selection (M/FS) */
|
||||
#define FS26_M_FS (0x1 << 31)
|
||||
/* Register Address + M/FS */
|
||||
#define FS26_REG_ADDR_SHIFT (25)
|
||||
#define FS26_REG_ADDR_MASK (0x7f << FS26_REG_ADDR_SHIFT)
|
||||
#define FS26_SET_REG_ADDR(n) (((n) << FS26_REG_ADDR_SHIFT) & FS26_REG_ADDR_MASK)
|
||||
#define FS26_GET_REG_ADDR(n) (((n) & FS26_REG_ADDR_MASK) >> FS26_REG_ADDR_SHIFT)
|
||||
/* Read/Write (reading = 0) */
|
||||
#define FS26_RW (0x1 << 24)
|
||||
|
||||
/* FS26 SPI Rx frame fields */
|
||||
|
||||
/* Device status flags */
|
||||
#define FS26_DEV_STATUS_SHIFT (24)
|
||||
#define FS26_DEV_STATUS_MASK (0xff << FS26_DEV_STATUS_SHIFT)
|
||||
#define FS26_GET_DEV_STATUS(n) (((n) << FS26_DEV_STATUS_SHIFT) & FS26_DEV_STATUS_MASK)
|
||||
/* Main State machine availability (M_AVAL) */
|
||||
#define FS26_M_AVAL (0x1 << 31)
|
||||
/* Fail Safe State machine status (FS_EN) */
|
||||
#define FS26_FS_EN (0x1 << 30)
|
||||
/* Interrupt notification from the Fail-Safe domain */
|
||||
#define FS26_FS_G (0x1 << 29)
|
||||
/* Interrupt notification from the M_COM_FLG register */
|
||||
#define FS26_COM_G (0x1 << 28)
|
||||
/* Interrupt notification from the M_WIO_FLG register */
|
||||
#define FS26_WIO_G (0x1 << 27)
|
||||
/* Interrupt notification from the M_VSUP_FLG register */
|
||||
#define FS26_VSUP_G (0x1 << 26)
|
||||
/* Interrupt notification from the M_REG_FLG register */
|
||||
#define FS26_REG_G (0x1 << 25)
|
||||
/* Interrupt notification from the M_TSD_FLG register */
|
||||
#define FS26_TSD_G (0x1 << 24)
|
||||
|
||||
/* FS26 SPI Tx/Rx frame common fields */
|
||||
|
||||
/* DATA_MSB */
|
||||
#define FS26_DATA_SHIFT (8)
|
||||
#define FS26_DATA_MASK (0xffff << FS26_DATA_SHIFT)
|
||||
#define FS26_SET_DATA(n) (((n) << FS26_DATA_SHIFT) & FS26_DATA_MASK)
|
||||
#define FS26_GET_DATA(n) (((n) & FS26_DATA_MASK) >> FS26_DATA_SHIFT)
|
||||
/* DATA_LSB */
|
||||
#define FS26_DATA_LSB_SHIFT (8)
|
||||
#define FS26_DATA_LSB_MASK (0xff << FS26_DATA_LSB_SHIFT)
|
||||
#define FS26_SET_DATA_LSB(n) (((n) << FS26_DATA_LSB_SHIFT) & FS26_DATA_LSB_MASK)
|
||||
#define FS26_GET_DATA_LSB(n) (((n) & FS26_DATA_LSB_MASK) >> FS26_DATA_LSB_SHIFT)
|
||||
/* DATA_MSB */
|
||||
#define FS26_DATA_MSB_SHIFT (16)
|
||||
#define FS26_DATA_MSB_MASK (0xff << FS26_DATA_MSB_SHIFT)
|
||||
#define FS26_SET_DATA_MSB(n) (((n) << FS26_DATA_MSB_SHIFT) & FS26_DATA_MSB_MASK)
|
||||
#define FS26_GET_DATA_MSB(n) (((n) & FS26_DATA_MSB_MASK) >> FS26_DATA_MSB_SHIFT)
|
||||
/* CRC */
|
||||
#define FS26_CRC_SHIFT (0)
|
||||
#define FS26_CRC_MASK (0xff << FS26_CRC_SHIFT)
|
||||
#define FS26_SET_CRC(n) (((n) << FS26_CRC_SHIFT) & FS26_CRC_MASK)
|
||||
#define FS26_GET_CRC(n) (((n) & FS26_CRC_MASK) >> FS26_CRC_SHIFT)
|
||||
|
||||
/* FS26 SPI register map */
|
||||
|
||||
#define FS26_M_DEVICE_ID (0x0)
|
||||
#define FS26_M_PROGID (0x1)
|
||||
#define FS26_M_STATUS (0x2)
|
||||
#define FS26_M_TSD_FLG (0x3)
|
||||
#define FS26_M_TSD_MSK (0x4)
|
||||
#define FS26_M_REG_FLG (0x5)
|
||||
#define FS26_M_REG_MSK (0x6)
|
||||
#define FS26_M_VSUP_FLG (0x7)
|
||||
#define FS26_M_VSUP_MSK (0x8)
|
||||
#define FS26_M_WIO_FLG (0x9)
|
||||
#define FS26_M_WIO_MSK (0xa)
|
||||
#define FS26_M_COM_FLG (0xb)
|
||||
#define FS26_M_COM_MSK (0xc)
|
||||
#define FS26_M_SYS_CFG (0xd)
|
||||
#define FS26_M_TSD_CFG (0xe)
|
||||
#define FS26_M_REG_CFG (0xf)
|
||||
#define FS26_M_WIO_CFG (0x10)
|
||||
#define FS26_M_REG_CTRL1 (0x11)
|
||||
#define FS26_M_REG_CTRL2 (0x12)
|
||||
#define FS26_M_AMUX_CTRL (0x13)
|
||||
#define FS26_M_LDT_CFG1 (0x14)
|
||||
#define FS26_M_LDT_CFG2 (0x15)
|
||||
#define FS26_M_LDT_CFG3 (0x16)
|
||||
#define FS26_M_LDT_CTRL (0x17)
|
||||
#define FS26_M_MEMORY0 (0x18)
|
||||
#define FS26_M_MEMORY1 (0x19)
|
||||
|
||||
/* FS26 Fail Safe register map */
|
||||
|
||||
#define FS26_FS_GRL_FLAGS (0x40)
|
||||
#define FS26_FS_I_OVUV_SAFE_REACTION1 (0x41)
|
||||
#define FS26_FS_I_NOT_OVUV_SAFE_REACTION1 (0x42)
|
||||
#define FS26_FS_I_OVUV_SAFE_REACTION2 (0x43)
|
||||
#define FS26_FS_I_NOT_OVUV_SAFE_REACTION2 (0x44)
|
||||
#define FS26_FS_I_WD_CFG (0x45)
|
||||
#define FS26_FS_I_NOT_WD_CFG (0x46)
|
||||
#define FS26_FS_I_SAFE_INPUTS (0x47)
|
||||
#define FS26_FS_I_NOT_SAFE_INPUTS (0x48)
|
||||
#define FS26_FS_I_FSSM (0x49)
|
||||
#define FS26_FS_I_NOT_FSSM (0x4a)
|
||||
#define FS26_FS_WDW_DURATION (0x4b)
|
||||
#define FS26_FS_NOT_WDW_DURATION (0x4c)
|
||||
#define FS26_FS_WD_ANSWER (0x4d)
|
||||
#define FS26_FS_WD_TOKEN (0x4e)
|
||||
#define FS26_FS_ABIST_ON_DEMAND (0x4f)
|
||||
#define FS26_FS_OVUV_REG_STATUS (0x50)
|
||||
#define FS26_FS_RELEASE_FS0B_FS1B (0x51)
|
||||
#define FS26_FS_SAFE_IOS_1 (0x52)
|
||||
#define FS26_FS_SAFE_IOS_2 (0x53)
|
||||
#define FS26_FS_DIAG_SAFETY1 (0x54)
|
||||
#define FS26_FS_DIAG_SAFETY2 (0x55)
|
||||
#define FS26_FS_INTB_MASK (0x56)
|
||||
#define FS26_FS_STATES (0x57)
|
||||
#define FS26_FS_LP_REQ (0x58)
|
||||
#define FS26_FS_LDT_LPSEL (0x59)
|
||||
|
||||
/* FS_I_OVUV_SAFE_REACTION1 register */
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_PRE */
|
||||
#define VMON_PRE_OV_FS_REACTION_SHIFT (14)
|
||||
#define VMON_PRE_OV_FS_REACTION_MASK (0x3 << VMON_PRE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_PRE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_OV_FS_REACTION_FS0B (0x1 << VMON_PRE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_PRE_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_PRE */
|
||||
#define VMON_PRE_UV_FS_REACTION_SHIFT (12)
|
||||
#define VMON_PRE_UV_FS_REACTION_MASK (0x3 << VMON_PRE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_PRE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_UV_FS_REACTION_FS0B (0x1 << VMON_PRE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_PRE_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_PRE_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_CORE */
|
||||
#define VMON_CORE_OV_FS_REACTION_SHIFT (10)
|
||||
#define VMON_CORE_OV_FS_REACTION_MASK (0x3 << VMON_CORE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_CORE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_OV_FS_REACTION_FS0B (0x1 << VMON_CORE_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_CORE_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_CORE */
|
||||
#define VMON_CORE_UV_FS_REACTION_SHIFT (8)
|
||||
#define VMON_CORE_UV_FS_REACTION_MASK (0x3 << VMON_CORE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_CORE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_UV_FS_REACTION_FS0B (0x1 << VMON_CORE_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_CORE_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_CORE_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_LDO1 */
|
||||
#define VMON_LDO1_OV_FS_REACTION_SHIFT (6)
|
||||
#define VMON_LDO1_OV_FS_REACTION_MASK (0x3 << VMON_LDO1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_LDO1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_OV_FS_REACTION_FS0B (0x1 << VMON_LDO1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_LDO1_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_LDO1 */
|
||||
#define VMON_LDO1_UV_FS_REACTION_SHIFT (4)
|
||||
#define VMON_LDO1_UV_FS_REACTION_MASK (0x3 << VMON_LDO1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_LDO1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_UV_FS_REACTION_FS0B (0x1 << VMON_LDO1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO1_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_LDO1_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_LDO2 */
|
||||
#define VMON_LDO2_OV_FS_REACTION_SHIFT (2)
|
||||
#define VMON_LDO2_OV_FS_REACTION_MASK (0x3 << VMON_LDO2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_LDO2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_OV_FS_REACTION_FS0B (0x1 << VMON_LDO2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_LDO2_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_LDO2 */
|
||||
#define VMON_LDO2_UV_FS_REACTION_SHIFT (0)
|
||||
#define VMON_LDO2_UV_FS_REACTION_MASK (0x3 << VMON_LDO2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_LDO2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_UV_FS_REACTION_FS0B (0x1 << VMON_LDO2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_LDO2_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_LDO2_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* FS_I_OVUV_SAFE_REACTION2 register */
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_EXT */
|
||||
#define VMON_EXT_OV_FS_REACTION_SHIFT (14)
|
||||
#define VMON_EXT_OV_FS_REACTION_MASK (0x3 << VMON_EXT_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_EXT_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_OV_FS_REACTION_FS0B (0x1 << VMON_EXT_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_EXT_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_EXT */
|
||||
#define VMON_EXT_UV_FS_REACTION_SHIFT (12)
|
||||
#define VMON_EXT_UV_FS_REACTION_MASK (0x3 << VMON_EXT_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_EXT_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_UV_FS_REACTION_FS0B (0x1 << VMON_EXT_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_EXT_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_EXT_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_REF */
|
||||
#define VMON_REF_OV_FS_REACTION_SHIFT (10)
|
||||
#define VMON_REF_OV_FS_REACTION_MASK (0x3 << VMON_REF_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_REF_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_OV_FS_REACTION_FS0B (0x1 << VMON_REF_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_REF_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_REF */
|
||||
#define VMON_REF_UV_FS_REACTION_SHIFT (8)
|
||||
#define VMON_REF_UV_FS_REACTION_MASK (0x3 << VMON_REF_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_REF_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_UV_FS_REACTION_FS0B (0x1 << VMON_REF_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_REF_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_REF_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_TRK2 */
|
||||
#define VMON_TRK2_OV_FS_REACTION_SHIFT (6)
|
||||
#define VMON_TRK2_OV_FS_REACTION_MASK (0x3 << VMON_TRK2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_TRK2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_OV_FS_REACTION_FS0B (0x1 << VMON_TRK2_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_TRK2_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_TRK2 */
|
||||
#define VMON_TRK2_UV_FS_REACTION_SHIFT (4)
|
||||
#define VMON_TRK2_UV_FS_REACTION_MASK (0x3 << VMON_TRK2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_TRK2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_UV_FS_REACTION_FS0B (0x1 << VMON_TRK2_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK2_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_TRK2_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of OV detection on VMON_TRK1 */
|
||||
#define VMON_TRK1_OV_FS_REACTION_SHIFT (2)
|
||||
#define VMON_TRK1_OV_FS_REACTION_MASK (0x3 << VMON_TRK1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_OV_FS_REACTION_NO_EFFECT (0x0 << VMON_TRK1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_OV_FS_REACTION_FS0B (0x1 << VMON_TRK1_OV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_OV_FS_REACTION_RSTB_FS0B (0x2 << VMON_TRK1_OV_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE outputs in case of UV detection on VMON_TRK1 */
|
||||
#define VMON_TRK1_UV_FS_REACTION_SHIFT (0)
|
||||
#define VMON_TRK1_UV_FS_REACTION_MASK (0x3 << VMON_TRK1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_UV_FS_REACTION_NO_EFFECT (0x0 << VMON_TRK1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_UV_FS_REACTION_FS0B (0x1 << VMON_TRK1_UV_FS_REACTION_SHIFT)
|
||||
#define VMON_TRK1_UV_FS_REACTION_RSTB_FS0B (0x2 << VMON_TRK1_UV_FS_REACTION_SHIFT)
|
||||
|
||||
/* FS26_FS_I_WD_CFG register */
|
||||
|
||||
/* Watchdog error counter limit */
|
||||
#define WD_ERR_LIMIT_SHIFT (14)
|
||||
#define WD_ERR_LIMIT_MASK (0x3 << WD_ERR_LIMIT_SHIFT)
|
||||
#define WD_ERR_LIMIT_8 (0x0 << WD_ERR_LIMIT_SHIFT)
|
||||
#define WD_ERR_LIMIT_6 (0x1 << WD_ERR_LIMIT_SHIFT)
|
||||
#define WD_ERR_LIMIT_4 (0x2 << WD_ERR_LIMIT_SHIFT)
|
||||
#define WD_ERR_LIMIT_2 (0x3 << WD_ERR_LIMIT_SHIFT)
|
||||
|
||||
/* Watchdog refresh counter limit */
|
||||
#define WD_RFR_LIMIT_SHIFT (11)
|
||||
#define WD_RFR_LIMIT_MASK (0x3 << WD_RFR_LIMIT_SHIFT)
|
||||
#define WD_RFR_LIMIT_6 (0x0 << WD_RFR_LIMIT_SHIFT)
|
||||
#define WD_RFR_LIMIT_4 (0x1 << WD_RFR_LIMIT_SHIFT)
|
||||
#define WD_RFR_LIMIT_2 (0x2 << WD_RFR_LIMIT_SHIFT)
|
||||
#define WD_RFR_LIMIT_1 (0x3 << WD_RFR_LIMIT_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE output in case of BAD Watchdog (data or timing) */
|
||||
#define WD_FS_REACTION_SHIFT (8)
|
||||
#define WD_FS_REACTION_MASK (0x3 << WD_FS_REACTION_SHIFT)
|
||||
#define WD_FS_REACTION_NO_ACTION (0x0 << WD_FS_REACTION_SHIFT)
|
||||
#define WD_FS_REACTION_FS0B (0x1 << WD_FS_REACTION_SHIFT)
|
||||
#define WD_FS_REACTION_RSTB_FS0B (0x2 << WD_FS_REACTION_SHIFT)
|
||||
|
||||
/* Reflect the value of the Watchdog Refresh Counter */
|
||||
#define WD_RFR_CNT_SHIFT (8)
|
||||
#define WD_RFR_CNT_MASK (0x7 << WD_RFR_CNT_SHIFT)
|
||||
#define WD_RFR_CNT(n) ((n) & (0x7 << WD_RFR_CNT_SHIFT))
|
||||
|
||||
/* Reflect the value of the Watchdog Error Counter */
|
||||
#define WD_ERR_CNT_SHIFT (0)
|
||||
#define WD_ERR_CNT_MASK (0xf << WD_ERR_CNT_SHIFT)
|
||||
#define WD_ERR_CNT(n) \
|
||||
(((n) & (0x7 << WD_RFR_CNT_SHIFT)) > 11) ? (11) : (((n) & (0x7 << WD_RFR_CNT_SHIFT)))
|
||||
|
||||
/* FS26_FS_I_SAFE_INPUTS register */
|
||||
|
||||
/* FCCU Monitoring Configuration */
|
||||
#define FCCU_CFG_SHIFT (13)
|
||||
#define FCCU_CFG_MASK (0x7 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_NO_MONITORING (0x0 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU1_FCCU2_PAIR (0x1 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU1_FCCU2_SINGLE (0x2 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU1_ONLY (0x3 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU2_ONLY (0x4 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU1_FCCU2_PWM (0x5 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU1_PWM_FCCU2_SINGLE (0x6 << FCCU_CFG_SHIFT)
|
||||
#define FCCU_CFG_FCCU2_PWM_FCCU1_SINGLE (0x7 << FCCU_CFG_SHIFT)
|
||||
|
||||
/* FCCU12 Fault Polarity */
|
||||
#define FCCU12_FLT_POL_SHIFT (12)
|
||||
#define FCCU12_FLT_POL_MASK (0x1 << FCCU12_FLT_POL_SHIFT)
|
||||
#define FCCU12_FLT_POL_FCCU1_0_FCCU2_1_IS_FAULT (0x0 << FCCU12_FLT_POL_SHIFT)
|
||||
#define FCCU12_FLT_POL_FCCU1_1_FCCU2_0_IS_FAULT (0x1 << FCCU12_FLT_POL_SHIFT)
|
||||
|
||||
/* FCCU1 Fault Polarity */
|
||||
#define FCCU1_FLT_POL_SHIFT (11)
|
||||
#define FCCU1_FLT_POL_MASK (0x1 << FCCU1_FLT_POL_SHIFT)
|
||||
#define FCCU1_FLT_POL_LOW (0x0 << FCCU1_FLT_POL_SHIFT)
|
||||
#define FCCU1_FLT_POL_HIGH (0x1 << FCCU1_FLT_POL_SHIFT)
|
||||
|
||||
/* FCCU2 Fault Polarity */
|
||||
#define FCCU2_FLT_POL_SHIFT (10)
|
||||
#define FCCU2_FLT_POL_MASK (0x1 << FCCU2_FLT_POL_SHIFT)
|
||||
#define FCCU2_FLT_POL_LOW (0x0 << FCCU2_FLT_POL_SHIFT)
|
||||
#define FCCU2_FLT_POL_HIGH (0x1 << FCCU2_FLT_POL_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE output in case of FAULT DETECTION ON FCCU12 */
|
||||
#define FCCU12_FS_REACTION_SHIFT (9)
|
||||
#define FCCU12_FS_REACTION_MASK (0x1 << FCCU12_FS_REACTION_SHIFT)
|
||||
#define FCCU12_FS_REACTION (FCCU12_FS_REACTION_MASK)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE output in case of FAULT DETECTION ON FCCU1 */
|
||||
#define FCCU1_FS_REACTION_SHIFT (8)
|
||||
#define FCCU1_FS_REACTION_MASK (0x1 << FCCU1_FS_REACTION_SHIFT)
|
||||
#define FCCU1_FS_REACTION (FCCU1_FS_REACTION_MASK)
|
||||
|
||||
/* Reaction on RSTB or FAIL SAFE output in case of FAULT DETECTION ON FCCU2 */
|
||||
#define FCCU2_FS_REACTION_SHIFT (7)
|
||||
#define FCCU2_FS_REACTION_MASK (0x1 << FCCU2_FS_REACTION_SHIFT)
|
||||
#define FCCU2_FS_REACTION (FCCU2_FS_REACTION_MASK)
|
||||
|
||||
/* ERRORMON Fault Polarity */
|
||||
#define ERRMON_FLT_POLARITY_SHIFT (5)
|
||||
#define ERRMON_FLT_POLARITY_MASK (0x1 << ERRMON_FLT_POLARITY_SHIFT)
|
||||
#define ERRMON_FLT_POLARITY_LOW (0x0 << ERRMON_FLT_POLARITY_SHIFT)
|
||||
#define ERRMON_FLT_POLARITY_HIGH (0x1 << ERRMON_FLT_POLARITY_SHIFT)
|
||||
|
||||
/* Acknowledge timing following a fault detection on ERRMON */
|
||||
#define ERRMON_ACK_TIME_SHIFT (3)
|
||||
#define ERRMON_ACK_TIME_MASK (0x3 << ERRMON_ACK_TIME_SHIFT)
|
||||
#define ERRMON_ACK_TIME_1MS (0x0 << ERRMON_ACK_TIME_SHIFT)
|
||||
#define ERRMON_ACK_TIME_8MS (0x1 << ERRMON_ACK_TIME_SHIFT)
|
||||
#define ERRMON_ACK_TIME_16MS (0x2 << ERRMON_ACK_TIME_SHIFT)
|
||||
#define ERRMON_ACK_TIME_32MS (0x3 << ERRMON_ACK_TIME_SHIFT)
|
||||
|
||||
/* Reaction on RSTB or Fail Safe output in case of fault detection on ERRMON */
|
||||
#define ERRMON_FS_REACTION_SHIFT (2)
|
||||
#define ERRMON_FS_REACTION_MASK (0x1 << FCCU2_FS_REACTION_SHIFT)
|
||||
#define ERRMON_FS_REACTION (FCCU2_FS_REACTION_MASK)
|
||||
|
||||
/* FCCU pin filtering time settings */
|
||||
#define FCCU12_FILT_SHIFT (0)
|
||||
#define FCCU12_FILT_MASK (0x3 << FCCU12_FILT_SHIFT)
|
||||
#define FCCU12_FILT_3US (0x0 << FCCU12_FILT_SHIFT)
|
||||
#define FCCU12_FILT_6US (0x1 << FCCU12_FILT_SHIFT)
|
||||
#define FCCU12_FILT_10US (0x2 << FCCU12_FILT_SHIFT)
|
||||
#define FCCU12_FILT_20US (0x3 << FCCU12_FILT_SHIFT)
|
||||
|
||||
/* FS26_FS_I_FSSM register */
|
||||
|
||||
/* Configure the maximum level of the fault counter */
|
||||
#define FLT_ERR_CNT_LIMIT_SHIFT (14)
|
||||
#define FLT_ERR_CNT_LIMIT_MASK (0x3 << FLT_ERR_CNT_LIMIT_SHIFT)
|
||||
#define FLT_ERR_CNT_LIMIT_2 (0x0 << FLT_ERR_CNT_LIMIT_SHIFT)
|
||||
#define FLT_ERR_CNT_LIMIT_6 (0x1 << FLT_ERR_CNT_LIMIT_SHIFT)
|
||||
#define FLT_ERR_CNT_LIMIT_8 (0x2 << FLT_ERR_CNT_LIMIT_SHIFT)
|
||||
#define FLT_ERR_CNT_LIMIT_12 (0x3 << FLT_ERR_CNT_LIMIT_SHIFT)
|
||||
|
||||
/* Configure the RSTB and FS0B behavior when fault error counter ≥ intermediate value */
|
||||
#define FLT_ERR_REACTION_SHIFT (8)
|
||||
#define FLT_ERR_REACTION_MASK (0x3 << FLT_ERR_REACTION_SHIFT)
|
||||
#define FLT_ERR_REACTION_NO_EFFECT (0x0 << FLT_ERR_REACTION_SHIFT)
|
||||
#define FLT_ERR_REACTION_FS0B (0x1 << FLT_ERR_REACTION_SHIFT)
|
||||
#define FLT_ERR_REACTION_RSTB_FS0B (0x2 << FLT_ERR_REACTION_SHIFT)
|
||||
|
||||
/* Reset duration configuration */
|
||||
#define RSTB_DUR_SHIFT (9)
|
||||
#define RSTB_DUR_MASK (0x1 << RSTB_DUR_SHIFT)
|
||||
#define RSTB_DUR_1MS (RSTB_DUR_MASK)
|
||||
#define RSTB_DUR_10MS (0)
|
||||
|
||||
/* Assert RSTB in case a short to high is detected on FS0B */
|
||||
#define BACKUP_SAFETY_PATH_FS0B_SHIFT (7)
|
||||
#define BACKUP_SAFETY_PATH_FS0B_MASK (0x1 << BACKUP_SAFETY_PATH_FS0B_SHIFT)
|
||||
#define BACKUP_SAFETY_PATH_FS0B (BACKUP_SAFETY_PATH_FS0B_MASK)
|
||||
|
||||
/* Assert RSTB in case a short to high is detected on FS1B */
|
||||
#define BACKUP_SAFETY_PATH_FS1B_SHIFT (6)
|
||||
#define BACKUP_SAFETY_PATH_FS1B_MASK (0x1 << BACKUP_SAFETY_PATH_FS1B_SHIFT)
|
||||
#define BACKUP_SAFETY_PATH_FS1B (BACKUP_SAFETY_PATH_FS1B_MASK)
|
||||
|
||||
/* Disable CLK Monitoring */
|
||||
#define CLK_MON_DIS_SHIFT (5)
|
||||
#define CLK_MON_DIS_MASK (0x1 << CLK_MON_DIS_SHIFT)
|
||||
#define CLK_MON_DIS (CLK_MON_DIS_MASK)
|
||||
|
||||
/* Disable 8s RSTB timer */
|
||||
#define DIS8S_SHIFT (4)
|
||||
#define DIS8S_MASK (0x1 << DIS8S_SHIFT)
|
||||
#define DIS8S (DIS8S_MASK)
|
||||
|
||||
/* Reflect the value of the Watchdog Error Counter */
|
||||
#define FLT_ERR_CNT_SHIFT (0)
|
||||
#define FLT_ERR_CNT_MASK (0xf << FLT_ERR_CNT_SHIFT)
|
||||
#define FLT_ERR_CNT(n) \
|
||||
((n & (0x7 << FLT_ERR_CNT_SHIFT)) > 12) ? (12) : ((n & (0x7 << FLT_ERR_CNT_SHIFT)))
|
||||
|
||||
/* FS26_FS_WDW_DURATION register */
|
||||
|
||||
/* Watchdog window period */
|
||||
#define WDW_PERIOD_SHIFT (12)
|
||||
#define WDW_PERIOD_MASK (0xf << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_DISABLE (0x0 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_1MS (0x1 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_2MS (0x2 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_3MS (0x3 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_4MS (0x4 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_6MS (0x5 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_8MS (0x6 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_12MS (0x7 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_16MS (0x8 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_24MS (0x9 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_32MS (0xa << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_64MS (0xb << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_128MS (0xc << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_256MS (0xd << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_512MS (0xe << WDW_PERIOD_SHIFT)
|
||||
#define WDW_PERIOD_1024MS (0xf << WDW_PERIOD_SHIFT)
|
||||
|
||||
/* Watchdog window duty cycle */
|
||||
#define WDW_DC_SHIFT (6)
|
||||
#define WDW_DC_MASK (0x7 << WDW_DC_SHIFT)
|
||||
#define WDW_DC_31_68 (0x0 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_DC_37_62 (0x1 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_DC_50_50 (0x2 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_DC_62_37 (0x3 << WDW_PERIOD_SHIFT)
|
||||
#define WDW_DC_68_31 (0x4 << WDW_PERIOD_SHIFT)
|
||||
|
||||
/* Watchdog window period */
|
||||
#define WDW_RECOVERY_SHIFT (0)
|
||||
#define WDW_RECOVERY_MASK (0xf << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_DISABLE (0x0 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_1MS (0x1 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_2MS (0x2 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_3MS (0x3 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_4MS (0x4 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_6MS (0x5 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_8MS (0x6 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_12MS (0x7 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_16MS (0x8 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_24MS (0x9 << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_32MS (0xa << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_64MS (0xb << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_128MS (0xc << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_256MS (0xd << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_512MS (0xe << WDW_RECOVERY_SHIFT)
|
||||
#define WDW_RECOVERY_1024MS (0xf << WDW_RECOVERY_SHIFT)
|
||||
|
||||
/* FS26_FS_DIAG_SAFETY1 register */
|
||||
|
||||
/* Bad WD refresh, Error in the data */
|
||||
#define BAD_WD_DATA_SHIFT (10)
|
||||
#define BAD_WD_DATA_MASK (0x1 << BAD_WD_DATA_SHIFT)
|
||||
#define BAD_WD_DATA (BAD_WD_DATA_MASK)
|
||||
|
||||
/* Bad WD refresh, Error in the timing */
|
||||
#define BAD_WD_TIMING_SHIFT (9)
|
||||
#define BAD_WD_TIMING_MASK (0x1 << BAD_WD_TIMING_SHIFT)
|
||||
#define BAD_WD_TIMING (BAD_WD_TIMING_MASK)
|
||||
|
||||
/* ABIST 1 pass */
|
||||
#define ABIST1_PASS_SHIFT (8)
|
||||
#define ABIST1_PASS_MASK (0x1 << ABIST1_PASS_SHIFT)
|
||||
#define ABIST1_PASS (ABIST1_PASS_MASK)
|
||||
|
||||
/* ABIST 2 pass */
|
||||
#define ABIST2_PASS_SHIFT (7)
|
||||
#define ABIST2_PASS_MASK (0x1 << ABIST2_PASS_SHIFT)
|
||||
#define ABIST2_PASS (ABIST2_PASS_MASK)
|
||||
|
||||
/* ABIST 2 done */
|
||||
#define ABIST2_DONE_SHIFT (6)
|
||||
#define ABIST2_DONE_MASK (0x1 << ABIST2_DONE_SHIFT)
|
||||
#define ABIST2_DONE (ABIST2_DONE_MASK)
|
||||
|
||||
/* SPI CLK error */
|
||||
#define SPI_FS_CLK_SHIFT (5)
|
||||
#define SPI_FS_CLK_MASK (0x1 << SPI_FS_CLK_SHIFT)
|
||||
#define SPI_FS_CLK (SPI_FS_CLK_MASK)
|
||||
|
||||
/* SPI invalid read/write error */
|
||||
#define SPI_FS_REQ_SHIFT (4)
|
||||
#define SPI_FS_REQ_MASK (0x1 << SPI_FS_REQ_SHIFT)
|
||||
#define SPI_FS_REQ (SPI_FS_REQ_MASK)
|
||||
|
||||
/* SPI CRC error */
|
||||
#define SPI_FS_CRC_SHIFT (3)
|
||||
#define SPI_FS_CRC_MASK (0x1 << SPI_FS_CRC_SHIFT)
|
||||
#define SPI_FS_CRC (SPI_FS_CRC_MASK)
|
||||
|
||||
/* FS OSC drift */
|
||||
#define FS_OSC_DRIFT_SHIFT (2)
|
||||
#define FS_OSC_DRIFT_MASK (0x1 << FS_OSC_DRIFT_SHIFT)
|
||||
#define FS_OSC_DRIFT (FS_OSC_DRIFT_MASK)
|
||||
|
||||
/* LBIST STATUS */
|
||||
#define LBIST_STATUS_SHIFT (0)
|
||||
#define LBIST_STATUS_MASK (0x3 << LBIST_STATUS_SHIFT)
|
||||
#define LBIST_STATUS (LBIST_STATUS_MASK)
|
||||
#define LBIST_STATUS_FAIL (0x0 << LBIST_STATUS_SHIFT)
|
||||
#define LBIST_STATUS_BYPASSED (0x1 << LBIST_STATUS_SHIFT)
|
||||
#define LBIST_STATUS_FAIL2 (0x2 << LBIST_STATUS_SHIFT)
|
||||
#define LBIST_STATUS_OK (0x3 << LBIST_STATUS_SHIFT)
|
||||
|
||||
/* FS26_FS_STATES register */
|
||||
|
||||
/* Leave debug mode */
|
||||
#define EXIT_DBG_MODE_SHIFT (14)
|
||||
#define EXIT_DBG_MODE_MASK (0x1 << EXIT_DBG_MODE_SHIFT)
|
||||
#define EXIT_DBG_MODE (EXIT_DBG_MODE_MASK)
|
||||
|
||||
/* debug mode */
|
||||
#define DBG_MODE_SHIFT (13)
|
||||
#define DBG_MODE_MASK (0x1 << DBG_MODE_SHIFT)
|
||||
#define DBG_MODE (DBG_MODE_MASK)
|
||||
|
||||
/* OTP crc error */
|
||||
#define OTP_CORRUPT_SHIFT (12)
|
||||
#define OTP_CORRUPT_MASK (0x1 << OTP_CORRUPT_SHIFT)
|
||||
#define OTP_CORRUPT (OTP_CORRUPT_MASK)
|
||||
|
||||
/* INIT register error */
|
||||
#define REG_CORRUPT_SHIFT (11)
|
||||
#define REG_CORRUPT_MASK (0x1 << REG_CORRUPT_SHIFT)
|
||||
#define REG_CORRUPT (REG_CORRUPT_MASK)
|
||||
|
||||
/* LBIST STATUS */
|
||||
#define FS_STATES_SHIFT (0)
|
||||
#define FS_STATES_MASK (0x1f << FS_STATES_SHIFT)
|
||||
#define FS_STATES (FS_STATES_MASK)
|
||||
#define FS_STATES_DEBUG_ENTRY (0x4 << FS_STATES_SHIFT)
|
||||
#define FS_STATES_ENABLE_MON (0x6 << FS_STATES_SHIFT)
|
||||
#define FS_STATES_RSTB_RELEASE (0x8 << FS_STATES_SHIFT)
|
||||
#define FS_STATES_INIT_FS (0x9 << FS_STATES_SHIFT)
|
||||
#define FS_STATES_SAFETY_OUT_NOT (0xa << FS_STATES_SHIFT)
|
||||
#define FS_STATES_NORMAL (0xb << FS_STATES_SHIFT)
|
||||
|
||||
/* FS26_FS_GRL_FLAGS register */
|
||||
|
||||
/* Report an issue in the communication (SPI) */
|
||||
#define FS_COM_G_SHIFT (15)
|
||||
#define FS_COM_G_MASK (0x1 << FS_COM_G_SHIFT)
|
||||
#define FS_COM_G (FS_COM_G_MASK)
|
||||
|
||||
/* Report an issue on the Watchdog Refresh */
|
||||
#define FS_WD_G_SHIFT (14)
|
||||
#define FS_WD_G_MASK (0x1 << FS_WD_G_SHIFT)
|
||||
#define FS_WD_G (FS_WD_G_MASK)
|
||||
|
||||
/* Report an issue in one of the Fail Safe IOs */
|
||||
#define FS_IO_G_SHIFT (13)
|
||||
#define FS_IO_G_MASK (0x1 << FS_IO_G_SHIFT)
|
||||
#define FS_IO_G (FS_IO_G_MASK)
|
||||
|
||||
/* Report an issue in one of the voltage monitoring (OV or UV) */
|
||||
#define FS_REG_OVUV_G_SHIFT (12)
|
||||
#define FS_REG_OVUV_G_MASK (0x1 << FS_REG_OVUV_G_SHIFT)
|
||||
#define FS_REG_OVUV_G (FS_REG_OVUV_G_MASK)
|
||||
|
||||
/* Report an issue on BIST (Logical or Analog) */
|
||||
#define FS_BIST_G_SHIFT (11)
|
||||
#define FS_BIST_G_MASK (0x1 << FS_BIST_G_SHIFT)
|
||||
#define FS_BIST_G (FS_BIST_G_MASK)
|
||||
|
||||
/* FS26_FS_SAFE_IOS_1 register */
|
||||
|
||||
/* Go Back to INIT Fail Safe Request */
|
||||
#define FS_GOTO_INIT_SHIFT (1)
|
||||
#define FS_GOTO_INIT_MASK (0x1 << FS_GOTO_INIT_SHIFT)
|
||||
#define FS_GOTO_INIT (FS_GOTO_INIT_MASK)
|
||||
|
||||
/* FS26_FS_INTB_MASK register */
|
||||
|
||||
/* Interrupt Mask on BAD_WD_REFRESH */
|
||||
#define BAD_WD_M (0x1 << 5)
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_WATCHDOG_WDT_NXP_FS26_H_ */
|
64
dts/bindings/watchdog/nxp,fs26-wdog.yaml
Normal file
64
dts/bindings/watchdog/nxp,fs26-wdog.yaml
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Copyright 2023 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
FS26 System Basis Chip (SBC) watchdog driver.
|
||||
|
||||
The FS26 features multiple voltage regulators to supply the microcontroller,
|
||||
peripheral ICs and communication interfaces. The FS26 also offers various
|
||||
functionalities for system control and monitoring, including a configurable
|
||||
watchdog counter to ensure the microcontroller is able to communicate with the
|
||||
FS26, which can react to any failure condition and place the system in a safe
|
||||
state. This driver covers only the watchdog functionality of FS26. The rest
|
||||
of the functionalities are not implemented.
|
||||
|
||||
The FS26 uses a 32-bit SPI interface. The MCU is the primary driving MOSI and
|
||||
FS26 is the secondary driving MISO. Therefore the FS26 devicetree node must be
|
||||
in a SPI bus. For example, if FS26 is connected to spi3 bus, on Chip Select 0:
|
||||
|
||||
&spi3 {
|
||||
// here there should be spi3 properties as needed
|
||||
status = "okay";
|
||||
|
||||
fs26_wdt: watchdog@0 {
|
||||
compatible = "nxp,fs26-wdog";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <DT_FREQ_M(5)>;
|
||||
type = "challenger";
|
||||
int-gpios = <&gpioa_h 3 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
When an FS26 internal interrupt occurs, the INTB pin generates a pulse to
|
||||
inform the microcontroller. The driver masks all interrupt sources except for
|
||||
bad watchdog refresh (BAD_WD_M). The GPIO pin where the interrupt signal is
|
||||
received must be configured from devicetree. In the example above, this is
|
||||
indicated through int-gpios property. It is also required to configure the
|
||||
external interrupt controller to receive interrupts on this pin.
|
||||
|
||||
compatible: "nxp,fs26-wdog"
|
||||
|
||||
include: spi-device.yaml
|
||||
|
||||
properties:
|
||||
type:
|
||||
required: true
|
||||
type: string
|
||||
enum:
|
||||
- simple
|
||||
- challenger
|
||||
description: |
|
||||
Watchdog type enabled on this device.
|
||||
|
||||
The Challenger watchdog monitoring feature is enabled for ASIL D devices.
|
||||
This mode is based on a question/answer process with the microcontroller.
|
||||
|
||||
The Simple watchdog monitoring feature is enabled for ASIL B devices. This
|
||||
mode uses a unique seed.
|
||||
|
||||
int-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: |
|
||||
GPIO to use to receive external interrupts from INTB signal.
|
Loading…
Reference in a new issue