Message ID | 1549628812-31235-1-git-send-email-sugaya.taichi@socionext.com |
---|---|
State | Superseded |
Headers | show |
Series | [v2,01/15] dt-bindings: sram: milbeaut: Add binding for Milbeaut smp-sram | expand |
On 08/02/2019 13:26, Sugaya Taichi wrote: > Add timer driver for Milbeaut SoCs series. > > The timer has two 32-bit width down counters, one of which is configured > as a clockevent device and the other is configured as a clock source. > > Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> Do want me to take it through my tree? > --- > drivers/clocksource/Kconfig | 9 ++ > drivers/clocksource/Makefile | 1 + > drivers/clocksource/timer-milbeaut.c | 161 +++++++++++++++++++++++++++++++++++ > 3 files changed, 171 insertions(+) > create mode 100644 drivers/clocksource/timer-milbeaut.c > > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > index a9e26f6..9101b8f 100644 > --- a/drivers/clocksource/Kconfig > +++ b/drivers/clocksource/Kconfig > @@ -634,4 +634,13 @@ config GX6605S_TIMER > help > This option enables support for gx6605s SOC's timer. > > +config MILBEAUT_TIMER > + bool "Milbeaut timer driver" if COMPILE_TEST > + depends on OF > + depends on ARM > + select TIMER_OF > + select CLKSRC_MMIO > + help > + Enables the support for Milbeaut timer driver. > + > endmenu > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile > index cdd210f..6f2543b 100644 > --- a/drivers/clocksource/Makefile > +++ b/drivers/clocksource/Makefile > @@ -55,6 +55,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o > obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o > obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o > obj-$(CONFIG_OWL_TIMER) += timer-owl.o > +obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o > obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o > obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o > obj-$(CONFIG_RDA_TIMER) += timer-rda.o > diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c > new file mode 100644 > index 0000000..f2019a8 > --- /dev/null > +++ b/drivers/clocksource/timer-milbeaut.c > @@ -0,0 +1,161 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + */ > + > +#include <linux/clk.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/irqreturn.h> > +#include <linux/sched_clock.h> > +#include "timer-of.h" > + > +#define MLB_TMR_TMCSR_OFS 0x0 > +#define MLB_TMR_TMR_OFS 0x4 > +#define MLB_TMR_TMRLR1_OFS 0x8 > +#define MLB_TMR_TMRLR2_OFS 0xc > +#define MLB_TMR_REGSZPCH 0x10 > + > +#define MLB_TMR_TMCSR_OUTL BIT(5) > +#define MLB_TMR_TMCSR_RELD BIT(4) > +#define MLB_TMR_TMCSR_INTE BIT(3) > +#define MLB_TMR_TMCSR_UF BIT(2) > +#define MLB_TMR_TMCSR_CNTE BIT(1) > +#define MLB_TMR_TMCSR_TRG BIT(0) > + > +#define MLB_TMR_TMCSR_CSL_DIV2 0 > +#define MLB_TMR_DIV_CNT 2 > + > +#define MLB_TMR_SRC_CH (1) > +#define MLB_TMR_EVT_CH (0) > + > +#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) > +#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) > + > +#define MLB_TMR_SRC_TMCSR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMCSR_OFS) > +#define MLB_TMR_SRC_TMR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMR_OFS) > +#define MLB_TMR_SRC_TMRLR1_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR1_OFS) > +#define MLB_TMR_SRC_TMRLR2_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR2_OFS) > + > +#define MLB_TMR_EVT_TMCSR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMCSR_OFS) > +#define MLB_TMR_EVT_TMR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMR_OFS) > +#define MLB_TMR_EVT_TMRLR1_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR1_OFS) > +#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) > + > +#define MLB_TIMER_RATING 500 > + > +static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) > +{ > + struct clock_event_device *clk = dev_id; > + struct timer_of *to = to_timer_of(clk); > + u32 val; > + > + val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + val &= ~MLB_TMR_TMCSR_UF; > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + > + clk->event_handler(clk); > + > + return IRQ_HANDLED; > +} > + > +static int mlb_set_state_periodic(struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + u32 val = MLB_TMR_TMCSR_CSL_DIV2; > + > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + > + writel_relaxed(to->of_clk.period, timer_of_base(to) + > + MLB_TMR_EVT_TMRLR1_OFS); > + val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | > + MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_set_state_oneshot(struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + u32 val = MLB_TMR_TMCSR_CSL_DIV2; > + > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_clkevt_next_event(unsigned long event, > + struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + > + writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); > + writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | > + MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | > + MLB_TMR_TMCSR_TRG, timer_of_base(to) + > + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_config_clock_source(struct timer_of *to) > +{ > + writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); > + writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + > + MLB_TMR_SRC_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_config_clock_event(struct timer_of *to) > +{ > + writel_relaxed(0, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static struct timer_of to = { > + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, > + > + .clkevt = { > + .name = "mlb-clkevt", > + .rating = MLB_TIMER_RATING, > + .cpumask = cpu_possible_mask, > + .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, > + .set_state_oneshot = mlb_set_state_oneshot, > + .set_state_periodic = mlb_set_state_periodic, > + .set_next_event = mlb_clkevt_next_event, > + }, > + > + .of_irq = { > + .flags = IRQF_TIMER | IRQF_IRQPOLL, > + .handler = mlb_timer_interrupt, > + }, > +}; > + > +static u64 notrace mlb_timer_sched_read(void) > +{ > + return ~readl_relaxed(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS); > +} > + > +static int __init mlb_timer_init(struct device_node *node) > +{ > + int ret; > + unsigned long rate; > + > + ret = timer_of_init(node, &to); > + if (ret) > + return ret; > + > + rate = timer_of_rate(&to) / MLB_TMR_DIV_CNT; > + mlb_config_clock_source(&to); > + clocksource_mmio_init(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS, > + node->name, rate, MLB_TIMER_RATING, 32, > + clocksource_mmio_readl_down); > + sched_clock_register(mlb_timer_sched_read, 32, rate); > + mlb_config_clock_event(&to); > + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 15, > + 0xffffffff); > + return 0; > +} > +TIMER_OF_DECLARE(mlb_peritimer, "socionext,milbeaut-timer", > + mlb_timer_init); > -- <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
Hi, On 2019/02/12 18:06, Daniel Lezcano wrote: > On 08/02/2019 13:26, Sugaya Taichi wrote: >> Add timer driver for Milbeaut SoCs series. >> >> The timer has two 32-bit width down counters, one of which is configured >> as a clockevent device and the other is configured as a clock source. >> >> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> > > Do want me to take it through my tree? > Yes, please. By the way, the patch series includes other sub-system drivers, so should it be splitted into each driver patch ? Thanks, Sugaya Taichi >> --- >> drivers/clocksource/Kconfig | 9 ++ >> drivers/clocksource/Makefile | 1 + >> drivers/clocksource/timer-milbeaut.c | 161 +++++++++++++++++++++++++++++++++++ >> 3 files changed, 171 insertions(+) >> create mode 100644 drivers/clocksource/timer-milbeaut.c >> >> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig >> index a9e26f6..9101b8f 100644 >> --- a/drivers/clocksource/Kconfig >> +++ b/drivers/clocksource/Kconfig >> @@ -634,4 +634,13 @@ config GX6605S_TIMER >> help >> This option enables support for gx6605s SOC's timer. >> >> +config MILBEAUT_TIMER >> + bool "Milbeaut timer driver" if COMPILE_TEST >> + depends on OF >> + depends on ARM >> + select TIMER_OF >> + select CLKSRC_MMIO >> + help >> + Enables the support for Milbeaut timer driver. >> + >> endmenu >> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile >> index cdd210f..6f2543b 100644 >> --- a/drivers/clocksource/Makefile >> +++ b/drivers/clocksource/Makefile >> @@ -55,6 +55,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o >> obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o >> obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o >> obj-$(CONFIG_OWL_TIMER) += timer-owl.o >> +obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o >> obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o >> obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o >> obj-$(CONFIG_RDA_TIMER) += timer-rda.o >> diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c >> new file mode 100644 >> index 0000000..f2019a8 >> --- /dev/null >> +++ b/drivers/clocksource/timer-milbeaut.c >> @@ -0,0 +1,161 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (C) 2018 Socionext Inc. >> + */ >> + >> +#include <linux/clk.h> >> +#include <linux/interrupt.h> >> +#include <linux/irq.h> >> +#include <linux/irqreturn.h> >> +#include <linux/sched_clock.h> >> +#include "timer-of.h" >> + >> +#define MLB_TMR_TMCSR_OFS 0x0 >> +#define MLB_TMR_TMR_OFS 0x4 >> +#define MLB_TMR_TMRLR1_OFS 0x8 >> +#define MLB_TMR_TMRLR2_OFS 0xc >> +#define MLB_TMR_REGSZPCH 0x10 >> + >> +#define MLB_TMR_TMCSR_OUTL BIT(5) >> +#define MLB_TMR_TMCSR_RELD BIT(4) >> +#define MLB_TMR_TMCSR_INTE BIT(3) >> +#define MLB_TMR_TMCSR_UF BIT(2) >> +#define MLB_TMR_TMCSR_CNTE BIT(1) >> +#define MLB_TMR_TMCSR_TRG BIT(0) >> + >> +#define MLB_TMR_TMCSR_CSL_DIV2 0 >> +#define MLB_TMR_DIV_CNT 2 >> + >> +#define MLB_TMR_SRC_CH (1) >> +#define MLB_TMR_EVT_CH (0) >> + >> +#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) >> +#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) >> + >> +#define MLB_TMR_SRC_TMCSR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMCSR_OFS) >> +#define MLB_TMR_SRC_TMR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMR_OFS) >> +#define MLB_TMR_SRC_TMRLR1_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR1_OFS) >> +#define MLB_TMR_SRC_TMRLR2_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR2_OFS) >> + >> +#define MLB_TMR_EVT_TMCSR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMCSR_OFS) >> +#define MLB_TMR_EVT_TMR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMR_OFS) >> +#define MLB_TMR_EVT_TMRLR1_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR1_OFS) >> +#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) >> + >> +#define MLB_TIMER_RATING 500 >> + >> +static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) >> +{ >> + struct clock_event_device *clk = dev_id; >> + struct timer_of *to = to_timer_of(clk); >> + u32 val; >> + >> + val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + val &= ~MLB_TMR_TMCSR_UF; >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + >> + clk->event_handler(clk); >> + >> + return IRQ_HANDLED; >> +} >> + >> +static int mlb_set_state_periodic(struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + u32 val = MLB_TMR_TMCSR_CSL_DIV2; >> + >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + >> + writel_relaxed(to->of_clk.period, timer_of_base(to) + >> + MLB_TMR_EVT_TMRLR1_OFS); >> + val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | >> + MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_set_state_oneshot(struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + u32 val = MLB_TMR_TMCSR_CSL_DIV2; >> + >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_clkevt_next_event(unsigned long event, >> + struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + >> + writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); >> + writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | >> + MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | >> + MLB_TMR_TMCSR_TRG, timer_of_base(to) + >> + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_config_clock_source(struct timer_of *to) >> +{ >> + writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); >> + writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + >> + MLB_TMR_SRC_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_config_clock_event(struct timer_of *to) >> +{ >> + writel_relaxed(0, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static struct timer_of to = { >> + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, >> + >> + .clkevt = { >> + .name = "mlb-clkevt", >> + .rating = MLB_TIMER_RATING, >> + .cpumask = cpu_possible_mask, >> + .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, >> + .set_state_oneshot = mlb_set_state_oneshot, >> + .set_state_periodic = mlb_set_state_periodic, >> + .set_next_event = mlb_clkevt_next_event, >> + }, >> + >> + .of_irq = { >> + .flags = IRQF_TIMER | IRQF_IRQPOLL, >> + .handler = mlb_timer_interrupt, >> + }, >> +}; >> + >> +static u64 notrace mlb_timer_sched_read(void) >> +{ >> + return ~readl_relaxed(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS); >> +} >> + >> +static int __init mlb_timer_init(struct device_node *node) >> +{ >> + int ret; >> + unsigned long rate; >> + >> + ret = timer_of_init(node, &to); >> + if (ret) >> + return ret; >> + >> + rate = timer_of_rate(&to) / MLB_TMR_DIV_CNT; >> + mlb_config_clock_source(&to); >> + clocksource_mmio_init(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS, >> + node->name, rate, MLB_TIMER_RATING, 32, >> + clocksource_mmio_readl_down); >> + sched_clock_register(mlb_timer_sched_read, 32, rate); >> + mlb_config_clock_event(&to); >> + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 15, >> + 0xffffffff); >> + return 0; >> +} >> +TIMER_OF_DECLARE(mlb_peritimer, "socionext,milbeaut-timer", >> + mlb_timer_init); >> > >
On 13/02/2019 11:34, Sugaya, Taichi wrote: > Hi, > > On 2019/02/12 18:06, Daniel Lezcano wrote: >> On 08/02/2019 13:26, Sugaya Taichi wrote: >>> Add timer driver for Milbeaut SoCs series. >>> >>> The timer has two 32-bit width down counters, one of which is configured >>> as a clockevent device and the other is configured as a clock source. >>> >>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> >> >> Do want me to take it through my tree? >> > > Yes, please. > > By the way, the patch series includes other sub-system drivers, so > should it be splitted into each driver patch ? Well usually changes are per sub-systems but in case of first submission you may ask linux-soc@ team to take all the patches together with the acked-by tags from those subsystems maintainer. Added in Cc: Arnd@ and linux-soc@ I'll wait a bit before applying the patch you clarify this. -- Daniel -- <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
On Thu, Feb 14, 2019 at 3:44 PM Daniel Lezcano <daniel.lezcano@linaro.org> wrote: > > On 13/02/2019 11:34, Sugaya, Taichi wrote: > > Hi, > > > > On 2019/02/12 18:06, Daniel Lezcano wrote: > >> On 08/02/2019 13:26, Sugaya Taichi wrote: > >>> Add timer driver for Milbeaut SoCs series. > >>> > >>> The timer has two 32-bit width down counters, one of which is configured > >>> as a clockevent device and the other is configured as a clock source. > >>> > >>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> > >> > >> Do want me to take it through my tree? > >> > > > > Yes, please. > > > > By the way, the patch series includes other sub-system drivers, so > > should it be splitted into each driver patch ? > > Well usually changes are per sub-systems but in case of first submission > you may ask linux-soc@ team to take all the patches together with the > acked-by tags from those subsystems maintainer. > > Added in Cc: Arnd@ and linux-soc@ > > I'll wait a bit before applying the patch you clarify this. Yes, I think merging them all together is best here. I saw the patches fly past but did not do a complete review, but if all other review comments are addressed, I'd suggest sending the entire series for inclusion to linux-soc@vger.kernel.org with the Acked-by/Reviewed-by tags from subsystem maintainers added in. Arnd
On 08/02/2019 13:26, Sugaya Taichi wrote: > Add timer driver for Milbeaut SoCs series. > > The timer has two 32-bit width down counters, one of which is configured > as a clockevent device and the other is configured as a clock source. > > Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/clocksource/Kconfig | 9 ++ > drivers/clocksource/Makefile | 1 + > drivers/clocksource/timer-milbeaut.c | 161 +++++++++++++++++++++++++++++++++++ > 3 files changed, 171 insertions(+) > create mode 100644 drivers/clocksource/timer-milbeaut.c > > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > index a9e26f6..9101b8f 100644 > --- a/drivers/clocksource/Kconfig > +++ b/drivers/clocksource/Kconfig > @@ -634,4 +634,13 @@ config GX6605S_TIMER > help > This option enables support for gx6605s SOC's timer. > > +config MILBEAUT_TIMER > + bool "Milbeaut timer driver" if COMPILE_TEST > + depends on OF > + depends on ARM > + select TIMER_OF > + select CLKSRC_MMIO > + help > + Enables the support for Milbeaut timer driver. > + > endmenu > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile > index cdd210f..6f2543b 100644 > --- a/drivers/clocksource/Makefile > +++ b/drivers/clocksource/Makefile > @@ -55,6 +55,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o > obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o > obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o > obj-$(CONFIG_OWL_TIMER) += timer-owl.o > +obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o > obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o > obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o > obj-$(CONFIG_RDA_TIMER) += timer-rda.o > diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c > new file mode 100644 > index 0000000..f2019a8 > --- /dev/null > +++ b/drivers/clocksource/timer-milbeaut.c > @@ -0,0 +1,161 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + */ > + > +#include <linux/clk.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/irqreturn.h> > +#include <linux/sched_clock.h> > +#include "timer-of.h" > + > +#define MLB_TMR_TMCSR_OFS 0x0 > +#define MLB_TMR_TMR_OFS 0x4 > +#define MLB_TMR_TMRLR1_OFS 0x8 > +#define MLB_TMR_TMRLR2_OFS 0xc > +#define MLB_TMR_REGSZPCH 0x10 > + > +#define MLB_TMR_TMCSR_OUTL BIT(5) > +#define MLB_TMR_TMCSR_RELD BIT(4) > +#define MLB_TMR_TMCSR_INTE BIT(3) > +#define MLB_TMR_TMCSR_UF BIT(2) > +#define MLB_TMR_TMCSR_CNTE BIT(1) > +#define MLB_TMR_TMCSR_TRG BIT(0) > + > +#define MLB_TMR_TMCSR_CSL_DIV2 0 > +#define MLB_TMR_DIV_CNT 2 > + > +#define MLB_TMR_SRC_CH (1) > +#define MLB_TMR_EVT_CH (0) > + > +#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) > +#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) > + > +#define MLB_TMR_SRC_TMCSR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMCSR_OFS) > +#define MLB_TMR_SRC_TMR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMR_OFS) > +#define MLB_TMR_SRC_TMRLR1_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR1_OFS) > +#define MLB_TMR_SRC_TMRLR2_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR2_OFS) > + > +#define MLB_TMR_EVT_TMCSR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMCSR_OFS) > +#define MLB_TMR_EVT_TMR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMR_OFS) > +#define MLB_TMR_EVT_TMRLR1_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR1_OFS) > +#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) > + > +#define MLB_TIMER_RATING 500 > + > +static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) > +{ > + struct clock_event_device *clk = dev_id; > + struct timer_of *to = to_timer_of(clk); > + u32 val; > + > + val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + val &= ~MLB_TMR_TMCSR_UF; > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + > + clk->event_handler(clk); > + > + return IRQ_HANDLED; > +} > + > +static int mlb_set_state_periodic(struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + u32 val = MLB_TMR_TMCSR_CSL_DIV2; > + > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + > + writel_relaxed(to->of_clk.period, timer_of_base(to) + > + MLB_TMR_EVT_TMRLR1_OFS); > + val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | > + MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_set_state_oneshot(struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + u32 val = MLB_TMR_TMCSR_CSL_DIV2; > + > + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_clkevt_next_event(unsigned long event, > + struct clock_event_device *clk) > +{ > + struct timer_of *to = to_timer_of(clk); > + > + writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); > + writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | > + MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | > + MLB_TMR_TMCSR_TRG, timer_of_base(to) + > + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_config_clock_source(struct timer_of *to) > +{ > + writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); > + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); > + writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + > + MLB_TMR_SRC_TMCSR_OFS); > + return 0; > +} > + > +static int mlb_config_clock_event(struct timer_of *to) > +{ > + writel_relaxed(0, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); > + return 0; > +} > + > +static struct timer_of to = { > + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, > + > + .clkevt = { > + .name = "mlb-clkevt", > + .rating = MLB_TIMER_RATING, > + .cpumask = cpu_possible_mask, > + .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, > + .set_state_oneshot = mlb_set_state_oneshot, > + .set_state_periodic = mlb_set_state_periodic, > + .set_next_event = mlb_clkevt_next_event, > + }, > + > + .of_irq = { > + .flags = IRQF_TIMER | IRQF_IRQPOLL, > + .handler = mlb_timer_interrupt, > + }, > +}; > + > +static u64 notrace mlb_timer_sched_read(void) > +{ > + return ~readl_relaxed(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS); > +} > + > +static int __init mlb_timer_init(struct device_node *node) > +{ > + int ret; > + unsigned long rate; > + > + ret = timer_of_init(node, &to); > + if (ret) > + return ret; > + > + rate = timer_of_rate(&to) / MLB_TMR_DIV_CNT; > + mlb_config_clock_source(&to); > + clocksource_mmio_init(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS, > + node->name, rate, MLB_TIMER_RATING, 32, > + clocksource_mmio_readl_down); > + sched_clock_register(mlb_timer_sched_read, 32, rate); > + mlb_config_clock_event(&to); > + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 15, > + 0xffffffff); > + return 0; > +} > +TIMER_OF_DECLARE(mlb_peritimer, "socionext,milbeaut-timer", > + mlb_timer_init); > -- <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
Hi, On 2019/02/15 0:18, Arnd Bergmann wrote: > On Thu, Feb 14, 2019 at 3:44 PM Daniel Lezcano > <daniel.lezcano@linaro.org> wrote: >> >> On 13/02/2019 11:34, Sugaya, Taichi wrote: >>> Hi, >>> >>> On 2019/02/12 18:06, Daniel Lezcano wrote: >>>> On 08/02/2019 13:26, Sugaya Taichi wrote: >>>>> Add timer driver for Milbeaut SoCs series. >>>>> >>>>> The timer has two 32-bit width down counters, one of which is configured >>>>> as a clockevent device and the other is configured as a clock source. >>>>> >>>>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> >>>> >>>> Do want me to take it through my tree? >>>> >>> >>> Yes, please. >>> >>> By the way, the patch series includes other sub-system drivers, so >>> should it be splitted into each driver patch ? >> >> Well usually changes are per sub-systems but in case of first submission >> you may ask linux-soc@ team to take all the patches together with the >> acked-by tags from those subsystems maintainer. >> >> Added in Cc: Arnd@ and linux-soc@ >> >> I'll wait a bit before applying the patch you clarify this. > > Yes, I think merging them all together is best here. > > I saw the patches fly past but did not do a complete review, > but if all other review comments are addressed, I'd suggest > sending the entire series for inclusion to linux-soc@vger.kernel.org > with the Acked-by/Reviewed-by tags from subsystem maintainers > added in. > > Arnd > Thank you for suggestion. OK. I will send the series to the ML with the Acked-by/Reviewed-by tags. Thanks, Sugaya Taichi
Hi, Daniel On 2019/02/15 0:22, Daniel Lezcano wrote: > On 08/02/2019 13:26, Sugaya Taichi wrote: >> Add timer driver for Milbeaut SoCs series. >> >> The timer has two 32-bit width down counters, one of which is configured >> as a clockevent device and the other is configured as a clock source. >> >> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> > > Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> > Thank you! >> --- >> drivers/clocksource/Kconfig | 9 ++ >> drivers/clocksource/Makefile | 1 + >> drivers/clocksource/timer-milbeaut.c | 161 +++++++++++++++++++++++++++++++++++ >> 3 files changed, 171 insertions(+) >> create mode 100644 drivers/clocksource/timer-milbeaut.c >> >> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig >> index a9e26f6..9101b8f 100644 >> --- a/drivers/clocksource/Kconfig >> +++ b/drivers/clocksource/Kconfig >> @@ -634,4 +634,13 @@ config GX6605S_TIMER >> help >> This option enables support for gx6605s SOC's timer. >> >> +config MILBEAUT_TIMER >> + bool "Milbeaut timer driver" if COMPILE_TEST >> + depends on OF >> + depends on ARM >> + select TIMER_OF >> + select CLKSRC_MMIO >> + help >> + Enables the support for Milbeaut timer driver. >> + >> endmenu >> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile >> index cdd210f..6f2543b 100644 >> --- a/drivers/clocksource/Makefile >> +++ b/drivers/clocksource/Makefile >> @@ -55,6 +55,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o >> obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o >> obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o >> obj-$(CONFIG_OWL_TIMER) += timer-owl.o >> +obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o >> obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o >> obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o >> obj-$(CONFIG_RDA_TIMER) += timer-rda.o >> diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c >> new file mode 100644 >> index 0000000..f2019a8 >> --- /dev/null >> +++ b/drivers/clocksource/timer-milbeaut.c >> @@ -0,0 +1,161 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (C) 2018 Socionext Inc. >> + */ >> + >> +#include <linux/clk.h> >> +#include <linux/interrupt.h> >> +#include <linux/irq.h> >> +#include <linux/irqreturn.h> >> +#include <linux/sched_clock.h> >> +#include "timer-of.h" >> + >> +#define MLB_TMR_TMCSR_OFS 0x0 >> +#define MLB_TMR_TMR_OFS 0x4 >> +#define MLB_TMR_TMRLR1_OFS 0x8 >> +#define MLB_TMR_TMRLR2_OFS 0xc >> +#define MLB_TMR_REGSZPCH 0x10 >> + >> +#define MLB_TMR_TMCSR_OUTL BIT(5) >> +#define MLB_TMR_TMCSR_RELD BIT(4) >> +#define MLB_TMR_TMCSR_INTE BIT(3) >> +#define MLB_TMR_TMCSR_UF BIT(2) >> +#define MLB_TMR_TMCSR_CNTE BIT(1) >> +#define MLB_TMR_TMCSR_TRG BIT(0) >> + >> +#define MLB_TMR_TMCSR_CSL_DIV2 0 >> +#define MLB_TMR_DIV_CNT 2 >> + >> +#define MLB_TMR_SRC_CH (1) >> +#define MLB_TMR_EVT_CH (0) >> + >> +#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) >> +#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) >> + >> +#define MLB_TMR_SRC_TMCSR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMCSR_OFS) >> +#define MLB_TMR_SRC_TMR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMR_OFS) >> +#define MLB_TMR_SRC_TMRLR1_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR1_OFS) >> +#define MLB_TMR_SRC_TMRLR2_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR2_OFS) >> + >> +#define MLB_TMR_EVT_TMCSR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMCSR_OFS) >> +#define MLB_TMR_EVT_TMR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMR_OFS) >> +#define MLB_TMR_EVT_TMRLR1_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR1_OFS) >> +#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) >> + >> +#define MLB_TIMER_RATING 500 >> + >> +static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) >> +{ >> + struct clock_event_device *clk = dev_id; >> + struct timer_of *to = to_timer_of(clk); >> + u32 val; >> + >> + val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + val &= ~MLB_TMR_TMCSR_UF; >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + >> + clk->event_handler(clk); >> + >> + return IRQ_HANDLED; >> +} >> + >> +static int mlb_set_state_periodic(struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + u32 val = MLB_TMR_TMCSR_CSL_DIV2; >> + >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + >> + writel_relaxed(to->of_clk.period, timer_of_base(to) + >> + MLB_TMR_EVT_TMRLR1_OFS); >> + val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | >> + MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_set_state_oneshot(struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + u32 val = MLB_TMR_TMCSR_CSL_DIV2; >> + >> + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_clkevt_next_event(unsigned long event, >> + struct clock_event_device *clk) >> +{ >> + struct timer_of *to = to_timer_of(clk); >> + >> + writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); >> + writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | >> + MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | >> + MLB_TMR_TMCSR_TRG, timer_of_base(to) + >> + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_config_clock_source(struct timer_of *to) >> +{ >> + writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); >> + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); >> + writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + >> + MLB_TMR_SRC_TMCSR_OFS); >> + return 0; >> +} >> + >> +static int mlb_config_clock_event(struct timer_of *to) >> +{ >> + writel_relaxed(0, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); >> + return 0; >> +} >> + >> +static struct timer_of to = { >> + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, >> + >> + .clkevt = { >> + .name = "mlb-clkevt", >> + .rating = MLB_TIMER_RATING, >> + .cpumask = cpu_possible_mask, >> + .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, >> + .set_state_oneshot = mlb_set_state_oneshot, >> + .set_state_periodic = mlb_set_state_periodic, >> + .set_next_event = mlb_clkevt_next_event, >> + }, >> + >> + .of_irq = { >> + .flags = IRQF_TIMER | IRQF_IRQPOLL, >> + .handler = mlb_timer_interrupt, >> + }, >> +}; >> + >> +static u64 notrace mlb_timer_sched_read(void) >> +{ >> + return ~readl_relaxed(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS); >> +} >> + >> +static int __init mlb_timer_init(struct device_node *node) >> +{ >> + int ret; >> + unsigned long rate; >> + >> + ret = timer_of_init(node, &to); >> + if (ret) >> + return ret; >> + >> + rate = timer_of_rate(&to) / MLB_TMR_DIV_CNT; >> + mlb_config_clock_source(&to); >> + clocksource_mmio_init(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS, >> + node->name, rate, MLB_TIMER_RATING, 32, >> + clocksource_mmio_readl_down); >> + sched_clock_register(mlb_timer_sched_read, 32, rate); >> + mlb_config_clock_event(&to); >> + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 15, >> + 0xffffffff); >> + return 0; >> +} >> +TIMER_OF_DECLARE(mlb_peritimer, "socionext,milbeaut-timer", >> + mlb_timer_init); >> > >
On Fri, Feb 15, 2019 at 3:25 AM Sugaya, Taichi <sugaya.taichi@socionext.com> wrote: > On 2019/02/15 0:18, Arnd Bergmann wrote: > > On Thu, Feb 14, 2019 at 3:44 PM Daniel Lezcano > > <daniel.lezcano@linaro.org> wrote: > >> > >> On 13/02/2019 11:34, Sugaya, Taichi wrote: > >>> Hi, > >>> > >>> On 2019/02/12 18:06, Daniel Lezcano wrote: > >>>> On 08/02/2019 13:26, Sugaya Taichi wrote: > >>>>> Add timer driver for Milbeaut SoCs series. > >>>>> > >>>>> The timer has two 32-bit width down counters, one of which is configured > >>>>> as a clockevent device and the other is configured as a clock source. > >>>>> > >>>>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> > >>>> > >>>> Do want me to take it through my tree? > >>>> > >>> > >>> Yes, please. > >>> > >>> By the way, the patch series includes other sub-system drivers, so > >>> should it be splitted into each driver patch ? > >> > >> Well usually changes are per sub-systems but in case of first submission > >> you may ask linux-soc@ team to take all the patches together with the > >> acked-by tags from those subsystems maintainer. > >> > >> Added in Cc: Arnd@ and linux-soc@ > >> > >> I'll wait a bit before applying the patch you clarify this. > > > > Yes, I think merging them all together is best here. > > > > I saw the patches fly past but did not do a complete review, > > but if all other review comments are addressed, I'd suggest > > sending the entire series for inclusion to linux-soc@vger.kernel.org > > with the Acked-by/Reviewed-by tags from subsystem maintainers > > added in. > > Thank you for suggestion. > OK. I will send the series to the ML with the Acked-by/Reviewed-by tags. One correction: please send the patches to address "soc@kernel.org" for inclusion. Arnd
Hi, > -----Original Message----- > From: linux-arm-kernel > [mailto:linux-arm-kernel-bounces@lists.infradead.org] On Behalf Of > Arnd Bergmann > Sent: Friday, February 15, 2019 6:08 PM > To: Sugaya, Taichi/菅谷 太一 > Cc: Kanematsu, Shinji/兼松 伸次; Masami Hiramatsu; Daniel Lezcano; > Linux Kernel Mailing List; Kasai, Kazuhiro/笠井 一洋; Jassi Brar; Orito, > Takao/織戸 誉生; Arnd Bergmann; linux-soc@vger.kernel.org; Thomas > Gleixner; Linux ARM > Subject: Re: [PATCH v2 06/15] clocksource/drivers/timer-milbeaut: > Introduce timer for Milbeaut SoCs > > On Fri, Feb 15, 2019 at 3:25 AM Sugaya, Taichi > <sugaya.taichi@socionext.com> wrote: > > On 2019/02/15 0:18, Arnd Bergmann wrote: > > > On Thu, Feb 14, 2019 at 3:44 PM Daniel Lezcano > > > <daniel.lezcano@linaro.org> wrote: > > >> > > >> On 13/02/2019 11:34, Sugaya, Taichi wrote: > > >>> Hi, > > >>> > > >>> On 2019/02/12 18:06, Daniel Lezcano wrote: > > >>>> On 08/02/2019 13:26, Sugaya Taichi wrote: > > >>>>> Add timer driver for Milbeaut SoCs series. > > >>>>> > > >>>>> The timer has two 32-bit width down counters, one of which is > configured > > >>>>> as a clockevent device and the other is configured as a clock > source. > > >>>>> > > >>>>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> > > >>>> > > >>>> Do want me to take it through my tree? > > >>>> > > >>> > > >>> Yes, please. > > >>> > > >>> By the way, the patch series includes other sub-system drivers, > so > > >>> should it be splitted into each driver patch ? > > >> > > >> Well usually changes are per sub-systems but in case of first > submission > > >> you may ask linux-soc@ team to take all the patches together with > the > > >> acked-by tags from those subsystems maintainer. > > >> > > >> Added in Cc: Arnd@ and linux-soc@ > > >> > > >> I'll wait a bit before applying the patch you clarify this. > > > > > > Yes, I think merging them all together is best here. > > > > > > I saw the patches fly past but did not do a complete review, > > > but if all other review comments are addressed, I'd suggest > > > sending the entire series for inclusion to linux-soc@vger.kernel.org > > > with the Acked-by/Reviewed-by tags from subsystem maintainers > > > added in. > > > > Thank you for suggestion. > > OK. I will send the series to the ML with the Acked-by/Reviewed-by tags. > > One correction: please send the patches to address "soc@kernel.org" > for inclusion. > I got it! Thanks, Sugaya Taichi > Arnd > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index a9e26f6..9101b8f 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -634,4 +634,13 @@ config GX6605S_TIMER help This option enables support for gx6605s SOC's timer. +config MILBEAUT_TIMER + bool "Milbeaut timer driver" if COMPILE_TEST + depends on OF + depends on ARM + select TIMER_OF + select CLKSRC_MMIO + help + Enables the support for Milbeaut timer driver. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index cdd210f..6f2543b 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o obj-$(CONFIG_OWL_TIMER) += timer-owl.o +obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o obj-$(CONFIG_RDA_TIMER) += timer-rda.o diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c new file mode 100644 index 0000000..f2019a8 --- /dev/null +++ b/drivers/clocksource/timer-milbeaut.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Socionext Inc. + */ + +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/irqreturn.h> +#include <linux/sched_clock.h> +#include "timer-of.h" + +#define MLB_TMR_TMCSR_OFS 0x0 +#define MLB_TMR_TMR_OFS 0x4 +#define MLB_TMR_TMRLR1_OFS 0x8 +#define MLB_TMR_TMRLR2_OFS 0xc +#define MLB_TMR_REGSZPCH 0x10 + +#define MLB_TMR_TMCSR_OUTL BIT(5) +#define MLB_TMR_TMCSR_RELD BIT(4) +#define MLB_TMR_TMCSR_INTE BIT(3) +#define MLB_TMR_TMCSR_UF BIT(2) +#define MLB_TMR_TMCSR_CNTE BIT(1) +#define MLB_TMR_TMCSR_TRG BIT(0) + +#define MLB_TMR_TMCSR_CSL_DIV2 0 +#define MLB_TMR_DIV_CNT 2 + +#define MLB_TMR_SRC_CH (1) +#define MLB_TMR_EVT_CH (0) + +#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) +#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) + +#define MLB_TMR_SRC_TMCSR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMCSR_OFS) +#define MLB_TMR_SRC_TMR_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMR_OFS) +#define MLB_TMR_SRC_TMRLR1_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR1_OFS) +#define MLB_TMR_SRC_TMRLR2_OFS (MLB_TMR_SRC_CH_OFS + MLB_TMR_TMRLR2_OFS) + +#define MLB_TMR_EVT_TMCSR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMCSR_OFS) +#define MLB_TMR_EVT_TMR_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMR_OFS) +#define MLB_TMR_EVT_TMRLR1_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR1_OFS) +#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) + +#define MLB_TIMER_RATING 500 + +static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *clk = dev_id; + struct timer_of *to = to_timer_of(clk); + u32 val; + + val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + val &= ~MLB_TMR_TMCSR_UF; + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + + clk->event_handler(clk); + + return IRQ_HANDLED; +} + +static int mlb_set_state_periodic(struct clock_event_device *clk) +{ + struct timer_of *to = to_timer_of(clk); + u32 val = MLB_TMR_TMCSR_CSL_DIV2; + + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + + writel_relaxed(to->of_clk.period, timer_of_base(to) + + MLB_TMR_EVT_TMRLR1_OFS); + val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | + MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + return 0; +} + +static int mlb_set_state_oneshot(struct clock_event_device *clk) +{ + struct timer_of *to = to_timer_of(clk); + u32 val = MLB_TMR_TMCSR_CSL_DIV2; + + writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + return 0; +} + +static int mlb_clkevt_next_event(unsigned long event, + struct clock_event_device *clk) +{ + struct timer_of *to = to_timer_of(clk); + + writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); + writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | + MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | + MLB_TMR_TMCSR_TRG, timer_of_base(to) + + MLB_TMR_EVT_TMCSR_OFS); + return 0; +} + +static int mlb_config_clock_source(struct timer_of *to) +{ + writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); + writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); + writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + + MLB_TMR_SRC_TMCSR_OFS); + return 0; +} + +static int mlb_config_clock_event(struct timer_of *to) +{ + writel_relaxed(0, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); + return 0; +} + +static struct timer_of to = { + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, + + .clkevt = { + .name = "mlb-clkevt", + .rating = MLB_TIMER_RATING, + .cpumask = cpu_possible_mask, + .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, + .set_state_oneshot = mlb_set_state_oneshot, + .set_state_periodic = mlb_set_state_periodic, + .set_next_event = mlb_clkevt_next_event, + }, + + .of_irq = { + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = mlb_timer_interrupt, + }, +}; + +static u64 notrace mlb_timer_sched_read(void) +{ + return ~readl_relaxed(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS); +} + +static int __init mlb_timer_init(struct device_node *node) +{ + int ret; + unsigned long rate; + + ret = timer_of_init(node, &to); + if (ret) + return ret; + + rate = timer_of_rate(&to) / MLB_TMR_DIV_CNT; + mlb_config_clock_source(&to); + clocksource_mmio_init(timer_of_base(&to) + MLB_TMR_SRC_TMR_OFS, + node->name, rate, MLB_TIMER_RATING, 32, + clocksource_mmio_readl_down); + sched_clock_register(mlb_timer_sched_read, 32, rate); + mlb_config_clock_event(&to); + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 15, + 0xffffffff); + return 0; +} +TIMER_OF_DECLARE(mlb_peritimer, "socionext,milbeaut-timer", + mlb_timer_init);
Add timer driver for Milbeaut SoCs series. The timer has two 32-bit width down counters, one of which is configured as a clockevent device and the other is configured as a clock source. Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com> --- drivers/clocksource/Kconfig | 9 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-milbeaut.c | 161 +++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 drivers/clocksource/timer-milbeaut.c -- 1.9.1