watchdog: add DesignWare watchdog driver
Driver is used on Quark SE and Quark D2000. Change-Id: I46b685a8886e86e2fa4071304713a73a7d2e4c96 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
9d6deb4e8c
commit
a9ed4ba9f5
8 changed files with 324 additions and 0 deletions
|
@ -55,4 +55,6 @@ source "drivers/adc/Kconfig"
|
|||
|
||||
source "drivers/rtc/Kconfig"
|
||||
|
||||
source "drivers/watchdog/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -18,4 +18,5 @@ obj-$(CONFIG_I2C) += i2c/
|
|||
obj-$(CONFIG_PWM) += pwm/
|
||||
obj-$(CONFIG_ADC) += adc/
|
||||
obj-$(CONFIG_ETHERNET) += ethernet/
|
||||
obj-$(CONFIG_WATCHDOG) += watchdog/
|
||||
obj-$(CONFIG_RTC) += rtc/
|
||||
|
|
15
drivers/watchdog/Kconfig
Normal file
15
drivers/watchdog/Kconfig
Normal file
|
@ -0,0 +1,15 @@
|
|||
menuconfig WATCHDOG
|
||||
bool
|
||||
prompt "Watchdog Support"
|
||||
default n
|
||||
help
|
||||
Include support for watchdogs.
|
||||
|
||||
if WATCHDOG
|
||||
config WDT_DW
|
||||
bool "Enable DesignWare Watchdog"
|
||||
default n
|
||||
help
|
||||
Enable watchdog timer.
|
||||
|
||||
endif
|
2
drivers/watchdog/Makefile
Normal file
2
drivers/watchdog/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_WATCHDOG) += wdt_static_irq_stubs.o
|
||||
obj-$(CONFIG_WDT_DW) += wdt_dw.o
|
125
drivers/watchdog/wdt_dw.c
Normal file
125
drivers/watchdog/wdt_dw.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <init.h>
|
||||
#include "wdt_dw.h"
|
||||
|
||||
void (*cb_fn)(void);
|
||||
|
||||
/**
|
||||
* Enables the clock for the peripheral watchdog
|
||||
*/
|
||||
static void wdt_dw_enable(void)
|
||||
{
|
||||
SCSS_PERIPHERAL->periph_cfg0 |= SCSS_PERIPH_CFG0_WDT_ENABLE;
|
||||
}
|
||||
|
||||
static void wdt_dw_disable(void)
|
||||
{
|
||||
/* Disable the clock for the peripheral watchdog */
|
||||
SCSS_PERIPHERAL->periph_cfg0 &= ~SCSS_PERIPH_CFG0_WDT_ENABLE;
|
||||
}
|
||||
|
||||
void wdt_dw_isr(void)
|
||||
{
|
||||
if (cb_fn) {
|
||||
(*cb_fn)();
|
||||
}
|
||||
}
|
||||
|
||||
static void wdt_dw_get_config(struct wdt_config *config)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IRQ_CONNECT_STATIC(wdt_dw, INT_WDT_IRQ, INT_WDT_IRQ_PRI, wdt_dw_isr, 0);
|
||||
|
||||
static void wdt_dw_reload(void) { WDT_DW->wdt_crr = WDT_CRR_VAL; }
|
||||
|
||||
static int wdt_dw_set_config(struct wdt_config *config)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
wdt_dw_enable();
|
||||
/* Set timeout value
|
||||
* [7:4] TOP_INIT - the initial timeout value is hardcoded in silicon,
|
||||
* only bits [3:0] TOP are relevant.
|
||||
* Once tickled TOP is loaded at the next expiration.
|
||||
*/
|
||||
uint32_t i;
|
||||
uint32_t ref = (1 << 16) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC /
|
||||
1000000); /* 2^16/FREQ_CPU */
|
||||
uint32_t timeout = config->timeout * 1000;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (timeout <= ref)
|
||||
break;
|
||||
ref = ref << 1;
|
||||
}
|
||||
if (i > 15) {
|
||||
ret = -1;
|
||||
i = 15;
|
||||
}
|
||||
WDT_DW->wdt_torr = i;
|
||||
|
||||
/* Set response mode */
|
||||
if (WDT_MODE_RESET == config->mode) {
|
||||
WDT_DW->wdt_cr &= ~WDT_CR_INT_ENABLE;
|
||||
} else {
|
||||
if (config->interrupt_fn) {
|
||||
cb_fn = config->interrupt_fn;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
WDT_DW->wdt_cr |= WDT_CR_INT_ENABLE;
|
||||
|
||||
IRQ_CONFIG(wdt_dw, INT_WDT_IRQ, 0);
|
||||
irq_enable(INT_WDT_IRQ);
|
||||
|
||||
/* unmask WDT interrupts to lmt */
|
||||
SCSS_INTERRUPT->int_watchdog_mask &= INT_UNMASK_IA;
|
||||
}
|
||||
|
||||
/* Enable WDT, cannot be disabled until soc reset */
|
||||
WDT_DW->wdt_cr |= WDT_CR_ENABLE;
|
||||
|
||||
wdt_dw_reload();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct wdt_driver_api wdt_dw_funcs = {
|
||||
.set_config = wdt_dw_set_config,
|
||||
.get_config = wdt_dw_get_config,
|
||||
.enable = wdt_dw_enable,
|
||||
.disable = wdt_dw_disable,
|
||||
.reload = wdt_dw_reload,
|
||||
};
|
||||
|
||||
int wdt_dw_init(struct device *dev)
|
||||
{
|
||||
dev->driver_api = &wdt_dw_funcs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct wdt_dw_dev_config wdt_dev = {
|
||||
.base_address = WDT_BASE_ADDR,
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(wdt, WDT_DRV_NAME, &wdt_dw_init, &wdt_dev);
|
||||
|
||||
micro_early_init(wdt, NULL);
|
61
drivers/watchdog/wdt_dw.h
Normal file
61
drivers/watchdog/wdt_dw.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WDT_DW_H_
|
||||
#define WDT_DW_H_
|
||||
|
||||
#include <board.h>
|
||||
#include <device.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
|
||||
/**
|
||||
* Watchdog timer register block type.
|
||||
*/
|
||||
struct wdt_dw {
|
||||
volatile uint32_t wdt_cr; /**< Control Register */
|
||||
volatile uint32_t wdt_torr; /**< Timeout Range Register */
|
||||
volatile uint32_t wdt_ccvr; /**< Current Counter Value Register */
|
||||
volatile uint32_t wdt_crr; /**< Current Restart Register */
|
||||
volatile uint32_t wdt_stat; /**< Interrupt Status Register */
|
||||
volatile uint32_t wdt_eoi; /**< Interrupt Clear Register */
|
||||
volatile uint32_t wdt_comp_param_5; /**< Component Parameters */
|
||||
volatile uint32_t wdt_comp_param_4; /**< Component Parameters */
|
||||
volatile uint32_t wdt_comp_param_3; /**< Component Parameters */
|
||||
volatile uint32_t wdt_comp_param_2; /**< Component Parameters */
|
||||
volatile uint32_t wdt_comp_param_1; /**< Component Parameters Register 1 */
|
||||
volatile uint32_t wdt_comp_version; /**< Component Version Register */
|
||||
volatile uint32_t wdt_comp_type; /**< Component Type Register */
|
||||
};
|
||||
|
||||
/** WDT register block */
|
||||
#define WDT_DW ((struct wdt_dw *)WDT_BASE_ADDR)
|
||||
|
||||
|
||||
#define WDT_CRR_VAL 0x76
|
||||
#define WDT_CR_ENABLE (1 << 0)
|
||||
#define WDT_CR_INT_ENABLE (1 << 1) /* interrupt mode enable - mode1 */
|
||||
|
||||
|
||||
#define WDT_DRV_NAME "wdt_dw"
|
||||
|
||||
struct wdt_dw_dev_config {
|
||||
uint32_t base_address;
|
||||
};
|
||||
|
||||
int wdt_dw_init(struct device *dev);
|
||||
|
||||
#endif /* WDT_DW_H_ */
|
32
drivers/watchdog/wdt_static_irq_stubs.S
Normal file
32
drivers/watchdog/wdt_static_irq_stubs.S
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Intel Corportation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#define _ASMLANGUAGE
|
||||
|
||||
#include <arch/x86/asm.h>
|
||||
#include <drivers/ioapic.h>
|
||||
|
||||
#if defined(CONFIG_WDT_DW)
|
||||
#if defined(CONFIG_IOAPIC)
|
||||
ioapic_mkstub wdt_dw wdt_dw_isr 0
|
||||
#endif /* CONFIG_IOAPIC */
|
||||
#endif
|
||||
|
||||
/* externs (internal APIs) */
|
||||
|
||||
GTEXT(_IntEnt)
|
||||
GTEXT(_IntExit)
|
86
include/watchdog.h
Normal file
86
include/watchdog.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WDT_H_
|
||||
#define _WDT_H_
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum { WDT_MODE_RESET = 0, WDT_MODE_INTERRUPT_RESET } wdt_mode_t;
|
||||
|
||||
/**
|
||||
* WDT configuration struct.
|
||||
*/
|
||||
struct wdt_config {
|
||||
uint32_t timeout;
|
||||
wdt_mode_t mode;
|
||||
void (*interrupt_fn)(void);
|
||||
};
|
||||
|
||||
typedef void (*wdt_api_enable)(void);
|
||||
typedef void (*wdt_api_disable)(void);
|
||||
typedef int (*wdt_api_set_config)(struct wdt_config *config);
|
||||
typedef void (*wdt_api_get_config)(struct wdt_config *config);
|
||||
typedef void (*wdt_api_reload)(void);
|
||||
|
||||
struct wdt_driver_api {
|
||||
wdt_api_enable enable;
|
||||
wdt_api_disable disable;
|
||||
wdt_api_get_config get_config;
|
||||
wdt_api_set_config set_config;
|
||||
wdt_api_reload reload;
|
||||
};
|
||||
|
||||
static inline void wdt_enable(struct device *dev)
|
||||
{
|
||||
struct wdt_driver_api *api;
|
||||
|
||||
api = (struct wdt_driver_api *)dev->driver_api;
|
||||
api->enable();
|
||||
}
|
||||
|
||||
static inline void wdt_disable(struct device *dev)
|
||||
{
|
||||
struct wdt_driver_api *api;
|
||||
|
||||
api = (struct wdt_driver_api *)dev->driver_api;
|
||||
api->disable();
|
||||
}
|
||||
|
||||
static inline void wdt_get_config(struct device *dev, struct wdt_config *config)
|
||||
{
|
||||
struct wdt_driver_api *api;
|
||||
|
||||
api = (struct wdt_driver_api *)dev->driver_api;
|
||||
api->get_config(config);
|
||||
}
|
||||
|
||||
static inline int wdt_set_config(struct device *dev, struct wdt_config *config)
|
||||
{
|
||||
struct wdt_driver_api *api;
|
||||
|
||||
api = (struct wdt_driver_api *)dev->driver_api;
|
||||
return api->set_config(config);
|
||||
}
|
||||
|
||||
static inline void wdt_reload(struct device *dev)
|
||||
{
|
||||
struct wdt_driver_api *api;
|
||||
|
||||
api = (struct wdt_driver_api *)dev->driver_api;
|
||||
api->reload();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue