Lines Matching +full:clk +full:- +full:delay +full:- +full:cycles
1 // SPDX-License-Identifier: GPL-2.0
3 * On-Chip RTC Support available on RZ/G3S SoC
10 #include <linux/clk.h>
12 #include <linux/delay.h>
93 * enum rtca3_alrm_set_step - RTCA3 alarm set steps
105 * struct rtca3_ppb_per_cycle - PPB per cycle
115 * struct rtca3_priv - RTCA3 private data structure
140 tmp = readb(priv->base + off); in rtca3_byte_update_bits()
143 writeb(tmp, priv->base + off); in rtca3_byte_update_bits()
150 val = readb(priv->base + RTCA3_RSR); in rtca3_alarm_handler_helper()
152 writeb(val & ~pending, priv->base + RTCA3_RSR); in rtca3_alarm_handler_helper()
155 rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF); in rtca3_alarm_handler_helper()
165 guard(spinlock)(&priv->lock); in rtca3_alarm_handler()
177 guard(spinlock)(&priv->lock); in rtca3_periodic_handler()
179 val = readb(priv->base + RTCA3_RSR); in rtca3_periodic_handler()
183 writeb(val & ~pending, priv->base + RTCA3_RSR); in rtca3_periodic_handler()
185 if (atomic_read(&priv->alrm_sstep) > RTCA3_ALRM_SSTEP_IRQ) { in rtca3_periodic_handler()
187 atomic_dec(&priv->alrm_sstep); in rtca3_periodic_handler()
189 if (atomic_read(&priv->alrm_sstep) == RTCA3_ALRM_SSTEP_IRQ) { in rtca3_periodic_handler()
196 readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, val, in rtca3_periodic_handler()
199 complete(&priv->set_alarm_completion); in rtca3_periodic_handler()
220 readb(priv->base + RTCA3_RSECCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
221 readb(priv->base + RTCA3_RMINCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
222 readb(priv->base + RTCA3_RHRCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
223 readb(priv->base + RTCA3_RWKCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
224 readb(priv->base + RTCA3_RDAYCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
225 readw(priv->base + RTCA3_RYRCNT + offset); in rtca3_prepare_cntalrm_regs_for_read()
227 readb(priv->base + RTCA3_RYRAREN); in rtca3_prepare_cntalrm_regs_for_read()
239 guard(spinlock_irqsave)(&priv->lock); in rtca3_read_time()
241 tmp = readb(priv->base + RTCA3_RCR2); in rtca3_read_time()
243 return -EINVAL; in rtca3_read_time()
250 sec = readb(priv->base + RTCA3_RSECCNT); in rtca3_read_time()
251 min = readb(priv->base + RTCA3_RMINCNT); in rtca3_read_time()
252 hour = readb(priv->base + RTCA3_RHRCNT); in rtca3_read_time()
253 wday = readb(priv->base + RTCA3_RWKCNT); in rtca3_read_time()
254 mday = readb(priv->base + RTCA3_RDAYCNT); in rtca3_read_time()
255 month = readb(priv->base + RTCA3_RMONCNT); in rtca3_read_time()
256 year = readw(priv->base + RTCA3_RYRCNT); in rtca3_read_time()
258 tmp = readb(priv->base + RTCA3_RSR); in rtca3_read_time()
269 return -ETIMEDOUT; in rtca3_read_time()
271 tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECCNT_SEC, sec)); in rtca3_read_time()
272 tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINCNT_MIN, min)); in rtca3_read_time()
273 tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRCNT_HR, hour)); in rtca3_read_time()
274 tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKCNT_WK, wday)); in rtca3_read_time()
275 tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYCNT_DAY, mday)); in rtca3_read_time()
276 tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONCNT_MONTH, month)) - 1; in rtca3_read_time()
279 tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900; in rtca3_read_time()
290 guard(spinlock_irqsave)(&priv->lock); in rtca3_set_time()
293 rcr2 = readb(priv->base + RTCA3_RCR2); in rtca3_set_time()
294 writeb(rcr2 & ~RTCA3_RCR2_START, priv->base + RTCA3_RCR2); in rtca3_set_time()
295 ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, in rtca3_set_time()
302 writeb(bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECCNT); in rtca3_set_time()
303 writeb(bin2bcd(tm->tm_min), priv->base + RTCA3_RMINCNT); in rtca3_set_time()
304 writeb(bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRCNT); in rtca3_set_time()
305 writeb(bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKCNT); in rtca3_set_time()
306 writeb(bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYCNT); in rtca3_set_time()
307 writeb(bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONCNT); in rtca3_set_time()
308 writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRCNT); in rtca3_set_time()
314 writeb(rcr2 | RTCA3_RCR2_START, priv->base + RTCA3_RCR2); in rtca3_set_time()
315 return readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, in rtca3_set_time()
338 return readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, in rtca3_alarm_irq_set_helper()
347 guard(spinlock_irqsave)(&priv->lock); in rtca3_alarm_irq_enable()
356 struct rtc_time *tm = &wkalrm->time; in rtca3_read_alarm()
360 guard(spinlock_irqsave)(&priv->lock); in rtca3_read_alarm()
362 sec = readb(priv->base + RTCA3_RSECAR); in rtca3_read_alarm()
363 min = readb(priv->base + RTCA3_RMINAR); in rtca3_read_alarm()
364 hour = readb(priv->base + RTCA3_RHRAR); in rtca3_read_alarm()
365 wday = readb(priv->base + RTCA3_RWKAR); in rtca3_read_alarm()
366 mday = readb(priv->base + RTCA3_RDAYAR); in rtca3_read_alarm()
367 month = readb(priv->base + RTCA3_RMONAR); in rtca3_read_alarm()
368 year = readw(priv->base + RTCA3_RYRAR); in rtca3_read_alarm()
370 tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECAR_SEC, sec)); in rtca3_read_alarm()
371 tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINAR_MIN, min)); in rtca3_read_alarm()
372 tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRAR_HR, hour)); in rtca3_read_alarm()
373 tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKAR_DAYW, wday)); in rtca3_read_alarm()
374 tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYAR_DATE, mday)); in rtca3_read_alarm()
375 tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONAR_MON, month)) - 1; in rtca3_read_alarm()
378 tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900; in rtca3_read_alarm()
380 wkalrm->enabled = !!(readb(priv->base + RTCA3_RCR1) & RTCA3_RCR1_AIE); in rtca3_read_alarm()
388 struct rtc_time *tm = &wkalrm->time; in rtca3_set_alarm()
392 scoped_guard(spinlock_irqsave, &priv->lock) { in rtca3_set_alarm()
393 tmp = readb(priv->base + RTCA3_RCR2); in rtca3_set_alarm()
395 return -EPERM; in rtca3_set_alarm()
398 rcr1 = readb(priv->base + RTCA3_RCR1); in rtca3_set_alarm()
400 writeb(rcr1, priv->base + RTCA3_RCR1); in rtca3_set_alarm()
401 ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, in rtca3_set_alarm()
408 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECAR); in rtca3_set_alarm()
409 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_min), priv->base + RTCA3_RMINAR); in rtca3_set_alarm()
410 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRAR); in rtca3_set_alarm()
411 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKAR); in rtca3_set_alarm()
412 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYAR); in rtca3_set_alarm()
413 writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONAR); in rtca3_set_alarm()
415 writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRAR); in rtca3_set_alarm()
416 writeb(RTCA3_AR_ENB, priv->base + RTCA3_RYRAREN); in rtca3_set_alarm()
422 atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_INIT); in rtca3_set_alarm()
423 reinit_completion(&priv->set_alarm_completion); in rtca3_set_alarm()
427 writeb(rcr1, priv->base + RTCA3_RCR1); in rtca3_set_alarm()
428 ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, in rtca3_set_alarm()
437 ret = wait_for_completion_interruptible_timeout(&priv->set_alarm_completion, in rtca3_set_alarm()
440 ret = -ETIMEDOUT; in rtca3_set_alarm()
444 scoped_guard(spinlock_irqsave, &priv->lock) { in rtca3_set_alarm()
445 ret = rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE, wkalrm->enabled); in rtca3_set_alarm()
446 atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); in rtca3_set_alarm()
452 scoped_guard(spinlock_irqsave, &priv->lock) { in rtca3_set_alarm()
457 writeb(rcr1 & ~RTCA3_RCR1_PIE, priv->base + RTCA3_RCR1); in rtca3_set_alarm()
458 readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, !(tmp & ~RTCA3_RCR1_PIE), in rtca3_set_alarm()
460 atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); in rtca3_set_alarm()
469 u8 val, radj, cycles; in rtca3_read_offset() local
472 scoped_guard(spinlock_irqsave, &priv->lock) { in rtca3_read_offset()
473 radj = readb(priv->base + RTCA3_RADJ); in rtca3_read_offset()
474 val = readb(priv->base + RTCA3_RCR2); in rtca3_read_offset()
477 cycles = FIELD_GET(RTCA3_RADJ_ADJ, radj); in rtca3_read_offset()
479 if (!cycles) { in rtca3_read_offset()
485 ppb_per_cycle = priv->ppb.ten_sec; in rtca3_read_offset()
487 ppb_per_cycle = priv->ppb.sixty_sec; in rtca3_read_offset()
489 *offset = cycles * ppb_per_cycle; in rtca3_read_offset()
492 *offset = -(*offset); in rtca3_read_offset()
500 int cycles, cycles10, cycles60; in rtca3_set_offset() local
508 cycles10 = DIV_ROUND_CLOSEST(offset, priv->ppb.ten_sec); in rtca3_set_offset()
509 cycles60 = DIV_ROUND_CLOSEST(offset, priv->ppb.sixty_sec); in rtca3_set_offset()
511 /* We can set b/w 1 and 63 clock cycles. */ in rtca3_set_offset()
512 if (cycles60 >= -RTCA3_RADJ_ADJ_MAX && in rtca3_set_offset()
514 cycles = cycles60; in rtca3_set_offset()
516 } else if (cycles10 >= -RTCA3_RADJ_ADJ_MAX && in rtca3_set_offset()
518 cycles = cycles10; in rtca3_set_offset()
521 return -ERANGE; in rtca3_set_offset()
524 radj = FIELD_PREP(RTCA3_RADJ_ADJ, abs(cycles)); in rtca3_set_offset()
525 if (!cycles) in rtca3_set_offset()
527 else if (cycles > 0) in rtca3_set_offset()
532 guard(spinlock_irqsave)(&priv->lock); in rtca3_set_offset()
534 tmp = readb(priv->base + RTCA3_RCR2); in rtca3_set_offset()
538 writeb(0, priv->base + RTCA3_RADJ); in rtca3_set_offset()
539 ret = readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, !tmp, in rtca3_set_offset()
545 ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, in rtca3_set_offset()
552 writeb(radj, priv->base + RTCA3_RADJ); in rtca3_set_offset()
553 return readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, (tmp == radj), in rtca3_set_offset()
567 static int rtca3_initial_setup(struct clk *clk, struct rtca3_priv *priv) in rtca3_initial_setup() argument
574 osc32k_rate = clk_get_rate(clk); in rtca3_initial_setup()
576 return -EINVAL; in rtca3_initial_setup()
580 priv->ppb.ten_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 10)); in rtca3_initial_setup()
581 priv->ppb.sixty_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 60)); in rtca3_initial_setup()
585 * we need to wait at least 6 cycles of the 32KHz clock after clock was enabled. in rtca3_initial_setup()
596 val = readb(priv->base + RTCA3_RCR2); in rtca3_initial_setup()
603 writeb(0, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
604 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), in rtca3_initial_setup()
615 writeb(val, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
616 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, (tmp & mask), in rtca3_initial_setup()
623 writeb(val | RTCA3_RCR2_RESET, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
624 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), in rtca3_initial_setup()
631 * from registers) after reset we need to wait 6 clock cycles before in rtca3_initial_setup()
637 writeb(0, priv->base + RTCA3_RADJ); in rtca3_initial_setup()
638 ret = readb_poll_timeout(priv->base + RTCA3_RADJ, tmp, !tmp, 10, in rtca3_initial_setup()
644 writeb(val, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
645 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, ((tmp & mask) == mask), in rtca3_initial_setup()
661 return readb_poll_timeout(priv->base + RTCA3_RCR1, tmp, ((tmp & RTCA3_RCR1_PES) == val), in rtca3_initial_setup()
667 struct device *dev = &pdev->dev; in rtca3_request_irqs()
674 ret = devm_request_irq(dev, irq, rtca3_alarm_handler, 0, "rtca3-alarm", priv); in rtca3_request_irqs()
677 priv->wakeup_irq = irq; in rtca3_request_irqs()
683 ret = devm_request_irq(dev, irq, rtca3_periodic_handler, 0, "rtca3-period", priv); in rtca3_request_irqs()
704 ret = reset_control_assert(priv->rstc); in rtca3_action()
706 dev_err(dev, "Failed to de-assert reset!"); in rtca3_action()
715 struct device *dev = &pdev->dev; in rtca3_probe()
717 struct clk *clk; in rtca3_probe() local
722 return -ENOMEM; in rtca3_probe()
724 priv->base = devm_platform_ioremap_resource(pdev, 0); in rtca3_probe()
725 if (IS_ERR(priv->base)) in rtca3_probe()
726 return PTR_ERR(priv->base); in rtca3_probe()
732 priv->rstc = devm_reset_control_get_shared(dev, NULL); in rtca3_probe()
733 if (IS_ERR(priv->rstc)) in rtca3_probe()
734 return PTR_ERR(priv->rstc); in rtca3_probe()
740 ret = reset_control_deassert(priv->rstc); in rtca3_probe()
752 * This must be an always-on clock to keep the RTC running even after in rtca3_probe()
755 clk = devm_clk_get_enabled(dev, "counter"); in rtca3_probe()
756 if (IS_ERR(clk)) in rtca3_probe()
757 return PTR_ERR(clk); in rtca3_probe()
759 spin_lock_init(&priv->lock); in rtca3_probe()
760 atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); in rtca3_probe()
761 init_completion(&priv->set_alarm_completion); in rtca3_probe()
763 ret = rtca3_initial_setup(clk, priv); in rtca3_probe()
771 device_init_wakeup(&pdev->dev, true); in rtca3_probe()
773 priv->rtc_dev = devm_rtc_allocate_device(&pdev->dev); in rtca3_probe()
774 if (IS_ERR(priv->rtc_dev)) in rtca3_probe()
775 return PTR_ERR(priv->rtc_dev); in rtca3_probe()
777 priv->rtc_dev->ops = &rtca3_ops; in rtca3_probe()
778 priv->rtc_dev->max_user_freq = 256; in rtca3_probe()
779 priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; in rtca3_probe()
780 priv->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; in rtca3_probe()
782 return devm_rtc_register_device(priv->rtc_dev); in rtca3_probe()
789 guard(spinlock_irqsave)(&priv->lock); in rtca3_remove()
806 if (atomic_read(&priv->alrm_sstep) != RTCA3_ALRM_SSTEP_DONE) in rtca3_suspend()
807 return -EBUSY; in rtca3_suspend()
809 enable_irq_wake(priv->wakeup_irq); in rtca3_suspend()
816 struct rtc_device *rtc_dev = priv->rtc_dev; in rtca3_clean_alarm()
845 guard(spinlock_irqsave)(&priv->lock); in rtca3_clean_alarm()
849 rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF); in rtca3_clean_alarm()
861 disable_irq_wake(priv->wakeup_irq); in rtca3_resume()
882 { .compatible = "renesas,rz-rtca3", },
889 .name = "rtc-rtca3",
898 MODULE_DESCRIPTION("Renesas RTCA-3 RTC driver");