|
@@ -332,3 +332,83 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
|
|
|
*/
|
|
|
static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
|
|
|
{
|
|
|
+ if (timer->posted)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
|
|
|
+ return;
|
|
|
+
|
|
|
+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
|
|
|
+ OMAP_TIMER_CTRL_POSTED, 0);
|
|
|
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
|
|
|
+ timer->posted = OMAP_TIMER_POSTED;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __omap_dm_timer_override_errata - override errata flags for a timer
|
|
|
+ * @timer: pointer to timer handle
|
|
|
+ * @errata: errata flags to be ignored
|
|
|
+ *
|
|
|
+ * For a given timer, override a timer errata by clearing the flags
|
|
|
+ * specified by the errata argument. A specific erratum should only be
|
|
|
+ * overridden for a timer if the timer is used in such a way the erratum
|
|
|
+ * has no impact.
|
|
|
+ */
|
|
|
+static inline void __omap_dm_timer_override_errata(struct omap_dm_timer *timer,
|
|
|
+ u32 errata)
|
|
|
+{
|
|
|
+ timer->errata &= ~errata;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,
|
|
|
+ int posted, unsigned long rate)
|
|
|
+{
|
|
|
+ u32 l;
|
|
|
+
|
|
|
+ l = __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
|
|
|
+ if (l & OMAP_TIMER_CTRL_ST) {
|
|
|
+ l &= ~0x1;
|
|
|
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted);
|
|
|
+#ifdef CONFIG_ARCH_OMAP2PLUS
|
|
|
+ /* Readback to make sure write has completed */
|
|
|
+ __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
|
|
|
+ /*
|
|
|
+ * Wait for functional clock period x 3.5 to make sure that
|
|
|
+ * timer is stopped
|
|
|
+ */
|
|
|
+ udelay(3500000 / rate + 1);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Ack possibly pending interrupt */
|
|
|
+ __raw_writel(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer,
|
|
|
+ u32 ctrl, unsigned int load,
|
|
|
+ int posted)
|
|
|
+{
|
|
|
+ __omap_dm_timer_write(timer, OMAP_TIMER_COUNTER_REG, load, posted);
|
|
|
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, ctrl, posted);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer,
|
|
|
+ unsigned int value)
|
|
|
+{
|
|
|
+ __raw_writel(value, timer->irq_ena);
|
|
|
+ __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned int
|
|
|
+__omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted)
|
|
|
+{
|
|
|
+ return __omap_dm_timer_read(timer, OMAP_TIMER_COUNTER_REG, posted);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
|
|
|
+ unsigned int value)
|
|
|
+{
|
|
|
+ __raw_writel(value, timer->irq_stat);
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* __ASM_ARCH_DMTIMER_H */
|