Microchip: MEC172x: watchdog driver
Update wdt driver to support MEC172x device Signed-off-by: Jay Vasanth <jay.vasanth@microchip.com>
This commit is contained in:
parent
5b16dd4326
commit
4120a889a4
4 changed files with 82 additions and 26 deletions
|
@ -16,8 +16,14 @@ LOG_MODULE_REGISTER(wdt_mchp_xec);
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define WDT_XEC_REG_BASE \
|
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
|
||||||
((WDT_Type *)(DT_INST_REG_ADDR(0)))
|
"add exactly one wdog node to the devicetree");
|
||||||
|
|
||||||
|
struct wdt_xec_config {
|
||||||
|
struct wdt_regs *regs;
|
||||||
|
uint8_t girq;
|
||||||
|
uint8_t girq_pos;
|
||||||
|
};
|
||||||
|
|
||||||
struct wdt_xec_data {
|
struct wdt_xec_data {
|
||||||
wdt_callback_t cb;
|
wdt_callback_t cb;
|
||||||
|
@ -26,10 +32,11 @@ struct wdt_xec_data {
|
||||||
|
|
||||||
static int wdt_xec_setup(const struct device *dev, uint8_t options)
|
static int wdt_xec_setup(const struct device *dev, uint8_t options)
|
||||||
{
|
{
|
||||||
WDT_Type *wdt_regs = WDT_XEC_REG_BASE;
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
struct wdt_xec_data *data = dev->data;
|
struct wdt_xec_data *data = dev->data;
|
||||||
|
struct wdt_regs *regs = cfg->regs;
|
||||||
|
|
||||||
if (wdt_regs->CTRL & MCHP_WDT_CTRL_EN) {
|
if (regs->CTRL & MCHP_WDT_CTRL_EN) {
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +51,12 @@ static int wdt_xec_setup(const struct device *dev, uint8_t options)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
|
if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
|
||||||
wdt_regs->CTRL |= MCHP_WDT_CTRL_JTAG_STALL_EN;
|
regs->CTRL |= MCHP_WDT_CTRL_JTAG_STALL_EN;
|
||||||
} else {
|
} else {
|
||||||
wdt_regs->CTRL &= ~MCHP_WDT_CTRL_JTAG_STALL_EN;
|
regs->CTRL &= ~MCHP_WDT_CTRL_JTAG_STALL_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
wdt_regs->CTRL |= MCHP_WDT_CTRL_EN;
|
regs->CTRL |= MCHP_WDT_CTRL_EN;
|
||||||
|
|
||||||
LOG_DBG("WDT Setup and enabled");
|
LOG_DBG("WDT Setup and enabled");
|
||||||
|
|
||||||
|
@ -58,14 +65,15 @@ static int wdt_xec_setup(const struct device *dev, uint8_t options)
|
||||||
|
|
||||||
static int wdt_xec_disable(const struct device *dev)
|
static int wdt_xec_disable(const struct device *dev)
|
||||||
{
|
{
|
||||||
WDT_Type *wdt_regs = WDT_XEC_REG_BASE;
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
struct wdt_xec_data *data = dev->data;
|
struct wdt_xec_data *data = dev->data;
|
||||||
|
struct wdt_regs *regs = cfg->regs;
|
||||||
|
|
||||||
if (!(wdt_regs->CTRL & MCHP_WDT_CTRL_EN)) {
|
if (!(regs->CTRL & MCHP_WDT_CTRL_EN)) {
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
wdt_regs->CTRL &= ~MCHP_WDT_CTRL_EN;
|
regs->CTRL &= ~MCHP_WDT_CTRL_EN;
|
||||||
data->timeout_installed = false;
|
data->timeout_installed = false;
|
||||||
|
|
||||||
LOG_DBG("WDT Disabled");
|
LOG_DBG("WDT Disabled");
|
||||||
|
@ -76,10 +84,11 @@ static int wdt_xec_disable(const struct device *dev)
|
||||||
static int wdt_xec_install_timeout(const struct device *dev,
|
static int wdt_xec_install_timeout(const struct device *dev,
|
||||||
const struct wdt_timeout_cfg *config)
|
const struct wdt_timeout_cfg *config)
|
||||||
{
|
{
|
||||||
WDT_Type *wdt_regs = WDT_XEC_REG_BASE;
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
struct wdt_xec_data *data = dev->data;
|
struct wdt_xec_data *data = dev->data;
|
||||||
|
struct wdt_regs *regs = cfg->regs;
|
||||||
|
|
||||||
if (wdt_regs->CTRL & MCHP_WDT_CTRL_EN) {
|
if (regs->CTRL & MCHP_WDT_CTRL_EN) {
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,20 +97,20 @@ static int wdt_xec_install_timeout(const struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wdt_regs->LOAD = 0;
|
regs->LOAD = 0;
|
||||||
|
|
||||||
data->cb = config->callback;
|
data->cb = config->callback;
|
||||||
if (data->cb) {
|
if (data->cb) {
|
||||||
wdt_regs->CTRL |= MCHP_WDT_CTRL_MODE_IRQ;
|
regs->CTRL |= MCHP_WDT_CTRL_MODE_IRQ;
|
||||||
wdt_regs->IEN |= MCHP_WDT_IEN_EVENT_IRQ_EN;
|
regs->IEN |= MCHP_WDT_IEN_EVENT_IRQ_EN;
|
||||||
|
|
||||||
LOG_DBG("WDT callback enabled");
|
LOG_DBG("WDT callback enabled");
|
||||||
} else {
|
} else {
|
||||||
/* Setting WDT_FLAG_RESET_SOC or not will have no effect:
|
/* Setting WDT_FLAG_RESET_SOC or not will have no effect:
|
||||||
* even after the cb, if anything is done, SoC will reset
|
* even after the cb, if anything is done, SoC will reset
|
||||||
*/
|
*/
|
||||||
wdt_regs->CTRL &= ~MCHP_WDT_CTRL_MODE_IRQ;
|
regs->CTRL &= ~MCHP_WDT_CTRL_MODE_IRQ;
|
||||||
wdt_regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;
|
regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;
|
||||||
|
|
||||||
LOG_DBG("WDT Reset enabled");
|
LOG_DBG("WDT Reset enabled");
|
||||||
}
|
}
|
||||||
|
@ -110,7 +119,7 @@ static int wdt_xec_install_timeout(const struct device *dev,
|
||||||
* (See datasheet 18.6.1.4: 33/32.768 KHz = 1.007ms)
|
* (See datasheet 18.6.1.4: 33/32.768 KHz = 1.007ms)
|
||||||
* Let's use the given window directly.
|
* Let's use the given window directly.
|
||||||
*/
|
*/
|
||||||
wdt_regs->LOAD = config->window.max;
|
regs->LOAD = config->window.max;
|
||||||
|
|
||||||
data->timeout_installed = true;
|
data->timeout_installed = true;
|
||||||
|
|
||||||
|
@ -119,26 +128,28 @@ static int wdt_xec_install_timeout(const struct device *dev,
|
||||||
|
|
||||||
static int wdt_xec_feed(const struct device *dev, int channel_id)
|
static int wdt_xec_feed(const struct device *dev, int channel_id)
|
||||||
{
|
{
|
||||||
WDT_Type *wdt_regs = WDT_XEC_REG_BASE;
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
|
struct wdt_regs *regs = cfg->regs;
|
||||||
|
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
ARG_UNUSED(channel_id);
|
ARG_UNUSED(channel_id);
|
||||||
|
|
||||||
if (!(wdt_regs->CTRL & MCHP_WDT_CTRL_EN)) {
|
if (!(regs->CTRL & MCHP_WDT_CTRL_EN)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DBG("WDT Kicking");
|
LOG_DBG("WDT Kicking");
|
||||||
|
|
||||||
wdt_regs->KICK = 1;
|
regs->KICK = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wdt_xec_isr(const struct device *dev)
|
static void wdt_xec_isr(const struct device *dev)
|
||||||
{
|
{
|
||||||
WDT_Type *wdt_regs = WDT_XEC_REG_BASE;
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
struct wdt_xec_data *data = dev->data;
|
struct wdt_xec_data *data = dev->data;
|
||||||
|
struct wdt_regs *regs = cfg->regs;
|
||||||
|
|
||||||
LOG_DBG("WDT ISR");
|
LOG_DBG("WDT ISR");
|
||||||
|
|
||||||
|
@ -146,8 +157,12 @@ static void wdt_xec_isr(const struct device *dev)
|
||||||
data->cb(dev, 0);
|
data->cb(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCHP_GIRQ_SRC(MCHP_WDT_GIRQ) = MCHP_WDT_GIRQ_VAL;
|
#ifdef CONFIG_SOC_SERIES_MEC172X
|
||||||
wdt_regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;
|
mchp_soc_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
|
||||||
|
#else
|
||||||
|
MCHP_GIRQ_SRC(MCHP_WDT_GIRQ) = BIT(cfg->girq_pos);
|
||||||
|
#endif
|
||||||
|
regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wdt_driver_api wdt_xec_api = {
|
static const struct wdt_driver_api wdt_xec_api = {
|
||||||
|
@ -159,11 +174,17 @@ static const struct wdt_driver_api wdt_xec_api = {
|
||||||
|
|
||||||
static int wdt_xec_init(const struct device *dev)
|
static int wdt_xec_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct wdt_xec_config const *cfg = dev->config;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) {
|
if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) {
|
||||||
wdt_xec_disable(dev);
|
wdt_xec_disable(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCHP_GIRQ_ENSET(MCHP_WDT_GIRQ) = MCHP_WDT_GIRQ_VAL;
|
#ifdef CONFIG_SOC_SERIES_MEC172X
|
||||||
|
mchp_soc_ecia_girq_src_en(cfg->girq, cfg->girq_pos);
|
||||||
|
#else
|
||||||
|
MCHP_GIRQ_ENSET(MCHP_WDT_GIRQ) = BIT(cfg->girq_pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||||
DT_INST_IRQ(0, priority),
|
DT_INST_IRQ(0, priority),
|
||||||
|
@ -173,9 +194,15 @@ static int wdt_xec_init(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct wdt_xec_config wdt_xec_config_0 = {
|
||||||
|
.regs = (struct wdt_regs *)(DT_INST_REG_ADDR(0)),
|
||||||
|
.girq = DT_INST_PROP_BY_IDX(0, girqs, 0),
|
||||||
|
.girq_pos = DT_INST_PROP_BY_IDX(0, girqs, 1),
|
||||||
|
};
|
||||||
|
|
||||||
static struct wdt_xec_data wdt_xec_dev_data;
|
static struct wdt_xec_data wdt_xec_dev_data;
|
||||||
|
|
||||||
DEVICE_DT_INST_DEFINE(0, wdt_xec_init, NULL,
|
DEVICE_DT_INST_DEFINE(0, wdt_xec_init, NULL,
|
||||||
&wdt_xec_dev_data, NULL,
|
&wdt_xec_dev_data, &wdt_xec_config_0,
|
||||||
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||||
&wdt_xec_api);
|
&wdt_xec_api);
|
||||||
|
|
|
@ -89,6 +89,8 @@
|
||||||
compatible = "microchip,xec-watchdog";
|
compatible = "microchip,xec-watchdog";
|
||||||
reg = <0x40000400 0x400>;
|
reg = <0x40000400 0x400>;
|
||||||
interrupts = <171 0>;
|
interrupts = <171 0>;
|
||||||
|
girqs = <21 2>;
|
||||||
|
pcrs = <1 9>;
|
||||||
label = "WDT_0";
|
label = "WDT_0";
|
||||||
};
|
};
|
||||||
uart0: uart@400f2400 {
|
uart0: uart@400f2400 {
|
||||||
|
|
|
@ -354,6 +354,7 @@
|
||||||
#gpio-cells=<2>;
|
#gpio-cells=<2>;
|
||||||
};
|
};
|
||||||
wdog: watchdog@40000400 {
|
wdog: watchdog@40000400 {
|
||||||
|
compatible = "microchip,xec-watchdog";
|
||||||
reg = <0x40000400 0x400>;
|
reg = <0x40000400 0x400>;
|
||||||
interrupts = <171 0>;
|
interrupts = <171 0>;
|
||||||
girqs = <21 2>;
|
girqs = <21 2>;
|
||||||
|
|
|
@ -16,3 +16,29 @@ properties:
|
||||||
|
|
||||||
interrupts:
|
interrupts:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
girqs:
|
||||||
|
type: array
|
||||||
|
required: true
|
||||||
|
description: Array of GIRQ numbers [8:26] and bit positions [0:31].
|
||||||
|
|
||||||
|
pcrs:
|
||||||
|
type: array
|
||||||
|
required: true
|
||||||
|
description: PCR sleep enable register index and bit position.
|
||||||
|
|
||||||
|
"#girq-cells":
|
||||||
|
type: int
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
"#pcr-cells":
|
||||||
|
type: int
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
girq-cells:
|
||||||
|
- girq_num
|
||||||
|
- bitpos
|
||||||
|
|
||||||
|
pcr-cells:
|
||||||
|
- reg_index
|
||||||
|
- bitpos
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue