2014-04-16 03:02:46

by Xiubo Li

[permalink] [raw]
Subject: [RFC][PATCH 0/3] Add Freescale FlexTimer Module timer.


Xiubo Li (3):
ARM: dts: vf610: Add Freescale FlexTimer Module timer node.
ARM: dts: vf610-twr: Enable Freescale FlexTimer Module timer.
clocksource: Add Freescale FlexTimer Module (FTM) timer support

arch/arm/boot/dts/vf610-twr.dts | 4 +
arch/arm/boot/dts/vf610.dtsi | 13 ++
drivers/clocksource/Kconfig | 5 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/fsl_ftm_timer.c | 238 ++++++++++++++++++++++++++++++++++++
5 files changed, 261 insertions(+)
create mode 100644 drivers/clocksource/fsl_ftm_timer.c

--
1.8.4


2014-04-16 03:03:46

by Xiubo Li

[permalink] [raw]
Subject: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support

The Freescale FlexTimer Module time reference is a 16-bit counter
that can be used as an unsigned or signed counter.one 16-bits
increase counter.

Here using the FTM0 as clock event device and the FTM1 as clock
source device.

Signed-off-by: Xiubo Li <[email protected]>
Cc: Shawn Guo <[email protected]>
Cc: Jingchang Lu <[email protected]>
---
drivers/clocksource/Kconfig | 5 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/fsl_ftm_timer.c | 238 ++++++++++++++++++++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644 drivers/clocksource/fsl_ftm_timer.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950f..28321c5 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -136,6 +136,11 @@ config CLKSRC_SAMSUNG_PWM
for all devicetree enabled platforms. This driver will be
needed only on systems that do not have the Exynos MCT available.

+config FSL_FTM_TIMER
+ bool
+ help
+ Support for Freescale FlexTimer Module (FTM) timer.
+
config VF_PIT_TIMER
bool
help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a..ce0a967 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
+obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o

obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
new file mode 100644
index 0000000..988449e
--- /dev/null
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -0,0 +1,238 @@
+/*
+ * Freescale FlexTimer Module (FTM) timer driver.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define FTM_OFFSET(n) (0x1000 * n)
+
+#define FTM_SC 0x00
+#define FTM_SC_CLK_SHIFT 3
+#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK 0x7
+#define FTM_SC_TOIE BIT(6)
+#define FTM_SC_TOF BIT(7)
+
+#define FTM_CNT 0x04
+#define FTM_MOD 0x08
+
+#define FTM_CSC_BASE 0x0C
+#define FTM_CSC_MSB BIT(5)
+#define FTM_CSC_MSA BIT(4)
+#define FTM_CSC_ELSB BIT(3)
+#define FTM_CSC_ELSA BIT(2)
+
+#define FTM_CV_BASE 0x10
+#define FTM_CNTIN 0x4C
+#define FTM_STATUS 0x50
+
+#define FTM_MODE 0x54
+#define FTM_MODE_FTMEN BIT(0)
+#define FTM_MODE_WPDIS BIT(2)
+#define FTM_MODE_PWMSYNC BIT(3)
+
+#define FTM_SYNC 0x58
+#define FTM_OUTINIT 0x5C
+#define FTM_OUTMASK 0x60
+#define FTM_COMBINE 0x64
+#define FTM_DEADTIME 0x68
+#define FTM_EXTTRIG 0x6C
+#define FTM_POL 0x70
+#define FTM_FMS 0x74
+#define FTM_FILTER 0x78
+#define FTM_FLTCTRL 0x7C
+#define FTM_QDCTRL 0x80
+#define FTM_CONF 0x84
+#define FTM_FLTPOL 0x88
+#define FTM_SYNCONF 0x8C
+#define FTM_INVCTRL 0x90
+#define FTM_SWOCTRL 0x94
+#define FTM_PWMLOAD 0x98
+
+static void __iomem *clksrc_base;
+static void __iomem *clkevt_base;
+static unsigned long peroidic_cyc;
+
+static inline void __init ftm_timer_enable(void __iomem *base)
+{
+ u32 val;
+
+ /* select and enable counter clock source */
+ val = __raw_readl(base + FTM_SC);
+ val &= ~FTM_SC_CLK_MASK;
+ val |= FTM_SC_CLK(1);
+ __raw_writel(val, base + FTM_SC);
+}
+
+static u64 ftm_read_sched_clock(void)
+{
+ return __raw_readl(clksrc_base + FTM_CNT);
+}
+
+static int __init ftm_clocksource_init(unsigned long freq)
+{
+ int ret;
+
+ __raw_writel(0x00, clksrc_base + FTM_CNTIN);
+ __raw_writel(~0UL, clksrc_base + FTM_MOD);
+ __raw_writel(0x1, clksrc_base + FTM_CNT);
+
+ sched_clock_register(ftm_read_sched_clock, 16, freq);
+ ret = clocksource_mmio_init(clksrc_base + FTM_CNT, "fsl-ftm",
+ freq, 300, 16, clocksource_mmio_readl_up);
+ if (ret)
+ return ret;
+
+ ftm_timer_enable(clksrc_base);
+
+ return 0;
+}
+
+static inline void ftm_irq_acknowledge(void)
+{
+ u32 val;
+
+ val = __raw_readl(clkevt_base + FTM_SC);
+ val &= ~FTM_SC_TOF;
+ __raw_writel(val, clkevt_base + FTM_SC);
+}
+
+static int ftm_set_next_event(unsigned long delta,
+ struct clock_event_device *unused)
+{
+ __raw_writel(delta, clkevt_base + FTM_MOD);
+
+ return 0;
+}
+
+static void ftm_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ ftm_set_next_event(peroidic_cyc, evt);
+ break;
+ default:
+ break;
+ }
+}
+
+static irqreturn_t ftm_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ ftm_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_ftm = {
+ .name = "Freescale ftm timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = ftm_set_mode,
+ .set_next_event = ftm_set_next_event,
+ .rating = 300,
+};
+
+static struct irqaction ftm_timer_irq = {
+ .name = "Freescale ftm timer",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ftm_timer_interrupt,
+ .dev_id = &clockevent_ftm,
+};
+
+static int __init ftm_clockevent_init(unsigned long freq, int irq)
+{
+ u32 val;
+
+ __raw_writel(0x00, clkevt_base + FTM_CNTIN);
+ __raw_writel(~0UL, clkevt_base + FTM_MOD);
+ __raw_writel(0x1, clksrc_base + FTM_CNT);
+
+ val = __raw_readl(clkevt_base + FTM_SC);
+ val |= FTM_SC_TOIE;
+ __raw_writel(val, clkevt_base + FTM_SC);
+
+ BUG_ON(setup_irq(irq, &ftm_timer_irq));
+
+ clockevent_ftm.cpumask = cpumask_of(0);
+ clockevent_ftm.irq = irq;
+
+ clockevents_config_and_register(&clockevent_ftm, freq, 1, 0xffff);
+
+ ftm_timer_enable(clkevt_base);
+
+ return 0;
+}
+
+static void __init calc_closest_cound_cyc(unsigned long freq)
+{
+ unsigned long ps = 0;
+
+ do {
+ peroidic_cyc = DIV_ROUND_CLOSEST(freq, HZ * (1 << ps++));
+ } while (peroidic_cyc > 0xFFFF);
+
+}
+
+static void __init ftm_timer_init(struct device_node *np)
+{
+ struct clk *ftm_clk;
+ void __iomem *timer_base;
+ unsigned long freq;
+ int irq;
+
+ timer_base = of_iomap(np, 0);
+ BUG_ON(!timer_base);
+
+ clksrc_base = timer_base + FTM_OFFSET(1);
+ clkevt_base = timer_base + FTM_OFFSET(0);
+
+ irq = irq_of_parse_and_map(np, 0);
+ BUG_ON(irq <= 0);
+
+ ftm_clk = of_clk_get_by_name(np, "ftm0_counter_en");
+ BUG_ON(IS_ERR(ftm_clk));
+ BUG_ON(clk_prepare_enable(ftm_clk));
+
+ ftm_clk = of_clk_get_by_name(np, "ftm1_counter_en");
+ BUG_ON(IS_ERR(ftm_clk));
+ BUG_ON(clk_prepare_enable(ftm_clk));
+
+ ftm_clk = of_clk_get_by_name(np, "ftm0");
+ BUG_ON(IS_ERR(ftm_clk));
+ BUG_ON(clk_prepare_enable(ftm_clk));
+
+ ftm_clk = of_clk_get_by_name(np, "ftm1");
+ BUG_ON(IS_ERR(ftm_clk));
+ BUG_ON(clk_prepare_enable(ftm_clk));
+
+ freq = clk_get_rate(ftm_clk);
+
+ calc_closest_cound_cyc(freq);
+
+ BUG_ON(ftm_clocksource_init(freq));
+
+ BUG_ON(ftm_clockevent_init(freq, irq));
+}
+CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-ftm-timer", ftm_timer_init);
--
1.8.4

