1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2016 IBM Corporation 4 * 5 * Joel Stanley <joel@jms.id.au> 6 */ 7 8 #include <linux/bits.h> 9 #include <linux/delay.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/kstrtox.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/of_irq.h> 17 #include <linux/platform_device.h> 18 #include <linux/watchdog.h> 19 20 static bool nowayout = WATCHDOG_NOWAYOUT; 21 module_param(nowayout, bool, 0); 22 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 23 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 24 25 struct aspeed_wdt_config { 26 u32 ext_pulse_width_mask; 27 u32 irq_shift; 28 u32 irq_mask; 29 }; 30 31 struct aspeed_wdt { 32 struct watchdog_device wdd; 33 void __iomem *base; 34 u32 ctrl; 35 const struct aspeed_wdt_config *cfg; 36 }; 37 38 static const struct aspeed_wdt_config ast2400_config = { 39 .ext_pulse_width_mask = 0xff, 40 .irq_shift = 0, 41 .irq_mask = 0, 42 }; 43 44 static const struct aspeed_wdt_config ast2500_config = { 45 .ext_pulse_width_mask = 0xfffff, 46 .irq_shift = 12, 47 .irq_mask = GENMASK(31, 12), 48 }; 49 50 static const struct aspeed_wdt_config ast2600_config = { 51 .ext_pulse_width_mask = 0xfffff, 52 .irq_shift = 0, 53 .irq_mask = GENMASK(31, 10), 54 }; 55 56 static const struct of_device_id aspeed_wdt_of_table[] = { 57 { .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config }, 58 { .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config }, 59 { .compatible = "aspeed,ast2600-wdt", .data = &ast2600_config }, 60 { }, 61 }; 62 MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); 63 64 #define WDT_STATUS 0x00 65 #define WDT_RELOAD_VALUE 0x04 66 #define WDT_RESTART 0x08 67 #define WDT_CTRL 0x0C 68 #define WDT_CTRL_BOOT_SECONDARY BIT(7) 69 #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) 70 #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) 71 #define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5) 72 #define WDT_CTRL_1MHZ_CLK BIT(4) 73 #define WDT_CTRL_WDT_EXT BIT(3) 74 #define WDT_CTRL_WDT_INTR BIT(2) 75 #define WDT_CTRL_RESET_SYSTEM BIT(1) 76 #define WDT_CTRL_ENABLE BIT(0) 77 #define WDT_TIMEOUT_STATUS 0x10 78 #define WDT_TIMEOUT_STATUS_IRQ BIT(2) 79 #define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1) 80 #define WDT_CLEAR_TIMEOUT_STATUS 0x14 81 #define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0) 82 83 /* 84 * WDT_RESET_WIDTH controls the characteristics of the external pulse (if 85 * enabled), specifically: 86 * 87 * * Pulse duration 88 * * Drive mode: push-pull vs open-drain 89 * * Polarity: Active high or active low 90 * 91 * Pulse duration configuration is available on both the AST2400 and AST2500, 92 * though the field changes between SoCs: 93 * 94 * AST2400: Bits 7:0 95 * AST2500: Bits 19:0 96 * 97 * This difference is captured in struct aspeed_wdt_config. 98 * 99 * The AST2500 exposes the drive mode and polarity options, but not in a 100 * regular fashion. For read purposes, bit 31 represents active high or low, 101 * and bit 30 represents push-pull or open-drain. With respect to write, magic 102 * values need to be written to the top byte to change the state of the drive 103 * mode and polarity bits. Any other value written to the top byte has no 104 * effect on the state of the drive mode or polarity bits. However, the pulse 105 * width value must be preserved (as desired) if written. 106 */ 107 #define WDT_RESET_WIDTH 0x18 108 #define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31) 109 #define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24) 110 #define WDT_ACTIVE_LOW_MAGIC (0x5A << 24) 111 #define WDT_RESET_WIDTH_PUSH_PULL BIT(30) 112 #define WDT_PUSH_PULL_MAGIC (0xA8 << 24) 113 #define WDT_OPEN_DRAIN_MAGIC (0x8A << 24) 114 115 #define WDT_RESTART_MAGIC 0x4755 116 117 /* 32 bits at 1MHz, in milliseconds */ 118 #define WDT_MAX_TIMEOUT_MS 4294967 119 #define WDT_DEFAULT_TIMEOUT 30 120 #define WDT_RATE_1MHZ 1000000 121 122 static struct aspeed_wdt *to_aspeed_wdt(struct watchdog_device *wdd) 123 { 124 return container_of(wdd, struct aspeed_wdt, wdd); 125 } 126 127 static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count) 128 { 129 wdt->ctrl |= WDT_CTRL_ENABLE; 130 131 writel(0, wdt->base + WDT_CTRL); 132 writel(count, wdt->base + WDT_RELOAD_VALUE); 133 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 134 writel(wdt->ctrl, wdt->base + WDT_CTRL); 135 } 136 137 static int aspeed_wdt_start(struct watchdog_device *wdd) 138 { 139 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 140 141 aspeed_wdt_enable(wdt, wdd->timeout * WDT_RATE_1MHZ); 142 143 return 0; 144 } 145 146 static int aspeed_wdt_stop(struct watchdog_device *wdd) 147 { 148 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 149 150 wdt->ctrl &= ~WDT_CTRL_ENABLE; 151 writel(wdt->ctrl, wdt->base + WDT_CTRL); 152 153 return 0; 154 } 155 156 static int aspeed_wdt_ping(struct watchdog_device *wdd) 157 { 158 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 159 160 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 161 162 return 0; 163 } 164 165 static int aspeed_wdt_set_timeout(struct watchdog_device *wdd, 166 unsigned int timeout) 167 { 168 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 169 u32 actual; 170 171 wdd->timeout = timeout; 172 173 actual = min(timeout, wdd->max_hw_heartbeat_ms / 1000); 174 175 writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE); 176 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 177 178 return 0; 179 } 180 181 static int aspeed_wdt_set_pretimeout(struct watchdog_device *wdd, 182 unsigned int pretimeout) 183 { 184 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 185 u32 actual = pretimeout * WDT_RATE_1MHZ; 186 u32 s = wdt->cfg->irq_shift; 187 u32 m = wdt->cfg->irq_mask; 188 189 wdd->pretimeout = pretimeout; 190 wdt->ctrl &= ~m; 191 if (pretimeout) 192 wdt->ctrl |= ((actual << s) & m) | WDT_CTRL_WDT_INTR; 193 else 194 wdt->ctrl &= ~WDT_CTRL_WDT_INTR; 195 196 writel(wdt->ctrl, wdt->base + WDT_CTRL); 197 198 return 0; 199 } 200 201 static int aspeed_wdt_restart(struct watchdog_device *wdd, 202 unsigned long action, void *data) 203 { 204 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 205 206 wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY; 207 aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000); 208 209 mdelay(1000); 210 211 return 0; 212 } 213 214 /* access_cs0 shows if cs0 is accessible, hence the reverted bit */ 215 static ssize_t access_cs0_show(struct device *dev, 216 struct device_attribute *attr, char *buf) 217 { 218 struct aspeed_wdt *wdt = dev_get_drvdata(dev); 219 u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS); 220 221 return sysfs_emit(buf, "%u\n", 222 !(status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)); 223 } 224 225 static ssize_t access_cs0_store(struct device *dev, 226 struct device_attribute *attr, const char *buf, 227 size_t size) 228 { 229 struct aspeed_wdt *wdt = dev_get_drvdata(dev); 230 unsigned long val; 231 232 if (kstrtoul(buf, 10, &val)) 233 return -EINVAL; 234 235 if (val) 236 writel(WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION, 237 wdt->base + WDT_CLEAR_TIMEOUT_STATUS); 238 239 return size; 240 } 241 242 /* 243 * This attribute exists only if the system has booted from the alternate 244 * flash with 'alt-boot' option. 245 * 246 * At alternate flash the 'access_cs0' sysfs node provides: 247 * ast2400: a way to get access to the primary SPI flash chip at CS0 248 * after booting from the alternate chip at CS1. 249 * ast2500: a way to restore the normal address mapping from 250 * (CS0->CS1, CS1->CS0) to (CS0->CS0, CS1->CS1). 251 * 252 * Clearing the boot code selection and timeout counter also resets to the 253 * initial state the chip select line mapping. When the SoC is in normal 254 * mapping state (i.e. booted from CS0), clearing those bits does nothing for 255 * both versions of the SoC. For alternate boot mode (booted from CS1 due to 256 * wdt2 expiration) the behavior differs as described above. 257 * 258 * This option can be used with wdt2 (watchdog1) only. 259 */ 260 static DEVICE_ATTR_RW(access_cs0); 261 262 static struct attribute *bswitch_attrs[] = { 263 &dev_attr_access_cs0.attr, 264 NULL 265 }; 266 ATTRIBUTE_GROUPS(bswitch); 267 268 static const struct watchdog_ops aspeed_wdt_ops = { 269 .start = aspeed_wdt_start, 270 .stop = aspeed_wdt_stop, 271 .ping = aspeed_wdt_ping, 272 .set_timeout = aspeed_wdt_set_timeout, 273 .set_pretimeout = aspeed_wdt_set_pretimeout, 274 .restart = aspeed_wdt_restart, 275 .owner = THIS_MODULE, 276 }; 277 278 static const struct watchdog_info aspeed_wdt_info = { 279 .options = WDIOF_KEEPALIVEPING 280 | WDIOF_MAGICCLOSE 281 | WDIOF_SETTIMEOUT, 282 .identity = KBUILD_MODNAME, 283 }; 284 285 static const struct watchdog_info aspeed_wdt_pretimeout_info = { 286 .options = WDIOF_KEEPALIVEPING 287 | WDIOF_PRETIMEOUT 288 | WDIOF_MAGICCLOSE 289 | WDIOF_SETTIMEOUT, 290 .identity = KBUILD_MODNAME, 291 }; 292 293 static irqreturn_t aspeed_wdt_irq(int irq, void *arg) 294 { 295 struct watchdog_device *wdd = arg; 296 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 297 u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS); 298 299 if (status & WDT_TIMEOUT_STATUS_IRQ) 300 watchdog_notify_pretimeout(wdd); 301 302 return IRQ_HANDLED; 303 } 304 305 static int aspeed_wdt_probe(struct platform_device *pdev) 306 { 307 struct device *dev = &pdev->dev; 308 const struct of_device_id *ofdid; 309 struct aspeed_wdt *wdt; 310 struct device_node *np; 311 const char *reset_type; 312 u32 duration; 313 u32 status; 314 int ret; 315 316 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); 317 if (!wdt) 318 return -ENOMEM; 319 320 np = dev->of_node; 321 322 ofdid = of_match_node(aspeed_wdt_of_table, np); 323 if (!ofdid) 324 return -EINVAL; 325 wdt->cfg = ofdid->data; 326 327 wdt->base = devm_platform_ioremap_resource(pdev, 0); 328 if (IS_ERR(wdt->base)) 329 return PTR_ERR(wdt->base); 330 331 wdt->wdd.info = &aspeed_wdt_info; 332 333 if (wdt->cfg->irq_mask) { 334 int irq = platform_get_irq_optional(pdev, 0); 335 336 if (irq > 0) { 337 ret = devm_request_irq(dev, irq, aspeed_wdt_irq, 338 IRQF_SHARED, dev_name(dev), 339 wdt); 340 if (ret) 341 return ret; 342 343 wdt->wdd.info = &aspeed_wdt_pretimeout_info; 344 } 345 } 346 347 wdt->wdd.ops = &aspeed_wdt_ops; 348 wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS; 349 wdt->wdd.parent = dev; 350 351 wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT; 352 watchdog_init_timeout(&wdt->wdd, 0, dev); 353 354 watchdog_set_nowayout(&wdt->wdd, nowayout); 355 356 /* 357 * On clock rates: 358 * - ast2400 wdt can run at PCLK, or 1MHz 359 * - ast2500 only runs at 1MHz, hard coding bit 4 to 1 360 * - ast2600 always runs at 1MHz 361 * 362 * Set the ast2400 to run at 1MHz as it simplifies the driver. 363 */ 364 if (of_device_is_compatible(np, "aspeed,ast2400-wdt")) 365 wdt->ctrl = WDT_CTRL_1MHZ_CLK; 366 367 /* 368 * Control reset on a per-device basis to ensure the 369 * host is not affected by a BMC reboot 370 */ 371 ret = of_property_read_string(np, "aspeed,reset-type", &reset_type); 372 if (ret) { 373 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; 374 } else { 375 if (!strcmp(reset_type, "cpu")) 376 wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU | 377 WDT_CTRL_RESET_SYSTEM; 378 else if (!strcmp(reset_type, "soc")) 379 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | 380 WDT_CTRL_RESET_SYSTEM; 381 else if (!strcmp(reset_type, "system")) 382 wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP | 383 WDT_CTRL_RESET_SYSTEM; 384 else if (strcmp(reset_type, "none")) 385 return -EINVAL; 386 } 387 if (of_property_read_bool(np, "aspeed,external-signal")) 388 wdt->ctrl |= WDT_CTRL_WDT_EXT; 389 if (of_property_read_bool(np, "aspeed,alt-boot")) 390 wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY; 391 392 if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { 393 /* 394 * The watchdog is running, but invoke aspeed_wdt_start() to 395 * write wdt->ctrl to WDT_CTRL to ensure the watchdog's 396 * configuration conforms to the driver's expectations. 397 * Primarily, ensure we're using the 1MHz clock source. 398 */ 399 aspeed_wdt_start(&wdt->wdd); 400 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); 401 } 402 403 if ((of_device_is_compatible(np, "aspeed,ast2500-wdt")) || 404 (of_device_is_compatible(np, "aspeed,ast2600-wdt"))) { 405 u32 reg = readl(wdt->base + WDT_RESET_WIDTH); 406 407 reg &= wdt->cfg->ext_pulse_width_mask; 408 if (of_property_read_bool(np, "aspeed,ext-active-high")) 409 reg |= WDT_ACTIVE_HIGH_MAGIC; 410 else 411 reg |= WDT_ACTIVE_LOW_MAGIC; 412 413 writel(reg, wdt->base + WDT_RESET_WIDTH); 414 415 reg &= wdt->cfg->ext_pulse_width_mask; 416 if (of_property_read_bool(np, "aspeed,ext-push-pull")) 417 reg |= WDT_PUSH_PULL_MAGIC; 418 else 419 reg |= WDT_OPEN_DRAIN_MAGIC; 420 421 writel(reg, wdt->base + WDT_RESET_WIDTH); 422 } 423 424 if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) { 425 u32 max_duration = wdt->cfg->ext_pulse_width_mask + 1; 426 427 if (duration == 0 || duration > max_duration) { 428 dev_err(dev, "Invalid pulse duration: %uus\n", 429 duration); 430 duration = max(1U, min(max_duration, duration)); 431 dev_info(dev, "Pulse duration set to %uus\n", 432 duration); 433 } 434 435 /* 436 * The watchdog is always configured with a 1MHz source, so 437 * there is no need to scale the microsecond value. However we 438 * need to offset it - from the datasheet: 439 * 440 * "This register decides the asserting duration of wdt_ext and 441 * wdt_rstarm signal. The default value is 0xFF. It means the 442 * default asserting duration of wdt_ext and wdt_rstarm is 443 * 256us." 444 * 445 * This implies a value of 0 gives a 1us pulse. 446 */ 447 writel(duration - 1, wdt->base + WDT_RESET_WIDTH); 448 } 449 450 status = readl(wdt->base + WDT_TIMEOUT_STATUS); 451 if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) { 452 wdt->wdd.bootstatus = WDIOF_CARDRESET; 453 454 if (of_device_is_compatible(np, "aspeed,ast2400-wdt") || 455 of_device_is_compatible(np, "aspeed,ast2500-wdt")) 456 wdt->wdd.groups = bswitch_groups; 457 } 458 459 dev_set_drvdata(dev, wdt); 460 461 return devm_watchdog_register_device(dev, &wdt->wdd); 462 } 463 464 static struct platform_driver aspeed_watchdog_driver = { 465 .probe = aspeed_wdt_probe, 466 .driver = { 467 .name = KBUILD_MODNAME, 468 .of_match_table = aspeed_wdt_of_table, 469 }, 470 }; 471 472 static int __init aspeed_wdt_init(void) 473 { 474 return platform_driver_register(&aspeed_watchdog_driver); 475 } 476 arch_initcall(aspeed_wdt_init); 477 478 static void __exit aspeed_wdt_exit(void) 479 { 480 platform_driver_unregister(&aspeed_watchdog_driver); 481 } 482 module_exit(aspeed_wdt_exit); 483 484 MODULE_DESCRIPTION("Aspeed Watchdog Driver"); 485 MODULE_LICENSE("GPL"); 486