* [PATCH v2 0/3] ARM: davinci: convert dm365 to using the new clocksource driver
@ 2019-12-24 10:03 ` Bartosz Golaszewski
0 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw)
To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner,
Kevin Hilman
Cc: Bartosz Golaszewski, linux-kernel, linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Hi Sekhar,
I'm resending this (with fixes) as other solutions have failed and I
think that this is a correct thing to do after all. In the end: with
this patch we do bring the clock to a defined state before enabling it.
Let me know what you think about it.
---
This is a follow-up to the big series converting DaVinci to using
a proper clocksource driver. Last time we couldn't merge the entire
series because of a bug that only appears on dm365 Soc when using
ancient u-boot.
This series contains a workaround for this problem, a patch finally
converting the platform as well as a removal of all obsolete code.
v1 -> v2:
- simplify patch 1/3 by using a boolean flag instead of caching the
value bits for TIM34
Bartosz Golaszewski (3):
clocksource: davinci: only enable tim34 in periodic mode once it's
initialized
ARM: davinci: dm365: switch to using the clocksource driver
ARM: davinci: remove legacy timer support
arch/arm/mach-davinci/Makefile | 3 +-
arch/arm/mach-davinci/devices-da8xx.c | 1 -
arch/arm/mach-davinci/devices.c | 19 -
arch/arm/mach-davinci/dm365.c | 22 +-
arch/arm/mach-davinci/include/mach/common.h | 17 -
arch/arm/mach-davinci/include/mach/time.h | 33 --
arch/arm/mach-davinci/time.c | 400 --------------------
drivers/clocksource/timer-davinci.c | 13 +-
8 files changed, 25 insertions(+), 483 deletions(-)
delete mode 100644 arch/arm/mach-davinci/include/mach/time.h
delete mode 100644 arch/arm/mach-davinci/time.c
--
2.23.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 0/3] ARM: davinci: convert dm365 to using the new clocksource driver @ 2019-12-24 10:03 ` Bartosz Golaszewski 0 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: linux-arm-kernel, linux-kernel, Bartosz Golaszewski From: Bartosz Golaszewski <bgolaszewski@baylibre.com> Hi Sekhar, I'm resending this (with fixes) as other solutions have failed and I think that this is a correct thing to do after all. In the end: with this patch we do bring the clock to a defined state before enabling it. Let me know what you think about it. --- This is a follow-up to the big series converting DaVinci to using a proper clocksource driver. Last time we couldn't merge the entire series because of a bug that only appears on dm365 Soc when using ancient u-boot. This series contains a workaround for this problem, a patch finally converting the platform as well as a removal of all obsolete code. v1 -> v2: - simplify patch 1/3 by using a boolean flag instead of caching the value bits for TIM34 Bartosz Golaszewski (3): clocksource: davinci: only enable tim34 in periodic mode once it's initialized ARM: davinci: dm365: switch to using the clocksource driver ARM: davinci: remove legacy timer support arch/arm/mach-davinci/Makefile | 3 +- arch/arm/mach-davinci/devices-da8xx.c | 1 - arch/arm/mach-davinci/devices.c | 19 - arch/arm/mach-davinci/dm365.c | 22 +- arch/arm/mach-davinci/include/mach/common.h | 17 - arch/arm/mach-davinci/include/mach/time.h | 33 -- arch/arm/mach-davinci/time.c | 400 -------------------- drivers/clocksource/timer-davinci.c | 13 +- 8 files changed, 25 insertions(+), 483 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/time.h delete mode 100644 arch/arm/mach-davinci/time.c -- 2.23.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized 2019-12-24 10:03 ` Bartosz Golaszewski @ 2019-12-24 10:03 ` Bartosz Golaszewski -1 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: Bartosz Golaszewski, linux-kernel, linux-arm-kernel 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 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized @ 2019-12-24 10:03 ` Bartosz Golaszewski 0 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: linux-arm-kernel, linux-kernel, Bartosz Golaszewski 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 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized 2019-12-24 10:03 ` Bartosz Golaszewski @ 2020-01-09 23:12 ` Daniel Lezcano -1 siblings, 0 replies; 12+ messages in thread From: Daniel Lezcano @ 2020-01-09 23:12 UTC (permalink / raw) To: Bartosz Golaszewski, Sekhar Nori, Thomas Gleixner, David Lechner, Kevin Hilman Cc: Bartosz Golaszewski, linux-kernel, linux-arm-kernel On 24/12/2019 11:03, Bartosz Golaszewski wrote: > 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; > } Why not move clockevents_config_and_register() after davinci_clocksource_init_tim34() is called ? -- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized @ 2020-01-09 23:12 ` Daniel Lezcano 0 siblings, 0 replies; 12+ messages in thread From: Daniel Lezcano @ 2020-01-09 23:12 UTC (permalink / raw) To: Bartosz Golaszewski, Sekhar Nori, Thomas Gleixner, David Lechner, Kevin Hilman Cc: linux-arm-kernel, linux-kernel, Bartosz Golaszewski On 24/12/2019 11:03, Bartosz Golaszewski wrote: > 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; > } Why not move clockevents_config_and_register() after davinci_clocksource_init_tim34() is called ? -- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized 2020-01-09 23:12 ` Daniel Lezcano @ 2020-01-10 17:05 ` Bartosz Golaszewski -1 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2020-01-10 17:05 UTC (permalink / raw) To: Daniel Lezcano Cc: David Lechner, Kevin Hilman, Bartosz Golaszewski, Sekhar Nori, LKML, Thomas Gleixner, arm-soc pt., 10 sty 2020 o 00:12 Daniel Lezcano <daniel.lezcano@linaro.org> napisał(a): > > On 24/12/2019 11:03, Bartosz Golaszewski wrote: > > 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> > > Why not move clockevents_config_and_register() after > davinci_clocksource_init_tim34() is called ? Ha! Yes, that works too. I'll send a v3 shortly. Bart _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized @ 2020-01-10 17:05 ` Bartosz Golaszewski 0 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2020-01-10 17:05 UTC (permalink / raw) To: Daniel Lezcano Cc: Bartosz Golaszewski, Sekhar Nori, Thomas Gleixner, David Lechner, Kevin Hilman, arm-soc, LKML pt., 10 sty 2020 o 00:12 Daniel Lezcano <daniel.lezcano@linaro.org> napisał(a): > > On 24/12/2019 11:03, Bartosz Golaszewski wrote: > > 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> > > Why not move clockevents_config_and_register() after > davinci_clocksource_init_tim34() is called ? Ha! Yes, that works too. I'll send a v3 shortly. Bart ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] ARM: davinci: dm365: switch to using the clocksource driver 2019-12-24 10:03 ` Bartosz Golaszewski @ 2019-12-24 10:03 ` Bartosz Golaszewski -1 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: Bartosz Golaszewski, linux-kernel, linux-arm-kernel From: Bartosz Golaszewski <bgolaszewski@baylibre.com> We now have a proper clocksource driver for davinci. Switch the dm365 platform to using it. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: David Lechner <david@lechnology.com> --- arch/arm/mach-davinci/dm365.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 9fc5c73cc0be..c1e0d46996e4 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -35,7 +35,8 @@ #include <mach/cputype.h> #include <mach/mux.h> #include <mach/serial.h> -#include <mach/time.h> + +#include <clocksource/timer-davinci.h> #include "asp.h" #include "davinci.h" @@ -660,10 +661,16 @@ static struct davinci_id dm365_ids[] = { }, }; -static struct davinci_timer_info dm365_timer_info = { - .timers = davinci_timer_instance, - .clockevent_id = T0_BOT, - .clocksource_id = T0_TOP, +/* + * Bottom half of timer0 is used for clockevent, top half is used for + * clocksource. + */ +static const struct davinci_timer_cfg dm365_timer_cfg = { + .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_128), + .irq = { + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)), + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)), + }, }; #define DM365_UART1_BASE (IO_PHYS + 0x106000) @@ -723,7 +730,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = { .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm365_pins, .pinmux_pins_num = ARRAY_SIZE(dm365_pins), - .timer_info = &dm365_timer_info, .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, @@ -771,6 +777,7 @@ void __init dm365_init_time(void) { void __iomem *pll1, *pll2, *psc; struct clk *clk; + int rv; clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ); @@ -789,7 +796,8 @@ void __init dm365_init_time(void) return; } - davinci_timer_init(clk); + rv = davinci_timer_register(clk, &dm365_timer_cfg); + WARN(rv, "Unable to register the timer: %d\n", rv); } void __init dm365_register_clocks(void) -- 2.23.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] ARM: davinci: dm365: switch to using the clocksource driver @ 2019-12-24 10:03 ` Bartosz Golaszewski 0 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: linux-arm-kernel, linux-kernel, Bartosz Golaszewski From: Bartosz Golaszewski <bgolaszewski@baylibre.com> We now have a proper clocksource driver for davinci. Switch the dm365 platform to using it. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: David Lechner <david@lechnology.com> --- arch/arm/mach-davinci/dm365.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 9fc5c73cc0be..c1e0d46996e4 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -35,7 +35,8 @@ #include <mach/cputype.h> #include <mach/mux.h> #include <mach/serial.h> -#include <mach/time.h> + +#include <clocksource/timer-davinci.h> #include "asp.h" #include "davinci.h" @@ -660,10 +661,16 @@ static struct davinci_id dm365_ids[] = { }, }; -static struct davinci_timer_info dm365_timer_info = { - .timers = davinci_timer_instance, - .clockevent_id = T0_BOT, - .clocksource_id = T0_TOP, +/* + * Bottom half of timer0 is used for clockevent, top half is used for + * clocksource. + */ +static const struct davinci_timer_cfg dm365_timer_cfg = { + .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_128), + .irq = { + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)), + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)), + }, }; #define DM365_UART1_BASE (IO_PHYS + 0x106000) @@ -723,7 +730,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = { .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm365_pins, .pinmux_pins_num = ARRAY_SIZE(dm365_pins), - .timer_info = &dm365_timer_info, .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, @@ -771,6 +777,7 @@ void __init dm365_init_time(void) { void __iomem *pll1, *pll2, *psc; struct clk *clk; + int rv; clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ); @@ -789,7 +796,8 @@ void __init dm365_init_time(void) return; } - davinci_timer_init(clk); + rv = davinci_timer_register(clk, &dm365_timer_cfg); + WARN(rv, "Unable to register the timer: %d\n", rv); } void __init dm365_register_clocks(void) -- 2.23.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] ARM: davinci: remove legacy timer support 2019-12-24 10:03 ` Bartosz Golaszewski @ 2019-12-24 10:03 ` Bartosz Golaszewski -1 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: Bartosz Golaszewski, linux-kernel, linux-arm-kernel From: Bartosz Golaszewski <bgolaszewski@baylibre.com> All platforms have now been switched to the new clocksource driver. Remove the old code and various no longer needed bits and pieces. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: David Lechner <david@lechnology.com> --- arch/arm/mach-davinci/Makefile | 3 +- arch/arm/mach-davinci/devices-da8xx.c | 1 - arch/arm/mach-davinci/devices.c | 19 - arch/arm/mach-davinci/include/mach/common.h | 17 - arch/arm/mach-davinci/include/mach/time.h | 33 -- arch/arm/mach-davinci/time.c | 400 -------------------- 6 files changed, 1 insertion(+), 472 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/time.h delete mode 100644 arch/arm/mach-davinci/time.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a03d8443ef08..58838a9de651 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -7,8 +7,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include # Common objects -obj-y := time.o serial.o usb.o \ - common.o sram.o +obj-y := serial.o usb.o common.o sram.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 2d69e704f7f6..feb206bdf6e1 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -21,7 +21,6 @@ #include <mach/common.h> #include <mach/cputype.h> #include <mach/da8xx.h> -#include <mach/time.h> #include "asp.h" #include "cpuidle.h" diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 3e447d468845..d912d62a0eca 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -17,7 +17,6 @@ #include <mach/hardware.h> #include <mach/cputype.h> #include <mach/mux.h> -#include <mach/time.h> #include "davinci.h" #include "irqs.h" @@ -303,21 +302,3 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata) davinci_gpio_device.dev.platform_data = pdata; return platform_device_register(&davinci_gpio_device); } - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -struct davinci_timer_instance davinci_timer_instance[2] = { - { - .base = DAVINCI_TIMER0_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34), - }, - { - .base = DAVINCI_TIMER1_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT34), - }, -}; - diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 9526e5da0d33..139b83de011d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -22,22 +22,6 @@ #define DAVINCI_INTC_START NR_IRQS #define DAVINCI_INTC_IRQ(_irqnum) (DAVINCI_INTC_START + (_irqnum)) -void davinci_timer_init(struct clk *clk); - -struct davinci_timer_instance { - u32 base; - u32 bottom_irq; - u32 top_irq; - unsigned long cmp_off; - unsigned int cmp_irq; -}; - -struct davinci_timer_info { - struct davinci_timer_instance *timers; - unsigned int clockevent_id; - unsigned int clocksource_id; -}; - struct davinci_gpio_controller; /* @@ -58,7 +42,6 @@ struct davinci_soc_info { u32 pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; - struct davinci_timer_info *timer_info; int gpio_type; u32 gpio_base; unsigned gpio_num; diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h deleted file mode 100644 index ba913736990f..000000000000 --- a/arch/arm/mach-davinci/include/mach/time.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Local header file for DaVinci time code. - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H -#define __ARCH_ARM_MACH_DAVINCI_TIME_H - -#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) - -enum { - T0_BOT, - T0_TOP, - T1_BOT, - T1_TOP, - NUM_TIMERS -}; - -#define IS_TIMER1(id) (id & 0x2) -#define IS_TIMER0(id) (!IS_TIMER1(id)) -#define IS_TIMER_TOP(id) ((id & 0x1)) -#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) - -#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0) - -extern struct davinci_timer_instance davinci_timer_instance[]; - -#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c deleted file mode 100644 index 740410a3bb6a..000000000000 --- a/arch/arm/mach-davinci/time.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * DaVinci timer subsystem - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/sched_clock.h> - -#include <asm/mach/irq.h> -#include <asm/mach/time.h> - -#include <mach/cputype.h> -#include <mach/hardware.h> -#include <mach/time.h> - -static struct clock_event_device clockevent_davinci; -static unsigned int davinci_clock_tick_rate; - -/* - * This driver configures the 2 64-bit count-up timers as 4 independent - * 32-bit count-up timers used as follows: - */ - -enum { - TID_CLOCKEVENT, - TID_CLOCKSOURCE, -}; - -/* Timer register offsets */ -#define PID12 0x0 -#define TIM12 0x10 -#define TIM34 0x14 -#define PRD12 0x18 -#define PRD34 0x1c -#define TCR 0x20 -#define TGCR 0x24 -#define WDTCR 0x28 - -/* Offsets of the 8 compare registers */ -#define CMP12_0 0x60 -#define CMP12_1 0x64 -#define CMP12_2 0x68 -#define CMP12_3 0x6c -#define CMP12_4 0x70 -#define CMP12_5 0x74 -#define CMP12_6 0x78 -#define CMP12_7 0x7c - -/* Timer register bitfields */ -#define TCR_ENAMODE_DISABLE 0x0 -#define TCR_ENAMODE_ONESHOT 0x1 -#define TCR_ENAMODE_PERIODIC 0x2 -#define TCR_ENAMODE_MASK 0x3 - -#define TGCR_TIMMODE_SHIFT 2 -#define TGCR_TIMMODE_64BIT_GP 0x0 -#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1 -#define TGCR_TIMMODE_64BIT_WDOG 0x2 -#define TGCR_TIMMODE_32BIT_CHAINED 0x3 - -#define TGCR_TIM12RS_SHIFT 0 -#define TGCR_TIM34RS_SHIFT 1 -#define TGCR_RESET 0x0 -#define TGCR_UNRESET 0x1 -#define TGCR_RESET_MASK 0x3 - -struct timer_s { - char *name; - unsigned int id; - unsigned long period; - unsigned long opts; - unsigned long flags; - void __iomem *base; - unsigned long tim_off; - unsigned long prd_off; - unsigned long enamode_shift; - struct irqaction irqaction; -}; -static struct timer_s timers[]; - -/* values for 'opts' field of struct timer_s */ -#define TIMER_OPTS_DISABLED 0x01 -#define TIMER_OPTS_ONESHOT 0x02 -#define TIMER_OPTS_PERIODIC 0x04 -#define TIMER_OPTS_STATE_MASK 0x07 - -#define TIMER_OPTS_USE_COMPARE 0x80000000 -#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE) - -static char *id_to_name[] = { - [T0_BOT] = "timer0_0", - [T0_TOP] = "timer0_1", - [T1_BOT] = "timer1_0", - [T1_TOP] = "timer1_1", -}; - -static int timer32_config(struct timer_s *t) -{ - u32 tcr; - struct davinci_soc_info *soc_info = &davinci_soc_info; - - if (USING_COMPARE(t)) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id); - - /* - * Next interrupt should be the current time reg value plus - * the new period (using 32-bit unsigned addition/wrapping - * to 0 on overflow). This assumes that the clocksource - * is setup to count to 2^32-1 before wrapping around to 0. - */ - __raw_writel(__raw_readl(t->base + t->tim_off) + t->period, - t->base + dtip[event_timer].cmp_off); - } else { - tcr = __raw_readl(t->base + TCR); - - /* disable timer */ - tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); - __raw_writel(tcr, t->base + TCR); - - /* reset counter to zero, set new period */ - __raw_writel(0, t->base + t->tim_off); - __raw_writel(t->period, t->base + t->prd_off); - - /* Set enable mode */ - if (t->opts & TIMER_OPTS_ONESHOT) - tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; - else if (t->opts & TIMER_OPTS_PERIODIC) - tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; - - __raw_writel(tcr, t->base + TCR); - } - return 0; -} - -static inline u32 timer32_read(struct timer_s *t) -{ - return __raw_readl(t->base + t->tim_off); -} - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_davinci; - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -/* called when 32-bit counter wraps */ -static irqreturn_t freerun_interrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static struct timer_s timers[] = { - [TID_CLOCKEVENT] = { - .name = "clockevent", - .opts = TIMER_OPTS_DISABLED, - .irqaction = { - .flags = IRQF_TIMER, - .handler = timer_interrupt, - } - }, - [TID_CLOCKSOURCE] = { - .name = "free-run counter", - .period = ~0, - .opts = TIMER_OPTS_PERIODIC, - .irqaction = { - .flags = IRQF_TIMER, - .handler = freerun_interrupt, - } - }, -}; - -static void __init timer_init(void) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - struct davinci_timer_instance *dtip = soc_info->timer_info->timers; - void __iomem *base[2]; - int i; - - /* Global init of each 64-bit timer as a whole */ - for(i=0; i<2; i++) { - u32 tgcr; - - base[i] = ioremap(dtip[i].base, SZ_4K); - if (WARN_ON(!base[i])) - continue; - - /* Disabled, Internal clock source */ - __raw_writel(0, base[i] + TCR); - - /* reset both timers, no pre-scaler for timer34 */ - tgcr = 0; - __raw_writel(tgcr, base[i] + TGCR); - - /* Set both timers to unchained 32-bit */ - tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; - __raw_writel(tgcr, base[i] + TGCR); - - /* Unreset timers */ - tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | - (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); - __raw_writel(tgcr, base[i] + TGCR); - - /* Init both counters to zero */ - __raw_writel(0, base[i] + TIM12); - __raw_writel(0, base[i] + TIM34); - } - - /* Init of each timer as a 32-bit timer */ - for (i=0; i< ARRAY_SIZE(timers); i++) { - struct timer_s *t = &timers[i]; - int timer = ID_TO_TIMER(t->id); - u32 irq; - - t->base = base[timer]; - if (!t->base) - continue; - - if (IS_TIMER_BOT(t->id)) { - t->enamode_shift = 6; - t->tim_off = TIM12; - t->prd_off = PRD12; - irq = dtip[timer].bottom_irq; - } else { - t->enamode_shift = 22; - t->tim_off = TIM34; - t->prd_off = PRD34; - irq = dtip[timer].top_irq; - } - - /* Register interrupt */ - t->irqaction.name = t->name; - t->irqaction.dev_id = (void *)t; - - if (t->irqaction.handler != NULL) { - irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; - setup_irq(irq, &t->irqaction); - } - } -} - -/* - * clocksource - */ -static u64 read_cycles(struct clocksource *cs) -{ - struct timer_s *t = &timers[TID_CLOCKSOURCE]; - - return (cycles_t)timer32_read(t); -} - -static struct clocksource clocksource_davinci = { - .rating = 300, - .read = read_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/* - * Overwrite weak default sched_clock with something more precise - */ -static u64 notrace davinci_read_sched_clock(void) -{ - return timer32_read(&timers[TID_CLOCKSOURCE]); -} - -/* - * clockevent - */ -static int davinci_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = cycles; - timer32_config(t); - return 0; -} - -static int davinci_shutdown(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_DISABLED; - return 0; -} - -static int davinci_set_oneshot(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_ONESHOT; - return 0; -} - -static int davinci_set_periodic(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = davinci_clock_tick_rate / (HZ); - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_PERIODIC; - timer32_config(t); - return 0; -} - -static struct clock_event_device clockevent_davinci = { - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = davinci_set_next_event, - .set_state_shutdown = davinci_shutdown, - .set_state_periodic = davinci_set_periodic, - .set_state_oneshot = davinci_set_oneshot, -}; - -void __init davinci_timer_init(struct clk *timer_clk) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - unsigned int clockevent_id; - unsigned int clocksource_id; - int i; - - clockevent_id = soc_info->timer_info->clockevent_id; - clocksource_id = soc_info->timer_info->clocksource_id; - - timers[TID_CLOCKEVENT].id = clockevent_id; - timers[TID_CLOCKSOURCE].id = clocksource_id; - - /* - * If using same timer for both clock events & clocksource, - * a compare register must be used to generate an event interrupt. - * This is equivalent to a oneshot timer only (not periodic). - */ - if (clockevent_id == clocksource_id) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(clockevent_id); - - /* Only bottom timers can use compare regs */ - if (IS_TIMER_TOP(clockevent_id)) - pr_warn("%s: Invalid use of system timers. Results unpredictable.\n", - __func__); - else if ((dtip[event_timer].cmp_off == 0) - || (dtip[event_timer].cmp_irq == 0)) - pr_warn("%s: Invalid timer instance setup. Results unpredictable.\n", - __func__); - else { - timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; - clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; - } - } - - BUG_ON(IS_ERR(timer_clk)); - clk_prepare_enable(timer_clk); - - /* init timer hw */ - timer_init(); - - davinci_clock_tick_rate = clk_get_rate(timer_clk); - - /* setup clocksource */ - clocksource_davinci.name = id_to_name[clocksource_id]; - if (clocksource_register_hz(&clocksource_davinci, - davinci_clock_tick_rate)) - pr_err("%s: can't register clocksource!\n", - clocksource_davinci.name); - - sched_clock_register(davinci_read_sched_clock, 32, - davinci_clock_tick_rate); - - /* setup clockevent */ - clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; - - clockevent_davinci.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_davinci, - davinci_clock_tick_rate, 1, 0xfffffffe); - - for (i=0; i< ARRAY_SIZE(timers); i++) - timer32_config(&timers[i]); -} -- 2.23.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] ARM: davinci: remove legacy timer support @ 2019-12-24 10:03 ` Bartosz Golaszewski 0 siblings, 0 replies; 12+ messages in thread From: Bartosz Golaszewski @ 2019-12-24 10:03 UTC (permalink / raw) To: Sekhar Nori, Daniel Lezcano, Thomas Gleixner, David Lechner, Kevin Hilman Cc: linux-arm-kernel, linux-kernel, Bartosz Golaszewski From: Bartosz Golaszewski <bgolaszewski@baylibre.com> All platforms have now been switched to the new clocksource driver. Remove the old code and various no longer needed bits and pieces. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: David Lechner <david@lechnology.com> --- arch/arm/mach-davinci/Makefile | 3 +- arch/arm/mach-davinci/devices-da8xx.c | 1 - arch/arm/mach-davinci/devices.c | 19 - arch/arm/mach-davinci/include/mach/common.h | 17 - arch/arm/mach-davinci/include/mach/time.h | 33 -- arch/arm/mach-davinci/time.c | 400 -------------------- 6 files changed, 1 insertion(+), 472 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/time.h delete mode 100644 arch/arm/mach-davinci/time.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a03d8443ef08..58838a9de651 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -7,8 +7,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include # Common objects -obj-y := time.o serial.o usb.o \ - common.o sram.o +obj-y := serial.o usb.o common.o sram.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 2d69e704f7f6..feb206bdf6e1 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -21,7 +21,6 @@ #include <mach/common.h> #include <mach/cputype.h> #include <mach/da8xx.h> -#include <mach/time.h> #include "asp.h" #include "cpuidle.h" diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 3e447d468845..d912d62a0eca 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -17,7 +17,6 @@ #include <mach/hardware.h> #include <mach/cputype.h> #include <mach/mux.h> -#include <mach/time.h> #include "davinci.h" #include "irqs.h" @@ -303,21 +302,3 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata) davinci_gpio_device.dev.platform_data = pdata; return platform_device_register(&davinci_gpio_device); } - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -struct davinci_timer_instance davinci_timer_instance[2] = { - { - .base = DAVINCI_TIMER0_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34), - }, - { - .base = DAVINCI_TIMER1_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT34), - }, -}; - diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 9526e5da0d33..139b83de011d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -22,22 +22,6 @@ #define DAVINCI_INTC_START NR_IRQS #define DAVINCI_INTC_IRQ(_irqnum) (DAVINCI_INTC_START + (_irqnum)) -void davinci_timer_init(struct clk *clk); - -struct davinci_timer_instance { - u32 base; - u32 bottom_irq; - u32 top_irq; - unsigned long cmp_off; - unsigned int cmp_irq; -}; - -struct davinci_timer_info { - struct davinci_timer_instance *timers; - unsigned int clockevent_id; - unsigned int clocksource_id; -}; - struct davinci_gpio_controller; /* @@ -58,7 +42,6 @@ struct davinci_soc_info { u32 pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; - struct davinci_timer_info *timer_info; int gpio_type; u32 gpio_base; unsigned gpio_num; diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h deleted file mode 100644 index ba913736990f..000000000000 --- a/arch/arm/mach-davinci/include/mach/time.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Local header file for DaVinci time code. - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H -#define __ARCH_ARM_MACH_DAVINCI_TIME_H - -#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) - -enum { - T0_BOT, - T0_TOP, - T1_BOT, - T1_TOP, - NUM_TIMERS -}; - -#define IS_TIMER1(id) (id & 0x2) -#define IS_TIMER0(id) (!IS_TIMER1(id)) -#define IS_TIMER_TOP(id) ((id & 0x1)) -#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) - -#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0) - -extern struct davinci_timer_instance davinci_timer_instance[]; - -#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c deleted file mode 100644 index 740410a3bb6a..000000000000 --- a/arch/arm/mach-davinci/time.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * DaVinci timer subsystem - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/sched_clock.h> - -#include <asm/mach/irq.h> -#include <asm/mach/time.h> - -#include <mach/cputype.h> -#include <mach/hardware.h> -#include <mach/time.h> - -static struct clock_event_device clockevent_davinci; -static unsigned int davinci_clock_tick_rate; - -/* - * This driver configures the 2 64-bit count-up timers as 4 independent - * 32-bit count-up timers used as follows: - */ - -enum { - TID_CLOCKEVENT, - TID_CLOCKSOURCE, -}; - -/* Timer register offsets */ -#define PID12 0x0 -#define TIM12 0x10 -#define TIM34 0x14 -#define PRD12 0x18 -#define PRD34 0x1c -#define TCR 0x20 -#define TGCR 0x24 -#define WDTCR 0x28 - -/* Offsets of the 8 compare registers */ -#define CMP12_0 0x60 -#define CMP12_1 0x64 -#define CMP12_2 0x68 -#define CMP12_3 0x6c -#define CMP12_4 0x70 -#define CMP12_5 0x74 -#define CMP12_6 0x78 -#define CMP12_7 0x7c - -/* Timer register bitfields */ -#define TCR_ENAMODE_DISABLE 0x0 -#define TCR_ENAMODE_ONESHOT 0x1 -#define TCR_ENAMODE_PERIODIC 0x2 -#define TCR_ENAMODE_MASK 0x3 - -#define TGCR_TIMMODE_SHIFT 2 -#define TGCR_TIMMODE_64BIT_GP 0x0 -#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1 -#define TGCR_TIMMODE_64BIT_WDOG 0x2 -#define TGCR_TIMMODE_32BIT_CHAINED 0x3 - -#define TGCR_TIM12RS_SHIFT 0 -#define TGCR_TIM34RS_SHIFT 1 -#define TGCR_RESET 0x0 -#define TGCR_UNRESET 0x1 -#define TGCR_RESET_MASK 0x3 - -struct timer_s { - char *name; - unsigned int id; - unsigned long period; - unsigned long opts; - unsigned long flags; - void __iomem *base; - unsigned long tim_off; - unsigned long prd_off; - unsigned long enamode_shift; - struct irqaction irqaction; -}; -static struct timer_s timers[]; - -/* values for 'opts' field of struct timer_s */ -#define TIMER_OPTS_DISABLED 0x01 -#define TIMER_OPTS_ONESHOT 0x02 -#define TIMER_OPTS_PERIODIC 0x04 -#define TIMER_OPTS_STATE_MASK 0x07 - -#define TIMER_OPTS_USE_COMPARE 0x80000000 -#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE) - -static char *id_to_name[] = { - [T0_BOT] = "timer0_0", - [T0_TOP] = "timer0_1", - [T1_BOT] = "timer1_0", - [T1_TOP] = "timer1_1", -}; - -static int timer32_config(struct timer_s *t) -{ - u32 tcr; - struct davinci_soc_info *soc_info = &davinci_soc_info; - - if (USING_COMPARE(t)) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id); - - /* - * Next interrupt should be the current time reg value plus - * the new period (using 32-bit unsigned addition/wrapping - * to 0 on overflow). This assumes that the clocksource - * is setup to count to 2^32-1 before wrapping around to 0. - */ - __raw_writel(__raw_readl(t->base + t->tim_off) + t->period, - t->base + dtip[event_timer].cmp_off); - } else { - tcr = __raw_readl(t->base + TCR); - - /* disable timer */ - tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); - __raw_writel(tcr, t->base + TCR); - - /* reset counter to zero, set new period */ - __raw_writel(0, t->base + t->tim_off); - __raw_writel(t->period, t->base + t->prd_off); - - /* Set enable mode */ - if (t->opts & TIMER_OPTS_ONESHOT) - tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; - else if (t->opts & TIMER_OPTS_PERIODIC) - tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; - - __raw_writel(tcr, t->base + TCR); - } - return 0; -} - -static inline u32 timer32_read(struct timer_s *t) -{ - return __raw_readl(t->base + t->tim_off); -} - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_davinci; - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -/* called when 32-bit counter wraps */ -static irqreturn_t freerun_interrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static struct timer_s timers[] = { - [TID_CLOCKEVENT] = { - .name = "clockevent", - .opts = TIMER_OPTS_DISABLED, - .irqaction = { - .flags = IRQF_TIMER, - .handler = timer_interrupt, - } - }, - [TID_CLOCKSOURCE] = { - .name = "free-run counter", - .period = ~0, - .opts = TIMER_OPTS_PERIODIC, - .irqaction = { - .flags = IRQF_TIMER, - .handler = freerun_interrupt, - } - }, -}; - -static void __init timer_init(void) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - struct davinci_timer_instance *dtip = soc_info->timer_info->timers; - void __iomem *base[2]; - int i; - - /* Global init of each 64-bit timer as a whole */ - for(i=0; i<2; i++) { - u32 tgcr; - - base[i] = ioremap(dtip[i].base, SZ_4K); - if (WARN_ON(!base[i])) - continue; - - /* Disabled, Internal clock source */ - __raw_writel(0, base[i] + TCR); - - /* reset both timers, no pre-scaler for timer34 */ - tgcr = 0; - __raw_writel(tgcr, base[i] + TGCR); - - /* Set both timers to unchained 32-bit */ - tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; - __raw_writel(tgcr, base[i] + TGCR); - - /* Unreset timers */ - tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | - (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); - __raw_writel(tgcr, base[i] + TGCR); - - /* Init both counters to zero */ - __raw_writel(0, base[i] + TIM12); - __raw_writel(0, base[i] + TIM34); - } - - /* Init of each timer as a 32-bit timer */ - for (i=0; i< ARRAY_SIZE(timers); i++) { - struct timer_s *t = &timers[i]; - int timer = ID_TO_TIMER(t->id); - u32 irq; - - t->base = base[timer]; - if (!t->base) - continue; - - if (IS_TIMER_BOT(t->id)) { - t->enamode_shift = 6; - t->tim_off = TIM12; - t->prd_off = PRD12; - irq = dtip[timer].bottom_irq; - } else { - t->enamode_shift = 22; - t->tim_off = TIM34; - t->prd_off = PRD34; - irq = dtip[timer].top_irq; - } - - /* Register interrupt */ - t->irqaction.name = t->name; - t->irqaction.dev_id = (void *)t; - - if (t->irqaction.handler != NULL) { - irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; - setup_irq(irq, &t->irqaction); - } - } -} - -/* - * clocksource - */ -static u64 read_cycles(struct clocksource *cs) -{ - struct timer_s *t = &timers[TID_CLOCKSOURCE]; - - return (cycles_t)timer32_read(t); -} - -static struct clocksource clocksource_davinci = { - .rating = 300, - .read = read_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/* - * Overwrite weak default sched_clock with something more precise - */ -static u64 notrace davinci_read_sched_clock(void) -{ - return timer32_read(&timers[TID_CLOCKSOURCE]); -} - -/* - * clockevent - */ -static int davinci_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = cycles; - timer32_config(t); - return 0; -} - -static int davinci_shutdown(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_DISABLED; - return 0; -} - -static int davinci_set_oneshot(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_ONESHOT; - return 0; -} - -static int davinci_set_periodic(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = davinci_clock_tick_rate / (HZ); - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_PERIODIC; - timer32_config(t); - return 0; -} - -static struct clock_event_device clockevent_davinci = { - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = davinci_set_next_event, - .set_state_shutdown = davinci_shutdown, - .set_state_periodic = davinci_set_periodic, - .set_state_oneshot = davinci_set_oneshot, -}; - -void __init davinci_timer_init(struct clk *timer_clk) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - unsigned int clockevent_id; - unsigned int clocksource_id; - int i; - - clockevent_id = soc_info->timer_info->clockevent_id; - clocksource_id = soc_info->timer_info->clocksource_id; - - timers[TID_CLOCKEVENT].id = clockevent_id; - timers[TID_CLOCKSOURCE].id = clocksource_id; - - /* - * If using same timer for both clock events & clocksource, - * a compare register must be used to generate an event interrupt. - * This is equivalent to a oneshot timer only (not periodic). - */ - if (clockevent_id == clocksource_id) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(clockevent_id); - - /* Only bottom timers can use compare regs */ - if (IS_TIMER_TOP(clockevent_id)) - pr_warn("%s: Invalid use of system timers. Results unpredictable.\n", - __func__); - else if ((dtip[event_timer].cmp_off == 0) - || (dtip[event_timer].cmp_irq == 0)) - pr_warn("%s: Invalid timer instance setup. Results unpredictable.\n", - __func__); - else { - timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; - clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; - } - } - - BUG_ON(IS_ERR(timer_clk)); - clk_prepare_enable(timer_clk); - - /* init timer hw */ - timer_init(); - - davinci_clock_tick_rate = clk_get_rate(timer_clk); - - /* setup clocksource */ - clocksource_davinci.name = id_to_name[clocksource_id]; - if (clocksource_register_hz(&clocksource_davinci, - davinci_clock_tick_rate)) - pr_err("%s: can't register clocksource!\n", - clocksource_davinci.name); - - sched_clock_register(davinci_read_sched_clock, 32, - davinci_clock_tick_rate); - - /* setup clockevent */ - clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; - - clockevent_davinci.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_davinci, - davinci_clock_tick_rate, 1, 0xfffffffe); - - for (i=0; i< ARRAY_SIZE(timers); i++) - timer32_config(&timers[i]); -} -- 2.23.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-01-10 17:05 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-12-24 10:03 [PATCH v2 0/3] ARM: davinci: convert dm365 to using the new clocksource driver Bartosz Golaszewski 2019-12-24 10:03 ` Bartosz Golaszewski 2019-12-24 10:03 ` [PATCH v2 1/3] clocksource: davinci: only enable tim34 in periodic mode once it's initialized Bartosz Golaszewski 2019-12-24 10:03 ` Bartosz Golaszewski 2020-01-09 23:12 ` Daniel Lezcano 2020-01-09 23:12 ` Daniel Lezcano 2020-01-10 17:05 ` Bartosz Golaszewski 2020-01-10 17:05 ` Bartosz Golaszewski 2019-12-24 10:03 ` [PATCH v2 2/3] ARM: davinci: dm365: switch to using the clocksource driver Bartosz Golaszewski 2019-12-24 10:03 ` Bartosz Golaszewski 2019-12-24 10:03 ` [PATCH v2 3/3] ARM: davinci: remove legacy timer support Bartosz Golaszewski 2019-12-24 10:03 ` Bartosz Golaszewski
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.