2014-04-16 03:03:43

by Xiubo Li

[permalink] [raw]
Subject: [RFC][PATCH 2/3] ARM: dts: vf610-twr: Enable Freescale FlexTimer Module timer.

Signed-off-by: Xiubo Li <[email protected]>
Cc: Shawn Guo <[email protected]>
Cc: Jingchang Lu <[email protected]>
---
arch/arm/boot/dts/vf610-twr.dts | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index e3a3805..0638847 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -130,6 +130,10 @@
};
};

+&ftm0 {
+ status = "okay";
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
--
1.8.4

2014-04-16 03:03:40

by Xiubo Li

[permalink] [raw]
Subject: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

Signed-off-by: Xiubo Li <[email protected]>
Cc: Shawn Guo <[email protected]>
Cc: Jingchang Lu <[email protected]>
---
arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 107e2c0..c3a276f 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -153,6 +153,19 @@
clock-names = "pit";
};

+ ftm0: ftm@40038000 {
+ compatible = "fsl,vf610-ftm-timer";
+ reg = <0x40038000 0x2000>;
+ interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "ftm0", "ftm1",
+ "ftm0_counter_en", "ftm1_counter_en";
+ clocks = <&clks VF610_CLK_FTM0>,
+ <&clks VF610_CLK_FTM1>,
+ <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
+ <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
+ status = "disabled";
+ };
+
wdog@4003e000 {
compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
--
1.8.4

2014-04-16 03:18:49

by Wang Dongsheng

[permalink] [raw]
Subject: RE: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support



> -----Original Message-----
> From: Xiubo Li [mailto:[email protected]]
> Sent: Wednesday, April 16, 2014 10:20 AM
> To: [email protected]; [email protected]; [email protected]; Lu
> Jingchang-B35083; Jin Zhengxiong-R64188; Wang Dongsheng-B40534
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Xiubo Li-B47053
> Subject: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM)
> timer support
>
> The Freescale FlexTimer Module time reference is a 16-bit counter
> that can be used as an unsigned or signed counter.one 16-bits
> increase counter.
>
> Here using the FTM0 as clock event device and the FTM1 as clock
> source device.
>
> Signed-off-by: Xiubo Li <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Jingchang Lu <[email protected]>
> ---
> drivers/clocksource/Kconfig | 5 +
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/fsl_ftm_timer.c | 238 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 244 insertions(+)
> create mode 100644 drivers/clocksource/fsl_ftm_timer.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cd6950f..28321c5 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -136,6 +136,11 @@ config CLKSRC_SAMSUNG_PWM
> for all devicetree enabled platforms. This driver will be
> needed only on systems that do not have the Exynos MCT available.
>
> +config FSL_FTM_TIMER
> + bool
> + help
> + Support for Freescale FlexTimer Module (FTM) timer.
> +
> config VF_PIT_TIMER
> bool
> help
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index c7ca50a..ce0a967 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
> obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
> obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
> obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
> +obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
> obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
>
> obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
> diff --git a/drivers/clocksource/fsl_ftm_timer.c
> b/drivers/clocksource/fsl_ftm_timer.c
> new file mode 100644
> index 0000000..988449e
> --- /dev/null
> +++ b/drivers/clocksource/fsl_ftm_timer.c
> @@ -0,0 +1,238 @@
> +/*
> + * Freescale FlexTimer Module (FTM) timer driver.
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/sched_clock.h>
> +
> +#define FTM_OFFSET(n) (0x1000 * n)
> +
> +#define FTM_SC 0x00
> +#define FTM_SC_CLK_SHIFT 3
> +#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
> +#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
> +#define FTM_SC_PS_MASK 0x7
> +#define FTM_SC_TOIE BIT(6)
> +#define FTM_SC_TOF BIT(7)
> +
> +#define FTM_CNT 0x04
> +#define FTM_MOD 0x08
> +
> +#define FTM_CSC_BASE 0x0C
> +#define FTM_CSC_MSB BIT(5)
> +#define FTM_CSC_MSA BIT(4)
> +#define FTM_CSC_ELSB BIT(3)
> +#define FTM_CSC_ELSA BIT(2)
> +
> +#define FTM_CV_BASE 0x10
> +#define FTM_CNTIN 0x4C
> +#define FTM_STATUS 0x50
> +
> +#define FTM_MODE 0x54
> +#define FTM_MODE_FTMEN BIT(0)
> +#define FTM_MODE_WPDIS BIT(2)
> +#define FTM_MODE_PWMSYNC BIT(3)
> +
> +#define FTM_SYNC 0x58
> +#define FTM_OUTINIT 0x5C
> +#define FTM_OUTMASK 0x60
> +#define FTM_COMBINE 0x64
> +#define FTM_DEADTIME 0x68
> +#define FTM_EXTTRIG 0x6C
> +#define FTM_POL 0x70
> +#define FTM_FMS 0x74
> +#define FTM_FILTER 0x78
> +#define FTM_FLTCTRL 0x7C
> +#define FTM_QDCTRL 0x80
> +#define FTM_CONF 0x84
> +#define FTM_FLTPOL 0x88
> +#define FTM_SYNCONF 0x8C
> +#define FTM_INVCTRL 0x90
> +#define FTM_SWOCTRL 0x94
> +#define FTM_PWMLOAD 0x98
> +
> +static void __iomem *clksrc_base;
> +static void __iomem *clkevt_base;
> +static unsigned long peroidic_cyc;
> +
> +static inline void __init ftm_timer_enable(void __iomem *base)
> +{
> + u32 val;
> +
> + /* select and enable counter clock source */
> + val = __raw_readl(base + FTM_SC);
> + val &= ~FTM_SC_CLK_MASK;
> + val |= FTM_SC_CLK(1);
> + __raw_writel(val, base + FTM_SC);
> +}
> +
> +static u64 ftm_read_sched_clock(void)
> +{
> + return __raw_readl(clksrc_base + FTM_CNT);
> +}
> +
> +static int __init ftm_clocksource_init(unsigned long freq)
> +{
> + int ret;
> +
> + __raw_writel(0x00, clksrc_base + FTM_CNTIN);
> + __raw_writel(~0UL, clksrc_base + FTM_MOD);
> + __raw_writel(0x1, clksrc_base + FTM_CNT);
> +
> + sched_clock_register(ftm_read_sched_clock, 16, freq);
> + ret = clocksource_mmio_init(clksrc_base + FTM_CNT, "fsl-ftm",
> + freq, 300, 16, clocksource_mmio_readl_up);
> + if (ret)
> + return ret;
> +
> + ftm_timer_enable(clksrc_base);
> +
> + return 0;
> +}
> +
> +static inline void ftm_irq_acknowledge(void)
> +{
> + u32 val;
> +
> + val = __raw_readl(clkevt_base + FTM_SC);
> + val &= ~FTM_SC_TOF;
> + __raw_writel(val, clkevt_base + FTM_SC);
> +}
> +
> +static int ftm_set_next_event(unsigned long delta,
> + struct clock_event_device *unused)
> +{
> + __raw_writel(delta, clkevt_base + FTM_MOD);
> +
> + return 0;
> +}
> +
> +static void ftm_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + ftm_set_next_event(peroidic_cyc, evt);
> + break;
> + default:
> + break;

