Re: [PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
Hi Vladimir, On Thu, 31 May 2018 at 10:36, Vladimir Zapolskiy wrote: > > Hi Clément, > > On 05/30/2018 03:03 PM, Clément Péron wrote: > > From: Colin Didier > > > > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. > > > > Signed-off-by: Colin Didier > > Signed-off-by: Clément Peron > > --- > > [snip] > > > +++ b/drivers/clocksource/timer-imx-epit.c > > @@ -0,0 +1,281 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * i.MX EPIT Timer > > + * > > + * Copyright (C) 2010 Sascha Hauer > > + * Copyright (C) 2018 Colin Didier > > + * Copyright (C) 2018 Clément Péron > > + */ > > + > > +#include > > +#include > > +#include > > The included header above still can be removed. Ok. > > I have no more comments about the code, I will try to find time to > test the driver, but please don't take it as a promise. Regarding the clks, i think the management of the ipg clk in the driver is useless has it is already handled by the imx clk driver. I remove the ipg clk and test it on i.MX6Q. My test is limited to disabled the GPT and enabled the EPIT in the device-tree { status = "disabled"; }; { status = "okay"; }; [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 4.17.0-rc6 (cperon@cperon-Latitude-7490) (gcc version 6.4.1 20170707 (Linaro GCC 6.4-2017.08)) #1 SMP PREEMPT Mon Jun 4 11:13:41 CEST 2018 [0.00] CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] OF: fdt: Machine model: Devialet Aerobase [0.00] Memory policy: Data cache writealloc [0.00] On node 0 totalpages: 262144 [0.00] Normal zone: 2048 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 262144 pages, LIFO batch:31 [0.00] random: get_random_bytes called from start_kernel+0x80/0x398 with crng_init=0 [0.00] percpu: Embedded 16 pages/cpu @(ptrval) s35084 r8192 d22260 u65536 [0.00] pcpu-alloc: s35084 r8192 d22260 u65536 alloc=16*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0.00] Built 1 zonelists, mobility grouping on. Total pages: 260096 [0.00] Kernel command line: console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.4:/opt/nfsroot,v3,tcp ip=dhcp [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Memory: 1029544K/1048576K available (6144K kernel code, 194K rwdata, 1312K rodata, 1024K init, 224K bss, 19032K reserved, 0K cma-reserved) [0.00] Virtual kernel memory layout: [0.00] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 [0.00] Preemptible hierarchical RCU implementation. [0.00] Tasks RCU enabled.\x00 [0.00] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 [0.00] L2C-310 errata 752271 769419 enabled [0.00] L2C-310 enabling early BRESP for Cortex-A9 [0.00] L2C-310 full line of zeros enabled for Cortex-A9 [0.00] L2C-310 ID prefetch enabled, offset 16 lines [0.00] L2C-310 dynamic clock gating enabled, standby mode enabled [0.00] L2C-310 cache controller enabled, 16 ways, 1024 kB [0.00] L2C-310: CACHE_ID 0x41c7, AUX_CTRL 0x76470001 [0.12] sched_clock: 32 bits at 66MHz, resolution 15ns, wraps every 32537631224ns [0.32] clocksource: epit: mask: 0x max_cycles: 0x, max_idle_ns: 28958491609 ns [0.001231] Calibrating delay loop... 1560.57 BogoMIPS (lpj=780288) [0.008161] pid_max: default: 32768 minimum: 301 [0.008336] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.008360] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.009042] CPU: Testing write buffer coherency: ok [0.009506] CPU0: thread -1, cpu 0, socket 0, mpidr 8000 [0.014238] Setting up static identity map for 0x1010 - 0x10100060 [0.015207] Hierarchical SRCU implementation. [0.017208] smp: Bringing up secondary CPUs ... [0.029147] CPU1: thread -1, cpu 1, socket 0, mpidr 8001 [0.041146] CPU2: thread -1, cpu 2, socket 0, mpidr 8002 [0.053146] CPU3: thread -1, cpu 3, socket 0, mpidr 8003 [0.053321] smp: Brought up 1 node, 4 CPUs [0.053340] SMP: Total of 4 processors activated (6303.74 BogoMIPS). [0.053349] CPU: All CPU(s) started in SVC mode. [0.054441] devtmpfs: initialized [0.063770] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 [0.064454] clocksource: jiffies: mask: 0x max_cycles: 0x, max_idle_ns: 1911260446275000 ns [0.064477] futex hash table entries: 1024 (order: 4, 65536 bytes) [0.064742] pinctrl core: initialized pinctrl subsystem [0.066693] NET: Registered protocol family 16 [0.068623] DMA: preallocated 256 KiB pool for atomic
Re: [PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
Hi Vladimir, On Thu, 31 May 2018 at 10:36, Vladimir Zapolskiy wrote: > > Hi Clément, > > On 05/30/2018 03:03 PM, Clément Péron wrote: > > From: Colin Didier > > > > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. > > > > Signed-off-by: Colin Didier > > Signed-off-by: Clément Peron > > --- > > [snip] > > > +++ b/drivers/clocksource/timer-imx-epit.c > > @@ -0,0 +1,281 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * i.MX EPIT Timer > > + * > > + * Copyright (C) 2010 Sascha Hauer > > + * Copyright (C) 2018 Colin Didier > > + * Copyright (C) 2018 Clément Péron > > + */ > > + > > +#include > > +#include > > +#include > > The included header above still can be removed. Ok. > > I have no more comments about the code, I will try to find time to > test the driver, but please don't take it as a promise. Regarding the clks, i think the management of the ipg clk in the driver is useless has it is already handled by the imx clk driver. I remove the ipg clk and test it on i.MX6Q. My test is limited to disabled the GPT and enabled the EPIT in the device-tree { status = "disabled"; }; { status = "okay"; }; [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 4.17.0-rc6 (cperon@cperon-Latitude-7490) (gcc version 6.4.1 20170707 (Linaro GCC 6.4-2017.08)) #1 SMP PREEMPT Mon Jun 4 11:13:41 CEST 2018 [0.00] CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] OF: fdt: Machine model: Devialet Aerobase [0.00] Memory policy: Data cache writealloc [0.00] On node 0 totalpages: 262144 [0.00] Normal zone: 2048 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 262144 pages, LIFO batch:31 [0.00] random: get_random_bytes called from start_kernel+0x80/0x398 with crng_init=0 [0.00] percpu: Embedded 16 pages/cpu @(ptrval) s35084 r8192 d22260 u65536 [0.00] pcpu-alloc: s35084 r8192 d22260 u65536 alloc=16*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0.00] Built 1 zonelists, mobility grouping on. Total pages: 260096 [0.00] Kernel command line: console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.4:/opt/nfsroot,v3,tcp ip=dhcp [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Memory: 1029544K/1048576K available (6144K kernel code, 194K rwdata, 1312K rodata, 1024K init, 224K bss, 19032K reserved, 0K cma-reserved) [0.00] Virtual kernel memory layout: [0.00] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 [0.00] Preemptible hierarchical RCU implementation. [0.00] Tasks RCU enabled.\x00 [0.00] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 [0.00] L2C-310 errata 752271 769419 enabled [0.00] L2C-310 enabling early BRESP for Cortex-A9 [0.00] L2C-310 full line of zeros enabled for Cortex-A9 [0.00] L2C-310 ID prefetch enabled, offset 16 lines [0.00] L2C-310 dynamic clock gating enabled, standby mode enabled [0.00] L2C-310 cache controller enabled, 16 ways, 1024 kB [0.00] L2C-310: CACHE_ID 0x41c7, AUX_CTRL 0x76470001 [0.12] sched_clock: 32 bits at 66MHz, resolution 15ns, wraps every 32537631224ns [0.32] clocksource: epit: mask: 0x max_cycles: 0x, max_idle_ns: 28958491609 ns [0.001231] Calibrating delay loop... 1560.57 BogoMIPS (lpj=780288) [0.008161] pid_max: default: 32768 minimum: 301 [0.008336] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.008360] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.009042] CPU: Testing write buffer coherency: ok [0.009506] CPU0: thread -1, cpu 0, socket 0, mpidr 8000 [0.014238] Setting up static identity map for 0x1010 - 0x10100060 [0.015207] Hierarchical SRCU implementation. [0.017208] smp: Bringing up secondary CPUs ... [0.029147] CPU1: thread -1, cpu 1, socket 0, mpidr 8001 [0.041146] CPU2: thread -1, cpu 2, socket 0, mpidr 8002 [0.053146] CPU3: thread -1, cpu 3, socket 0, mpidr 8003 [0.053321] smp: Brought up 1 node, 4 CPUs [0.053340] SMP: Total of 4 processors activated (6303.74 BogoMIPS). [0.053349] CPU: All CPU(s) started in SVC mode. [0.054441] devtmpfs: initialized [0.063770] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 [0.064454] clocksource: jiffies: mask: 0x max_cycles: 0x, max_idle_ns: 1911260446275000 ns [0.064477] futex hash table entries: 1024 (order: 4, 65536 bytes) [0.064742] pinctrl core: initialized pinctrl subsystem [0.066693] NET: Registered protocol family 16 [0.068623] DMA: preallocated 256 KiB pool for atomic
Re: [PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
Hi Clément, On 05/30/2018 03:03 PM, Clément Péron wrote: > From: Colin Didier > > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. > > Signed-off-by: Colin Didier > Signed-off-by: Clément Peron > --- [snip] > +++ b/drivers/clocksource/timer-imx-epit.c > @@ -0,0 +1,281 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * i.MX EPIT Timer > + * > + * Copyright (C) 2010 Sascha Hauer > + * Copyright (C) 2018 Colin Didier > + * Copyright (C) 2018 Clément Péron > + */ > + > +#include > +#include > +#include The included header above still can be removed. I have no more comments about the code, I will try to find time to test the driver, but please don't take it as a promise. -- With best wishes, Vladimir
Re: [PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
Hi Clément, On 05/30/2018 03:03 PM, Clément Péron wrote: > From: Colin Didier > > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. > > Signed-off-by: Colin Didier > Signed-off-by: Clément Peron > --- [snip] > +++ b/drivers/clocksource/timer-imx-epit.c > @@ -0,0 +1,281 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * i.MX EPIT Timer > + * > + * Copyright (C) 2010 Sascha Hauer > + * Copyright (C) 2018 Colin Didier > + * Copyright (C) 2018 Clément Péron > + */ > + > +#include > +#include > +#include The included header above still can be removed. I have no more comments about the code, I will try to find time to test the driver, but please don't take it as a promise. -- With best wishes, Vladimir
[PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
From: Colin Didier Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. Signed-off-by: Colin Didier Signed-off-by: Clément Peron --- drivers/clocksource/Kconfig | 11 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-imx-epit.c | 281 +++ 3 files changed, 293 insertions(+) create mode 100644 drivers/clocksource/timer-imx-epit.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 8e8a09755d10..790478afd02c 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -576,6 +576,17 @@ config H8300_TPU This enables the clocksource for the H8300 platform with the H8S2678 cpu. +config CLKSRC_IMX_EPIT + bool "Clocksource using i.MX EPIT" + depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST) + select CLKSRC_MMIO + help + This enables EPIT support available on some i.MX platforms. + Normally you don't have a reason to do so as the EPIT has + the same features and uses the same clocks as the GPT. + Anyway, on some systems the GPT may be in use for other + purposes. + config CLKSRC_IMX_GPT bool "Clocksource using i.MX GPT" if COMPILE_TEST depends on ARM && CLKDEV_LOOKUP diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 00caf37e52f9..d9426f69ec69 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o obj-$(CONFIG_CLKSRC_TANGO_XTAL)+= tango_xtal.o +obj-$(CONFIG_CLKSRC_IMX_EPIT) += timer-imx-epit.o obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o obj-$(CONFIG_ASM9260_TIMER)+= asm9260_timer.o diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c new file mode 100644 index ..7e92fcab10d3 --- /dev/null +++ b/drivers/clocksource/timer-imx-epit.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * i.MX EPIT Timer + * + * Copyright (C) 2010 Sascha Hauer + * Copyright (C) 2018 Colin Didier + * Copyright (C) 2018 Clément Péron + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EPITCR 0x00 +#define EPITSR 0x04 +#define EPITLR 0x08 +#define EPITCMPR 0x0c +#define EPITCNR0x10 + +#define EPITCR_EN BIT(0) +#define EPITCR_ENMOD BIT(1) +#define EPITCR_OCIEN BIT(2) +#define EPITCR_RLD BIT(3) +#define EPITCR_PRESC(x)(((x) & 0xfff) << 4) +#define EPITCR_SWR BIT(16) +#define EPITCR_IOVWBIT(17) +#define EPITCR_DBGEN BIT(18) +#define EPITCR_WAITEN BIT(19) +#define EPITCR_RES BIT(20) +#define EPITCR_STOPEN BIT(21) +#define EPITCR_OM_DISCON (0 << 22) +#define EPITCR_OM_TOGGLE (1 << 22) +#define EPITCR_OM_CLEAR(2 << 22) +#define EPITCR_OM_SET (3 << 22) +#define EPITCR_CLKSRC_OFF (0 << 24) +#define EPITCR_CLKSRC_PERIPHERAL (1 << 24) +#define EPITCR_CLKSRC_REF_HIGH (2 << 24) +#define EPITCR_CLKSRC_REF_LOW (3 << 24) + +#define EPITSR_OCIFBIT(0) + +struct epit_timer { + void __iomem *base; + int irq; + struct clk *clk_per; + struct clock_event_device ced; + struct irqaction act; +}; + +static void __iomem *sched_clock_reg; + +static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced) +{ + return container_of(ced, struct epit_timer, ced); +} + +static inline void epit_irq_disable(struct epit_timer *epittm) +{ + u32 val; + + val = readl_relaxed(epittm->base + EPITCR); + writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR); +} + +static inline void epit_irq_enable(struct epit_timer *epittm) +{ + u32 val; + + val = readl_relaxed(epittm->base + EPITCR); + writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR); +} + +static void epit_irq_acknowledge(struct epit_timer *epittm) +{ + writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR); +} + +static u64 notrace epit_read_sched_clock(void) +{ + return ~readl_relaxed(sched_clock_reg); +} + +static int epit_set_next_event(unsigned long cycles, + struct clock_event_device *ced) +{ + struct epit_timer *epittm = to_epit_timer(ced); + unsigned long tcmp; + + tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles; +
[PATCH v4 4/5] clocksource: add driver for i.MX EPIT timer
From: Colin Didier Add driver for NXP's EPIT timer used in i.MX 6 family of SoC. Signed-off-by: Colin Didier Signed-off-by: Clément Peron --- drivers/clocksource/Kconfig | 11 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-imx-epit.c | 281 +++ 3 files changed, 293 insertions(+) create mode 100644 drivers/clocksource/timer-imx-epit.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 8e8a09755d10..790478afd02c 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -576,6 +576,17 @@ config H8300_TPU This enables the clocksource for the H8300 platform with the H8S2678 cpu. +config CLKSRC_IMX_EPIT + bool "Clocksource using i.MX EPIT" + depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST) + select CLKSRC_MMIO + help + This enables EPIT support available on some i.MX platforms. + Normally you don't have a reason to do so as the EPIT has + the same features and uses the same clocks as the GPT. + Anyway, on some systems the GPT may be in use for other + purposes. + config CLKSRC_IMX_GPT bool "Clocksource using i.MX GPT" if COMPILE_TEST depends on ARM && CLKDEV_LOOKUP diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 00caf37e52f9..d9426f69ec69 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o obj-$(CONFIG_CLKSRC_TANGO_XTAL)+= tango_xtal.o +obj-$(CONFIG_CLKSRC_IMX_EPIT) += timer-imx-epit.o obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o obj-$(CONFIG_ASM9260_TIMER)+= asm9260_timer.o diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c new file mode 100644 index ..7e92fcab10d3 --- /dev/null +++ b/drivers/clocksource/timer-imx-epit.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * i.MX EPIT Timer + * + * Copyright (C) 2010 Sascha Hauer + * Copyright (C) 2018 Colin Didier + * Copyright (C) 2018 Clément Péron + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EPITCR 0x00 +#define EPITSR 0x04 +#define EPITLR 0x08 +#define EPITCMPR 0x0c +#define EPITCNR0x10 + +#define EPITCR_EN BIT(0) +#define EPITCR_ENMOD BIT(1) +#define EPITCR_OCIEN BIT(2) +#define EPITCR_RLD BIT(3) +#define EPITCR_PRESC(x)(((x) & 0xfff) << 4) +#define EPITCR_SWR BIT(16) +#define EPITCR_IOVWBIT(17) +#define EPITCR_DBGEN BIT(18) +#define EPITCR_WAITEN BIT(19) +#define EPITCR_RES BIT(20) +#define EPITCR_STOPEN BIT(21) +#define EPITCR_OM_DISCON (0 << 22) +#define EPITCR_OM_TOGGLE (1 << 22) +#define EPITCR_OM_CLEAR(2 << 22) +#define EPITCR_OM_SET (3 << 22) +#define EPITCR_CLKSRC_OFF (0 << 24) +#define EPITCR_CLKSRC_PERIPHERAL (1 << 24) +#define EPITCR_CLKSRC_REF_HIGH (2 << 24) +#define EPITCR_CLKSRC_REF_LOW (3 << 24) + +#define EPITSR_OCIFBIT(0) + +struct epit_timer { + void __iomem *base; + int irq; + struct clk *clk_per; + struct clock_event_device ced; + struct irqaction act; +}; + +static void __iomem *sched_clock_reg; + +static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced) +{ + return container_of(ced, struct epit_timer, ced); +} + +static inline void epit_irq_disable(struct epit_timer *epittm) +{ + u32 val; + + val = readl_relaxed(epittm->base + EPITCR); + writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR); +} + +static inline void epit_irq_enable(struct epit_timer *epittm) +{ + u32 val; + + val = readl_relaxed(epittm->base + EPITCR); + writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR); +} + +static void epit_irq_acknowledge(struct epit_timer *epittm) +{ + writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR); +} + +static u64 notrace epit_read_sched_clock(void) +{ + return ~readl_relaxed(sched_clock_reg); +} + +static int epit_set_next_event(unsigned long cycles, + struct clock_event_device *ced) +{ + struct epit_timer *epittm = to_epit_timer(ced); + unsigned long tcmp; + + tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles; +