Lines Matching +full:clock +full:- +full:presc

1 // SPDX-License-Identifier: GPL-2.0
32 #define IWDG_EWCR 0x14 /* Early Wake-up Register */
100 u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr; in stm32_iwdg_start() local
103 dev_dbg(wdd->parent, "%s\n", __func__); in stm32_iwdg_start()
105 if (!wdd->pretimeout) in stm32_iwdg_start()
106 wdd->pretimeout = 3 * wdd->timeout / 4; in stm32_iwdg_start()
108 tout = clamp_t(unsigned int, wdd->timeout, in stm32_iwdg_start()
109 wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000); in stm32_iwdg_start()
110 ptot = clamp_t(unsigned int, tout - wdd->pretimeout, in stm32_iwdg_start()
111 wdd->min_timeout, tout); in stm32_iwdg_start()
113 presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1); in stm32_iwdg_start()
116 presc = roundup_pow_of_two(presc); in stm32_iwdg_start()
117 iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT; in stm32_iwdg_start()
118 iwdg_rlr = ((tout * wdt->rate) / presc) - 1; in stm32_iwdg_start()
119 iwdg_ewcr = ((ptot * wdt->rate) / presc) - 1; in stm32_iwdg_start()
122 reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); in stm32_iwdg_start()
125 reg_write(wdt->regs, IWDG_PR, iwdg_pr); in stm32_iwdg_start()
126 reg_write(wdt->regs, IWDG_RLR, iwdg_rlr); in stm32_iwdg_start()
127 if (wdt->data->has_early_wakeup) in stm32_iwdg_start()
128 reg_write(wdt->regs, IWDG_EWCR, iwdg_ewcr | EWCR_EWIE); in stm32_iwdg_start()
129 reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); in stm32_iwdg_start()
132 ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, iwdg_sr, in stm32_iwdg_start()
136 dev_err(wdd->parent, "Fail to set prescaler, reload regs\n"); in stm32_iwdg_start()
141 reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); in stm32_iwdg_start()
150 dev_dbg(wdd->parent, "%s\n", __func__); in stm32_iwdg_ping()
153 reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); in stm32_iwdg_ping()
161 dev_dbg(wdd->parent, "%s timeout: %d sec\n", __func__, timeout); in stm32_iwdg_set_timeout()
163 wdd->timeout = timeout; in stm32_iwdg_set_timeout()
174 dev_dbg(wdd->parent, "%s pretimeout: %d sec\n", __func__, pretimeout); in stm32_iwdg_set_pretimeout()
176 wdd->pretimeout = pretimeout; in stm32_iwdg_set_pretimeout()
190 reg = reg_read(wdt->regs, IWDG_EWCR); in stm32_iwdg_isr()
192 reg_write(wdt->regs, IWDG_EWCR, reg); in stm32_iwdg_isr()
207 struct device *dev = &pdev->dev; in stm32_iwdg_clk_init()
210 wdt->clk_lsi = devm_clk_get(dev, "lsi"); in stm32_iwdg_clk_init()
211 if (IS_ERR(wdt->clk_lsi)) in stm32_iwdg_clk_init()
212 return dev_err_probe(dev, PTR_ERR(wdt->clk_lsi), "Unable to get lsi clock\n"); in stm32_iwdg_clk_init()
214 /* optional peripheral clock */ in stm32_iwdg_clk_init()
215 if (wdt->data->has_pclk) { in stm32_iwdg_clk_init()
216 wdt->clk_pclk = devm_clk_get(dev, "pclk"); in stm32_iwdg_clk_init()
217 if (IS_ERR(wdt->clk_pclk)) in stm32_iwdg_clk_init()
218 return dev_err_probe(dev, PTR_ERR(wdt->clk_pclk), in stm32_iwdg_clk_init()
219 "Unable to get pclk clock\n"); in stm32_iwdg_clk_init()
221 ret = clk_prepare_enable(wdt->clk_pclk); in stm32_iwdg_clk_init()
223 dev_err(dev, "Unable to prepare pclk clock\n"); in stm32_iwdg_clk_init()
228 wdt->clk_pclk); in stm32_iwdg_clk_init()
233 ret = clk_prepare_enable(wdt->clk_lsi); in stm32_iwdg_clk_init()
235 dev_err(dev, "Unable to prepare lsi clock\n"); in stm32_iwdg_clk_init()
239 wdt->clk_lsi); in stm32_iwdg_clk_init()
243 wdt->rate = clk_get_rate(wdt->clk_lsi); in stm32_iwdg_clk_init()
272 { .compatible = "st,stm32-iwdg", .data = &stm32_iwdg_data },
273 { .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_data },
281 struct device_node *np = pdev->dev.of_node; in stm32_iwdg_irq_init()
282 struct watchdog_device *wdd = &wdt->wdd; in stm32_iwdg_irq_init()
283 struct device *dev = &pdev->dev; in stm32_iwdg_irq_init()
286 if (!wdt->data->has_early_wakeup) in stm32_iwdg_irq_init()
293 if (of_property_read_bool(np, "wakeup-source")) { in stm32_iwdg_irq_init()
308 wdd->info = &stm32_iwdg_preinfo; in stm32_iwdg_irq_init()
314 struct device *dev = &pdev->dev; in stm32_iwdg_probe()
321 return -ENOMEM; in stm32_iwdg_probe()
323 wdt->data = of_device_get_match_data(&pdev->dev); in stm32_iwdg_probe()
324 if (!wdt->data) in stm32_iwdg_probe()
325 return -ENODEV; in stm32_iwdg_probe()
328 wdt->regs = devm_platform_ioremap_resource(pdev, 0); in stm32_iwdg_probe()
329 if (IS_ERR(wdt->regs)) in stm32_iwdg_probe()
330 return PTR_ERR(wdt->regs); in stm32_iwdg_probe()
337 wdd = &wdt->wdd; in stm32_iwdg_probe()
338 wdd->parent = dev; in stm32_iwdg_probe()
339 wdd->info = &stm32_iwdg_info; in stm32_iwdg_probe()
340 wdd->ops = &stm32_iwdg_ops; in stm32_iwdg_probe()
341 wdd->timeout = DEFAULT_TIMEOUT; in stm32_iwdg_probe()
342 wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate); in stm32_iwdg_probe()
343 wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler * in stm32_iwdg_probe()
344 1000) / wdt->rate; in stm32_iwdg_probe()
346 /* Initialize IRQ, this might override wdd->info, hence it is here. */ in stm32_iwdg_probe()
357 * (Means U-Boot/bootloaders leaves the watchdog running) in stm32_iwdg_probe()
370 set_bit(WDOG_HW_RUNNING, &wdd->status); in stm32_iwdg_probe()