[v2,06/15] clocksource/drivers/timer-milbeaut: Introduce timer for Milbeaut SoCs

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
Related show

Commit Message

Sugaya Taichi Feb. 8, 2019, 12:26 p.m.
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

Comments

Daniel Lezcano Feb. 12, 2019, 9:06 a.m. | #1
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
Sugaya Taichi Feb. 13, 2019, 10:34 a.m. | #2
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);

>>

> 

>
Daniel Lezcano Feb. 14, 2019, 2:44 p.m. | #3
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
Arnd Bergmann Feb. 14, 2019, 3:18 p.m. | #4
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
Daniel Lezcano Feb. 14, 2019, 3:22 p.m. | #5
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
Sugaya Taichi Feb. 15, 2019, 2:25 a.m. | #6
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
Sugaya Taichi Feb. 15, 2019, 2:26 a.m. | #7
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);

>>

> 

>
Arnd Bergmann Feb. 15, 2019, 9:07 a.m. | #8
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
Sugaya Taichi Feb. 15, 2019, 1:14 p.m. | #9
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

Patch

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);