Lines Matching +full:start +full:- +full:year
1 // SPDX-License-Identifier: GPL-2.0
3 * On-Chip RTC Support available on RZ/G3S SoC
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()
215 * registers, year alarm enable register, bits RCR2.AADJE, AADJP, in rtca3_prepare_cntalrm_regs_for_read()
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()
237 u16 year; in rtca3_read_time() local
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()
277 year = FIELD_GET(RTCA3_RYRCNT_YEAR, year); in rtca3_read_time()
278 year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20); 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()
313 /* Start RTC. */ 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()
358 u16 year; in rtca3_read_alarm() local
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()
376 year = FIELD_GET(RTCA3_RYRAR_YR, year); in rtca3_read_alarm()
377 year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20); 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()
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()
485 ppb_per_cycle = priv->ppb.ten_sec; in rtca3_read_offset()
487 ppb_per_cycle = priv->ppb.sixty_sec; in rtca3_read_offset()
492 *offset = -(*offset); in rtca3_read_offset()
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()
512 if (cycles60 >= -RTCA3_RADJ_ADJ_MAX && in rtca3_set_offset()
516 } else if (cycles10 >= -RTCA3_RADJ_ADJ_MAX && in rtca3_set_offset()
521 return -ERANGE; 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()
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()
590 val = readb(priv->base + RTCA3_RCR2); in rtca3_initial_setup()
600 writeb(0, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
601 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), in rtca3_initial_setup()
612 writeb(val, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
613 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, (tmp & mask), in rtca3_initial_setup()
620 writeb(val | RTCA3_RCR2_RESET, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
621 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), in rtca3_initial_setup()
634 writeb(0, priv->base + RTCA3_RADJ); in rtca3_initial_setup()
635 ret = readb_poll_timeout(priv->base + RTCA3_RADJ, tmp, !tmp, 10, in rtca3_initial_setup()
638 /* Start the RTC and enable automatic time error adjustment. */ in rtca3_initial_setup()
641 writeb(val, priv->base + RTCA3_RCR2); in rtca3_initial_setup()
642 ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, ((tmp & mask) == mask), in rtca3_initial_setup()
650 * (RCR2.START bit = 1) to be able to read the counters after a return from in rtca3_initial_setup()
658 return readb_poll_timeout(priv->base + RTCA3_RCR1, tmp, ((tmp & RTCA3_RCR1_PES) == val), in rtca3_initial_setup()
664 struct device *dev = &pdev->dev; in rtca3_request_irqs()
671 ret = devm_request_irq(dev, irq, rtca3_alarm_handler, 0, "rtca3-alarm", priv); in rtca3_request_irqs()
674 priv->wakeup_irq = irq; in rtca3_request_irqs()
680 ret = devm_request_irq(dev, irq, rtca3_periodic_handler, 0, "rtca3-period", priv); in rtca3_request_irqs()
701 ret = reset_control_assert(priv->rstc); in rtca3_action()
703 dev_err(dev, "Failed to de-assert reset!"); in rtca3_action()
712 struct device *dev = &pdev->dev; in rtca3_probe()
719 return -ENOMEM; in rtca3_probe()
721 priv->base = devm_platform_ioremap_resource(pdev, 0); in rtca3_probe()
722 if (IS_ERR(priv->base)) in rtca3_probe()
723 return PTR_ERR(priv->base); in rtca3_probe()
729 priv->rstc = devm_reset_control_get_shared(dev, NULL); in rtca3_probe()
730 if (IS_ERR(priv->rstc)) in rtca3_probe()
731 return PTR_ERR(priv->rstc); in rtca3_probe()
737 ret = reset_control_deassert(priv->rstc); in rtca3_probe()
749 * This must be an always-on clock to keep the RTC running even after in rtca3_probe()
756 spin_lock_init(&priv->lock); in rtca3_probe()
757 atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); in rtca3_probe()
758 init_completion(&priv->set_alarm_completion); in rtca3_probe()
768 device_init_wakeup(&pdev->dev, true); in rtca3_probe()
770 priv->rtc_dev = devm_rtc_allocate_device(&pdev->dev); in rtca3_probe()
771 if (IS_ERR(priv->rtc_dev)) in rtca3_probe()
772 return PTR_ERR(priv->rtc_dev); in rtca3_probe()
774 priv->rtc_dev->ops = &rtca3_ops; in rtca3_probe()
775 priv->rtc_dev->max_user_freq = 256; in rtca3_probe()
776 priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; in rtca3_probe()
777 priv->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; in rtca3_probe()
779 return devm_rtc_register_device(priv->rtc_dev); in rtca3_probe()
786 guard(spinlock_irqsave)(&priv->lock); in rtca3_remove()
803 if (atomic_read(&priv->alrm_sstep) != RTCA3_ALRM_SSTEP_DONE) in rtca3_suspend()
804 return -EBUSY; in rtca3_suspend()
806 enable_irq_wake(priv->wakeup_irq); in rtca3_suspend()
813 struct rtc_device *rtc_dev = priv->rtc_dev; in rtca3_clean_alarm()
842 guard(spinlock_irqsave)(&priv->lock); in rtca3_clean_alarm()
846 rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF); in rtca3_clean_alarm()
858 disable_irq_wake(priv->wakeup_irq); in rtca3_resume()
863 * RCR2.START = 1 to be able to read the counters after a return from low in rtca3_resume()
879 { .compatible = "renesas,rz-rtca3", },
886 .name = "rtc-rtca3",
895 MODULE_DESCRIPTION("Renesas RTCA-3 RTC driver");