ARM: OMAP3+: Implement timer workaround for errata i103 and i767

Errata Titles:
i103: Delay needed to read some GP timer, WD timer and sync timer registers
      after wakeup (OMAP3/4)
i767: Delay needed to read some GP timer registers after wakeup (OMAP5)

Description:
If a General Purpose Timer (GPTimer) is in posted mode (TSICR [2].POSTED=1),
due to internal resynchronizations, values read in TCRR, TCAR1 and TCAR2
registers right after the timer interface clock (L4) goes from stopped to
active may not return the expected values. The most common event leading to
this situation occurs upon wake up from idle.

GPTimer non-posted synchronization mode is not impacted by this limitation.

Workarounds:
1). Disable posted mode
2). Use static dependency between timer clock domain and MPUSS clock domain
3). Use no-idle mode when the timer is active

Workarounds #2 and #3 are not pratical from a power standpoint and so
workaround #1 has been implemented. Disabling posted mode adds some CPU overhead
for configuring the timers as the CPU has to wait for the write to complete.
However, disabling posted mode guarantees correct operation.

Please note that it is safe to use posted mode for timers if the counter
register will never be read. An example of this is the clock-event system
timer. This is used by the kernel to schedule events however, the timers
counter is never read. Given that the kernel configures this timer often yet
never reads the counter register it is safe to enable posted mode in this case.
Hence, for the timer used for kernel clock-events, posted mode is enabled by
overriding the errata for devices that are impacted by this defect.

Although both dmtimers and watchdogs are impacted by this defect this patch only
implements the workaround for the dmtimer. Currently the watchdog driver does
not read the counter register and so no workaround is necessary.

Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx devices.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Fix timer posted mode support

Currently the dmtimer posted mode is being enabled when the function
__omap_dm_timer_reset() is called. This function is only being called for
OMAP1 timers and OMAP2+ timers that are being used as system timers. Hence,
for OMAP2+ timers that are NOT being used as a system timer, posted mode is
not enabled but the "timer->posted" variable is still set (incorrectly) in
the omap_dm_timer_prepare() function.

This is a regression introduced by commit 3392cdd3 (ARM: OMAP: dmtimer:
switch-over to platform device driver) which change the code to only call
omap_dm_timer_reset() for OMAP1 devices. Although this is a regression from
the original code it only impacts performance and so is not needed for stable.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP2+: Don't use __omap_dm_timer_reset()

Currently OMAP2+ devices are using the function __omap_dm_timer_reset() to
configure the clock-activity, idle, wakeup-enable and auto-idle fields in the
timer OCP_CFG register. The name of the function is mis-leading because this
function does not actually perform a reset of the timer.

For OMAP2+ devices, HWMOD is responsible for reseting and configuring the
timer OCP_CFG register. Therefore, do not use __omap_dm_timer_reset() for
OMAP2+ devices and rely on HWMOD. Furthermore, some timer instances do not
have the fields clock-activity, wakeup-enable and auto-idle and so this
function could configure the OCP_CFG register incorrectly.

Currently HWMOD is not configuring the clock-activity field in the OCP_CFG
register for timers that have this field. Commit 0f0d080 (ARM: OMAP: DMTimer:
Use posted mode) configures the clock-activity field to keep the f-clk enabled
so that the wake-up capability is enabled. Therefore, add the appropriate flags
to the timer HWMOD structures to configure this field in the same way.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Fix dmtimer reset for timer1

In commit e32f7ec2 (ARM: OMAP: Fix 32 kHz timer and modify GP timer to use GPT1)
a fix was added to prevent timer1 being reset in the function
omap_dm_timer_reset() because timer1 was being used as the system timer for
OMAP2 devices. Although timer1 is still used by most OMAP2+ devices as a system
timer the function omap_dm_timer_reset() is now only being called for OMAP1
devices and OMAP1 does not use timer1 as a system timer. Therefore, clean-up
and simplify the code by removing the check in omap_dm_timer_reset().

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Clean-up dmtimer reset code

Only OMAP1 devices use the omap_dm_timer_reset() and so require the
omap_dm_timer_wait_for_reset() and __omap_dm_timer_reset() functions.
Therefore combine these into a single function called omap_dm_timer_reset()
and simplify the code.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Clean-up timer posted mode support

The dmtimer functions to read and write the dmtimer registers are currently
defined as follows ...

static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
						int posted);
static inline void __omap_dm_timer_write(struct omap_dm_timer *timer,
						u32 reg, u32 val, int posted);

The posted variable indicates if the timer is configured to use the posted mode
when performing register accesses. The posted mode configuration of the dmtimer
is stored in the omap_dm_timer structure that is also being passed to the above
functions and therefore we do not need to pass the posted variable separately.
Therefore, simplify the above functions by removing the posted variable as an
argument as this is not necessary.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Add dmtimer interrupt disable function

The OMAP dmtimer driver does not currently have a function to disable the
timer interrupts. For some timer instances the timer interrupt enable
function can be used to disable the interrupts because the same interrupt
enable register is used to disable interrupts. However, some timer instances
have separate interrupt enable/disable registers and so this will not work.
Therefore, add a dedicated function to disable interrupts.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
ARM: OMAP: Remove unnecessary call to clk_get()

Whenever we call the function omap_dm_timer_set_source() to set the clock
source of a dmtimer we look-up the dmtimer functional clock source by
calling clk_get(). This is not necessary because on requesting a dmtimer
we look-up the functional clock source and store it in the omap_dm_timer
structure. So instead of looking up the clock again used the clock handle
that stored in the omap_dm_timer structure.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>