Remove this break;

> + }
> +}
> +
> +static irqreturn_t ftm_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = dev_id;
> +
> + ftm_irq_acknowledge();
> +
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct clock_event_device clockevent_ftm = {
> + .name = "Freescale ftm timer",
> + .features = CLOCK_EVT_FEAT_PERIODIC,
> + .set_mode = ftm_set_mode,
> + .set_next_event = ftm_set_next_event,
> + .rating = 300,
> +};
> +
> +static struct irqaction ftm_timer_irq = {
> + .name = "Freescale ftm timer",
> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
> + .handler = ftm_timer_interrupt,
> + .dev_id = &clockevent_ftm,
> +};
> +
> +static int __init ftm_clockevent_init(unsigned long freq, int irq)
> +{
> + u32 val;
> +
> + __raw_writel(0x00, clkevt_base + FTM_CNTIN);
> + __raw_writel(~0UL, clkevt_base + FTM_MOD);
> + __raw_writel(0x1, clksrc_base + FTM_CNT);
> +
> + val = __raw_readl(clkevt_base + FTM_SC);
> + val |= FTM_SC_TOIE;
> + __raw_writel(val, clkevt_base + FTM_SC);
> +
> + BUG_ON(setup_irq(irq, &ftm_timer_irq));
> +
> + clockevent_ftm.cpumask = cpumask_of(0);
> + clockevent_ftm.irq = irq;
> +
> + clockevents_config_and_register(&clockevent_ftm, freq, 1, 0xffff);
> +
> + ftm_timer_enable(clkevt_base);
> +
> + return 0;
> +}
> +
> +static void __init calc_closest_cound_cyc(unsigned long freq)
> +{
> + unsigned long ps = 0;
> +
> + do {
> + peroidic_cyc = DIV_ROUND_CLOSEST(freq, HZ * (1 << ps++));
> + } while (peroidic_cyc > 0xFFFF);
> +
> +}
> +
> +static void __init ftm_timer_init(struct device_node *np)
> +{
> + struct clk *ftm_clk;
> + void __iomem *timer_base;
> + unsigned long freq;
> + int irq;
> +
> + timer_base = of_iomap(np, 0);
> + BUG_ON(!timer_base);
> +
> + clksrc_base = timer_base + FTM_OFFSET(1);
> + clkevt_base = timer_base + FTM_OFFSET(0);
> +
> + irq = irq_of_parse_and_map(np, 0);
> + BUG_ON(irq <= 0);
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm0_counter_en");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm1_counter_en");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm0");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm1");

