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 34 /* IWDG registers offsets */ 35 #define IWDG_KR_OFFSET U(0x00) 36 #define IWDG_PR_OFFSET U(0x04) 37 #define IWDG_RLR_OFFSET U(0x08) 38 #define IWDG_SR_OFFSET U(0x0C) 39 #define IWDG_EWCR_OFFSET U(0x14) 40 #define IWDG_VERR_OFFSET U(0x3F4) 41 42 #define IWDG_KR_WPROT_KEY U(0x0000) 43 #define IWDG_KR_ACCESS_KEY U(0x5555) 44 #define IWDG_KR_RELOAD_KEY U(0xAAAA) 45 #define IWDG_KR_START_KEY U(0xCCCC) 46 47 /* Use a fixed prescaler divider of 256 */ 48 #define IWDG_PRESCALER_256 U(256) 49 #define IWDG_PR_DIV_256 U(0x06) 50 #define IWDG_PR_DIV_MASK GENMASK_32(3, 0) 51 52 #define IWDG_SR_PVU BIT(0) 53 #define IWDG_SR_RVU BIT(1) 54 #define IWDG_SR_WVU BIT(2) 55 #define IWDG_SR_EWU BIT(3) 56 #define IWDG_SR_UPDATE_MASK (IWDG_SR_PVU | IWDG_SR_RVU | IWDG_SR_WVU | \ 57 IWDG_SR_EWU) 58 #define IWDG_SR_ONF BIT(8) 59 60 #define IWDG_EWCR_EWIE BIT(15) 61 #define IWDG_EWCR_EWIC BIT(14) 62 63 #define IWDG_VERR_REV_MASK GENMASK_32(7, 0) 64 65 /* 66 * Values for struct stm32_iwdg_device::flags 67 * IWDG_FLAGS_ENABLED Watchdog has been enabled 68 */ 69 #define IWDG_FLAGS_ENABLED BIT(0) 70 71 /* 72 * IWDG watch instance data 73 * @base - IWDG interface IOMEM base address 74 * @clk_pclk - Bus clock 75 * @clk_lsi - IWDG source clock 76 * @flags - Property flags for the IWDG instance 77 * @timeout - Watchdog elaspure timeout 78 * @hw_version - Watchdog HW version 79 * @last_refresh - Time of last watchdog refresh 80 * @wdt_chip - Wathcdog chip instance 81 */ 82 struct stm32_iwdg_device { 83 struct io_pa_va base; 84 struct clk *clk_pclk; 85 struct clk *clk_lsi; 86 uint32_t flags; 87 unsigned long timeout; 88 unsigned int hw_version; 89 TEE_Time last_refresh; 90 struct wdt_chip wdt_chip; 91 }; 92 93 static vaddr_t get_base(struct stm32_iwdg_device *iwdg) 94 { 95 return io_pa_or_va(&iwdg->base, 1); 96 } 97 98 static void iwdg_wdt_set_enabled(struct stm32_iwdg_device *iwdg) 99 { 100 iwdg->flags |= IWDG_FLAGS_ENABLED; 101 } 102 103 static bool iwdg_wdt_is_enabled(struct stm32_iwdg_device *iwdg) 104 { 105 return iwdg->flags & IWDG_FLAGS_ENABLED; 106 } 107 108 /* Return counter value to related to input timeout in seconds, or 0 on error */ 109 static uint32_t iwdg_timeout_cnt(struct stm32_iwdg_device *iwdg, 110 unsigned long to_sec) 111 { 112 uint64_t reload = (uint64_t)to_sec * clk_get_rate(iwdg->clk_lsi); 113 uint64_t cnt = (reload / IWDG_PRESCALER_256) - 1; 114 115 /* Be safe and expect any counter to be above 2 */ 116 if (cnt > IWDG_CNT_MASK || cnt < 3) 117 return 0; 118 119 return cnt; 120 } 121 122 /* Wait IWDG programming completes */ 123 static TEE_Result iwdg_wait_sync(struct stm32_iwdg_device *iwdg) 124 { 125 uint64_t timeout_ref = timeout_init_us(IWDG_TIMEOUT_US); 126 vaddr_t iwdg_base = get_base(iwdg); 127 128 while (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK) 129 if (timeout_elapsed(timeout_ref)) 130 break; 131 132 if (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK) 133 return TEE_ERROR_GENERIC; 134 135 return TEE_SUCCESS; 136 } 137 138 static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg) 139 { 140 TEE_Result res = TEE_ERROR_GENERIC; 141 vaddr_t iwdg_base = get_base(iwdg); 142 uint32_t rlr_value = 0; 143 144 assert(iwdg_wdt_is_enabled(iwdg)); 145 146 rlr_value = iwdg_timeout_cnt(iwdg, iwdg->timeout); 147 if (!rlr_value) 148 return TEE_ERROR_GENERIC; 149 150 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); 151 io_write32(iwdg_base + IWDG_PR_OFFSET, IWDG_PR_DIV_256); 152 io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value); 153 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 154 155 res = iwdg_wait_sync(iwdg); 156 157 return res; 158 } 159 160 static void iwdg_start(struct stm32_iwdg_device *iwdg) 161 { 162 TEE_Result res = TEE_ERROR_GENERIC; 163 164 res = tee_time_get_sys_time(&iwdg->last_refresh); 165 if (res) 166 panic(); 167 168 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY); 169 170 iwdg_wdt_set_enabled(iwdg); 171 } 172 173 static void iwdg_refresh(struct stm32_iwdg_device *iwdg) 174 { 175 TEE_Result res = TEE_ERROR_GENERIC; 176 177 res = tee_time_get_sys_time(&iwdg->last_refresh); 178 if (res) 179 panic(); 180 181 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 182 } 183 184 /* Operators for watchdog OP-TEE interface */ 185 static struct stm32_iwdg_device *wdt_chip_to_iwdg(struct wdt_chip *chip) 186 { 187 return container_of(chip, struct stm32_iwdg_device, wdt_chip); 188 } 189 190 static TEE_Result iwdg_wdt_init(struct wdt_chip *chip, 191 unsigned long *min_timeout, 192 unsigned long *max_timeout) 193 { 194 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 195 unsigned long rate = clk_get_rate(iwdg->clk_lsi); 196 197 if (!rate) 198 return TEE_ERROR_GENERIC; 199 200 /* Be safe and expect any counter to be above 2 */ 201 *min_timeout = 3 * IWDG_PRESCALER_256 / rate; 202 *max_timeout = (IWDG_CNT_MASK + 1) * IWDG_PRESCALER_256 / rate; 203 204 return TEE_SUCCESS; 205 } 206 207 static void iwdg_wdt_start(struct wdt_chip *chip) 208 { 209 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 210 211 iwdg_start(iwdg); 212 213 if (configure_timeout(iwdg)) 214 panic(); 215 } 216 217 static void iwdg_wdt_refresh(struct wdt_chip *chip) 218 { 219 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 220 221 iwdg_refresh(iwdg); 222 } 223 224 static TEE_Result iwdg_wdt_set_timeout(struct wdt_chip *chip, 225 unsigned long timeout) 226 { 227 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 228 229 if (!iwdg_timeout_cnt(iwdg, timeout)) 230 return TEE_ERROR_BAD_PARAMETERS; 231 232 iwdg->timeout = timeout; 233 234 if (iwdg_wdt_is_enabled(iwdg)) { 235 TEE_Result res = TEE_ERROR_GENERIC; 236 237 res = configure_timeout(iwdg); 238 if (res) 239 return res; 240 } 241 242 return TEE_SUCCESS; 243 } 244 245 static TEE_Result iwdg_wdt_get_timeleft(struct wdt_chip *chip, bool *is_started, 246 unsigned long *timeleft) 247 { 248 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 249 TEE_Result res = TEE_ERROR_GENERIC; 250 TEE_Time time = { }; 251 TEE_Time now = { }; 252 253 *is_started = iwdg_wdt_is_enabled(iwdg); 254 255 if (!*is_started) 256 return TEE_SUCCESS; 257 258 res = tee_time_get_sys_time(&now); 259 if (res) 260 panic(); 261 262 time.seconds = iwdg->timeout; 263 TEE_TIME_ADD(iwdg->last_refresh, time, time); 264 if (TEE_TIME_LE(time, now)) { 265 *timeleft = 0; 266 } else { 267 TEE_TIME_SUB(time, now, time); 268 *timeleft = time.seconds; 269 } 270 271 return TEE_SUCCESS; 272 } 273 274 static const struct wdt_ops stm32_iwdg_ops = { 275 .init = iwdg_wdt_init, 276 .start = iwdg_wdt_start, 277 .ping = iwdg_wdt_refresh, 278 .set_timeout = iwdg_wdt_set_timeout, 279 .get_timeleft = iwdg_wdt_get_timeleft, 280 }; 281 DECLARE_KEEP_PAGER(stm32_iwdg_ops); 282 283 /* Driver initialization */ 284 static TEE_Result stm32_iwdg_parse_fdt(struct stm32_iwdg_device *iwdg, 285 const void *fdt, int node) 286 { 287 TEE_Result res = TEE_ERROR_GENERIC; 288 struct dt_node_info dt_info = { }; 289 const fdt32_t *cuint = NULL; 290 291 fdt_fill_device_info(fdt, &dt_info, node); 292 293 if (dt_info.reg == DT_INFO_INVALID_REG || 294 dt_info.reg_size == DT_INFO_INVALID_REG_SIZE) 295 panic(); 296 297 res = clk_dt_get_by_name(fdt, node, "pclk", &iwdg->clk_pclk); 298 if (res) 299 return res; 300 301 res = clk_dt_get_by_name(fdt, node, "lsi", &iwdg->clk_lsi); 302 if (res) 303 return res; 304 305 /* Get IOMEM address */ 306 iwdg->base.pa = dt_info.reg; 307 io_pa_or_va_secure(&iwdg->base, dt_info.reg_size); 308 assert(iwdg->base.va); 309 310 /* Get and check timeout value */ 311 cuint = fdt_getprop(fdt, node, "timeout-sec", NULL); 312 if (!cuint) 313 return TEE_ERROR_BAD_PARAMETERS; 314 315 iwdg->timeout = (int)fdt32_to_cpu(*cuint); 316 if (!iwdg->timeout) 317 return TEE_ERROR_BAD_PARAMETERS; 318 319 if (!iwdg_timeout_cnt(iwdg, iwdg->timeout)) { 320 EMSG("Timeout %lu not applicable", iwdg->timeout); 321 return TEE_ERROR_BAD_PARAMETERS; 322 } 323 324 return TEE_SUCCESS; 325 } 326 327 static void iwdg_wdt_get_version_and_status(struct stm32_iwdg_device *iwdg) 328 { 329 vaddr_t iwdg_base = get_base(iwdg); 330 uint32_t rlr_value = 0; 331 332 iwdg->hw_version = io_read32(iwdg_base + IWDG_VERR_OFFSET) & 333 IWDG_VERR_REV_MASK; 334 335 /* Test if watchdog is already running */ 336 if (iwdg->hw_version >= IWDG_ONF_MIN_VER) { 337 if (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_ONF) 338 iwdg_wdt_set_enabled(iwdg); 339 } else { 340 /* 341 * Workaround for old versions without IWDG_SR_ONF bit: 342 * - write in IWDG_RLR_OFFSET 343 * - wait for sync 344 * - if sync succeeds, then iwdg is running 345 */ 346 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); 347 348 rlr_value = io_read32(iwdg_base + IWDG_RLR_OFFSET); 349 io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value); 350 351 if (!iwdg_wait_sync(iwdg)) 352 iwdg_wdt_set_enabled(iwdg); 353 354 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_WPROT_KEY); 355 } 356 357 DMSG("Watchdog is %sabled", iwdg_wdt_is_enabled(iwdg) ? "en" : "dis"); 358 } 359 360 static TEE_Result stm32_iwdg_setup(struct stm32_iwdg_device *iwdg, 361 const void *fdt, int node) 362 { 363 TEE_Result res = TEE_SUCCESS; 364 365 res = stm32_iwdg_parse_fdt(iwdg, fdt, node); 366 if (res) 367 return res; 368 369 /* Enable watchdog source and bus clocks once for all */ 370 if (clk_enable(iwdg->clk_lsi)) 371 panic(); 372 373 if (clk_enable(iwdg->clk_pclk)) 374 panic(); 375 376 iwdg_wdt_get_version_and_status(iwdg); 377 378 if (iwdg_wdt_is_enabled(iwdg)) { 379 /* Configure timeout if watchdog is already enabled */ 380 res = configure_timeout(iwdg); 381 if (res) 382 panic(); 383 384 iwdg_refresh(iwdg); 385 } 386 387 return TEE_SUCCESS; 388 } 389 390 static TEE_Result stm32_iwdg_probe(const void *fdt, int node, 391 const void *compat_data __unused) 392 { 393 struct stm32_iwdg_device *iwdg = NULL; 394 TEE_Result res = TEE_SUCCESS; 395 396 iwdg = calloc(1, sizeof(*iwdg)); 397 if (!iwdg) 398 return TEE_ERROR_OUT_OF_MEMORY; 399 400 res = stm32_iwdg_setup(iwdg, fdt, node); 401 if (res) 402 goto out; 403 404 iwdg->wdt_chip.ops = &stm32_iwdg_ops; 405 406 res = watchdog_register(&iwdg->wdt_chip); 407 408 out: 409 if (res) 410 free(iwdg); 411 412 return res; 413 } 414 415 static const struct dt_device_match stm32_iwdg_match_table[] = { 416 { .compatible = "st,stm32mp1-iwdg" }, 417 { } 418 }; 419 420 DEFINE_DT_DRIVER(stm32_iwdg_dt_driver) = { 421 .name = "stm32-iwdg", 422 .match_table = stm32_iwdg_match_table, 423 .probe = stm32_iwdg_probe, 424 }; 425