mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-07 07:46:59 +02:00
watchdog: at91sam9_wdt: Add SAM9X60 support
SAM9X60 has a slightly different watchdog implementation: - Timer value moved into a new register WLR - Some MR register fields have their position changed This patch add SAM9X60 support, also adds a compatible for SAMA5D4 which is the same as existing SAM9260. Signed-off-by: Zixun LI <admin@hifiphile.com> Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
c8bf2d686d
commit
ac46b48d30
@ -19,9 +19,16 @@
|
||||
|
||||
#else
|
||||
|
||||
enum {
|
||||
AT91_WDT_MODE_SAM9260 = 0,
|
||||
AT91_WDT_MODE_SAM9X60 = 1
|
||||
};
|
||||
|
||||
struct at91_wdt_priv {
|
||||
void __iomem *regs;
|
||||
u32 mr;
|
||||
u32 wddis;
|
||||
u8 mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -33,14 +40,22 @@ struct at91_wdt_priv {
|
||||
|
||||
/* Watchdog Mode Register*/
|
||||
#define AT91_WDT_MR 0x04
|
||||
#define AT91_WDT_MR_WDV(x) (x & 0xfff)
|
||||
#define AT91_WDT_MR_WDV(x) ((x) & 0xfff)
|
||||
#define AT91_SAM9X60_MR_PERIODRST 0x00000010
|
||||
#define AT91_WDT_MR_WDFIEN 0x00001000
|
||||
#define AT91_SAM9X60_MR_WDDIS 0x00001000
|
||||
#define AT91_WDT_MR_WDRSTEN 0x00002000
|
||||
#define AT91_WDT_MR_WDRPROC 0x00004000
|
||||
#define AT91_WDT_MR_WDDIS 0x00008000
|
||||
#define AT91_WDT_MR_WDD(x) ((x & 0xfff) << 16)
|
||||
#define AT91_WDT_MR_WDD(x) (((x) & 0xfff) << 16)
|
||||
#define AT91_WDT_MR_WDDBGHLT 0x10000000
|
||||
#define AT91_SAM9X60_MR_WDIDLEHLT 0x10000000
|
||||
#define AT91_WDT_MR_WDIDLEHLT 0x20000000
|
||||
#define AT91_SAM9X60_MR_WDDBGHLT 0x20000000
|
||||
|
||||
/* Watchdog Window Level Register */
|
||||
#define AT91_SAM9X60_WLR 0x0c
|
||||
#define AT91_SAM9X60_WLR_COUNTER(x) ((x) & 0xfff)
|
||||
|
||||
/* Hardware timeout in seconds */
|
||||
#define WDT_MAX_TIMEOUT 16
|
||||
|
@ -49,7 +49,7 @@ static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
|
||||
ticks = WDT_SEC2TICKS(timeout);
|
||||
|
||||
/* Check if disabled */
|
||||
if (readl(wdt->regs + AT91_WDT_MR) & AT91_WDT_MR_WDDIS) {
|
||||
if (readl(wdt->regs + AT91_WDT_MR) & wdt->wddis) {
|
||||
printf("sorry, watchdog is disabled\n");
|
||||
return -1;
|
||||
}
|
||||
@ -60,11 +60,21 @@ static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
|
||||
* Since WDV is a 12-bit counter, the maximum period is
|
||||
* 4096 / 256 = 16 seconds.
|
||||
*/
|
||||
wdt->mr = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */
|
||||
| AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */
|
||||
| AT91_WDT_MR_WDD(0xfff) /* restart at any time */
|
||||
| AT91_WDT_MR_WDV(ticks); /* timer value */
|
||||
writel(wdt->mr, wdt->regs + AT91_WDT_MR);
|
||||
|
||||
if (wdt->mode == AT91_WDT_MODE_SAM9260) {
|
||||
wdt->mr = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */
|
||||
| AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */
|
||||
| AT91_WDT_MR_WDD(0xfff) /* restart at any time */
|
||||
| AT91_WDT_MR_WDV(ticks); /* timer value */
|
||||
writel(wdt->mr, wdt->regs + AT91_WDT_MR);
|
||||
} else if (wdt->mode == AT91_WDT_MODE_SAM9X60) {
|
||||
writel(AT91_SAM9X60_WLR_COUNTER(ticks), /* timer value */
|
||||
wdt->regs + AT91_SAM9X60_WLR);
|
||||
|
||||
wdt->mr = AT91_SAM9X60_MR_PERIODRST /* causes watchdog reset */
|
||||
| AT91_SAM9X60_MR_WDDBGHLT; /* disabled in debug mode */
|
||||
writel(wdt->mr, wdt->regs + AT91_WDT_MR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -74,7 +84,7 @@ static int at91_wdt_stop(struct udevice *dev)
|
||||
struct at91_wdt_priv *wdt = dev_get_priv(dev);
|
||||
|
||||
/* Disable Watchdog Timer */
|
||||
wdt->mr |= AT91_WDT_MR_WDDIS;
|
||||
wdt->mr |= wdt->wddis;
|
||||
writel(wdt->mr, wdt->regs + AT91_WDT_MR);
|
||||
|
||||
return 0;
|
||||
@ -96,7 +106,14 @@ static const struct wdt_ops at91_wdt_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id at91_wdt_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9260-wdt" },
|
||||
{ .compatible = "atmel,at91sam9260-wdt",
|
||||
.data = AT91_WDT_MODE_SAM9260 },
|
||||
{ .compatible = "atmel,sama5d4-wdt",
|
||||
.data = AT91_WDT_MODE_SAM9260 },
|
||||
{ .compatible = "microchip,sam9x60-wdt",
|
||||
.data = AT91_WDT_MODE_SAM9X60 },
|
||||
{ .compatible = "microchip,sama7g5-wdt",
|
||||
.data = AT91_WDT_MODE_SAM9X60 },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -108,6 +125,12 @@ static int at91_wdt_probe(struct udevice *dev)
|
||||
if (!wdt->regs)
|
||||
return -EINVAL;
|
||||
|
||||
wdt->mode = dev_get_driver_data(dev);
|
||||
if (wdt->mode == AT91_WDT_MODE_SAM9260)
|
||||
wdt->wddis = AT91_WDT_MR_WDDIS;
|
||||
else if (wdt->mode == AT91_WDT_MODE_SAM9X60)
|
||||
wdt->wddis = AT91_SAM9X60_MR_WDDIS;
|
||||
|
||||
debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user