Lines Matching refs:iwdg

120 static uint32_t sr_ewif_mask(struct stm32_iwdg_device *iwdg)  in sr_ewif_mask()  argument
122 if (iwdg->hw_version >= IWDG_ICR_MIN_VER) in sr_ewif_mask()
128 static vaddr_t get_base(struct stm32_iwdg_device *iwdg) in get_base() argument
130 return io_pa_or_va(&iwdg->base, 1); in get_base()
133 static void iwdg_wdt_set_enabled(struct stm32_iwdg_device *iwdg) in iwdg_wdt_set_enabled() argument
135 iwdg->flags |= IWDG_FLAGS_ENABLED; in iwdg_wdt_set_enabled()
138 static bool iwdg_wdt_is_enabled(struct stm32_iwdg_device *iwdg) in iwdg_wdt_is_enabled() argument
140 return iwdg->flags & IWDG_FLAGS_ENABLED; in iwdg_wdt_is_enabled()
144 static uint32_t iwdg_timeout_cnt(struct stm32_iwdg_device *iwdg, in iwdg_timeout_cnt() argument
147 uint64_t reload = (uint64_t)to_sec * clk_get_rate(iwdg->clk_lsi); in iwdg_timeout_cnt()
158 static TEE_Result iwdg_wait_sync(struct stm32_iwdg_device *iwdg) in iwdg_wait_sync() argument
161 vaddr_t iwdg_base = get_base(iwdg); in iwdg_wait_sync()
173 static void stm32_iwdg_it_ack(struct stm32_iwdg_device *iwdg) in stm32_iwdg_it_ack() argument
175 vaddr_t iwdg_base = get_base(iwdg); in stm32_iwdg_it_ack()
177 if (iwdg->hw_version >= IWDG_ICR_MIN_VER) in stm32_iwdg_it_ack()
186 struct stm32_iwdg_device *iwdg = h->data; in stm32_iwdg_it_handler() local
187 vaddr_t iwdg_base = get_base(iwdg); in stm32_iwdg_it_handler()
189 DMSG("CPU %u IT Watchdog %#"PRIxPA, cpu, iwdg->base.pa); in stm32_iwdg_it_handler()
192 if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & sr_ewif_mask(iwdg))) in stm32_iwdg_it_handler()
203 stm32_iwdg_it_ack(iwdg); in stm32_iwdg_it_handler()
205 if (iwdg->nb_int > 0) { in stm32_iwdg_it_handler()
207 if (iwdg->nb_int < ULONG_MAX) in stm32_iwdg_it_handler()
208 iwdg->nb_int--; in stm32_iwdg_it_handler()
209 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); in stm32_iwdg_it_handler()
218 static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg) in configure_timeout() argument
221 vaddr_t iwdg_base = get_base(iwdg); in configure_timeout()
225 assert(iwdg_wdt_is_enabled(iwdg)); in configure_timeout()
227 rlr_value = iwdg_timeout_cnt(iwdg, iwdg->timeout); in configure_timeout()
231 if (iwdg->itr_handler) { in configure_timeout()
232 ewie_value = iwdg_timeout_cnt(iwdg, iwdg->early_timeout); in configure_timeout()
233 interrupt_enable(iwdg->itr_chip, iwdg->itr_num); in configure_timeout()
244 res = iwdg_wait_sync(iwdg); in configure_timeout()
251 static void iwdg_start(struct stm32_iwdg_device *iwdg) in iwdg_start() argument
255 res = tee_time_get_sys_time(&iwdg->last_refresh); in iwdg_start()
259 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY); in iwdg_start()
261 iwdg_wdt_set_enabled(iwdg); in iwdg_start()
264 static void iwdg_refresh(struct stm32_iwdg_device *iwdg) in iwdg_refresh() argument
268 res = tee_time_get_sys_time(&iwdg->last_refresh); in iwdg_refresh()
272 io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); in iwdg_refresh()
285 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_init() local
286 unsigned long rate = clk_get_rate(iwdg->clk_lsi); in iwdg_wdt_init()
300 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_start() local
302 iwdg_start(iwdg); in iwdg_wdt_start()
303 if (iwdg->reset && iwdg->itr_handler) in iwdg_wdt_start()
304 stm32_iwdg_it_ack(iwdg); in iwdg_wdt_start()
306 if (configure_timeout(iwdg)) in iwdg_wdt_start()
309 if (iwdg->reset) in iwdg_wdt_start()
310 if (rstctrl_assert(iwdg->reset)) in iwdg_wdt_start()
316 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_stop() local
318 if (iwdg->reset) { in iwdg_wdt_stop()
319 if (rstctrl_deassert(iwdg->reset)) in iwdg_wdt_stop()
321 if (iwdg->itr_handler) in iwdg_wdt_stop()
322 interrupt_disable(iwdg->itr_chip, iwdg->itr_num); in iwdg_wdt_stop()
326 iwdg->saved_nb_int = ULONG_MAX; in iwdg_wdt_stop()
327 iwdg->nb_int = ULONG_MAX; in iwdg_wdt_stop()
332 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_refresh() local
334 iwdg->nb_int = iwdg->saved_nb_int; in iwdg_wdt_refresh()
335 iwdg_refresh(iwdg); in iwdg_wdt_refresh()
338 static void stm32_iwdg_handle_timeouts(struct stm32_iwdg_device *iwdg, in stm32_iwdg_handle_timeouts() argument
346 rate = clk_get_rate(iwdg->clk_lsi); in stm32_iwdg_handle_timeouts()
347 iwdg->max_hw_timeout = (IWDG_CNT_MASK + 1) * IWDG_PRESCALER_1024 / rate; in stm32_iwdg_handle_timeouts()
349 if (timeout_sec > iwdg->max_hw_timeout) { in stm32_iwdg_handle_timeouts()
351 interval = iwdg->max_hw_timeout - IWDG_ETIMEOUT_SEC; in stm32_iwdg_handle_timeouts()
355 iwdg->timeout = w; in stm32_iwdg_handle_timeouts()
356 iwdg->early_timeout = IWDG_ETIMEOUT_SEC; in stm32_iwdg_handle_timeouts()
358 iwdg->timeout = timeout_sec; in stm32_iwdg_handle_timeouts()
359 if (iwdg->timeout >= 2 * IWDG_ETIMEOUT_SEC) in stm32_iwdg_handle_timeouts()
360 iwdg->early_timeout = IWDG_ETIMEOUT_SEC; in stm32_iwdg_handle_timeouts()
362 iwdg->early_timeout = iwdg->timeout / 4; in stm32_iwdg_handle_timeouts()
365 if (!iwdg->early_timeout) in stm32_iwdg_handle_timeouts()
366 iwdg->early_timeout = 1; in stm32_iwdg_handle_timeouts()
368 iwdg->saved_nb_int = n; in stm32_iwdg_handle_timeouts()
369 iwdg->nb_int = n; in stm32_iwdg_handle_timeouts()
375 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_set_timeout() local
377 if (iwdg_wdt_is_enabled(iwdg)) { in iwdg_wdt_set_timeout()
380 stm32_iwdg_handle_timeouts(iwdg, timeout); in iwdg_wdt_set_timeout()
382 res = configure_timeout(iwdg); in iwdg_wdt_set_timeout()
393 struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); in iwdg_wdt_get_timeleft() local
398 *is_started = iwdg_wdt_is_enabled(iwdg); in iwdg_wdt_get_timeleft()
408 (iwdg->timeout - iwdg->early_timeout) * iwdg->saved_nb_int in iwdg_wdt_get_timeleft()
409 + iwdg->early_timeout; in iwdg_wdt_get_timeleft()
410 TEE_TIME_ADD(iwdg->last_refresh, time, time); in iwdg_wdt_get_timeleft()
432 static TEE_Result stm32_iwdg_parse_fdt(struct stm32_iwdg_device *iwdg, in stm32_iwdg_parse_fdt() argument
445 res = clk_dt_get_by_name(fdt, node, "pclk", &iwdg->clk_pclk); in stm32_iwdg_parse_fdt()
449 res = clk_dt_get_by_name(fdt, node, "lsi", &iwdg->clk_lsi); in stm32_iwdg_parse_fdt()
453 res = interrupt_dt_get(fdt, node, &iwdg->itr_chip, &iwdg->itr_num); in stm32_iwdg_parse_fdt()
457 res = interrupt_create_handler(iwdg->itr_chip, iwdg->itr_num, in stm32_iwdg_parse_fdt()
458 stm32_iwdg_it_handler, iwdg, 0, in stm32_iwdg_parse_fdt()
459 &iwdg->itr_handler); in stm32_iwdg_parse_fdt()
464 res = rstctrl_dt_get_by_index(fdt, node, 0, &iwdg->reset); in stm32_iwdg_parse_fdt()
469 iwdg->base.pa = dt_info.reg; in stm32_iwdg_parse_fdt()
470 io_pa_or_va_secure(&iwdg->base, dt_info.reg_size); in stm32_iwdg_parse_fdt()
471 assert(iwdg->base.va); in stm32_iwdg_parse_fdt()
480 iwdg->timeout = (int)fdt32_to_cpu(*cuint); in stm32_iwdg_parse_fdt()
481 if (!iwdg->timeout) { in stm32_iwdg_parse_fdt()
489 interrupt_remove_free_handler(iwdg->itr_handler); in stm32_iwdg_parse_fdt()
494 static void iwdg_wdt_get_version_and_status(struct stm32_iwdg_device *iwdg) in iwdg_wdt_get_version_and_status() argument
496 vaddr_t iwdg_base = get_base(iwdg); in iwdg_wdt_get_version_and_status()
499 iwdg->hw_version = io_read32(iwdg_base + IWDG_VERR_OFFSET) & in iwdg_wdt_get_version_and_status()
503 if (iwdg->hw_version >= IWDG_ONF_MIN_VER) { in iwdg_wdt_get_version_and_status()
505 iwdg_wdt_set_enabled(iwdg); in iwdg_wdt_get_version_and_status()
518 if (!iwdg_wait_sync(iwdg)) in iwdg_wdt_get_version_and_status()
519 iwdg_wdt_set_enabled(iwdg); in iwdg_wdt_get_version_and_status()
524 DMSG("Watchdog is %sabled", iwdg_wdt_is_enabled(iwdg) ? "en" : "dis"); in iwdg_wdt_get_version_and_status()
530 struct stm32_iwdg_device *iwdg = PM_CALLBACK_GET_HANDLE(pm_handle); in stm32_iwdg_pm() local
533 clk_enable(iwdg->clk_lsi); in stm32_iwdg_pm()
534 clk_enable(iwdg->clk_pclk); in stm32_iwdg_pm()
536 clk_disable(iwdg->clk_lsi); in stm32_iwdg_pm()
537 clk_disable(iwdg->clk_pclk); in stm32_iwdg_pm()
547 struct stm32_iwdg_device *iwdg = NULL; in stm32_iwdg_probe() local
550 iwdg = calloc(1, sizeof(*iwdg)); in stm32_iwdg_probe()
551 if (!iwdg) in stm32_iwdg_probe()
554 res = stm32_iwdg_parse_fdt(iwdg, fdt, node); in stm32_iwdg_probe()
559 if (clk_enable(iwdg->clk_lsi)) in stm32_iwdg_probe()
562 if (clk_enable(iwdg->clk_pclk)) in stm32_iwdg_probe()
565 iwdg_wdt_get_version_and_status(iwdg); in stm32_iwdg_probe()
567 res = iwdg_wdt_set_timeout(&iwdg->wdt_chip, iwdg->timeout); in stm32_iwdg_probe()
571 if (iwdg_wdt_is_enabled(iwdg)) in stm32_iwdg_probe()
572 iwdg_wdt_refresh(&iwdg->wdt_chip); in stm32_iwdg_probe()
574 iwdg->wdt_chip.ops = &stm32_iwdg_ops; in stm32_iwdg_probe()
576 register_pm_core_service_cb(stm32_iwdg_pm, iwdg, "stm32-iwdg"); in stm32_iwdg_probe()
578 res = watchdog_register(&iwdg->wdt_chip); in stm32_iwdg_probe()
585 unregister_pm_core_service_cb(stm32_iwdg_pm, iwdg); in stm32_iwdg_probe()
587 free(iwdg); in stm32_iwdg_probe()