/* * WDT_RESET_WIDTH controls the characteristics of the external pulse (if * enabled), specifically: * * * Pulse duration * * Drive mode: push-pull vs open-drain * * Polarity: Active high or active low * * Pulse duration configuration is available on both the AST2400 and AST2500, * though the field changes between SoCs: * * AST2400: Bits 7:0 * AST2500: Bits 19:0 * * This difference is captured in struct aspeed_wdt_config. * * The AST2500 exposes the drive mode and polarity options, but not in a * regular fashion. For read purposes, bit 31 represents active high or low, * and bit 30 represents push-pull or open-drain. With respect to write, magic * values need to be written to the top byte to change the state of the drive * mode and polarity bits. Any other value written to the top byte has no * effect on the state of the drive mode or polarity bits. However, the pulse * width value must be preserved (as desired) if written.
*/ #define WDT_RESET_WIDTH 0x18 #define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31) #define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24) #define WDT_ACTIVE_LOW_MAGIC (0x5A << 24) #define WDT_RESET_WIDTH_PUSH_PULL BIT(30) #define WDT_PUSH_PULL_MAGIC (0xA8 << 24) #define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
#define WDT_RESTART_MAGIC 0x4755
/* 32 bits at 1MHz, in milliseconds */ #define WDT_MAX_TIMEOUT_MS 4294967 #define WDT_DEFAULT_TIMEOUT 30 #define WDT_RATE_1MHZ 1000000
if (val)
writel(WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION,
wdt->base + WDT_CLEAR_TIMEOUT_STATUS);
return size;
}
/* * This attribute exists only if the system has booted from the alternate * flash with 'alt-boot' option. * * At alternate flash the 'access_cs0' sysfs node provides: * ast2400: a way to get access to the primary SPI flash chip at CS0 * after booting from the alternate chip at CS1. * ast2500: a way to restore the normal address mapping from * (CS0->CS1, CS1->CS0) to (CS0->CS0, CS1->CS1). * * Clearing the boot code selection and timeout counter also resets to the * initial state the chip select line mapping. When the SoC is in normal * mapping state (i.e. booted from CS0), clearing those bits does nothing for * both versions of the SoC. For alternate boot mode (booted from CS1 due to * wdt2 expiration) the behavior differs as described above. * * This option can be used with wdt2 (watchdog1) only.
*/ static DEVICE_ATTR_RW(access_cs0);
/* * On clock rates: * - ast2400 wdt can run at PCLK, or 1MHz * - ast2500 only runs at 1MHz, hard coding bit 4 to 1 * - ast2600 always runs at 1MHz * * Set the ast2400 to run at 1MHz as it simplifies the driver.
*/ if (of_device_is_compatible(np, "aspeed,ast2400-wdt"))
wdt->ctrl = WDT_CTRL_1MHZ_CLK;
/* * Control reset on a per-device basis to ensure the * host is not affected by a BMC reboot
*/
ret = of_property_read_string(np, "aspeed,reset-type", &reset_type); if (ret) {
wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
} else { if (!strcmp(reset_type, "cpu"))
wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU |
WDT_CTRL_RESET_SYSTEM; elseif (!strcmp(reset_type, "soc"))
wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC |
WDT_CTRL_RESET_SYSTEM; elseif (!strcmp(reset_type, "system"))
wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP |
WDT_CTRL_RESET_SYSTEM; elseif (strcmp(reset_type, "none")) return -EINVAL;
} if (of_property_read_bool(np, "aspeed,external-signal"))
wdt->ctrl |= WDT_CTRL_WDT_EXT; if (of_property_read_bool(np, "aspeed,alt-boot"))
wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY;
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { /* * The watchdog is running, but invoke aspeed_wdt_start() to * write wdt->ctrl to WDT_CTRL to ensure the watchdog's * configuration conforms to the driver's expectations. * Primarily, ensure we're using the 1MHz clock source.
*/
aspeed_wdt_start(&wdt->wdd);
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
if (duration == 0 || duration > max_duration) {
dev_err(dev, "Invalid pulse duration: %uus\n",
duration);
duration = max(1U, min(max_duration, duration));
dev_info(dev, "Pulse duration set to %uus\n",
duration);
}
/* * The watchdog is always configured with a 1MHz source, so * there is no need to scale the microsecond value. However we * need to offset it - from the datasheet: * * "This register decides the asserting duration of wdt_ext and * wdt_rstarm signal. The default value is 0xFF. It means the * default asserting duration of wdt_ext and wdt_rstarm is * 256us." * * This implies a value of 0 gives a 1us pulse.
*/
writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
}
aspeed_wdt_update_bootstatus(pdev, wdt);
status = readl(wdt->base + WDT_TIMEOUT_STATUS); if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) { if (of_device_is_compatible(np, "aspeed,ast2400-wdt") ||
of_device_is_compatible(np, "aspeed,ast2500-wdt"))
wdt->wdd.groups = bswitch_groups;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.