Lines Matching full:rtc
2 * RTC driver for the Armada 38x Marvell SoCs
21 #include <linux/rtc.h>
91 /* Initialize the RTC-MBUS bridge timing */
92 void (*update_mbus_timing)(struct armada38x_rtc *rtc);
93 u32 (*read_rtc_reg)(struct armada38x_rtc *rtc, u8 rtc_reg);
94 void (*clear_isr)(struct armada38x_rtc *rtc);
95 void (*unmask_interrupt)(struct armada38x_rtc *rtc);
101 * register write to the RTC hard macro so that the required update
103 * According to errata RES-3124064, Write to any RTC register
104 * may fail. As a workaround, before writing to RTC
105 * register, issue a dummy write of 0x0 twice to RTC Status
109 static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) in rtc_delayed_write() argument
111 writel(0, rtc->regs + RTC_STATUS); in rtc_delayed_write()
112 writel(0, rtc->regs + RTC_STATUS); in rtc_delayed_write()
113 writel(val, rtc->regs + offset); in rtc_delayed_write()
117 /* Update RTC-MBUS bridge timing parameters */
118 static void rtc_update_38x_mbus_timing_params(struct armada38x_rtc *rtc) in rtc_update_38x_mbus_timing_params() argument
122 reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); in rtc_update_38x_mbus_timing_params()
127 writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); in rtc_update_38x_mbus_timing_params()
130 static void rtc_update_8k_mbus_timing_params(struct armada38x_rtc *rtc) in rtc_update_8k_mbus_timing_params() argument
134 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); in rtc_update_8k_mbus_timing_params()
139 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); in rtc_update_8k_mbus_timing_params()
141 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); in rtc_update_8k_mbus_timing_params()
144 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); in rtc_update_8k_mbus_timing_params()
147 static u32 read_rtc_register(struct armada38x_rtc *rtc, u8 rtc_reg) in read_rtc_register() argument
149 return readl(rtc->regs + rtc_reg); in read_rtc_register()
152 static u32 read_rtc_register_38x_wa(struct armada38x_rtc *rtc, u8 rtc_reg) in read_rtc_register_38x_wa() argument
157 rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg); in read_rtc_register_38x_wa()
158 rtc->val_to_freq[i].freq = 0; in read_rtc_register_38x_wa()
163 u32 value = rtc->val_to_freq[i].value; in read_rtc_register_38x_wa()
165 while (rtc->val_to_freq[j].freq) { in read_rtc_register_38x_wa()
166 if (rtc->val_to_freq[j].value == value) { in read_rtc_register_38x_wa()
167 rtc->val_to_freq[j].freq++; in read_rtc_register_38x_wa()
173 if (!rtc->val_to_freq[j].freq) { in read_rtc_register_38x_wa()
174 rtc->val_to_freq[j].value = value; in read_rtc_register_38x_wa()
175 rtc->val_to_freq[j].freq = 1; in read_rtc_register_38x_wa()
178 if (rtc->val_to_freq[j].freq > max) { in read_rtc_register_38x_wa()
180 max = rtc->val_to_freq[j].freq; in read_rtc_register_38x_wa()
191 return rtc->val_to_freq[index_max].value; in read_rtc_register_38x_wa()
194 static void armada38x_clear_isr(struct armada38x_rtc *rtc) in armada38x_clear_isr() argument
196 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_clear_isr()
198 writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_clear_isr()
201 static void armada38x_unmask_interrupt(struct armada38x_rtc *rtc) in armada38x_unmask_interrupt() argument
203 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_unmask_interrupt()
205 writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT); in armada38x_unmask_interrupt()
208 static void armada8k_clear_isr(struct armada38x_rtc *rtc) in armada8k_clear_isr() argument
210 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR); in armada8k_clear_isr()
213 static void armada8k_unmask_interrupt(struct armada38x_rtc *rtc) in armada8k_unmask_interrupt() argument
215 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_IMR); in armada8k_unmask_interrupt()
220 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_time() local
223 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_time()
224 time = rtc->data->read_rtc_reg(rtc, RTC_TIME); in armada38x_rtc_read_time()
225 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_time()
232 static void armada38x_rtc_reset(struct armada38x_rtc *rtc) in armada38x_rtc_reset() argument
236 reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST); in armada38x_rtc_reset()
237 /* If bits [7:0] are non-zero, assume RTC was uninitialized */ in armada38x_rtc_reset()
239 rtc_delayed_write(0, rtc, RTC_CONF_TEST); in armada38x_rtc_reset()
241 rtc_delayed_write(0, rtc, RTC_TIME); in armada38x_rtc_reset()
242 rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc, in armada38x_rtc_reset()
244 rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR); in armada38x_rtc_reset()
246 rtc->initialized = true; in armada38x_rtc_reset()
251 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_time() local
260 if (!rtc->initialized) in armada38x_rtc_set_time()
261 armada38x_rtc_reset(rtc); in armada38x_rtc_set_time()
263 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_set_time()
264 rtc_delayed_write(time, rtc, RTC_TIME); in armada38x_rtc_set_time()
265 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_set_time()
273 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_alarm() local
275 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); in armada38x_rtc_read_alarm()
276 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_read_alarm()
279 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_alarm()
281 time = rtc->data->read_rtc_reg(rtc, reg); in armada38x_rtc_read_alarm()
282 val = rtc->data->read_rtc_reg(rtc, reg_irq) & RTC_IRQ_AL_EN; in armada38x_rtc_read_alarm()
284 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_alarm()
294 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_alarm() local
295 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); in armada38x_rtc_set_alarm()
296 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_set_alarm()
305 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_set_alarm()
307 rtc_delayed_write(time, rtc, reg); in armada38x_rtc_set_alarm()
310 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); in armada38x_rtc_set_alarm()
311 rtc->data->unmask_interrupt(rtc); in armada38x_rtc_set_alarm()
314 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_set_alarm()
323 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_alarm_irq_enable() local
324 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_alarm_irq_enable()
327 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_alarm_irq_enable()
330 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); in armada38x_rtc_alarm_irq_enable()
332 rtc_delayed_write(0, rtc, reg_irq); in armada38x_rtc_alarm_irq_enable()
334 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_alarm_irq_enable()
341 struct armada38x_rtc *rtc = data; in armada38x_rtc_alarm_irq() local
344 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); in armada38x_rtc_alarm_irq()
346 dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq); in armada38x_rtc_alarm_irq()
348 spin_lock(&rtc->lock); in armada38x_rtc_alarm_irq()
350 rtc->data->clear_isr(rtc); in armada38x_rtc_alarm_irq()
351 val = rtc->data->read_rtc_reg(rtc, reg_irq); in armada38x_rtc_alarm_irq()
353 rtc_delayed_write(0, rtc, reg_irq); in armada38x_rtc_alarm_irq()
355 rtc_delayed_write(1 << rtc->data->alarm, rtc, RTC_STATUS); in armada38x_rtc_alarm_irq()
357 spin_unlock(&rtc->lock); in armada38x_rtc_alarm_irq()
366 rtc_update_irq(rtc->rtc_dev, 1, event); in armada38x_rtc_alarm_irq()
384 * "offset" in the RTC interface is defined as:
415 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_read_offset() local
419 spin_lock_irqsave(&rtc->lock, flags); in armada38x_rtc_read_offset()
420 ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR); in armada38x_rtc_read_offset()
421 spin_unlock_irqrestore(&rtc->lock, flags); in armada38x_rtc_read_offset()
432 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_set_offset() local
461 rtc_delayed_write(ccr, rtc, RTC_CCR); in armada38x_rtc_set_offset()
503 .compatible = "marvell,armada-380-rtc",
507 .compatible = "marvell,armada-8k-rtc",
518 struct armada38x_rtc *rtc; in armada38x_rtc_probe() local
526 rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), in armada38x_rtc_probe()
528 if (!rtc) in armada38x_rtc_probe()
531 rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR, in armada38x_rtc_probe()
533 if (!rtc->val_to_freq) in armada38x_rtc_probe()
536 spin_lock_init(&rtc->lock); in armada38x_rtc_probe()
538 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); in armada38x_rtc_probe()
539 rtc->regs = devm_ioremap_resource(&pdev->dev, res); in armada38x_rtc_probe()
540 if (IS_ERR(rtc->regs)) in armada38x_rtc_probe()
541 return PTR_ERR(rtc->regs); in armada38x_rtc_probe()
542 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc"); in armada38x_rtc_probe()
543 rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res); in armada38x_rtc_probe()
544 if (IS_ERR(rtc->regs_soc)) in armada38x_rtc_probe()
545 return PTR_ERR(rtc->regs_soc); in armada38x_rtc_probe()
547 rtc->irq = platform_get_irq(pdev, 0); in armada38x_rtc_probe()
549 if (rtc->irq < 0) { in armada38x_rtc_probe()
551 return rtc->irq; in armada38x_rtc_probe()
554 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); in armada38x_rtc_probe()
555 if (IS_ERR(rtc->rtc_dev)) in armada38x_rtc_probe()
556 return PTR_ERR(rtc->rtc_dev); in armada38x_rtc_probe()
558 if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq, in armada38x_rtc_probe()
559 0, pdev->name, rtc) < 0) { in armada38x_rtc_probe()
561 rtc->irq = -1; in armada38x_rtc_probe()
563 platform_set_drvdata(pdev, rtc); in armada38x_rtc_probe()
565 if (rtc->irq != -1) { in armada38x_rtc_probe()
567 rtc->rtc_dev->ops = &armada38x_rtc_ops; in armada38x_rtc_probe()
573 rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq; in armada38x_rtc_probe()
575 rtc->data = (struct armada38x_rtc_data *)match->data; in armada38x_rtc_probe()
577 /* Update RTC-MBUS bridge timing parameters */ in armada38x_rtc_probe()
578 rtc->data->update_mbus_timing(rtc); in armada38x_rtc_probe()
580 ret = rtc_register_device(rtc->rtc_dev); in armada38x_rtc_probe()
582 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); in armada38x_rtc_probe()
591 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_suspend() local
593 return enable_irq_wake(rtc->irq); in armada38x_rtc_suspend()
602 struct armada38x_rtc *rtc = dev_get_drvdata(dev); in armada38x_rtc_resume() local
604 /* Update RTC-MBUS bridge timing parameters */ in armada38x_rtc_resume()
605 rtc->data->update_mbus_timing(rtc); in armada38x_rtc_resume()
607 return disable_irq_wake(rtc->irq); in armada38x_rtc_resume()
619 .name = "armada38x-rtc",
627 MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");