Lines Matching +full:zynqmp +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/clk.h>
47 #define RTC_MIN_OFFSET -32768000
55 struct clk *rtc_clk;
71 writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); in xlnx_rtc_set_time()
81 writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_set_time()
92 status = readl(xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_read_time()
99 read_time = readl(xrtcdev->reg_base + RTC_CUR_TM); in xlnx_rtc_read_time()
105 * Since we add +1 sec while writing, we need to -1 sec while in xlnx_rtc_read_time()
108 read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1; in xlnx_rtc_read_time()
119 rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time); in xlnx_rtc_read_alarm()
120 alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM; in xlnx_rtc_read_alarm()
135 status = readl(xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_alarm_irq_enable()
141 return -ETIMEDOUT; in xlnx_rtc_alarm_irq_enable()
143 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_alarm_irq_enable()
146 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); in xlnx_rtc_alarm_irq_enable()
148 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); in xlnx_rtc_alarm_irq_enable()
159 alarm_time = rtc_tm_to_time64(&alrm->time); in xlnx_rtc_set_alarm()
161 writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM)); in xlnx_rtc_set_alarm()
163 xlnx_rtc_alarm_irq_enable(dev, alrm->enabled); in xlnx_rtc_set_alarm()
173 rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL); in xlnx_init_rtc()
175 writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL); in xlnx_init_rtc()
182 unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); in xlnx_rtc_read_offset()
186 calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD); in xlnx_rtc_read_offset()
189 offset_val = offset_val - RTC_CALIB_DEF; in xlnx_rtc_read_offset()
205 unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); in xlnx_rtc_set_offset()
212 return -ERANGE; in xlnx_rtc_set_offset()
221 max_tick--; in xlnx_rtc_set_offset()
233 /* Zynqmp RTC uses second and fractional tick in xlnx_rtc_set_offset()
243 writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); in xlnx_rtc_set_offset()
263 status = readl(xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_interrupt()
269 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); in xlnx_rtc_interrupt()
272 rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF); in xlnx_rtc_interrupt()
286 xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); in xlnx_rtc_probe()
288 return -ENOMEM; in xlnx_rtc_probe()
292 xrtcdev->rtc = devm_rtc_allocate_device(&pdev->dev); in xlnx_rtc_probe()
293 if (IS_ERR(xrtcdev->rtc)) in xlnx_rtc_probe()
294 return PTR_ERR(xrtcdev->rtc); in xlnx_rtc_probe()
296 xrtcdev->rtc->ops = &xlnx_rtc_ops; in xlnx_rtc_probe()
297 xrtcdev->rtc->range_max = U32_MAX; in xlnx_rtc_probe()
299 xrtcdev->reg_base = devm_platform_ioremap_resource(pdev, 0); in xlnx_rtc_probe()
300 if (IS_ERR(xrtcdev->reg_base)) in xlnx_rtc_probe()
301 return PTR_ERR(xrtcdev->reg_base); in xlnx_rtc_probe()
304 pending_alrm_irq = readl(xrtcdev->reg_base + RTC_INT_STS) & RTC_INT_ALRM; in xlnx_rtc_probe()
306 writel(pending_alrm_irq, xrtcdev->reg_base + RTC_INT_STS); in xlnx_rtc_probe()
309 alarm_time = readl(xrtcdev->reg_base + RTC_ALRM); in xlnx_rtc_probe()
310 current_time = readl(xrtcdev->reg_base + RTC_CUR_TM); in xlnx_rtc_probe()
314 xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm"); in xlnx_rtc_probe()
315 if (xrtcdev->alarm_irq < 0) in xlnx_rtc_probe()
316 return xrtcdev->alarm_irq; in xlnx_rtc_probe()
317 ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq, in xlnx_rtc_probe()
319 dev_name(&pdev->dev), xrtcdev); in xlnx_rtc_probe()
321 dev_err(&pdev->dev, "request irq failed\n"); in xlnx_rtc_probe()
325 xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec"); in xlnx_rtc_probe()
326 if (xrtcdev->sec_irq < 0) in xlnx_rtc_probe()
327 return xrtcdev->sec_irq; in xlnx_rtc_probe()
328 ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq, in xlnx_rtc_probe()
330 dev_name(&pdev->dev), xrtcdev); in xlnx_rtc_probe()
332 dev_err(&pdev->dev, "request irq failed\n"); in xlnx_rtc_probe()
337 xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc"); in xlnx_rtc_probe()
338 if (IS_ERR(xrtcdev->rtc_clk)) { in xlnx_rtc_probe()
339 if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER) in xlnx_rtc_probe()
340 dev_warn(&pdev->dev, "Device clock not found.\n"); in xlnx_rtc_probe()
342 xrtcdev->freq = clk_get_rate(xrtcdev->rtc_clk); in xlnx_rtc_probe()
343 if (!xrtcdev->freq) { in xlnx_rtc_probe()
344 ret = of_property_read_u32(pdev->dev.of_node, "calibration", in xlnx_rtc_probe()
345 &xrtcdev->freq); in xlnx_rtc_probe()
347 xrtcdev->freq = RTC_CALIB_DEF; in xlnx_rtc_probe()
349 ret = readl(xrtcdev->reg_base + RTC_CALIB_RD); in xlnx_rtc_probe()
351 writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR)); in xlnx_rtc_probe()
355 /* Re-enable alarm interrupt if a valid alarm was found */ in xlnx_rtc_probe()
357 writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); in xlnx_rtc_probe()
359 device_init_wakeup(&pdev->dev, true); in xlnx_rtc_probe()
361 return devm_rtc_register_device(xrtcdev->rtc); in xlnx_rtc_probe()
366 xlnx_rtc_alarm_irq_enable(&pdev->dev, 0); in xlnx_rtc_remove()
367 device_init_wakeup(&pdev->dev, false); in xlnx_rtc_remove()
375 enable_irq_wake(xrtcdev->alarm_irq); in xlnx_rtc_suspend()
387 disable_irq_wake(xrtcdev->alarm_irq); in xlnx_rtc_resume()
397 {.compatible = "xlnx,zynqmp-rtc" },