1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Cadence WDT driver - Used by Xilinx Zynq 4 * 5 * Copyright (C) 2010 - 2014 Xilinx, Inc. 6 * 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/init.h> 11 #include <linux/interrupt.h> 12 #include <linux/io.h> 13 #include <linux/irq.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/watchdog.h> 19 20 #define CDNS_WDT_DEFAULT_TIMEOUT 10 21 /* Supports 1 - 516 sec */ 22 #define CDNS_WDT_MIN_TIMEOUT 1 23 #define CDNS_WDT_MAX_TIMEOUT 516 24 25 /* Restart key */ 26 #define CDNS_WDT_RESTART_KEY 0x00001999 27 28 /* Counter register access key */ 29 #define CDNS_WDT_REGISTER_ACCESS_KEY 0x00920000 30 31 /* Counter value divisor */ 32 #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000 33 34 /* Clock prescaler value and selection */ 35 #define CDNS_WDT_PRESCALE_64 64 36 #define CDNS_WDT_PRESCALE_512 512 37 #define CDNS_WDT_PRESCALE_4096 4096 38 #define CDNS_WDT_PRESCALE_SELECT_64 1 39 #define CDNS_WDT_PRESCALE_SELECT_512 2 40 #define CDNS_WDT_PRESCALE_SELECT_4096 3 41 42 /* Input clock frequency */ 43 #define CDNS_WDT_CLK_10MHZ 10000000 44 #define CDNS_WDT_CLK_75MHZ 75000000 45 46 /* Counter maximum value */ 47 #define CDNS_WDT_COUNTER_MAX 0xFFF 48 49 static int wdt_timeout; 50 static int nowayout = WATCHDOG_NOWAYOUT; 51 52 module_param(wdt_timeout, int, 0644); 53 MODULE_PARM_DESC(wdt_timeout, 54 "Watchdog time in seconds. (default=" 55 __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")"); 56 57 module_param(nowayout, int, 0644); 58 MODULE_PARM_DESC(nowayout, 59 "Watchdog cannot be stopped once started (default=" 60 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 61 62 /** 63 * struct cdns_wdt - Watchdog device structure 64 * @regs: baseaddress of device 65 * @rst: reset flag 66 * @clk: struct clk * of a clock source 67 * @prescaler: for saving prescaler value 68 * @ctrl_clksel: counter clock prescaler selection 69 * @io_lock: spinlock for IO register access 70 * @cdns_wdt_device: watchdog device structure 71 * 72 * Structure containing parameters specific to cadence watchdog. 73 */ 74 struct cdns_wdt { 75 void __iomem *regs; 76 bool rst; 77 struct clk *clk; 78 u32 prescaler; 79 u32 ctrl_clksel; 80 spinlock_t io_lock; 81 struct watchdog_device cdns_wdt_device; 82 }; 83 84 /* Write access to Registers */ 85 static inline void cdns_wdt_writereg(struct cdns_wdt *wdt, u32 offset, u32 val) 86 { 87 writel_relaxed(val, wdt->regs + offset); 88 } 89 90 /*************************Register Map**************************************/ 91 92 /* Register Offsets for the WDT */ 93 #define CDNS_WDT_ZMR_OFFSET 0x0 /* Zero Mode Register */ 94 #define CDNS_WDT_CCR_OFFSET 0x4 /* Counter Control Register */ 95 #define CDNS_WDT_RESTART_OFFSET 0x8 /* Restart Register */ 96 #define CDNS_WDT_SR_OFFSET 0xC /* Status Register */ 97 98 /* 99 * Zero Mode Register - This register controls how the time out is indicated 100 * and also contains the access code to allow writes to the register (0xABC). 101 */ 102 #define CDNS_WDT_ZMR_WDEN_MASK 0x00000001 /* Enable the WDT */ 103 #define CDNS_WDT_ZMR_RSTEN_MASK 0x00000002 /* Enable the reset output */ 104 #define CDNS_WDT_ZMR_IRQEN_MASK 0x00000004 /* Enable IRQ output */ 105 #define CDNS_WDT_ZMR_RSTLEN_16 0x00000030 /* Reset pulse of 16 pclk cycles */ 106 #define CDNS_WDT_ZMR_ZKEY_VAL 0x00ABC000 /* Access key, 0xABC << 12 */ 107 /* 108 * Counter Control register - This register controls how fast the timer runs 109 * and the reset value and also contains the access code to allow writes to 110 * the register. 111 */ 112 #define CDNS_WDT_CCR_CRV_MASK 0x00003FFC /* Counter reset value */ 113 114 /** 115 * cdns_wdt_stop - Stop the watchdog. 116 * 117 * @wdd: watchdog device 118 * 119 * Read the contents of the ZMR register, clear the WDEN bit 120 * in the register and set the access key for successful write. 121 * 122 * Return: always 0 123 */ 124 static int cdns_wdt_stop(struct watchdog_device *wdd) 125 { 126 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 127 128 spin_lock(&wdt->io_lock); 129 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, 130 CDNS_WDT_ZMR_ZKEY_VAL & (~CDNS_WDT_ZMR_WDEN_MASK)); 131 spin_unlock(&wdt->io_lock); 132 133 return 0; 134 } 135 136 /** 137 * cdns_wdt_reload - Reload the watchdog timer (i.e. pat the watchdog). 138 * 139 * @wdd: watchdog device 140 * 141 * Write the restart key value (0x00001999) to the restart register. 142 * 143 * Return: always 0 144 */ 145 static int cdns_wdt_reload(struct watchdog_device *wdd) 146 { 147 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 148 149 spin_lock(&wdt->io_lock); 150 cdns_wdt_writereg(wdt, CDNS_WDT_RESTART_OFFSET, 151 CDNS_WDT_RESTART_KEY); 152 spin_unlock(&wdt->io_lock); 153 154 return 0; 155 } 156 157 /** 158 * cdns_wdt_start - Enable and start the watchdog. 159 * 160 * @wdd: watchdog device 161 * 162 * The counter value is calculated according to the formula: 163 * calculated count = (timeout * clock) / prescaler + 1. 164 * The calculated count is divided by 0x1000 to obtain the field value 165 * to write to counter control register. 166 * Clears the contents of prescaler and counter reset value. Sets the 167 * prescaler to 4096 and the calculated count and access key 168 * to write to CCR Register. 169 * Sets the WDT (WDEN bit) and either the Reset signal(RSTEN bit) 170 * or Interrupt signal(IRQEN) with a specified cycles and the access 171 * key to write to ZMR Register. 172 * 173 * Return: always 0 174 */ 175 static int cdns_wdt_start(struct watchdog_device *wdd) 176 { 177 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 178 unsigned int data = 0; 179 unsigned short count; 180 unsigned long clock_f = clk_get_rate(wdt->clk); 181 182 /* 183 * Counter value divisor to obtain the value of 184 * counter reset to be written to control register. 185 */ 186 count = (wdd->timeout * (clock_f / wdt->prescaler)) / 187 CDNS_WDT_COUNTER_VALUE_DIVISOR + 1; 188 189 if (count > CDNS_WDT_COUNTER_MAX) 190 count = CDNS_WDT_COUNTER_MAX; 191 192 spin_lock(&wdt->io_lock); 193 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, 194 CDNS_WDT_ZMR_ZKEY_VAL); 195 196 count = (count << 2) & CDNS_WDT_CCR_CRV_MASK; 197 198 /* Write counter access key first to be able write to register */ 199 data = count | CDNS_WDT_REGISTER_ACCESS_KEY | wdt->ctrl_clksel; 200 cdns_wdt_writereg(wdt, CDNS_WDT_CCR_OFFSET, data); 201 data = CDNS_WDT_ZMR_WDEN_MASK | CDNS_WDT_ZMR_RSTLEN_16 | 202 CDNS_WDT_ZMR_ZKEY_VAL; 203 204 /* Reset on timeout if specified in device tree. */ 205 if (wdt->rst) { 206 data |= CDNS_WDT_ZMR_RSTEN_MASK; 207 data &= ~CDNS_WDT_ZMR_IRQEN_MASK; 208 } else { 209 data &= ~CDNS_WDT_ZMR_RSTEN_MASK; 210 data |= CDNS_WDT_ZMR_IRQEN_MASK; 211 } 212 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, data); 213 cdns_wdt_writereg(wdt, CDNS_WDT_RESTART_OFFSET, 214 CDNS_WDT_RESTART_KEY); 215 spin_unlock(&wdt->io_lock); 216 217 return 0; 218 } 219 220 /** 221 * cdns_wdt_settimeout - Set a new timeout value for the watchdog device. 222 * 223 * @wdd: watchdog device 224 * @new_time: new timeout value that needs to be set 225 * Return: 0 on success 226 * 227 * Update the watchdog_device timeout with new value which is used when 228 * cdns_wdt_start is called. 229 */ 230 static int cdns_wdt_settimeout(struct watchdog_device *wdd, 231 unsigned int new_time) 232 { 233 wdd->timeout = new_time; 234 235 return cdns_wdt_start(wdd); 236 } 237 238 /** 239 * cdns_wdt_irq_handler - Notifies of watchdog timeout. 240 * 241 * @irq: interrupt number 242 * @dev_id: pointer to a platform device structure 243 * Return: IRQ_HANDLED 244 * 245 * The handler is invoked when the watchdog times out and a 246 * reset on timeout has not been enabled. 247 */ 248 static irqreturn_t cdns_wdt_irq_handler(int irq, void *dev_id) 249 { 250 struct platform_device *pdev = dev_id; 251 252 dev_info(&pdev->dev, 253 "Watchdog timed out. Internal reset not enabled\n"); 254 255 return IRQ_HANDLED; 256 } 257 258 /* 259 * Info structure used to indicate the features supported by the device 260 * to the upper layers. This is defined in watchdog.h header file. 261 */ 262 static const struct watchdog_info cdns_wdt_info = { 263 .identity = "cdns_wdt watchdog", 264 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 265 WDIOF_MAGICCLOSE, 266 }; 267 268 /* Watchdog Core Ops */ 269 static const struct watchdog_ops cdns_wdt_ops = { 270 .owner = THIS_MODULE, 271 .start = cdns_wdt_start, 272 .stop = cdns_wdt_stop, 273 .ping = cdns_wdt_reload, 274 .set_timeout = cdns_wdt_settimeout, 275 }; 276 277 /************************Platform Operations*****************************/ 278 /** 279 * cdns_wdt_probe - Probe call for the device. 280 * 281 * @pdev: handle to the platform device structure. 282 * Return: 0 on success, negative error otherwise. 283 * 284 * It does all the memory allocation and registration for the device. 285 */ 286 static int cdns_wdt_probe(struct platform_device *pdev) 287 { 288 struct resource *res; 289 int ret, irq; 290 unsigned long clock_f; 291 struct cdns_wdt *wdt; 292 struct watchdog_device *cdns_wdt_device; 293 294 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 295 if (!wdt) 296 return -ENOMEM; 297 298 cdns_wdt_device = &wdt->cdns_wdt_device; 299 cdns_wdt_device->info = &cdns_wdt_info; 300 cdns_wdt_device->ops = &cdns_wdt_ops; 301 cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT; 302 cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT; 303 cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT; 304 305 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 306 wdt->regs = devm_ioremap_resource(&pdev->dev, res); 307 if (IS_ERR(wdt->regs)) 308 return PTR_ERR(wdt->regs); 309 310 /* Register the interrupt */ 311 wdt->rst = of_property_read_bool(pdev->dev.of_node, "reset-on-timeout"); 312 irq = platform_get_irq(pdev, 0); 313 if (!wdt->rst && irq >= 0) { 314 ret = devm_request_irq(&pdev->dev, irq, cdns_wdt_irq_handler, 0, 315 pdev->name, pdev); 316 if (ret) { 317 dev_err(&pdev->dev, 318 "cannot register interrupt handler err=%d\n", 319 ret); 320 return ret; 321 } 322 } 323 324 /* Initialize the members of cdns_wdt structure */ 325 cdns_wdt_device->parent = &pdev->dev; 326 327 ret = watchdog_init_timeout(cdns_wdt_device, wdt_timeout, &pdev->dev); 328 if (ret) { 329 dev_err(&pdev->dev, "unable to set timeout value\n"); 330 return ret; 331 } 332 333 watchdog_set_nowayout(cdns_wdt_device, nowayout); 334 watchdog_stop_on_reboot(cdns_wdt_device); 335 watchdog_set_drvdata(cdns_wdt_device, wdt); 336 337 wdt->clk = devm_clk_get(&pdev->dev, NULL); 338 if (IS_ERR(wdt->clk)) { 339 dev_err(&pdev->dev, "input clock not found\n"); 340 ret = PTR_ERR(wdt->clk); 341 return ret; 342 } 343 344 ret = clk_prepare_enable(wdt->clk); 345 if (ret) { 346 dev_err(&pdev->dev, "unable to enable clock\n"); 347 return ret; 348 } 349 350 clock_f = clk_get_rate(wdt->clk); 351 if (clock_f <= CDNS_WDT_CLK_75MHZ) { 352 wdt->prescaler = CDNS_WDT_PRESCALE_512; 353 wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512; 354 } else { 355 wdt->prescaler = CDNS_WDT_PRESCALE_4096; 356 wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_4096; 357 } 358 359 spin_lock_init(&wdt->io_lock); 360 361 ret = watchdog_register_device(cdns_wdt_device); 362 if (ret) { 363 dev_err(&pdev->dev, "Failed to register wdt device\n"); 364 goto err_clk_disable; 365 } 366 platform_set_drvdata(pdev, wdt); 367 368 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", 369 wdt->regs, cdns_wdt_device->timeout, 370 nowayout ? ", nowayout" : ""); 371 372 return 0; 373 374 err_clk_disable: 375 clk_disable_unprepare(wdt->clk); 376 377 return ret; 378 } 379 380 /** 381 * cdns_wdt_remove - Probe call for the device. 382 * 383 * @pdev: handle to the platform device structure. 384 * Return: 0 on success, otherwise negative error. 385 * 386 * Unregister the device after releasing the resources. 387 */ 388 static int cdns_wdt_remove(struct platform_device *pdev) 389 { 390 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 391 392 cdns_wdt_stop(&wdt->cdns_wdt_device); 393 watchdog_unregister_device(&wdt->cdns_wdt_device); 394 clk_disable_unprepare(wdt->clk); 395 396 return 0; 397 } 398 399 /** 400 * cdns_wdt_shutdown - Stop the device. 401 * 402 * @pdev: handle to the platform structure. 403 * 404 */ 405 static void cdns_wdt_shutdown(struct platform_device *pdev) 406 { 407 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 408 409 cdns_wdt_stop(&wdt->cdns_wdt_device); 410 clk_disable_unprepare(wdt->clk); 411 } 412 413 /** 414 * cdns_wdt_suspend - Stop the device. 415 * 416 * @dev: handle to the device structure. 417 * Return: 0 always. 418 */ 419 static int __maybe_unused cdns_wdt_suspend(struct device *dev) 420 { 421 struct cdns_wdt *wdt = dev_get_drvdata(dev); 422 423 if (watchdog_active(&wdt->cdns_wdt_device)) { 424 cdns_wdt_stop(&wdt->cdns_wdt_device); 425 clk_disable_unprepare(wdt->clk); 426 } 427 428 return 0; 429 } 430 431 /** 432 * cdns_wdt_resume - Resume the device. 433 * 434 * @dev: handle to the device structure. 435 * Return: 0 on success, errno otherwise. 436 */ 437 static int __maybe_unused cdns_wdt_resume(struct device *dev) 438 { 439 int ret; 440 struct cdns_wdt *wdt = dev_get_drvdata(dev); 441 442 if (watchdog_active(&wdt->cdns_wdt_device)) { 443 ret = clk_prepare_enable(wdt->clk); 444 if (ret) { 445 dev_err(dev, "unable to enable clock\n"); 446 return ret; 447 } 448 cdns_wdt_start(&wdt->cdns_wdt_device); 449 } 450 451 return 0; 452 } 453 454 static SIMPLE_DEV_PM_OPS(cdns_wdt_pm_ops, cdns_wdt_suspend, cdns_wdt_resume); 455 456 static const struct of_device_id cdns_wdt_of_match[] = { 457 { .compatible = "cdns,wdt-r1p2", }, 458 { /* end of table */ } 459 }; 460 MODULE_DEVICE_TABLE(of, cdns_wdt_of_match); 461 462 /* Driver Structure */ 463 static struct platform_driver cdns_wdt_driver = { 464 .probe = cdns_wdt_probe, 465 .remove = cdns_wdt_remove, 466 .shutdown = cdns_wdt_shutdown, 467 .driver = { 468 .name = "cdns-wdt", 469 .of_match_table = cdns_wdt_of_match, 470 .pm = &cdns_wdt_pm_ops, 471 }, 472 }; 473 474 module_platform_driver(cdns_wdt_driver); 475 476 MODULE_AUTHOR("Xilinx, Inc."); 477 MODULE_DESCRIPTION("Watchdog driver for Cadence WDT"); 478 MODULE_LICENSE("GPL"); 479