Why dts is not have ftm1 node?

Regards,
-Dongsheng

> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + freq = clk_get_rate(ftm_clk);
> +
> + calc_closest_cound_cyc(freq);
> +
> + BUG_ON(ftm_clocksource_init(freq));
> +
> + BUG_ON(ftm_clockevent_init(freq, irq));
> +}
> +CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-ftm-timer", ftm_timer_init);
> --
> 1.8.4
>

2014-04-16 03:46:20

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support

[...]
> > +static void ftm_set_mode(enum clock_event_mode mode,
> > + struct clock_event_device *evt)
> > +{
> > + switch (mode) {
> > + case CLOCK_EVT_MODE_PERIODIC:
> > + ftm_set_next_event(peroidic_cyc, evt);
> > + break;
> > + default:
> > + break;
>
> Remove this break;
>

I'll revise this.


> > + }
> > +}


[...]
> > +static void __init ftm_timer_init(struct device_node *np)
> > +{
> > + struct clk *ftm_clk;
> > + void __iomem *timer_base;
> > + unsigned long freq;
> > + int irq;
> > +
> > + timer_base = of_iomap(np, 0);
> > + BUG_ON(!timer_base);
> > +
> > + clksrc_base = timer_base + FTM_OFFSET(1);
> > + clkevt_base = timer_base + FTM_OFFSET(0);
> > +
> > + irq = irq_of_parse_and_map(np, 0);
> > + BUG_ON(irq <= 0);
> > +
> > + ftm_clk = of_clk_get_by_name(np, "ftm0_counter_en");
> > + BUG_ON(IS_ERR(ftm_clk));
> > + BUG_ON(clk_prepare_enable(ftm_clk));
> > +
> > + ftm_clk = of_clk_get_by_name(np, "ftm1_counter_en");
> > + BUG_ON(IS_ERR(ftm_clk));
> > + BUG_ON(clk_prepare_enable(ftm_clk));
> > +
> > + ftm_clk = of_clk_get_by_name(np, "ftm0");
> > + BUG_ON(IS_ERR(ftm_clk));
> > + BUG_ON(clk_prepare_enable(ftm_clk));
> > +
> > + ftm_clk = of_clk_get_by_name(np, "ftm1");
>
> Why dts is not have ftm1 node?
>

Because the 'ftm0: ftm@40038000' node is used to ftm0
and ftm1 device nodes at the same time.

May using 'ftm: ftm@40038000' will be much better ?

Thanks,

BRs
Xiubo


2014-04-16 04:01:06

by Wang Dongsheng

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.



> -----Original Message-----
> From: Xiubo Li [mailto:[email protected]]
> Sent: Wednesday, April 16, 2014 10:20 AM
> To: [email protected]; [email protected]; [email protected]; Lu
> Jingchang-B35083; Jin Zhengxiong-R64188; Wang Dongsheng-B40534
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Xiubo Li-B47053
> Subject: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer
> node.
>
> Signed-off-by: Xiubo Li <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Jingchang Lu <[email protected]>
> ---
> arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> index 107e2c0..c3a276f 100644
> --- a/arch/arm/boot/dts/vf610.dtsi
> +++ b/arch/arm/boot/dts/vf610.dtsi
> @@ -153,6 +153,19 @@
> clock-names = "pit";
> };
>
> + ftm0: ftm@40038000 {
> + compatible = "fsl,vf610-ftm-timer";
> + reg = <0x40038000 0x2000>;
> + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> + clock-names = "ftm0", "ftm1",
> + "ftm0_counter_en", "ftm1_counter_en";
> + clocks = <&clks VF610_CLK_FTM0>,
> + <&clks VF610_CLK_FTM1>,
> + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> + status = "disabled";
> + };
> +

They need to be separated. ftm0, ftm1.

> wdog@4003e000 {
> compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> reg = <0x4003e000 0x1000>;
> --
> 1.8.4
>

2014-04-16 06:08:50

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

> > --- a/arch/arm/boot/dts/vf610.dtsi
> > +++ b/arch/arm/boot/dts/vf610.dtsi
> > @@ -153,6 +153,19 @@
> > clock-names = "pit";
> > };
> >
> > + ftm0: ftm@40038000 {
> > + compatible = "fsl,vf610-ftm-timer";
> > + reg = <0x40038000 0x2000>;
> > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > + clock-names = "ftm0", "ftm1",
> > + "ftm0_counter_en", "ftm1_counter_en";
> > + clocks = <&clks VF610_CLK_FTM0>,
> > + <&clks VF610_CLK_FTM1>,
> > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > + status = "disabled";
> > + };
> > +
>
> They need to be separated. ftm0, ftm1.
>

