1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2017-2025, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <assert.h> 7 #include <drivers/clk.h> 8 #include <drivers/clk_dt.h> 9 #include <drivers/wdt.h> 10 #include <io.h> 11 #include <keep.h> 12 #include <kernel/boot.h> 13 #include <kernel/delay.h> 14 #include <kernel/dt.h> 15 #include <kernel/dt_driver.h> 16 #include <kernel/interrupt.h> 17 #include <kernel/misc.h> 18 #include <kernel/panic.h> 19 #include <kernel/pm.h> 20 #include <kernel/spinlock.h> 21 #include <kernel/tee_time.h> 22 #include <libfdt.h> 23 #include <mm/core_memprot.h> 24 #include <sm/sm.h> 25 #include <stm32_util.h> 26 #include <string.h> 27 #include <trace.h> 28 29 /* IWDG Compatibility */ 30 #define IWDG_TIMEOUT_US U(10000) 31 #define IWDG_CNT_MASK GENMASK_32(11, 0) 32 #define IWDG_ONF_MIN_VER U(0x31) 33 #define IWDG_ICR_MIN_VER U(0x40) 34 35 /* IWDG registers offsets */ 36 #define IWDG_KR_OFFSET U(0x00) 37 #define IWDG_PR_OFFSET U(0x04) 38 #define IWDG_RLR_OFFSET U(0x08) 39 #define IWDG_SR_OFFSET U(0x0C) 40 #define IWDG_EWCR_OFFSET U(0x14) 41 #define IWDG_ICR_OFFSET U(0x18) 42 #define IWDG_VERR_OFFSET U(0x3F4) 43 44 #define IWDG_KR_WPROT_KEY U(0x0000) 45 #define IWDG_KR_ACCESS_KEY U(0x5555) 46 #define IWDG_KR_RELOAD_KEY U(0xAAAA) 47 #define IWDG_KR_START_KEY U(0xCCCC) 48 49 /* Use a fixed prescaler divider of 256 */ 50 #define IWDG_PRESCALER_256 U(256) 51 #define IWDG_PR_DIV_256 U(0x06) 52 #define IWDG_PR_DIV_MASK GENMASK_32(3, 0) 53 54 #define IWDG_SR_PVU BIT(0) 55 #define IWDG_SR_RVU BIT(1) 56 #define IWDG_SR_WVU BIT(2) 57 #define IWDG_SR_EWU BIT(3) 58 #define IWDG_SR_UPDATE_MASK (IWDG_SR_PVU | IWDG_SR_RVU | IWDG_SR_WVU | \ 59 IWDG_SR_EWU) 60 #define IWDG_SR_ONF BIT(8) 61 #define IWDG_SR_EWIF BIT(14) 62 #define IWDG_SR_EWIF_V40 BIT(15) 63 64 #define IWDG_EWCR_EWIE BIT(15) 65 #define IWDG_EWCR_EWIC BIT(14) 66 67 #define IWDG_ICR_EWIC BIT(15) 68 69 #define IWDG_VERR_REV_MASK GENMASK_32(7, 0) 70 71 /* Define default early timeout delay to 5 sec before timeout */ 72 #define IWDG_ETIMEOUT_SEC U(5) 73 74 /* 75 * Values for struct stm32_iwdg_device::flags 76 * IWDG_FLAGS_ENABLED Watchdog has been enabled 77 */ 78 #define IWDG_FLAGS_ENABLED BIT(0) 79 80 /* 81 * IWDG watch instance data 82 * @base - IWDG interface IOMEM base address 83 * @clk_pclk - Bus clock 84 * @clk_lsi - IWDG source clock 85 * @itr_chip - Interrupt chip device 86 * @itr_num - Interrupt number for the IWDG instance 87 * @itr_handler - Interrupt handler 88 * @flags - Property flags for the IWDG instance 89 * @timeout - Watchdog elaspure timeout 90 * @hw_version - Watchdog HW version 91 * @last_refresh - Time of last watchdog refresh 92 * @wdt_chip - Wathcdog chip instance 93 */ 94 struct stm32_iwdg_device { 95 struct io_pa_va base; 96 struct clk *clk_pclk; 97 struct clk *clk_lsi; 98 struct itr_chip *itr_chip; 99 size_t itr_num; 100 struct itr_handler *itr_handler; 101 uint32_t flags; 102 unsigned long timeout; 103 unsigned int hw_version; 104 TEE_Time last_refresh; 105 struct wdt_chip wdt_chip; 106 }; 107 108 static uint32_t sr_ewif_mask(struct stm32_iwdg_device *iwdg) 109 { 110 if (iwdg->hw_version >= IWDG_ICR_MIN_VER) 111 return IWDG_SR_EWIF_V40; 112 else 113 return IWDG_SR_EWIF; 114 } 115 116 static vaddr_t get_base(struct stm32_iwdg_device *iwdg) 117 { 118 return io_pa_or_va(&iwdg->base, 1); 119 } 120 121 static void iwdg_wdt_set_enabled(struct stm32_iwdg_device *iwdg) 122 { 123 iwdg->flags |= IWDG_FLAGS_ENABLED; 124 } 125 126 static bool iwdg_wdt_is_enabled(struct stm32_iwdg_device *iwdg) 127 { 128 return iwdg->flags & IWDG_FLAGS_ENABLED; 129 } 130 131 /* Return counter value to related to input timeout in seconds, or 0 on error */ 132 static uint32_t iwdg_timeout_cnt(struct stm32_iwdg_device *iwdg, 133 unsigned long to_sec) 134 { 135 uint64_t reload = (uint64_t)to_sec * clk_get_rate(iwdg->clk_lsi); 136 uint64_t cnt = (reload / IWDG_PRESCALER_256) - 1; 137 138 /* Be safe and expect any counter to be above 2 */ 139 if (cnt > IWDG_CNT_MASK || cnt < 3) 140 return 0; 141 142 return cnt; 143 } 144 145 /* Wait IWDG programming completes */ 146 static TEE_Result iwdg_wait_sync(struct stm32_iwdg_device *iwdg) 147 { 148 uint64_t timeout_ref = timeout_init_us(IWDG_TIMEOUT_US); 149 vaddr_t iwdg_base = get_base(iwdg); 150 151 while (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK) 152 if (timeout_elapsed(timeout_ref)) 153 break; 154 155 if (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK) 156 return TEE_ERROR_GENERIC; 157 158 return TEE_SUCCESS; 159 } 160 161 static enum itr_return stm32_iwdg_it_handler(struct itr_handler *h) 162 { 163 unsigned int __maybe_unused cpu = get_core_pos(); 164 struct stm32_iwdg_device *iwdg = h->data; 165 vaddr_t iwdg_base = get_base(iwdg); 166 167 DMSG("CPU %u IT Watchdog %#"PRIxPA, cpu, iwdg->base.pa); 168 169 /* Check for spurious interrupt */ 170 if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & sr_ewif_mask(iwdg))) 171 return ITRR_NONE; 172 173 /* 174 * Writing IWDG_EWCR_EWIT triggers a watchdog refresh. 175 * To prevent the watchdog refresh, write-protect all the registers; 176 * this makes read-only all IWDG_EWCR fields except IWDG_EWCR_EWIC. 177 */ 178 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_WPROT_KEY); 179 180 /* Disable early interrupt */ 181 if (iwdg->hw_version >= IWDG_ICR_MIN_VER) 182 io_setbits32(iwdg_base + IWDG_ICR_OFFSET, IWDG_ICR_EWIC); 183 else 184 io_setbits32(iwdg_base + IWDG_EWCR_OFFSET, IWDG_EWCR_EWIC); 185 186 panic("Watchdog"); 187 188 return ITRR_HANDLED; 189 } 190 DECLARE_KEEP_PAGER(stm32_iwdg_it_handler); 191 192 static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg) 193 { 194 TEE_Result res = TEE_ERROR_GENERIC; 195 vaddr_t iwdg_base = get_base(iwdg); 196 uint32_t rlr_value = 0; 197 uint32_t ewie_value = 0; 198 uint32_t early_timeout = 0; 199 200 assert(iwdg_wdt_is_enabled(iwdg)); 201 202 rlr_value = iwdg_timeout_cnt(iwdg, iwdg->timeout); 203 if (!rlr_value) 204 return TEE_ERROR_GENERIC; 205 206 if (iwdg->itr_handler) { 207 if (iwdg->timeout >= 2 * IWDG_ETIMEOUT_SEC) 208 early_timeout = IWDG_ETIMEOUT_SEC; 209 else 210 early_timeout = iwdg->timeout / 4; 211 ewie_value = iwdg_timeout_cnt(iwdg, early_timeout); 212 interrupt_enable(iwdg->itr_chip, iwdg->itr_num); 213 } 214 215 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); 216 io_write32(iwdg_base + IWDG_PR_OFFSET, IWDG_PR_DIV_256); 217 io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value); 218 if (ewie_value && 219 !(io_read32(iwdg_base + IWDG_EWCR_OFFSET) & IWDG_EWCR_EWIE)) 220 io_write32(iwdg_base + IWDG_EWCR_OFFSET, 221 ewie_value | IWDG_EWCR_EWIE); 222 223 res = iwdg_wait_sync(iwdg); 224 225 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 226 227 return res; 228 } 229 230 static void iwdg_start(struct stm32_iwdg_device *iwdg) 231 { 232 TEE_Result res = TEE_ERROR_GENERIC; 233 234 res = tee_time_get_sys_time(&iwdg->last_refresh); 235 if (res) 236 panic(); 237 238 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY); 239 240 iwdg_wdt_set_enabled(iwdg); 241 } 242 243 static void iwdg_refresh(struct stm32_iwdg_device *iwdg) 244 { 245 TEE_Result res = TEE_ERROR_GENERIC; 246 247 res = tee_time_get_sys_time(&iwdg->last_refresh); 248 if (res) 249 panic(); 250 251 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 252 } 253 254 /* Operators for watchdog OP-TEE interface */ 255 static struct stm32_iwdg_device *wdt_chip_to_iwdg(struct wdt_chip *chip) 256 { 257 return container_of(chip, struct stm32_iwdg_device, wdt_chip); 258 } 259 260 static TEE_Result iwdg_wdt_init(struct wdt_chip *chip, 261 unsigned long *min_timeout, 262 unsigned long *max_timeout) 263 { 264 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 265 unsigned long rate = clk_get_rate(iwdg->clk_lsi); 266 267 if (!rate) 268 return TEE_ERROR_GENERIC; 269 270 /* Be safe and expect any counter to be above 2 */ 271 *min_timeout = 3 * IWDG_PRESCALER_256 / rate; 272 *max_timeout = (IWDG_CNT_MASK + 1) * IWDG_PRESCALER_256 / rate; 273 274 return TEE_SUCCESS; 275 } 276 277 static void iwdg_wdt_start(struct wdt_chip *chip) 278 { 279 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 280 281 iwdg_start(iwdg); 282 283 if (configure_timeout(iwdg)) 284 panic(); 285 } 286 287 static void iwdg_wdt_refresh(struct wdt_chip *chip) 288 { 289 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 290 291 iwdg_refresh(iwdg); 292 } 293 294 static TEE_Result iwdg_wdt_set_timeout(struct wdt_chip *chip, 295 unsigned long timeout) 296 { 297 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 298 299 if (!iwdg_timeout_cnt(iwdg, timeout)) 300 return TEE_ERROR_BAD_PARAMETERS; 301 302 iwdg->timeout = timeout; 303 304 if (iwdg_wdt_is_enabled(iwdg)) { 305 TEE_Result res = TEE_ERROR_GENERIC; 306 307 res = configure_timeout(iwdg); 308 if (res) 309 return res; 310 } 311 312 return TEE_SUCCESS; 313 } 314 315 static TEE_Result iwdg_wdt_get_timeleft(struct wdt_chip *chip, bool *is_started, 316 unsigned long *timeleft) 317 { 318 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 319 TEE_Result res = TEE_ERROR_GENERIC; 320 TEE_Time time = { }; 321 TEE_Time now = { }; 322 323 *is_started = iwdg_wdt_is_enabled(iwdg); 324 325 if (!*is_started) 326 return TEE_SUCCESS; 327 328 res = tee_time_get_sys_time(&now); 329 if (res) 330 panic(); 331 332 time.seconds = iwdg->timeout; 333 TEE_TIME_ADD(iwdg->last_refresh, time, time); 334 if (TEE_TIME_LE(time, now)) { 335 *timeleft = 0; 336 } else { 337 TEE_TIME_SUB(time, now, time); 338 *timeleft = time.seconds; 339 } 340 341 return TEE_SUCCESS; 342 } 343 344 static const struct wdt_ops stm32_iwdg_ops = { 345 .init = iwdg_wdt_init, 346 .start = iwdg_wdt_start, 347 .ping = iwdg_wdt_refresh, 348 .set_timeout = iwdg_wdt_set_timeout, 349 .get_timeleft = iwdg_wdt_get_timeleft, 350 }; 351 DECLARE_KEEP_PAGER(stm32_iwdg_ops); 352 353 /* Driver initialization */ 354 static TEE_Result stm32_iwdg_parse_fdt(struct stm32_iwdg_device *iwdg, 355 const void *fdt, int node) 356 { 357 TEE_Result res = TEE_ERROR_GENERIC; 358 struct dt_node_info dt_info = { }; 359 const fdt32_t *cuint = NULL; 360 361 fdt_fill_device_info(fdt, &dt_info, node); 362 363 if (dt_info.reg == DT_INFO_INVALID_REG || 364 dt_info.reg_size == DT_INFO_INVALID_REG_SIZE) 365 panic(); 366 367 res = clk_dt_get_by_name(fdt, node, "pclk", &iwdg->clk_pclk); 368 if (res) 369 return res; 370 371 res = clk_dt_get_by_name(fdt, node, "lsi", &iwdg->clk_lsi); 372 if (res) 373 return res; 374 375 res = interrupt_dt_get(fdt, node, &iwdg->itr_chip, &iwdg->itr_num); 376 if (res && res != TEE_ERROR_ITEM_NOT_FOUND) 377 return res; 378 if (!res) { 379 res = interrupt_create_handler(iwdg->itr_chip, iwdg->itr_num, 380 stm32_iwdg_it_handler, iwdg, 0, 381 &iwdg->itr_handler); 382 if (res) 383 return res; 384 } 385 386 /* Get IOMEM address */ 387 iwdg->base.pa = dt_info.reg; 388 io_pa_or_va_secure(&iwdg->base, dt_info.reg_size); 389 assert(iwdg->base.va); 390 391 /* Get and check timeout value */ 392 cuint = fdt_getprop(fdt, node, "timeout-sec", NULL); 393 if (!cuint) { 394 res = TEE_ERROR_BAD_PARAMETERS; 395 goto err_itr; 396 } 397 398 iwdg->timeout = (int)fdt32_to_cpu(*cuint); 399 if (!iwdg->timeout) { 400 res = TEE_ERROR_BAD_PARAMETERS; 401 goto err_itr; 402 } 403 404 if (!iwdg_timeout_cnt(iwdg, iwdg->timeout)) { 405 EMSG("Timeout %lu not applicable", iwdg->timeout); 406 res = TEE_ERROR_BAD_PARAMETERS; 407 goto err_itr; 408 } 409 410 return TEE_SUCCESS; 411 412 err_itr: 413 interrupt_remove_free_handler(iwdg->itr_handler); 414 415 return res; 416 } 417 418 static void iwdg_wdt_get_version_and_status(struct stm32_iwdg_device *iwdg) 419 { 420 vaddr_t iwdg_base = get_base(iwdg); 421 uint32_t rlr_value = 0; 422 423 iwdg->hw_version = io_read32(iwdg_base + IWDG_VERR_OFFSET) & 424 IWDG_VERR_REV_MASK; 425 426 /* Test if watchdog is already running */ 427 if (iwdg->hw_version >= IWDG_ONF_MIN_VER) { 428 if (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_ONF) 429 iwdg_wdt_set_enabled(iwdg); 430 } else { 431 /* 432 * Workaround for old versions without IWDG_SR_ONF bit: 433 * - write in IWDG_RLR_OFFSET 434 * - wait for sync 435 * - if sync succeeds, then iwdg is running 436 */ 437 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); 438 439 rlr_value = io_read32(iwdg_base + IWDG_RLR_OFFSET); 440 io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value); 441 442 if (!iwdg_wait_sync(iwdg)) 443 iwdg_wdt_set_enabled(iwdg); 444 445 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_WPROT_KEY); 446 } 447 448 DMSG("Watchdog is %sabled", iwdg_wdt_is_enabled(iwdg) ? "en" : "dis"); 449 } 450 451 static TEE_Result stm32_iwdg_setup(struct stm32_iwdg_device *iwdg, 452 const void *fdt, int node) 453 { 454 TEE_Result res = TEE_SUCCESS; 455 456 res = stm32_iwdg_parse_fdt(iwdg, fdt, node); 457 if (res) 458 return res; 459 460 /* Enable watchdog source and bus clocks once for all */ 461 if (clk_enable(iwdg->clk_lsi)) 462 panic(); 463 464 if (clk_enable(iwdg->clk_pclk)) 465 panic(); 466 467 iwdg_wdt_get_version_and_status(iwdg); 468 469 if (iwdg_wdt_is_enabled(iwdg)) { 470 /* Configure timeout if watchdog is already enabled */ 471 res = configure_timeout(iwdg); 472 if (res) 473 panic(); 474 475 iwdg_refresh(iwdg); 476 } 477 478 return TEE_SUCCESS; 479 } 480 481 static TEE_Result stm32_iwdg_probe(const void *fdt, int node, 482 const void *compat_data __unused) 483 { 484 struct stm32_iwdg_device *iwdg = NULL; 485 TEE_Result res = TEE_SUCCESS; 486 487 iwdg = calloc(1, sizeof(*iwdg)); 488 if (!iwdg) 489 return TEE_ERROR_OUT_OF_MEMORY; 490 491 res = stm32_iwdg_setup(iwdg, fdt, node); 492 if (res) 493 goto out; 494 495 iwdg->wdt_chip.ops = &stm32_iwdg_ops; 496 497 res = watchdog_register(&iwdg->wdt_chip); 498 499 out: 500 if (res) 501 free(iwdg); 502 503 return res; 504 } 505 506 static const struct dt_device_match stm32_iwdg_match_table[] = { 507 { .compatible = "st,stm32mp1-iwdg" }, 508 { } 509 }; 510 511 DEFINE_DT_DRIVER(stm32_iwdg_dt_driver) = { 512 .name = "stm32-iwdg", 513 .match_table = stm32_iwdg_match_table, 514 .probe = stm32_iwdg_probe, 515 }; 516