Messages in this thread Patch in this message | | | From | Bartosz Golaszewski <> | Subject | [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized | Date | Tue, 24 Dec 2019 11:03:26 +0100 |
| |
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The DM365 platform has a strange quirk (only present when using ancient u-boot - mainline u-boot v2013.01 and later works fine) where if we enable the second half of the timer in periodic mode before we do its initialization - the time won't start flowing and we can't boot.
When using more recent u-boot, we can enable the timer, then reinitialize it and all works fine.
I've been unable to figure out why that is, but a workaround for this is straightforward - don't enable the tim34 timer in periodic mode until it's properly initialized.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> --- drivers/clocksource/timer-davinci.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c index 62745c962049..2801f21bb0e2 100644 --- a/drivers/clocksource/timer-davinci.c +++ b/drivers/clocksource/timer-davinci.c @@ -62,6 +62,7 @@ static struct { struct clocksource dev; void __iomem *base; unsigned int tim_off; + bool initialized; } davinci_clocksource; static struct davinci_clockevent * @@ -94,8 +95,9 @@ static void davinci_tim12_shutdown(void __iomem *base) * halves. In this case TIM34 runs in periodic mode and we must * not modify it. */ - tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC << - DAVINCI_TIMER_ENAMODE_SHIFT_TIM34; + if (likely(davinci_clocksource.initialized)) + tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC << + DAVINCI_TIMER_ENAMODE_SHIFT_TIM34; writel_relaxed(tcr, base + DAVINCI_TIMER_REG_TCR); } @@ -107,8 +109,9 @@ static void davinci_tim12_set_oneshot(void __iomem *base) tcr = DAVINCI_TIMER_ENAMODE_ONESHOT << DAVINCI_TIMER_ENAMODE_SHIFT_TIM12; /* Same as above. */ - tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC << - DAVINCI_TIMER_ENAMODE_SHIFT_TIM34; + if (likely(davinci_clocksource.initialized)) + tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC << + DAVINCI_TIMER_ENAMODE_SHIFT_TIM34; writel_relaxed(tcr, base + DAVINCI_TIMER_REG_TCR); } @@ -206,6 +209,8 @@ static void davinci_clocksource_init_tim34(void __iomem *base) writel_relaxed(0x0, base + DAVINCI_TIMER_REG_TIM34); writel_relaxed(UINT_MAX, base + DAVINCI_TIMER_REG_PRD34); writel_relaxed(tcr, base + DAVINCI_TIMER_REG_TCR); + + davinci_clocksource.initialized = true; } /* -- 2.23.0
| |