Well, if so the driver will adjust much more to and I do think one dts
Node is okey.

The dts patches of this series are just for testing and reference for
The timer driver on Vybrid-twr.

Thanks,

BRs
Xiubo

> > wdog@4003e000 {
> > compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> > reg = <0x4003e000 0x1000>;
> > --
> > 1.8.4
> >

2014-04-16 09:00:12

by Shawn Guo

[permalink] [raw]
Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

On Wed, Apr 16, 2014 at 10:19:45AM +0800, Xiubo Li wrote:
> Signed-off-by: Xiubo Li <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Jingchang Lu <[email protected]>
> ---
> arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> index 107e2c0..c3a276f 100644
> --- a/arch/arm/boot/dts/vf610.dtsi
> +++ b/arch/arm/boot/dts/vf610.dtsi
> @@ -153,6 +153,19 @@
> clock-names = "pit";
> };
>
> + ftm0: ftm@40038000 {
> + compatible = "fsl,vf610-ftm-timer";
> + reg = <0x40038000 0x2000>;
> + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> + clock-names = "ftm0", "ftm1",
> + "ftm0_counter_en", "ftm1_counter_en";
> + clocks = <&clks VF610_CLK_FTM0>,
> + <&clks VF610_CLK_FTM1>,
> + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> + status = "disabled";

For such completely internal block which has no pins route out on board,
we should probably just not have this "disabled" status line.

Shawn

> + };
> +
> wdog@4003e000 {
> compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> reg = <0x4003e000 0x1000>;
> --
> 1.8.4
>
>

2014-04-16 09:07:45

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

On 04/16/2014 04:19 AM, Xiubo Li wrote:
> Signed-off-by: Xiubo Li <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Jingchang Lu <[email protected]>

That deserves a patch description and an update of the documentation.

Thanks
-- Daniel

> ---
> arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> index 107e2c0..c3a276f 100644
> --- a/arch/arm/boot/dts/vf610.dtsi
> +++ b/arch/arm/boot/dts/vf610.dtsi
> @@ -153,6 +153,19 @@
> clock-names = "pit";
> };
>
> + ftm0: ftm@40038000 {
> + compatible = "fsl,vf610-ftm-timer";
> + reg = <0x40038000 0x2000>;
> + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> + clock-names = "ftm0", "ftm1",
> + "ftm0_counter_en", "ftm1_counter_en";
> + clocks = <&clks VF610_CLK_FTM0>,
> + <&clks VF610_CLK_FTM1>,
> + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> + status = "disabled";
> + };
> +
> wdog@4003e000 {
> compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> reg = <0x4003e000 0x1000>;
>


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

2014-04-16 09:38:40

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

> Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module
> timer node.
>
> On 04/16/2014 04:19 AM, Xiubo Li wrote:
> > Signed-off-by: Xiubo Li <[email protected]>
> > Cc: Shawn Guo <[email protected]>
> > Cc: Jingchang Lu <[email protected]>
>
> That deserves a patch description and an update of the documentation.
>

Yes, I'll add this.


Thanks,

BRs
Xiubo


> Thanks
> -- Daniel
>
> > ---
> > arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
> > 1 file changed, 13 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> > index 107e2c0..c3a276f 100644
> > --- a/arch/arm/boot/dts/vf610.dtsi
> > +++ b/arch/arm/boot/dts/vf610.dtsi
> > @@ -153,6 +153,19 @@
> > clock-names = "pit";
> > };
> >
> > + ftm0: ftm@40038000 {
> > + compatible = "fsl,vf610-ftm-timer";
> > + reg = <0x40038000 0x2000>;
> > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > + clock-names = "ftm0", "ftm1",
> > + "ftm0_counter_en", "ftm1_counter_en";
> > + clocks = <&clks VF610_CLK_FTM0>,
> > + <&clks VF610_CLK_FTM1>,
> > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > + status = "disabled";
> > + };
> > +
> > wdog@4003e000 {
> > compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> > reg = <0x4003e000 0x1000>;
> >
>
>
> --
> <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
>
>

????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-04-16 09:40:16

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.


> Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module
> timer node.
>
> On Wed, Apr 16, 2014 at 10:19:45AM +0800, Xiubo Li wrote:
> > Signed-off-by: Xiubo Li <[email protected]>
> > Cc: Shawn Guo <[email protected]>
> > Cc: Jingchang Lu <[email protected]>
> > ---
> > arch/arm/boot/dts/vf610.dtsi | 13 +++++++++++++
> > 1 file changed, 13 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> > index 107e2c0..c3a276f 100644
> > --- a/arch/arm/boot/dts/vf610.dtsi
> > +++ b/arch/arm/boot/dts/vf610.dtsi
> > @@ -153,6 +153,19 @@
> > clock-names = "pit";
> > };
> >
> > + ftm0: ftm@40038000 {
> > + compatible = "fsl,vf610-ftm-timer";
> > + reg = <0x40038000 0x2000>;
> > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > + clock-names = "ftm0", "ftm1",
> > + "ftm0_counter_en", "ftm1_counter_en";
> > + clocks = <&clks VF610_CLK_FTM0>,
> > + <&clks VF610_CLK_FTM1>,
> > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > + status = "disabled";
>
> For such completely internal block which has no pins route out on board,
> we should probably just not have this "disabled" status line.
>

Yes, I'll fix it.

Thanks,

BRs
Xiubo


> Shawn
>
> > + };
> > +
> > wdog@4003e000 {
> > compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
> > reg = <0x4003e000 0x1000>;
> > --
> > 1.8.4
> >
> >

2014-04-17 07:49:36

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

> > + ftm0: ftm@40038000 {
> > + compatible = "fsl,vf610-ftm-timer";
> > + reg = <0x40038000 0x2000>;
> > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > + clock-names = "ftm0", "ftm1",
> > + "ftm0_counter_en", "ftm1_counter_en";
> > + clocks = <&clks VF610_CLK_FTM0>,
> > + <&clks VF610_CLK_FTM1>,
> > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > + status = "disabled";
>
> For such completely internal block which has no pins route out on board,
> we should probably just not have this "disabled" status line.
>

Well, from IEEE 1275, there defined a standard 'status' property indicating
The operational status of one device. The 'status' property has four possible
values: 'okay/ok', 'disabled', 'fail' and 'fail-xxx'.

If it is absent, that means the status of the device is unknown or okay.

If discard the status line here in vf610.dtsi, this device will be enabled
as default though 'no pins route out' on the board, and actually there has
pins route out on the board, as timer devices here we just not use it, but
as PWM devices the pins will be used.

How about let the node disabled in vf610.dtsi, and then enable it in vf610-twr.dts
if it will be used in TWR board... ?

Thanks,

BRs
Xiubo

2014-04-17 08:22:54

by Shawn Guo

[permalink] [raw]
Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

On Thu, Apr 17, 2014 at 07:49:31AM +0000, [email protected] wrote:
> > > + ftm0: ftm@40038000 {
> > > + compatible = "fsl,vf610-ftm-timer";
> > > + reg = <0x40038000 0x2000>;
> > > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > > + clock-names = "ftm0", "ftm1",
> > > + "ftm0_counter_en", "ftm1_counter_en";
> > > + clocks = <&clks VF610_CLK_FTM0>,
> > > + <&clks VF610_CLK_FTM1>,
> > > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > > + status = "disabled";
> >
> > For such completely internal block which has no pins route out on board,
> > we should probably just not have this "disabled" status line.
> >
>
> Well, from IEEE 1275, there defined a standard 'status' property indicating
> The operational status of one device. The 'status' property has four possible
> values: 'okay/ok', 'disabled', 'fail' and 'fail-xxx'.
>
> If it is absent, that means the status of the device is unknown or okay.

Yes, missing 'disabled' status equals to a 'okay' status from Linux
implementation. Then, the device is always available in device tree,
and Linux Kconfig option will control whether the driver for the device
is enabled.

>
> If discard the status line here in vf610.dtsi, this device will be enabled
> as default though 'no pins route out' on the board, and actually there has
> pins route out on the board, as timer devices here we just not use it, but
> as PWM devices the pins will be used.
>
> How about let the node disabled in vf610.dtsi, and then enable it in vf610-twr.dts
> if it will be used in TWR board... ?

Okay. If there is some use cases that have board level configuration
like pin out, I'm fine with your existing code.

Shawn

2014-04-17 08:34:56

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module timer node.

> Subject: Re: [RFC][PATCH 1/3] ARM: dts: vf610: Add Freescale FlexTimer Module
> timer node.
>
> On Thu, Apr 17, 2014 at 07:49:31AM +0000, [email protected] wrote:
> > > > + ftm0: ftm@40038000 {
> > > > + compatible = "fsl,vf610-ftm-timer";
> > > > + reg = <0x40038000 0x2000>;
> > > > + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
> > > > + clock-names = "ftm0", "ftm1",
> > > > + "ftm0_counter_en", "ftm1_counter_en";
> > > > + clocks = <&clks VF610_CLK_FTM0>,
> > > > + <&clks VF610_CLK_FTM1>,
> > > > + <&clks VF610_CLK_FTM0_EXT_FIX_EN>,
> > > > + <&clks VF610_CLK_FTM1_EXT_FIX_EN>;
> > > > + status = "disabled";
> > >
> > > For such completely internal block which has no pins route out on board,
> > > we should probably just not have this "disabled" status line.
> > >
> >
> > Well, from IEEE 1275, there defined a standard 'status' property indicating
> > The operational status of one device. The 'status' property has four
> possible
> > values: 'okay/ok', 'disabled', 'fail' and 'fail-xxx'.
> >
> > If it is absent, that means the status of the device is unknown or okay.
>
> Yes, missing 'disabled' status equals to a 'okay' status from Linux
> implementation. Then, the device is always available in device tree,
> and Linux Kconfig option will control whether the driver for the device
> is enabled.
>
> >
> > If discard the status line here in vf610.dtsi, this device will be enabled
> > as default though 'no pins route out' on the board, and actually there has
> > pins route out on the board, as timer devices here we just not use it, but
> > as PWM devices the pins will be used.
> >
> > How about let the node disabled in vf610.dtsi, and then enable it in vf610-
> twr.dts
> > if it will be used in TWR board... ?
>
> Okay. If there is some use cases that have board level configuration
> like pin out, I'm fine with your existing code.
>

@Shawn,

I'll send the v2 patch series of this.

Thanks very much for your comments.

BRs
Xiubo



> Shawn

2014-04-17 14:22:43

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support

On 04/16/2014 04:19 AM, Xiubo Li wrote:
> The Freescale FlexTimer Module time reference is a 16-bit counter
> that can be used as an unsigned or signed counter.one 16-bits
> increase counter.
>
> Here using the FTM0 as clock event device and the FTM1 as clock
> source device.

As it is a new driver, please add a more elaborated description of the
timer.

> Signed-off-by: Xiubo Li <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Jingchang Lu <[email protected]>
> ---
> drivers/clocksource/Kconfig | 5 +
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/fsl_ftm_timer.c | 238 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 244 insertions(+)
> create mode 100644 drivers/clocksource/fsl_ftm_timer.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cd6950f..28321c5 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -136,6 +136,11 @@ config CLKSRC_SAMSUNG_PWM
> for all devicetree enabled platforms. This driver will be
> needed only on systems that do not have the Exynos MCT available.
>
> +config FSL_FTM_TIMER
> + bool
> + help
> + Support for Freescale FlexTimer Module (FTM) timer.
> +
> config VF_PIT_TIMER
> bool
> help
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index c7ca50a..ce0a967 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
> obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
> obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
> obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
> +obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
> obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
>
> obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
> diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
> new file mode 100644
> index 0000000..988449e
> --- /dev/null
> +++ b/drivers/clocksource/fsl_ftm_timer.c
> @@ -0,0 +1,238 @@
> +/*
> + * Freescale FlexTimer Module (FTM) timer driver.
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/sched_clock.h>

Could you check all these headers are effectively needed ?

> +#define FTM_OFFSET(n) (0x1000 * n)
> +
> +#define FTM_SC 0x00
> +#define FTM_SC_CLK_SHIFT 3
> +#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
> +#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
> +#define FTM_SC_PS_MASK 0x7
> +#define FTM_SC_TOIE BIT(6)
> +#define FTM_SC_TOF BIT(7)
> +
> +#define FTM_CNT 0x04
> +#define FTM_MOD 0x08
> +
> +#define FTM_CSC_BASE 0x0C
> +#define FTM_CSC_MSB BIT(5)
> +#define FTM_CSC_MSA BIT(4)
> +#define FTM_CSC_ELSB BIT(3)
> +#define FTM_CSC_ELSA BIT(2)
> +
> +#define FTM_CV_BASE 0x10
> +#define FTM_CNTIN 0x4C
> +#define FTM_STATUS 0x50
> +
> +#define FTM_MODE 0x54
> +#define FTM_MODE_FTMEN BIT(0)
> +#define FTM_MODE_WPDIS BIT(2)
> +#define FTM_MODE_PWMSYNC BIT(3)
> +
> +#define FTM_SYNC 0x58
> +#define FTM_OUTINIT 0x5C
> +#define FTM_OUTMASK 0x60
> +#define FTM_COMBINE 0x64
> +#define FTM_DEADTIME 0x68
> +#define FTM_EXTTRIG 0x6C
> +#define FTM_POL 0x70
> +#define FTM_FMS 0x74
> +#define FTM_FILTER 0x78
> +#define FTM_FLTCTRL 0x7C
> +#define FTM_QDCTRL 0x80
> +#define FTM_CONF 0x84
> +#define FTM_FLTPOL 0x88
> +#define FTM_SYNCONF 0x8C
> +#define FTM_INVCTRL 0x90
> +#define FTM_SWOCTRL 0x94
> +#define FTM_PWMLOAD 0x98

Please remove the unused macros.

> +
> +static void __iomem *clksrc_base;
> +static void __iomem *clkevt_base;
> +static unsigned long peroidic_cyc;
> +
> +static inline void __init ftm_timer_enable(void __iomem *base)
> +{
> + u32 val;
> +
> + /* select and enable counter clock source */
> + val = __raw_readl(base + FTM_SC);
> + val &= ~FTM_SC_CLK_MASK;
> + val |= FTM_SC_CLK(1);
> + __raw_writel(val, base + FTM_SC);
> +}
> +
> +static u64 ftm_read_sched_clock(void)
> +{
> + return __raw_readl(clksrc_base + FTM_CNT);
> +}
> +
> +static int __init ftm_clocksource_init(unsigned long freq)
> +{
> + int ret;
> +
> + __raw_writel(0x00, clksrc_base + FTM_CNTIN);
> + __raw_writel(~0UL, clksrc_base + FTM_MOD);
> + __raw_writel(0x1, clksrc_base + FTM_CNT);
> +
> + sched_clock_register(ftm_read_sched_clock, 16, freq);
> + ret = clocksource_mmio_init(clksrc_base + FTM_CNT, "fsl-ftm",
> + freq, 300, 16, clocksource_mmio_readl_up);
> + if (ret)
> + return ret;
> +
> + ftm_timer_enable(clksrc_base);
> +
> + return 0;
> +}
> +
> +static inline void ftm_irq_acknowledge(void)
> +{
> + u32 val;
> +
> + val = __raw_readl(clkevt_base + FTM_SC);
> + val &= ~FTM_SC_TOF;
> + __raw_writel(val, clkevt_base + FTM_SC);
> +}
> +
> +static int ftm_set_next_event(unsigned long delta,
> + struct clock_event_device *unused)
> +{
> + __raw_writel(delta, clkevt_base + FTM_MOD);
> +
> + return 0;
> +}
> +
> +static void ftm_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + ftm_set_next_event(peroidic_cyc, evt);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +static irqreturn_t ftm_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = dev_id;
> +
> + ftm_irq_acknowledge();
> +
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct clock_event_device clockevent_ftm = {
> + .name = "Freescale ftm timer",
> + .features = CLOCK_EVT_FEAT_PERIODIC,
> + .set_mode = ftm_set_mode,
> + .set_next_event = ftm_set_next_event,
> + .rating = 300,
> +};
> +
> +static struct irqaction ftm_timer_irq = {
> + .name = "Freescale ftm timer",
> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
> + .handler = ftm_timer_interrupt,
> + .dev_id = &clockevent_ftm,
> +};
> +
> +static int __init ftm_clockevent_init(unsigned long freq, int irq)
> +{
> + u32 val;
> +
> + __raw_writel(0x00, clkevt_base + FTM_CNTIN);
> + __raw_writel(~0UL, clkevt_base + FTM_MOD);
> + __raw_writel(0x1, clksrc_base + FTM_CNT);
> +
> + val = __raw_readl(clkevt_base + FTM_SC);
> + val |= FTM_SC_TOIE;
> + __raw_writel(val, clkevt_base + FTM_SC);
> +
> + BUG_ON(setup_irq(irq, &ftm_timer_irq));
> +
> + clockevent_ftm.cpumask = cpumask_of(0);
> + clockevent_ftm.irq = irq;
> +
> + clockevents_config_and_register(&clockevent_ftm, freq, 1, 0xffff);
> +
> + ftm_timer_enable(clkevt_base);
> +
> + return 0;
> +}
> +
> +static void __init calc_closest_cound_cyc(unsigned long freq)
> +{
> + unsigned long ps = 0;
> +
> + do {
> + peroidic_cyc = DIV_ROUND_CLOSEST(freq, HZ * (1 << ps++));
> + } while (peroidic_cyc > 0xFFFF);
> +
> +}
> +
> +static void __init ftm_timer_init(struct device_node *np)
> +{
> + struct clk *ftm_clk;
> + void __iomem *timer_base;
> + unsigned long freq;
> + int irq;
> +
> + timer_base = of_iomap(np, 0);
> + BUG_ON(!timer_base);
> +
> + clksrc_base = timer_base + FTM_OFFSET(1);
> + clkevt_base = timer_base + FTM_OFFSET(0);
> +
> + irq = irq_of_parse_and_map(np, 0);
> + BUG_ON(irq <= 0);
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm0_counter_en");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm1_counter_en");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm0");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + ftm_clk = of_clk_get_by_name(np, "ftm1");
> + BUG_ON(IS_ERR(ftm_clk));
> + BUG_ON(clk_prepare_enable(ftm_clk));
> +
> + freq = clk_get_rate(ftm_clk);
> +
> + calc_closest_cound_cyc(freq);
> +
> + BUG_ON(ftm_clocksource_init(freq));
> +
> + BUG_ON(ftm_clockevent_init(freq, irq));
> +}
> +CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-ftm-timer", ftm_timer_init);


I am not a big fan of those BUG_ON every line. Could you please replace
it by dev_err().

That is also not in the logic of a single zImage.

Thanks
-- 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

2014-04-18 03:47:29

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support

> > Here using the FTM0 as clock event device and the FTM1 as clock
> > source device.
>
> As it is a new driver, please add a more elaborated description of the
> timer.
>

Please see the next version.


> > +#include <linux/clk.h>
> > +#include <linux/clockchips.h>
> > +#include <linux/clocksource.h>
> > +#include <linux/err.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/sched_clock.h>
>
> Could you check all these headers are effectively needed ?
>

Yes, I will.



> > +#define FTM_OFFSET(n) (0x1000 * n)
> > +
> > +#define FTM_SC 0x00
> > +#define FTM_SC_CLK_SHIFT 3
> > +#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
> > +#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
> > +#define FTM_SC_PS_MASK 0x7
> > +#define FTM_SC_TOIE BIT(6)
> > +#define FTM_SC_TOF BIT(7)
> > +
> > +#define FTM_CNT 0x04
> > +#define FTM_MOD 0x08
> > +
> > +#define FTM_CSC_BASE 0x0C
> > +#define FTM_CSC_MSB BIT(5)
> > +#define FTM_CSC_MSA BIT(4)
> > +#define FTM_CSC_ELSB BIT(3)
> > +#define FTM_CSC_ELSA BIT(2)
> > +
> > +#define FTM_CV_BASE 0x10
> > +#define FTM_CNTIN 0x4C
> > +#define FTM_STATUS 0x50
> > +
> > +#define FTM_MODE 0x54
> > +#define FTM_MODE_FTMEN BIT(0)
> > +#define FTM_MODE_WPDIS BIT(2)
> > +#define FTM_MODE_PWMSYNC BIT(3)
> > +
> > +#define FTM_SYNC 0x58
> > +#define FTM_OUTINIT 0x5C
> > +#define FTM_OUTMASK 0x60
> > +#define FTM_COMBINE 0x64
> > +#define FTM_DEADTIME 0x68
> > +#define FTM_EXTTRIG 0x6C
> > +#define FTM_POL 0x70
> > +#define FTM_FMS 0x74
> > +#define FTM_FILTER 0x78
> > +#define FTM_FLTCTRL 0x7C
> > +#define FTM_QDCTRL 0x80
> > +#define FTM_CONF 0x84
> > +#define FTM_FLTPOL 0x88
> > +#define FTM_SYNCONF 0x8C
> > +#define FTM_INVCTRL 0x90
> > +#define FTM_SWOCTRL 0x94
> > +#define FTM_PWMLOAD 0x98
>
> Please remove the unused macros.
>

Okay.


> > +
> > + freq = clk_get_rate(ftm_clk);
> > +
> > + calc_closest_cound_cyc(freq);
> > +
> > + BUG_ON(ftm_clocksource_init(freq));
> > +
> > + BUG_ON(ftm_clockevent_init(freq, irq));
> > +}
> > +CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-ftm-timer", ftm_timer_init);
>
>
> I am not a big fan of those BUG_ON every line. Could you please replace
> it by dev_err().
>
> That is also not in the logic of a single zImage.
>

Yes, if so, I will revise this.


Thanks,

BRs
Xiubo



????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-04-18 03:56:15

by Xiubo Li

[permalink] [raw]
Subject: RE: [RFC][PATCH 3/3] clocksource: Add Freescale FlexTimer Module (FTM) timer support

> > + freq = clk_get_rate(ftm_clk);
> > +
> > + calc_closest_cound_cyc(freq);
> > +
> > + BUG_ON(ftm_clocksource_init(freq));
> > +
> > + BUG_ON(ftm_clockevent_init(freq, irq));
> > +}
> > +CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-ftm-timer", ftm_timer_init);
>
>
> I am not a big fan of those BUG_ON every line. Could you please replace
> it by dev_err().
>

While, for the FlexTimer driver, there hasn't any device creation and
registering, so I'll use pr_err() instead of dev_err()...

Thanks

BRs
Xiubo
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?