diff options
Diffstat (limited to 'arch/arm/plat-omap/include')
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 1bee0ac88760..ac16f1e9d0e0 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h | |||
@@ -66,6 +66,16 @@ | |||
66 | #define OMAP_TIMER_NEEDS_RESET 0x10000000 | 66 | #define OMAP_TIMER_NEEDS_RESET 0x10000000 |
67 | #define OMAP_TIMER_HAS_DSP_IRQ 0x08000000 | 67 | #define OMAP_TIMER_HAS_DSP_IRQ 0x08000000 |
68 | 68 | ||
69 | /* | ||
70 | * timer errata flags | ||
71 | * | ||
72 | * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This | ||
73 | * errata prevents us from using posted mode on these devices, unless the | ||
74 | * timer counter register is never read. For more details please refer to | ||
75 | * the OMAP3/4/5 errata documents. | ||
76 | */ | ||
77 | #define OMAP_TIMER_ERRATA_I103_I767 0x80000000 | ||
78 | |||
69 | struct omap_timer_capability_dev_attr { | 79 | struct omap_timer_capability_dev_attr { |
70 | u32 timer_capability; | 80 | u32 timer_capability; |
71 | }; | 81 | }; |
@@ -97,6 +107,7 @@ struct timer_regs { | |||
97 | struct dmtimer_platform_data { | 107 | struct dmtimer_platform_data { |
98 | /* set_timer_src - Only used for OMAP1 devices */ | 108 | /* set_timer_src - Only used for OMAP1 devices */ |
99 | int (*set_timer_src)(struct platform_device *pdev, int source); | 109 | int (*set_timer_src)(struct platform_device *pdev, int source); |
110 | u32 timer_errata; | ||
100 | u32 timer_capability; | 111 | u32 timer_capability; |
101 | int (*get_context_loss_count)(struct device *); | 112 | int (*get_context_loss_count)(struct device *); |
102 | }; | 113 | }; |
@@ -273,6 +284,7 @@ struct omap_dm_timer { | |||
273 | int ctx_loss_count; | 284 | int ctx_loss_count; |
274 | int revision; | 285 | int revision; |
275 | u32 capability; | 286 | u32 capability; |
287 | u32 errata; | ||
276 | struct platform_device *pdev; | 288 | struct platform_device *pdev; |
277 | struct list_head node; | 289 | struct list_head node; |
278 | }; | 290 | }; |
@@ -344,10 +356,46 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer, | |||
344 | l |= 1 << 2; | 356 | l |= 1 << 2; |
345 | 357 | ||
346 | __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); | 358 | __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); |
359 | } | ||
360 | |||
361 | /* | ||
362 | * __omap_dm_timer_enable_posted - enables write posted mode | ||
363 | * @timer: pointer to timer instance handle | ||
364 | * | ||
365 | * Enables the write posted mode for the timer. When posted mode is enabled | ||
366 | * writes to certain timer registers are immediately acknowledged by the | ||
367 | * internal bus and hence prevents stalling the CPU waiting for the write to | ||
368 | * complete. Enabling this feature can improve performance for writing to the | ||
369 | * timer registers. | ||
370 | */ | ||
371 | static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer) | ||
372 | { | ||
373 | if (timer->posted) | ||
374 | return; | ||
375 | |||
376 | if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) | ||
377 | return; | ||
347 | 378 | ||
348 | /* Match hardware reset default of posted mode */ | ||
349 | __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, | 379 | __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, |
350 | OMAP_TIMER_CTRL_POSTED, 0); | 380 | OMAP_TIMER_CTRL_POSTED, 0); |
381 | timer->context.tsicr = OMAP_TIMER_CTRL_POSTED; | ||
382 | timer->posted = OMAP_TIMER_POSTED; | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * __omap_dm_timer_override_errata - override errata flags for a timer | ||
387 | * @timer: pointer to timer handle | ||
388 | * @errata: errata flags to be ignored | ||
389 | * | ||
390 | * For a given timer, override a timer errata by clearing the flags | ||
391 | * specified by the errata argument. A specific erratum should only be | ||
392 | * overridden for a timer if the timer is used in such a way the erratum | ||
393 | * has no impact. | ||
394 | */ | ||
395 | static inline void __omap_dm_timer_override_errata(struct omap_dm_timer *timer, | ||
396 | u32 errata) | ||
397 | { | ||
398 | timer->errata &= ~errata; | ||
351 | } | 399 | } |
352 | 400 | ||
353 | static inline int __omap_dm_timer_set_source(struct clk *timer_fck, | 401 | static inline int __omap_dm_timer_set_source(struct clk *timer_fck, |