1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <assert.h> 7 #include <drivers/clk.h> 8 #include <drivers/clk_dt.h> 9 #include <drivers/stm32_iwdg.h> 10 #include <drivers/wdt.h> 11 #include <io.h> 12 #include <keep.h> 13 #include <kernel/boot.h> 14 #include <kernel/delay.h> 15 #include <kernel/dt.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(1000) 30 #define IWDG_CNT_MASK GENMASK_32(11, 0) 31 32 /* IWDG registers offsets */ 33 #define IWDG_KR_OFFSET U(0x00) 34 #define IWDG_PR_OFFSET U(0x04) 35 #define IWDG_RLR_OFFSET U(0x08) 36 #define IWDG_SR_OFFSET U(0x0C) 37 #define IWDG_EWCR_OFFSET U(0x14) 38 39 #define IWDG_KR_ACCESS_KEY U(0x5555) 40 #define IWDG_KR_RELOAD_KEY U(0xAAAA) 41 #define IWDG_KR_START_KEY U(0xCCCC) 42 43 /* Use a fixed prescaler divider of 256 */ 44 #define IWDG_PRESCALER_256 U(256) 45 #define IWDG_PR_DIV_256 U(0x06) 46 #define IWDG_PR_DIV_MASK GENMASK_32(3, 0) 47 48 #define IWDG_SR_PVU BIT(0) 49 #define IWDG_SR_RVU BIT(1) 50 #define IWDG_SR_WVU BIT(2) 51 #define IWDG_SR_EWU BIT(3) 52 #define IWDG_SR_UPDATE_MASK (IWDG_SR_PVU | IWDG_SR_RVU | IWDG_SR_WVU | \ 53 IWDG_SR_EWU) 54 55 #define IWDG_EWCR_EWIE BIT(15) 56 #define IWDG_EWCR_EWIC BIT(14) 57 58 /* 59 * Values for struct stm32_iwdg_device::flags 60 * IWDG_FLAGS_HW_ENABLED Watchdog is enabled by BootROM 61 * IWDG_FLAGS_DISABLE_ON_STOP Watchdog is freezed in SoC STOP mode 62 * IWDG_FLAGS_DISABLE_ON_STANDBY Watchdog is freezed in SoC STANDBY mode 63 * IWDG_FLAGS_NON_SECURE Instance is assigned to non-secure world 64 * IWDG_FLAGS_ENABLED Watchdog has been enabled 65 */ 66 #define IWDG_FLAGS_HW_ENABLED BIT(0) 67 #define IWDG_FLAGS_DISABLE_ON_STOP BIT(1) 68 #define IWDG_FLAGS_DISABLE_ON_STANDBY BIT(2) 69 #define IWDG_FLAGS_NON_SECURE BIT(3) 70 #define IWDG_FLAGS_ENABLED BIT(4) 71 72 /* 73 * IWDG watch instance data 74 * @base - IWDG interface IOMEM base address 75 * @clock - Bus clock 76 * @clk_lsi - IWDG source clock 77 * @flags - Property flags for the IWDG instance 78 * @timeout - Watchdog elaspure timeout 79 * @wdt_chip - Wathcdog chip instance 80 * @link - Link in registered watchdog instance list 81 */ 82 struct stm32_iwdg_device { 83 struct io_pa_va base; 84 struct clk *clock; 85 struct clk *clk_lsi; 86 uint32_t flags; 87 unsigned long timeout; 88 struct wdt_chip wdt_chip; 89 SLIST_ENTRY(stm32_iwdg_device) link; 90 }; 91 92 static unsigned int iwdg_lock = SPINLOCK_UNLOCK; 93 94 static SLIST_HEAD(iwdg_dev_list_head, stm32_iwdg_device) iwdg_dev_list = 95 SLIST_HEAD_INITIALIZER(iwdg_dev_list_head); 96 97 static vaddr_t get_base(struct stm32_iwdg_device *iwdg) 98 { 99 return io_pa_or_va(&iwdg->base, 1); 100 } 101 102 static bool is_assigned_to_nsec(struct stm32_iwdg_device *iwdg) 103 { 104 return iwdg->flags & IWDG_FLAGS_NON_SECURE; 105 } 106 107 static bool is_enable(struct stm32_iwdg_device *iwdg) 108 { 109 return iwdg->flags & IWDG_FLAGS_ENABLED; 110 } 111 112 /* Return counter value to related to input timeout in seconds, or 0 on error */ 113 static uint32_t iwdg_timeout_cnt(struct stm32_iwdg_device *iwdg, 114 unsigned long to_sec) 115 { 116 uint64_t reload = (uint64_t)to_sec * clk_get_rate(iwdg->clk_lsi); 117 uint64_t cnt = (reload / IWDG_PRESCALER_256) - 1; 118 119 /* Be safe and expect any counter to be above 2 */ 120 if (cnt > IWDG_CNT_MASK || cnt < 3) 121 return 0; 122 123 return cnt; 124 } 125 126 /* Wait IWDG programming completes */ 127 static TEE_Result iwdg_wait_sync(struct stm32_iwdg_device *iwdg) 128 { 129 uint64_t timeout_ref = timeout_init_us(IWDG_TIMEOUT_US); 130 vaddr_t iwdg_base = get_base(iwdg); 131 132 while (io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK) 133 if (timeout_elapsed(timeout_ref)) 134 break; 135 136 if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_UPDATE_MASK)) 137 return TEE_ERROR_GENERIC; 138 139 return TEE_SUCCESS; 140 } 141 142 static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg) 143 { 144 TEE_Result res = TEE_ERROR_GENERIC; 145 vaddr_t iwdg_base = get_base(iwdg); 146 uint32_t rlr_value = 0; 147 148 assert(is_enable(iwdg)); 149 150 rlr_value = iwdg_timeout_cnt(iwdg, iwdg->timeout); 151 if (!rlr_value) 152 return TEE_ERROR_GENERIC; 153 154 clk_enable(iwdg->clock); 155 156 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); 157 io_write32(iwdg_base + IWDG_PR_OFFSET, IWDG_PR_DIV_256); 158 io_write32(iwdg_base + IWDG_RLR_OFFSET, rlr_value); 159 io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 160 161 res = iwdg_wait_sync(iwdg); 162 163 clk_disable(iwdg->clock); 164 165 return res; 166 } 167 168 static void iwdg_start(struct stm32_iwdg_device *iwdg) 169 { 170 clk_enable(iwdg->clock); 171 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY); 172 clk_disable(iwdg->clock); 173 174 iwdg->flags |= IWDG_FLAGS_ENABLED; 175 } 176 177 static void iwdg_refresh(struct stm32_iwdg_device *iwdg) 178 { 179 clk_enable(iwdg->clock); 180 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); 181 clk_disable(iwdg->clock); 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 void iwdg_wdt_start(struct wdt_chip *chip) 191 { 192 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 193 194 iwdg_start(iwdg); 195 196 if (configure_timeout(iwdg)) 197 panic(); 198 } 199 200 static void iwdg_wdt_refresh(struct wdt_chip *chip) 201 { 202 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 203 204 iwdg_refresh(iwdg); 205 } 206 207 static TEE_Result iwdg_wdt_set_timeout(struct wdt_chip *chip, 208 unsigned long timeout) 209 { 210 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); 211 212 if (!iwdg_timeout_cnt(iwdg, timeout)) 213 return TEE_ERROR_BAD_PARAMETERS; 214 215 iwdg->timeout = timeout; 216 217 if (is_enable(iwdg)) { 218 TEE_Result res = TEE_ERROR_GENERIC; 219 220 res = configure_timeout(iwdg); 221 if (res) 222 return res; 223 } 224 225 return TEE_SUCCESS; 226 } 227 228 static const struct wdt_ops stm32_iwdg_ops = { 229 .start = iwdg_wdt_start, 230 .ping = iwdg_wdt_refresh, 231 .set_timeout = iwdg_wdt_set_timeout, 232 }; 233 DECLARE_KEEP_PAGER(stm32_iwdg_ops); 234 235 /* Refresh all registered watchdogs */ 236 void stm32_iwdg_refresh(void) 237 { 238 struct stm32_iwdg_device *iwdg = NULL; 239 uint32_t exceptions = cpu_spin_lock_xsave(&iwdg_lock); 240 241 SLIST_FOREACH(iwdg, &iwdg_dev_list, link) 242 iwdg_refresh(iwdg); 243 244 cpu_spin_unlock_xrestore(&iwdg_lock, exceptions); 245 } 246 247 /* Driver initialization */ 248 static TEE_Result stm32_iwdg_parse_fdt(struct stm32_iwdg_device *iwdg, 249 const void *fdt, int node) 250 { 251 TEE_Result res = TEE_ERROR_GENERIC; 252 struct dt_node_info dt_info = { }; 253 const fdt32_t *cuint = NULL; 254 255 _fdt_fill_device_info(fdt, &dt_info, node); 256 257 if (dt_info.reg == DT_INFO_INVALID_REG || 258 dt_info.reg_size == DT_INFO_INVALID_REG_SIZE) 259 panic(); 260 261 res = clk_dt_get_by_name(fdt, node, "pclk", &iwdg->clock); 262 if (res) 263 return res; 264 265 res = clk_dt_get_by_name(fdt, node, "lsi", &iwdg->clk_lsi); 266 if (res) 267 return res; 268 269 if (dt_info.status == DT_STATUS_OK_NSEC) 270 iwdg->flags |= IWDG_FLAGS_NON_SECURE; 271 272 /* Get IOMEM address */ 273 iwdg->base.pa = dt_info.reg; 274 275 if (iwdg->flags & IWDG_FLAGS_NON_SECURE) 276 io_pa_or_va_nsec(&iwdg->base, dt_info.reg_size); 277 else 278 io_pa_or_va_secure(&iwdg->base, dt_info.reg_size); 279 280 assert(iwdg->base.va); 281 282 /* Get and check timeout value */ 283 cuint = fdt_getprop(fdt, node, "timeout-sec", NULL); 284 if (!cuint) 285 return TEE_ERROR_BAD_PARAMETERS; 286 287 iwdg->timeout = (int)fdt32_to_cpu(*cuint); 288 if (!iwdg->timeout) 289 return TEE_ERROR_BAD_PARAMETERS; 290 291 if (!iwdg_timeout_cnt(iwdg, iwdg->timeout)) { 292 EMSG("Timeout %lu not applicable", iwdg->timeout); 293 return TEE_ERROR_BAD_PARAMETERS; 294 } 295 296 /* DT can specify low power cases */ 297 if (!fdt_getprop(fdt, node, "stm32,enable-on-stop", NULL)) 298 iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STOP; 299 300 if (!fdt_getprop(fdt, node, "stm32,enable-on-standby", NULL)) 301 iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STANDBY; 302 303 return TEE_SUCCESS; 304 } 305 306 /* Platform should override this function to provide IWDG fuses configuration */ 307 TEE_Result __weak stm32_get_iwdg_otp_config(paddr_t pbase __unused, 308 struct stm32_iwdg_otp_data *otp_d) 309 { 310 otp_d->hw_enabled = false; 311 otp_d->disable_on_stop = false; 312 otp_d->disable_on_standby = false; 313 314 return TEE_SUCCESS; 315 } 316 317 static TEE_Result stm32_iwdg_setup(struct stm32_iwdg_device *iwdg, 318 const void *fdt, int node) 319 { 320 struct stm32_iwdg_otp_data otp_data = { }; 321 TEE_Result res = TEE_SUCCESS; 322 323 res = stm32_iwdg_parse_fdt(iwdg, fdt, node); 324 if (res) 325 return res; 326 327 res = stm32_get_iwdg_otp_config(iwdg->base.pa, &otp_data); 328 if (res) 329 return res; 330 331 if (otp_data.hw_enabled) 332 iwdg->flags |= IWDG_FLAGS_HW_ENABLED; 333 if (otp_data.disable_on_stop) 334 iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STOP; 335 if (otp_data.disable_on_standby) 336 iwdg->flags |= IWDG_FLAGS_DISABLE_ON_STANDBY; 337 338 /* Enable watchdog source clock once for all */ 339 clk_enable(iwdg->clk_lsi); 340 341 if (otp_data.hw_enabled) { 342 iwdg->flags |= IWDG_FLAGS_ENABLED; 343 344 /* Configure timeout if watchdog is already enabled */ 345 res = configure_timeout(iwdg); 346 if (res) 347 return res; 348 349 iwdg_refresh(iwdg); 350 } 351 352 return TEE_SUCCESS; 353 } 354 355 static TEE_Result stm32_iwdg_register(struct stm32_iwdg_device *iwdg) 356 { 357 TEE_Result res = TEE_ERROR_GENERIC; 358 359 if (is_assigned_to_nsec(iwdg)) { 360 stm32mp_register_non_secure_periph_iomem(iwdg->base.pa); 361 } else { 362 stm32mp_register_secure_periph_iomem(iwdg->base.pa); 363 364 /* Expose watchdog runtime service only to secure IWDG */ 365 iwdg->wdt_chip.ops = &stm32_iwdg_ops; 366 367 res = watchdog_register(&iwdg->wdt_chip); 368 if (res) 369 return res; 370 } 371 372 SLIST_INSERT_HEAD(&iwdg_dev_list, iwdg, link); 373 374 return TEE_SUCCESS; 375 } 376 377 static TEE_Result stm32_iwdg_probe(const void *fdt, int node, 378 const void *compat_data __unused) 379 { 380 struct stm32_iwdg_device *iwdg = NULL; 381 TEE_Result res = TEE_SUCCESS; 382 383 iwdg = calloc(1, sizeof(*iwdg)); 384 if (!iwdg) 385 return TEE_ERROR_OUT_OF_MEMORY; 386 387 res = stm32_iwdg_setup(iwdg, fdt, node); 388 if (res) 389 goto err; 390 391 res = stm32_iwdg_register(iwdg); 392 if (res) 393 goto err; 394 395 return TEE_SUCCESS; 396 397 err: 398 free(iwdg); 399 return res; 400 } 401 402 static const struct dt_device_match stm32_iwdg_match_table[] = { 403 { .compatible = "st,stm32mp1-iwdg" }, 404 { } 405 }; 406 407 DEFINE_DT_DRIVER(stm32_iwdg_dt_driver) = { 408 .name = "stm32-iwdg", 409 .match_table = stm32_iwdg_match_table, 410 .probe = stm32_iwdg_probe, 411 }; 412