[PATCH v5 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
ATCPIT100 is often used on the Andes architecture, This timer provide 4 PIT channels. Each PIT channel is a multi-function timer, can be configured as 32,16,8 bit timers or PWM as well. For system timer it will set channel 1 32-bit timer0 as clock source and count downwards until underflow and restart again. It also set channel 0 32-bit timer0 as clock event and count downwards until condition match. It will generate an interrupt for handling periodically. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu Reviewed-by: Linus Walleij --- drivers/clocksource/Kconfig | 7 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-atcpit100.c | 255 ++ 3 files changed, 263 insertions(+) create mode 100644 drivers/clocksource/timer-atcpit100.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc60620..8c57ef2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -615,4 +615,11 @@ config CLKSRC_ST_LPC Enable this option to use the Low Power controller timer as clocksource. +config CLKSRC_ATCPIT100 + bool "Clocksource for AE3XX platform" + depends on NDS32 || COMPILE_TEST + depends on HAS_IOMEM + help + This option enables support for the Andestech AE3XX platform timers. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 72711f1..7d072f5 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -75,3 +75,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o +obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c new file mode 100644 index 000..0077fdb --- /dev/null +++ b/drivers/clocksource/timer-atcpit100.c @@ -0,0 +1,255 @@ +/* + * Andestech ATCPIT100 Timer Device Driver Implementation + * + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "timer-of.h" + +/* + * Definition of register offsets + */ + +/* ID and Revision Register */ +#define ID_REV 0x0 + +/* Configuration Register */ +#define CFG0x10 + +/* Interrupt Enable Register */ +#define INT_EN 0x14 +#define CH_INT_EN(c, i)((1<event_handler(evt); + + return IRQ_HANDLED; +} + +static struct timer_of to = { + .flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE, + + .clkevt = { + .name = "atcpit100_tick", + .rating = 300, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_state_shutdown = atcpit100_clkevt_shutdown, + .set_state_periodic = atcpit100_clkevt_set_periodic, + .set_state_oneshot = atcpit100_clkevt_set_oneshot, + .tick_resume = atcpit100_clkevt_shutdown, + .set_next_event = atcpit100_clkevt_next_event, + .cpumask = cpu_all_mask, + }, + + .of_irq = { + .handler = atcpit100_timer_interrupt, + .flags = IRQF_TIMER | IRQF_IRQPOLL, + }, + + /* +* FIXME: we currently only support clocking using PCLK +* and using EXTCLK is not supported in the driver. +*/ + .of_clk = { + .name = "PCLK", + } +}; + +static u64 notrace atcpit100_timer_sched_read(void) +{ + return ~readl(timer_of_base(&to) + CH1_CNT); +} + +static int __init atcpit100_timer_init(struct device_node *node) +{ + int ret; + u32 val; + void __iomem *base; + + ret = timer_of_init(node, &to); + if (ret) + return ret; + + base = timer_of_base(&to); + + sched_clock_register(atcpit100_timer_sched_read, 32, + timer_of_rate(&to)); + + ret = clocksource_mmio_init(base + CH1_CNT, + node->name, timer_of_rate(&to), 300, 32, + clocksource_mmio_readl_down); + + if (ret) { + pr_err("Failed to register clocksourc
[PATCH v5 2/3] clocksource/drivers/atcpit100: VDSO support
VDSO needs real-time cycle count to ensure the time accuracy. Unlike others, nds32 architecture does not define clock source, hence VDSO needs atcpit100 offering real-time cycle count to derive the correct time. Signed-off-by: Vincent Chen Signed-off-by: Rick Chen Signed-off-by: Greentime Hu --- drivers/clocksource/timer-atcpit100.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c index 0077fdb..1be6c0a 100644 --- a/drivers/clocksource/timer-atcpit100.c +++ b/drivers/clocksource/timer-atcpit100.c @@ -29,6 +29,9 @@ #include #include #include "timer-of.h" +#ifdef CONFIG_NDS32 +#include +#endif /* * Definition of register offsets @@ -211,6 +214,14 @@ static u64 notrace atcpit100_timer_sched_read(void) return ~readl(timer_of_base(&to) + CH1_CNT); } +#ifdef CONFIG_NDS32 +static void fill_vdso_need_info(void) +{ + timer_info.cycle_count_down = true; + timer_info.cycle_count_reg_offset = CH1_CNT; +} +#endif + static int __init atcpit100_timer_init(struct device_node *node) { int ret; @@ -249,6 +260,10 @@ static int __init atcpit100_timer_init(struct device_node *node) val = readl(base + INT_EN); writel(val | CH0INT0EN, base + INT_EN); +#ifdef CONFIG_NDS32 + fill_vdso_need_info(); +#endif + return ret; } -- 2.7.4
[PATCH v5 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
Add a document to describe Andestech atcpit100 timer and binding information. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu Acked-by: Rob Herring --- .../bindings/timer/andestech,atcpit100-timer.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt new file mode 100644 index 000..14812f68 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt @@ -0,0 +1,33 @@ +Andestech ATCPIT100 timer +-- +ATCPIT100 is a generic IP block from Andes Technology, embedded in +Andestech AE3XX platforms and other designs. + +This timer is a set of compact multi-function timers, which can be +used as pulse width modulators (PWM) as well as simple timers. + +It supports up to 4 PIT channels. Each PIT channel is a +multi-function timer and provide the following usage scenarios: +One 32-bit timer +Two 16-bit timers +Four 8-bit timers +One 16-bit PWM +One 16-bit timer and one 8-bit PWM +Two 8-bit timer and one 8-bit PWM + +Required properties: +- compatible : Should be "andestech,atcpit100" +- reg : Address and length of the register set +- interrupts : Reference to the timer interrupt +- clocks : a clock to provide the tick rate for "andestech,atcpit100" +- clock-names : should be "PCLK" for the peripheral clock source. + +Examples: + +timer0: timer@f040 { + compatible = "andestech,atcpit100"; + reg = <0xf040 0x1000>; + interrupts = <2 4>; + clocks = <&apb>; + clock-names = "PCLK"; +}; -- 2.7.4
[PATCH v5 0/3] Add andestech atcpit100 timer
Changelog v5: - Patch 1/3: Changes - Patch 2/3: New - Patch 3/3: Changes [Patch 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer 1 No need to split out the Makefile patch from the actual driver. Suggested by Arnd Bergmann 2 Add of_clk.name = "PCLK" to be explicit on what we use. Suggested by Linus Walleij 3 Remove the GENERIC_CLOCKEVENTS from Kconfig. Suggested by Daniel Lezcano 4 Add depends on NDS32 || COMPILE_TEST in Kconfig Suggested by Greentime Hu [Patch 2/3] clocksource/drivers/atcpit100: VDSO support Why implemented in timer driver, please see details from https://lkml.org/lkml/2017/12/8/362 [PATCH v3 17/33] nds32: VDSO support. Suggested by Mark Rutland Here Mark Rutlan suggested as below: You should not add properties to arbitrary DT bindings to handle a Linux implementation detail. Please remove this DT code, and have the drivers for those timer blocks export this information to your vdso code somehow. [Patch 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc Fix incorrect description about PCLK. Suggested by Linus Walleij Rick Chen (3): clocksource/drivers/atcpit100: Add andestech atcpit100 timer clocksource/drivers/atcpit100: VDSO support dt-bindings: timer: Add andestech atcpit100 timer binding doc .../bindings/timer/andestech,atcpit100-timer.txt | 33 +++ drivers/clocksource/Kconfig| 7 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-atcpit100.c | 270 + 4 files changed, 311 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt create mode 100644 drivers/clocksource/timer-atcpit100.c -- 2.7.4
[PATCH v4 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
Add a document to describe Andestech atcpit100 timer and binding information. Signed-off-by: Rick Chen Acked-by: Rob Herring Signed-off-by: Greentime Hu --- .../bindings/timer/andestech,atcpit100-timer.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt new file mode 100644 index 000..b97ff32 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt @@ -0,0 +1,33 @@ +Andestech ATCPIT100 timer +-- +ATCPIT100 is a generic IP block from Andes Technology, embedded in +Andestech AE3XX platforms and other designs. + +This timer is a set of compact multi-function timers, which can be +used as pulse width modulators (PWM) as well as simple timers. + +It supports up to 4 PIT channels. Each PIT channel is a +multi-function timer and provide the following usage scenarios: +One 32-bit timer +Two 16-bit timers +Four 8-bit timers +One 16-bit PWM +One 16-bit timer and one 8-bit PWM +Two 8-bit timer and one 8-bit PWM + +Required properties: +- compatible : Should be "andestech,atcpit100" +- reg : Address and length of the register set +- interrupts : Reference to the timer interrupt +- clocks : a clock to provide the tick rate for "andestech,atcpit100" +- clock-names : should be "PCLK" for the external tick timer. + +Examples: + +timer0: timer@f040 { + compatible = "andestech,atcpit100"; + reg = <0xf040 0x1000>; + interrupts = <2 4>; + clocks = <&clk_pll>; + clock-names = "PCLK"; +}; -- 2.7.4
[PATCH v4 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
ATCPIT100 is often used on the Andes architecture, This timer provide 4 PIT channels. Each PIT channel is a multi-function timer, can be configured as 32,16,8 bit timers or PWM as well. For system timer it will set channel 1 32-bit timer0 as clock source and count downwards until underflow and restart again. It also set channel 0 32-bit timer0 as clock event and count downwards until condition match. It will generate an interrupt for handling periodically. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu --- drivers/clocksource/timer-atcpit100.c | 248 ++ 1 file changed, 248 insertions(+) create mode 100644 drivers/clocksource/timer-atcpit100.c diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c new file mode 100644 index 000..fb0a4e4 --- /dev/null +++ b/drivers/clocksource/timer-atcpit100.c @@ -0,0 +1,248 @@ +/* + * Andestech ATCPIT100 Timer Device Driver Implementation + * + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation + + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "timer-of.h" + +/* + * Definition of register offsets + */ + +/* ID and Revision Register */ +#define ID_REV 0x0 + +/* Configuration Register */ +#define CFG0x10 + +/* Interrupt Enable Register */ +#define INT_EN 0x14 +#define CH_INT_EN(c, i)((1<event_handler(evt); + + return IRQ_HANDLED; +} + +static struct timer_of to = { + .flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE, + + .clkevt = { + .name = "atcpit100_tick", + .rating = 300, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_state_shutdown = atcpit100_clkevt_shutdown, + .set_state_periodic = atcpit100_clkevt_set_periodic, + .set_state_oneshot = atcpit100_clkevt_set_oneshot, + .tick_resume = atcpit100_clkevt_shutdown, + .set_next_event = atcpit100_clkevt_next_event, + .cpumask = cpu_all_mask, + }, + + .of_irq = { + .handler = atcpit100_timer_interrupt, + .flags = IRQF_TIMER | IRQF_IRQPOLL, + }, +}; + +static u64 notrace atcpit100_timer_sched_read(void) +{ + return ~readl(timer_of_base(&to) + CH1_CNT); +} + +static int __init atcpit100_timer_init(struct device_node *node) +{ + int ret; + u32 val; + void __iomem *base; + + ret = timer_of_init(node, &to); + if (ret) + return ret; + + base = timer_of_base(&to); + + sched_clock_register(atcpit100_timer_sched_read, 32, + timer_of_rate(&to)); + + ret = clocksource_mmio_init(base + CH1_CNT, + node->name, timer_of_rate(&to), 300, 32, + clocksource_mmio_readl_down); + + if (ret) { + pr_err("Failed to register clocksource\n"); + return ret; + } + + /* clear channel 0 timer0 interrupt */ + atcpit100_timer_clear_interrupt(base); + + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), + TIMER_SYNC_TICKS, 0x); + atcpit100_ch0_tmr0_en(base); + atcpit100_ch1_tmr0_en(base); + atcpit100_clocksource_start(base); + atcpit100_clkevt_time_start(base); + + /* Enable channel 0 timer0 interrupt */ + val = readl(base + INT_EN); + writel(val | CH0INT0EN, base + INT_EN); + + return ret; +} + +TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_timer_init); -- 2.7.4
[PATCH v4 2/3] clocksource/drivers/Kconfig: Support andestech atcpit100 timer
Add CLKSRC_ATCPIT100 for Andestech atcpit100 timer selection. It often be used in Andestech AE3XX platform. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu --- drivers/clocksource/Kconfig | 6 ++ drivers/clocksource/Makefile | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc60620..e950066 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -615,4 +615,10 @@ config CLKSRC_ST_LPC Enable this option to use the Low Power controller timer as clocksource. +config CLKSRC_ATCPIT100 + bool "Clocksource for AE3XX platform" if COMPILE_TEST + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + help + This option enables support for the Andestech AE3XX platform timers. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dbc1ad1..24d15bd 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -74,3 +74,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o +obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o -- 2.7.4
[PATCH v4 0/3] Add andestech atcpit100 timer
Changelog v4: - Patch 1/3: Changes - Patch 2/3: No changes - Patch 3/3: Changes Patch 1/3 1 Pre-compute some definetions 2 Remove PWM relative 3 Refine coding style 4 Wrap some calls into functions 4 Use timer-of API 5 Correct commit content use channel1 timer0 as clock source use channel0 timer0 as clock event Patch 3/3 Remove description about clock-frequency Add clocks description for timer-of API Rick Chen (3): clocksource/drivers/atcpit100: Add andestech atcpit100 timer clocksource/drivers/Kconfig: Support andestech atcpit100 timer dt-bindings: timer: Add andestech atcpit100 timer binding doc .../bindings/timer/andestech,atcpit100-timer.txt | 33 +++ drivers/clocksource/Kconfig| 6 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-atcpit100.c | 248 + 4 files changed, 288 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt create mode 100644 drivers/clocksource/timer-atcpit100.c -- Changelog v3: Patch 1/3 Fix warning from kbuild test robot when make ARCH=x86_64 Patch 3/3 Acked-by: Rob Herring -- Changelog v2: Patch 3/3 1 Add commit msg 2 Change rick to full name Rick Chen 3 MOdify S-o-b 2.7.4
[PATCH v3 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
ATCPIT100 is often used on the Andes architecture, This timer provide 4 PIT channels. Each PIT channel is a multi-function timer, can be configured as 32,16,8 bit timers or PWM as well. For system timer it will set 32-bit timer0 as clock source and count downwards until underflow and restart again. It also set 32-bit timer1 as clock event and count downwards until condition match. It will generate an interrupt for handling periodically. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu --- drivers/clocksource/timer-atcpit100.c | 199 ++ 1 file changed, 199 insertions(+) create mode 100644 drivers/clocksource/timer-atcpit100.c diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c new file mode 100644 index 000..1a5538b --- /dev/null +++ b/drivers/clocksource/timer-atcpit100.c @@ -0,0 +1,199 @@ +/* + * Andestech ATCPIT100 Timer Device Driver Implementation + * + * Copyright (C) 2016 Andes Technology Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void __iomem *base; +static u32 freq; + +/* + * Definition of register offsets + */ + +/* ID and Revision Register */ +#define ID_REV 0x0 + +/* Configuration Register */ +#define CFG0x10 + +/* Interrupt Enable Register */ +#define INT_EN 0x14 +#define CH_INT_EN(c, i)((1<event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction timer1_irq = { + .name = "Timer Tick", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler= timer1_interrupt, + .dev_id = &clockevent_atcpit100 +}; + +static void __init atcpit100_clockevent_init(int irq) +{ + struct clock_event_device *evt = &clockevent_atcpit100; + + evt->mult = div_sc(freq, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0x, evt); + evt->min_delta_ns = clockevent_delta2ns(3, evt); + clockevents_register_device(evt); + setup_irq(irq, &timer1_irq); +} + +static int __init atcpit100_init(struct device_node *dev) +{ + int irq; + + base = of_iomap(dev, 0); + if (!base) { + pr_warn("Can't remap registers"); + return -ENXIO; + } + + if (of_property_read_u32(dev, "clock-frequency", &freq)) { + pr_warn("Can't read clock-frequency"); + return -EINVAL; + } + irq = irq_of_parse_and_map(dev, 0); + + if (irq <= 0) { + pr_warn("Failed to map timer IRQ\n"); + return -EINVAL; + } + pr_info("ATCPIT100 timer 1 installed on IRQ %d, with clock %d at %d HZ. in %p\n", + irq, freq, HZ, base); + writel(APB_CLK|TMR_32, base + CH_CTL(0)); + writel(readl(base + INT_EN) | CH_INT_EN(0, 0), base + INT_EN); + writel(readl(base + CH_EN) | CH_TMR_EN(0, 0), base + CH_EN); + atcpit100_clocksource_init(); + atcpit100_clockevent_init(irq); + + return 0; +} + +TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_init); -- 2.7.4
[PATCH v3 2/3] clocksource/drivers/Kconfig: Support andestech atcpit100 timer
Add CLKSRC_ATCPIT100 for Andestech atcpit100 timer selection. It often be used in Andestech AE3XX platform. Signed-off-by: Rick Chen Signed-off-by: Greentime Hu --- drivers/clocksource/Kconfig | 6 ++ drivers/clocksource/Makefile | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc60620..e950066 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -615,4 +615,10 @@ config CLKSRC_ST_LPC Enable this option to use the Low Power controller timer as clocksource. +config CLKSRC_ATCPIT100 + bool "Clocksource for AE3XX platform" if COMPILE_TEST + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + help + This option enables support for the Andestech AE3XX platform timers. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dbc1ad1..24d15bd 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -74,3 +74,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o +obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o -- 2.7.4
[PATCH v3 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
Add a document to describe Andestech atcpit100 timer and binding information. Signed-off-by: Rick Chen Acked-by: Rob Herring Signed-off-by: Greentime Hu --- .../bindings/timer/andestech,atcpit100-timer.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt new file mode 100644 index 000..a87278a --- /dev/null +++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt @@ -0,0 +1,31 @@ +Andestech ATCPIT100 timer +-- +ATCPIT100 is a generic IP block from Andes Technology, embedded in +Andestech AE3XX platforms and other designs. + +This timer is a set of compact multi-function timers, which can be +used as pulse width modulators (PWM) as well as simple timers. + +It supports up to 4 PIT channels. Each PIT channel is a +multi-function timer and provide the following usage scenarios: +One 32-bit timer +Two 16-bit timers +Four 8-bit timers +One 16-bit PWM +One 16-bit timer and one 8-bit PWM +Two 8-bit timer and one 8-bit PWM + +Required properties: +- compatible : Should be "andestech,atcpit100" +- reg : Address and length of the register set +- interrupts : Reference to the timer interrupt +- clock-frequency : The rate in HZ in input of the Andestech ATCPIT100 timer + +Examples: + +timer0: timer@f040 { + compatible = "andestech,atcpit100"; + reg = <0xf040 0x1000>; + interrupts = <2 4>; + clock-frequency = <3000>; +}; -- 2.7.4
[PATCH v3 0/3] *** Fix warning from kbuild test robot ***
*** Fix warnings when make with ARCH=x86_64 from auto build test *** rick (3): clocksource/drivers/atcpit100: Add andestech atcpit100 timer clocksource/drivers/Kconfig: Support andestech atcpit100 timer dt-bindings: timer: Add andestech atcpit100 timer binding doc .../bindings/timer/andestech,atcpit100-timer.txt | 31 drivers/clocksource/Kconfig| 6 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-atcpit100.c | 199 + 4 files changed, 237 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt create mode 100644 drivers/clocksource/timer-atcpit100.c -- 2.7.4
[PATCH v2 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
ATCPIT100 is often used on the Andes architecture, This timer provide 4 PIT channels. Each PIT channel is a multi-function timer, can be configured as 32,16,8 bit timers or PWM as well. For system timer it will set 32-bit timer0 as clock source and count downwards until underflow and restart again. It also set 32-bit timer1 as clock event and count downwards until condition match. It will generate an interrupt for handling periodically. Signed-off-by: Greentime Hu Signed-off-by: Rick Chen --- drivers/clocksource/timer-atcpit100.c | 199 ++ 1 file changed, 199 insertions(+) create mode 100644 drivers/clocksource/timer-atcpit100.c diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c new file mode 100644 index 000..6b224c4 --- /dev/null +++ b/drivers/clocksource/timer-atcpit100.c @@ -0,0 +1,199 @@ +/* + * Andestech ATCPIT100 Timer Device Driver Implementation + * + * Copyright (C) 2016 Andes Technology Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void __iomem *base; +static u32 freq; + +/* + * Definition of register offsets + */ + +/* ID and Revision Register */ +#define ID_REV 0x0 + +/* Configuration Register */ +#define CFG0x10 + +/* Interrupt Enable Register */ +#define INT_EN 0x14 +#define CH_INT_EN(c, i)((1<event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction timer1_irq = { + .name = "Timer Tick", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler= timer1_interrupt, + .dev_id = &clockevent_atcpit100 +}; + +static void __init atcpit100_clockevent_init(int irq) +{ + struct clock_event_device *evt = &clockevent_atcpit100; + + evt->mult = div_sc(freq, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0x, evt); + evt->min_delta_ns = clockevent_delta2ns(3, evt); + clockevents_register_device(evt); + setup_irq(irq, &timer1_irq); +} + +static int __init atcpit100_init(struct device_node *dev) +{ + int irq; + + base = of_iomap(dev, 0); + if (!base) { + pr_warn("Can't remap registers"); + return -ENXIO; + } + + if (of_property_read_u32(dev, "clock-frequency", &freq)) { + pr_warn("Can't read clock-frequency"); + return -EINVAL; + } + irq = irq_of_parse_and_map(dev, 0); + + if (irq <= 0) { + pr_warn("Failed to map timer IRQ\n"); + return -EINVAL; + } + pr_info("ATCPIT100 timer 1 installed on IRQ %d, with clock %d at %d HZ. in 0x%08x\r\n", + irq, freq, HZ, (u32)base); + writel(APB_CLK|TMR_32, base + CH_CTL(0)); + writel(readl(base + INT_EN) | CH_INT_EN(0, 0), base + INT_EN); + writel(readl(base + CH_EN) | CH_TMR_EN(0, 0), base + CH_EN); + atcpit100_clocksource_init(); + atcpit100_clockevent_init(irq); + + return 0; +} + +TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_init); -- 2.7.4
[PATCH v2 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
Add a document to describe Andestech atcpit100 timer and binding information. Signed-off-by: Greentime Hu Signed-off-by: Rick Chen --- .../bindings/timer/andestech,atcpit100-timer.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt new file mode 100644 index 000..a87278a --- /dev/null +++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt @@ -0,0 +1,31 @@ +Andestech ATCPIT100 timer +-- +ATCPIT100 is a generic IP block from Andes Technology, embedded in +Andestech AE3XX platforms and other designs. + +This timer is a set of compact multi-function timers, which can be +used as pulse width modulators (PWM) as well as simple timers. + +It supports up to 4 PIT channels. Each PIT channel is a +multi-function timer and provide the following usage scenarios: +One 32-bit timer +Two 16-bit timers +Four 8-bit timers +One 16-bit PWM +One 16-bit timer and one 8-bit PWM +Two 8-bit timer and one 8-bit PWM + +Required properties: +- compatible : Should be "andestech,atcpit100" +- reg : Address and length of the register set +- interrupts : Reference to the timer interrupt +- clock-frequency : The rate in HZ in input of the Andestech ATCPIT100 timer + +Examples: + +timer0: timer@f040 { + compatible = "andestech,atcpit100"; + reg = <0xf040 0x1000>; + interrupts = <2 4>; + clock-frequency = <3000>; +}; -- 2.7.4
[PATCH v2 2/3] clocksource/drivers/Kconfig: Support andestech atcpit100 timer
Add CLKSRC_ATCPIT100 for Andestech atcpit100 timer selection. It often be used in Andestech AE3XX platform. Signed-off-by: Greentime Hu Signed-off-by: Rick Chen --- drivers/clocksource/Kconfig | 6 ++ drivers/clocksource/Makefile | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc60620..e950066 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -615,4 +615,10 @@ config CLKSRC_ST_LPC Enable this option to use the Low Power controller timer as clocksource. +config CLKSRC_ATCPIT100 + bool "Clocksource for AE3XX platform" if COMPILE_TEST + depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + help + This option enables support for the Andestech AE3XX platform timers. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dbc1ad1..24d15bd 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -74,3 +74,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o +obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o -- 2.7.4