Lines Matching full:rtc
3 * RTC driver for the Armada 38x Marvell SoCs
16 #include <linux/rtc.h>
86 /* Initialize the RTC-MBUS bridge timing */
87 void (*update_mbus_timing)(struct armada38x_rtc *rtc);
88 u32 (*read_rtc_reg)(struct armada38x_rtc *rtc, u8 rtc_reg);
89 void (*clear_isr)(struct armada38x_rtc *rtc);
90 void (*unmask_interrupt)(struct armada38x_rtc *rtc);
96 * register write to the RTC hard macro so that the required update
98 * According to errata RES-3124064, Write to any RTC register
99 * may fail. As a workaround, before writing to RTC
100 * register, issue a dummy write of 0x0 twice to RTC Status
104 static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) in rtc_delayed_write() argument
106 writel(0, rtc->regs + RTC_STATUS); in rtc_delayed_write()
107 writel(0, rtc->regs + RTC_STATUS); in rtc_delayed_write()
108 writel(val, rtc->regs + offset); in rtc_delayed_write()
112 /* Update RTC-MBUS bridge timing parameters */
113 static void rtc_update_38x_mbus_timing_params(struct armada38x_rtc *rtc) in rtc_update_38x_mbus_timing_params() argument
117 reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); in rtc_update_38x_mbus_timing_params()
122 writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); in rtc_update_38x_mbus_timing_params()
125 static void rtc_update_8k_mbus_timing_params(struct armada38x_rtc *rtc) in rtc_update_8k_mbus_timing_params() argument
129 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); in rtc_update_8k_mbus_timing_params()
134 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); in rtc_update_8k_mbus_timing_params()
136 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); in rtc_update_8k_mbus_timing_params()
139 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); in rtc_update_8k_mbus_timing_params()
142 static u32 read_rtc_register(struct armada38x_rtc *rtc, u8 rtc_reg) in read_rtc_register() argument
144 return readl(rtc->regs + rtc_reg); in read_rtc_register()
147 static u32 read_rtc_register_38x_wa(struct armada38x_rtc *rtc, u8 rtc_reg) in read_rtc_register_38x_wa() argument
152 rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg); in read_rtc_register_38x_wa()
153 rtc->val_to_freq[i].freq = 0; in read_rtc_register_38x_wa()
158 u32 value = rtc->val_to_freq[i].value; in read_rtc_register_38x_wa()
160 while (rtc->val_to_freq[j].freq) { in read_rtc_register_38x_wa()
161 if (rtc->val_to_freq[j].value == value) { in read_rtc_register_38x_wa()
162 rtc->val_to_freq[j].freq++; in read_rtc_register_38x_wa()
168 if (!rtc->val_to_freq[j].freq) { in read_rtc_register_38x_wa()
169 rtc->val_to_freq[j].value = value; in read_rtc_register_38x_wa()
170 rtc->val_to_freq[j].freq = 1; in read_rtc_register_38x_wa()
173 if (rtc->val_to_freq[j].freq > max) { in read_rtc_register_38x_wa()
175 max = rtc->val_to_freq[j].freq; in read_rtc_register_38x_wa()
186 return rtc->val_to_freq[index_max].value; in read_rtc_register_38x_wa()
189 static void armada38x_clear_isr(struct armada38x_rtc *rtc) in armada38x_clear_isr() argument
191 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_clear_isr()
193 writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_clear_isr()
196 static void armada38x_unmask_interrupt(struct armada38x_rtc *rtc) in armada38x_unmask_interrupt() argument
198 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_unmask_interrupt()
200 writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_unmask_interrupt()
203 static void armada8k_clear_isr(struct armada38x_rtc *rtc) in armada8k_clear_isr() argument
205 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR); in armada8k_clear_isr()
208 static void armada8k_unmask_interrupt(struct armada38x_rtc *rtc) in armada8k_unmask_interrupt() argument
210 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_IMR); in armada8k_unmask_interrupt()
215 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_time() local
218 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_time()
219 time = rtc->data->read_rtc_reg(rtc, RTC_TIME); in armada38x_rtc_read_time()
220 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_time()
227 static void armada38x_rtc_reset(struct armada38x_rtc *rtc) in armada38x_rtc_reset() argument
231 reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST); in armada38x_rtc_reset()
232 /* If bits [7:0] are non-zero, assume RTC was uninitialized */ in armada38x_rtc_reset()
234 rtc_delayed_write(0, rtc, RTC_CONF_TEST); in armada38x_rtc_reset()
236 rtc_delayed_write(0, rtc, RTC_TIME); in armada38x_rtc_reset()
237 rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc, in armada38x_rtc_reset()
239 rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR); in armada38x_rtc_reset()
241 rtc->initialized = true; in armada38x_rtc_reset()
246 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_time() local
251 if (!rtc->initialized) in armada38x_rtc_set_time()
252 armada38x_rtc_reset(rtc); in armada38x_rtc_set_time()
254 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_set_time()
255 rtc_delayed_write(time, rtc, RTC_TIME); in armada38x_rtc_set_time()
256 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_set_time()
263 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_alarm() local
265 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); in armada38x_rtc_read_alarm()
266 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_read_alarm()
269 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_alarm()
271 time = rtc->data->read_rtc_reg(rtc, reg); in armada38x_rtc_read_alarm()
272 val = rtc->data->read_rtc_reg(rtc, reg_irq) & RTC_IRQ_AL_EN; in armada38x_rtc_read_alarm()
274 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_alarm()
284 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_alarm() local
285 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); in armada38x_rtc_set_alarm()
286 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_set_alarm()
291 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_set_alarm()
293 rtc_delayed_write(time, rtc, reg); in armada38x_rtc_set_alarm()
296 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); in armada38x_rtc_set_alarm()
297 rtc->data->unmask_interrupt(rtc); in armada38x_rtc_set_alarm()
300 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_set_alarm()
308 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_alarm_irq_enable() local
309 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_alarm_irq_enable()
312 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_alarm_irq_enable()
315 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); in armada38x_rtc_alarm_irq_enable()
317 rtc_delayed_write(0, rtc, reg_irq); in armada38x_rtc_alarm_irq_enable()
319 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_alarm_irq_enable()
326 struct armada38x_rtc *rtc = data; in armada38x_rtc_alarm_irq() local
329 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_alarm_irq()
331 dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq); in armada38x_rtc_alarm_irq()
333 spin_lock(&rtc->lock); in armada38x_rtc_alarm_irq()
335 rtc->data->clear_isr(rtc); in armada38x_rtc_alarm_irq()
336 val = rtc->data->read_rtc_reg(rtc, reg_irq); in armada38x_rtc_alarm_irq()
338 rtc_delayed_write(0, rtc, reg_irq); in armada38x_rtc_alarm_irq()
340 rtc_delayed_write(1 << rtc->data->alarm, rtc, RTC_STATUS); in armada38x_rtc_alarm_irq()
342 spin_unlock(&rtc->lock); in armada38x_rtc_alarm_irq()
351 rtc_update_irq(rtc->rtc_dev, 1, event); in armada38x_rtc_alarm_irq()
369 * "offset" in the RTC interface is defined as:
400 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_offset() local
404 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_offset()
405 ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR); in armada38x_rtc_read_offset()
406 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_offset()
417 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_offset() local
446 rtc_delayed_write(ccr, rtc, RTC_CCR); in armada38x_rtc_set_offset()
480 .compatible = "marvell,armada-380-rtc",
484 .compatible = "marvell,armada-8k-rtc",
495 struct armada38x_rtc *rtc; in armada38x_rtc_probe() local
497 rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), in armada38x_rtc_probe()
499 if (!rtc) in armada38x_rtc_probe()
502 rtc->data = of_device_get_match_data(&pdev->dev); in armada38x_rtc_probe()
504 rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR, in armada38x_rtc_probe()
506 if (!rtc->val_to_freq) in armada38x_rtc_probe()
509 spin_lock_init(&rtc->lock); in armada38x_rtc_probe()
511 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); in armada38x_rtc_probe()
512 rtc->regs = devm_ioremap_resource(&pdev->dev, res); in armada38x_rtc_probe()
513 if (IS_ERR(rtc->regs)) in armada38x_rtc_probe()
514 return PTR_ERR(rtc->regs); in armada38x_rtc_probe()
515 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc"); in armada38x_rtc_probe()
516 rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res); in armada38x_rtc_probe()
517 if (IS_ERR(rtc->regs_soc)) in armada38x_rtc_probe()
518 return PTR_ERR(rtc->regs_soc); in armada38x_rtc_probe()
520 rtc->irq = platform_get_irq(pdev, 0); in armada38x_rtc_probe()
521 if (rtc->irq < 0) in armada38x_rtc_probe()
522 return rtc->irq; in armada38x_rtc_probe()
524 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); in armada38x_rtc_probe()
525 if (IS_ERR(rtc->rtc_dev)) in armada38x_rtc_probe()
526 return PTR_ERR(rtc->rtc_dev); in armada38x_rtc_probe()
528 if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq, in armada38x_rtc_probe()
529 0, pdev->name, rtc) < 0) { in armada38x_rtc_probe()
531 rtc->irq = -1; in armada38x_rtc_probe()
533 platform_set_drvdata(pdev, rtc); in armada38x_rtc_probe()
535 if (rtc->irq != -1) in armada38x_rtc_probe()
538 clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features); in armada38x_rtc_probe()
540 /* Update RTC-MBUS bridge timing parameters */ in armada38x_rtc_probe()
541 rtc->data->update_mbus_timing(rtc); in armada38x_rtc_probe()
543 rtc->rtc_dev->ops = &armada38x_rtc_ops; in armada38x_rtc_probe()
544 rtc->rtc_dev->range_max = U32_MAX; in armada38x_rtc_probe()
546 return devm_rtc_register_device(rtc->rtc_dev); in armada38x_rtc_probe()
553 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_suspend() local
555 return enable_irq_wake(rtc->irq); in armada38x_rtc_suspend()
564 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_resume() local
566 /* Update RTC-MBUS bridge timing parameters */ in armada38x_rtc_resume()
567 rtc->data->update_mbus_timing(rtc); in armada38x_rtc_resume()
569 return disable_irq_wake(rtc->irq); in armada38x_rtc_resume()
581 .name = "armada38x-rtc",
589 MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");