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