Message ID | 1370856955-10514-1-git-send-email-sebastian.hesselbarth@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: > This patch add a DT enabled driver for timers found on Marvell Orion SoCs > (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- > running clocksource on timer0 and a clockevent source on timer1. > Corresponding device tree documentation is also added. > > Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> It looks good for me. Sebastian, shall I take it through my tree (it will go to Thomas's tree) ? Thanks -- Daniel > --- > Changelog: > v3->v4: > - export thread-safe access to TIMER_CTRL register to use with watchdog > - remove IRQF_DISABLED and add .irq to clock event (Suggested by Daniel Lezcano) > > Notes: > - This is only an update to clocksource driver, the remaining patches are > not resent as they have not been changed. > - I will not rework orion watchdog driver for this patch set. It is written > Kirkwood/Orion5x specific although it will also work on Dove and it is messing > with shared registers. It has done it before, so I consider it broken anyway. > I (or somebody else) will take care of proper watchdog later. > - An updated branch can be found on > git://github.com/shesselba/linux-dove.git orion-irqchip-for-v3.11_v4 > > Cc: Grant Likely <grant.likely@linaro.org> > Cc: Rob Herring <rob.herring@calxeda.com> > Cc: Rob Landley <rob@landley.net> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: John Stultz <john.stultz@linaro.org> > Cc: Russell King <linux@arm.linux.org.uk> > Cc: Jason Cooper <jason@lakedaemon.net> > Cc: Andrew Lunn <andrew@lunn.ch> > Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> > Cc: Gregory Clement <gregory.clement@free-electrons.com> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org> > Cc: devicetree-discuss@lists.ozlabs.org > Cc: linux-doc@vger.kernel.org > Cc: linux-arm-kernel@lists.infradead.org > Cc: linux-kernel@vger.kernel.org > --- > .../bindings/timer/marvell,orion-timer.txt | 17 +++ > drivers/clocksource/Kconfig | 5 + > drivers/clocksource/Makefile | 1 + > drivers/clocksource/time-orion.c | 150 ++++++++++++++++++++ > 4 files changed, 173 insertions(+), 0 deletions(-) > create mode 100644 Documentation/devicetree/bindings/timer/marvell,orion-timer.txt > create mode 100644 drivers/clocksource/time-orion.c > > diff --git a/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt b/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt > new file mode 100644 > index 0000000..62bb826 > --- /dev/null > +++ b/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt > @@ -0,0 +1,17 @@ > +Marvell Orion SoC timer > + > +Required properties: > +- compatible: shall be "marvell,orion-timer" > +- reg: base address of the timer register starting with TIMERS CONTROL register > +- interrupt-parent: phandle of the bridge interrupt controller > +- interrupts: should contain the interrupts for Timer0 and Timer1 > +- clocks: phandle of timer reference clock (tclk) > + > +Example: > + timer: timer { > + compatible = "marvell,orion-timer"; > + reg = <0x20300 0x20>; > + interrupt-parent = <&bridge_intc>; > + interrupts = <1>, <2>; > + clocks = <&core_clk 0>; > + }; > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > index f151c6c..2404869 100644 > --- a/drivers/clocksource/Kconfig > +++ b/drivers/clocksource/Kconfig > @@ -25,6 +25,11 @@ config DW_APB_TIMER_OF > config ARMADA_370_XP_TIMER > bool > > +config ORION_TIMER > + select CLKSRC_OF > + select CLKSRC_MMIO > + bool > + > config SUN4I_TIMER > bool > > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile > index 8d979c7..d1e8d68 100644 > --- a/drivers/clocksource/Makefile > +++ b/drivers/clocksource/Makefile > @@ -15,6 +15,7 @@ obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o > obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o > obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o > obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o > +obj-$(CONFIG_ORION_TIMER) += time-orion.o > obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o > obj-$(CONFIG_ARCH_MARCO) += timer-marco.o > obj-$(CONFIG_ARCH_MXS) += mxs_timer.o > diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c > new file mode 100644 > index 0000000..ad7df17 > --- /dev/null > +++ b/drivers/clocksource/time-orion.c > @@ -0,0 +1,150 @@ > +/* > + * Marvell Orion SoC timer handling. > + * > + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> > + * > + * This file is licensed under the terms of the GNU General Public > + * License version 2. This program is licensed "as is" without any > + * warranty of any kind, whether express or implied. > + * > + * Timer 0 is used as free-running clocksource, while timer 1 is > + * used as clock_event_device. > + */ > + > +#include <linux/kernel.h> > +#include <linux/bitops.h> > +#include <linux/clk.h> > +#include <linux/clockchips.h> > +#include <linux/interrupt.h> > +#include <linux/of_address.h> > +#include <linux/of_irq.h> > +#include <linux/spinlock.h> > +#include <asm/sched_clock.h> > + > +#define TIMER_CTRL 0x00 > +#define TIMER0_EN BIT(0) > +#define TIMER0_RELOAD_EN BIT(1) > +#define TIMER1_EN BIT(2) > +#define TIMER1_RELOAD_EN BIT(3) > +#define TIMER0_RELOAD 0x10 > +#define TIMER0_VAL 0x14 > +#define TIMER1_RELOAD 0x18 > +#define TIMER1_VAL 0x1c > + > +#define ORION_ONESHOT_MIN 1 > +#define ORION_ONESHOT_MAX 0xfffffffe > + > +static void __iomem *timer_base; > +static DEFINE_SPINLOCK(timer_ctrl_lock); > + > +/* > + * Thread-safe access to TIMER_CTRL register > + * (shared with watchdog timer) > + */ > +void orion_timer_ctrl_clrset(u32 clr, u32 set) > +{ > + spin_lock(&timer_ctrl_lock); > + writel((readl(timer_base + TIMER_CTRL) & ~clr) | set, > + timer_base + TIMER_CTRL); > + spin_unlock(&timer_ctrl_lock); > +} > +EXPORT_SYMBOL(orion_timer_ctrl_clrset); > + > +/* > + * Free-running clocksource handling. > + */ > +static u32 notrace orion_read_sched_clock(void) > +{ > + return ~readl(timer_base + TIMER0_VAL); > +} > + > +/* > + * Clockevent handling. > + */ > +static u32 ticks_per_jiffy; > + > +static int orion_clkevt_next_event(unsigned long delta, > + struct clock_event_device *dev) > +{ > + /* setup and enable one-shot timer */ > + writel(delta, timer_base + TIMER1_VAL); > + orion_timer_ctrl_clrset(TIMER1_RELOAD_EN, TIMER1_EN); > + > + return 0; > +} > + > +static void orion_clkevt_mode(enum clock_event_mode mode, > + struct clock_event_device *dev) > +{ > + if (mode == CLOCK_EVT_MODE_PERIODIC) { > + /* setup and enable periodic timer at 1/HZ intervals */ > + writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); > + writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); > + orion_timer_ctrl_clrset(0, TIMER1_RELOAD_EN | TIMER1_EN); > + } else { > + /* disable timer */ > + orion_timer_ctrl_clrset(TIMER1_RELOAD_EN | TIMER1_EN, 0); > + } > +} > + > +static struct clock_event_device orion_clkevt = { > + .name = "orion_event", > + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, > + .shift = 32, > + .rating = 300, > + .set_next_event = orion_clkevt_next_event, > + .set_mode = orion_clkevt_mode, > +}; > + > +static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) > +{ > + orion_clkevt.event_handler(&orion_clkevt); > + return IRQ_HANDLED; > +} > + > +static struct irqaction orion_clkevt_irq = { > + .name = "orion_event", > + .flags = IRQF_TIMER, > + .handler = orion_clkevt_irq_handler, > +}; > + > +static void __init orion_timer_init(struct device_node *np) > +{ > + struct clk *clk; > + int irq; > + > + /* timer registers are shared with watchdog timer */ > + timer_base = of_iomap(np, 0); > + if (!timer_base) > + panic("%s: unable to map resource\n", np->name); > + > + clk = of_clk_get(np, 0); > + if (IS_ERR(clk)) > + panic("%s: unable to get clk\n", np->name); > + clk_prepare_enable(clk); > + > + /* we are only interested in timer1 irq */ > + irq = irq_of_parse_and_map(np, 1); > + if (irq <= 0) > + panic("%s: unable to parse timer1 irq\n", np->name); > + > + /* setup timer0 as free-running clocksource */ > + writel(~0, timer_base + TIMER0_VAL); > + writel(~0, timer_base + TIMER0_RELOAD); > + orion_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | TIMER0_EN); > + clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", > + clk_get_rate(clk), 300, 32, > + clocksource_mmio_readl_down); > + setup_sched_clock(orion_read_sched_clock, 32, clk_get_rate(clk)); > + > + /* setup timer1 as clockevent timer */ > + if (setup_irq(irq, &orion_clkevt_irq)) > + panic("%s: unable to setup irq\n", np->name); > + > + ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; > + orion_clkevt.cpumask = cpumask_of(0); > + orion_clkevt.irq = irq; > + clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), > + ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); > +} > +CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); >
On 06/10/13 18:04, Daniel Lezcano wrote: > On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: >> This patch add a DT enabled driver for timers found on Marvell Orion SoCs >> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- >> running clocksource on timer0 and a clockevent source on timer1. >> Corresponding device tree documentation is also added. >> >> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> > > It looks good for me. > > Sebastian, > > shall I take it through my tree (it will go to Thomas's tree) ? Daniel, I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go through Thomas' or John's tree? If you want to take it, I am fine with it but guess I am not the one to choose here ;) Sebastian
On 06/10/2013 06:31 PM, Sebastian Hesselbarth wrote: > On 06/10/13 18:04, Daniel Lezcano wrote: >> On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: >>> This patch add a DT enabled driver for timers found on Marvell Orion >>> SoCs >>> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- >>> running clocksource on timer0 and a clockevent source on timer1. >>> Corresponding device tree documentation is also added. >>> >>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> >> >> It looks good for me. >> >> Sebastian, >> >> shall I take it through my tree (it will go to Thomas's tree) ? > > Daniel, > > I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go > through Thomas' or John's tree? If you want to take it, I am fine with > it but guess I am not the one to choose here ;) Actually, I am giving a hand to John and Thomas. I take the patches for clockevents (and also for clocksource if both are mixed and John did not pick it yet) and Thomas pulls from my tree [1]. If there is no dependency with any other patches of your patchset, which seems to be the case, I will queue it for 3.11. -- Daniel [1] https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timers/core&id=762cf9695d714d312ef7369bed1b9f9467c9e64e
On 06/10/13 18:44, Daniel Lezcano wrote: > On 06/10/2013 06:31 PM, Sebastian Hesselbarth wrote: >> On 06/10/13 18:04, Daniel Lezcano wrote: >>> On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: >>>> This patch add a DT enabled driver for timers found on Marvell Orion >>>> SoCs >>>> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- >>>> running clocksource on timer0 and a clockevent source on timer1. >>>> Corresponding device tree documentation is also added. >>>> >>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> >>> >>> It looks good for me. >>> >>> Sebastian, >>> >>> shall I take it through my tree (it will go to Thomas's tree) ? >> >> Daniel, >> >> I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go >> through Thomas' or John's tree? If you want to take it, I am fine with >> it but guess I am not the one to choose here ;) > > Actually, I am giving a hand to John and Thomas. I take the patches for > clockevents (and also for clocksource if both are mixed and John did not > pick it yet) and Thomas pulls from my tree [1]. > > If there is no dependency with any other patches of your patchset, which > seems to be the case, I will queue it for 3.11. Ok, thanks! Sebastian
On 06/10/2013 06:47 PM, Sebastian Hesselbarth wrote: > On 06/10/13 18:44, Daniel Lezcano wrote: >> On 06/10/2013 06:31 PM, Sebastian Hesselbarth wrote: >>> On 06/10/13 18:04, Daniel Lezcano wrote: >>>> On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: >>>>> This patch add a DT enabled driver for timers found on Marvell Orion >>>>> SoCs >>>>> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a >>>>> free- >>>>> running clocksource on timer0 and a clockevent source on timer1. >>>>> Corresponding device tree documentation is also added. >>>>> >>>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> >>>> >>>> It looks good for me. >>>> >>>> Sebastian, >>>> >>>> shall I take it through my tree (it will go to Thomas's tree) ? >>> >>> Daniel, >>> >>> I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go >>> through Thomas' or John's tree? If you want to take it, I am fine with >>> it but guess I am not the one to choose here ;) >> >> Actually, I am giving a hand to John and Thomas. I take the patches for >> clockevents (and also for clocksource if both are mixed and John did not >> pick it yet) and Thomas pulls from my tree [1]. >> >> If there is no dependency with any other patches of your patchset, which >> seems to be the case, I will queue it for 3.11. > > Ok, thanks! I have a lot of ^M in the patch ... dos2unix removed them but I am wondering how they get there ?
On Mon, Jun 10, 2013 at 07:06:38PM +0200, Daniel Lezcano wrote: > On 06/10/2013 06:47 PM, Sebastian Hesselbarth wrote: > > On 06/10/13 18:44, Daniel Lezcano wrote: > >> On 06/10/2013 06:31 PM, Sebastian Hesselbarth wrote: > >>> On 06/10/13 18:04, Daniel Lezcano wrote: > >>>> On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: > >>>>> This patch add a DT enabled driver for timers found on Marvell Orion > >>>>> SoCs > >>>>> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a > >>>>> free- > >>>>> running clocksource on timer0 and a clockevent source on timer1. > >>>>> Corresponding device tree documentation is also added. > >>>>> > >>>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> > >>>> > >>>> It looks good for me. > >>>> > >>>> Sebastian, > >>>> > >>>> shall I take it through my tree (it will go to Thomas's tree) ? > >>> > >>> Daniel, > >>> > >>> I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go > >>> through Thomas' or John's tree? If you want to take it, I am fine with > >>> it but guess I am not the one to choose here ;) > >> > >> Actually, I am giving a hand to John and Thomas. I take the patches for > >> clockevents (and also for clocksource if both are mixed and John did not > >> pick it yet) and Thomas pulls from my tree [1]. > >> > >> If there is no dependency with any other patches of your patchset, which > >> seems to be the case, I will queue it for 3.11. > > > > Ok, thanks! > > I have a lot of ^M in the patch ... dos2unix removed them but I am > wondering how they get there ? He sent it with git-send-mail, how are you extracting it from Thunderbird? thx, Jason.
On 06/10/2013 07:09 PM, Jason Cooper wrote: > On Mon, Jun 10, 2013 at 07:06:38PM +0200, Daniel Lezcano wrote: >> On 06/10/2013 06:47 PM, Sebastian Hesselbarth wrote: >>> On 06/10/13 18:44, Daniel Lezcano wrote: >>>> On 06/10/2013 06:31 PM, Sebastian Hesselbarth wrote: >>>>> On 06/10/13 18:04, Daniel Lezcano wrote: >>>>>> On 06/10/2013 11:35 AM, Sebastian Hesselbarth wrote: >>>>>>> This patch add a DT enabled driver for timers found on Marvell Orion >>>>>>> SoCs >>>>>>> (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a >>>>>>> free- >>>>>>> running clocksource on timer0 and a clockevent source on timer1. >>>>>>> Corresponding device tree documentation is also added. >>>>>>> >>>>>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> >>>>>> >>>>>> It looks good for me. >>>>>> >>>>>> Sebastian, >>>>>> >>>>>> shall I take it through my tree (it will go to Thomas's tree) ? >>>>> >>>>> Daniel, >>>>> >>>>> I checked MAINTAINERS and thought clocksource, i.e. patch 2/6, would go >>>>> through Thomas' or John's tree? If you want to take it, I am fine with >>>>> it but guess I am not the one to choose here ;) >>>> >>>> Actually, I am giving a hand to John and Thomas. I take the patches for >>>> clockevents (and also for clocksource if both are mixed and John did not >>>> pick it yet) and Thomas pulls from my tree [1]. >>>> >>>> If there is no dependency with any other patches of your patchset, which >>>> seems to be the case, I will queue it for 3.11. >>> >>> Ok, thanks! >> >> I have a lot of ^M in the patch ... dos2unix removed them but I am >> wondering how they get there ? > > He sent it with git-send-mail, how are you extracting it from > Thunderbird? I use a script to extract the patch from my mailbox. I am using it for years now I did not face these spurious characters before. Anyway, it seems not related to the patch itself, I will handle that. Thanks -- Daniel
On Mon, Jun 10, 2013 at 11:35:55AM +0200, Sebastian Hesselbarth wrote: > This patch add a DT enabled driver for timers found on Marvell Orion SoCs > (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- > running clocksource on timer0 and a clockevent source on timer1. > Corresponding device tree documentation is also added. > > Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> > --- > Changelog: > v3->v4: > - export thread-safe access to TIMER_CTRL register to use with watchdog > - remove IRQF_DISABLED and add .irq to clock event (Suggested by Daniel Lezcano) > > Notes: > - This is only an update to clocksource driver, the remaining patches are > not resent as they have not been changed. > - I will not rework orion watchdog driver for this patch set. It is written > Kirkwood/Orion5x specific although it will also work on Dove and it is messing > with shared registers. It has done it before, so I consider it broken anyway. > I (or somebody else) will take care of proper watchdog later. > - An updated branch can be found on > git://github.com/shesselba/linux-dove.git orion-irqchip-for-v3.11_v4 Hi Sebastian You can add a Tested-by: Andrew Lunn <andrew@lunn.ch> I tested on my kirkwood QNAP. CPU0 2: 6062 bridge-interrupt-ctrl orion_event 9: 0 f1010140.gpio Reset 15: 0 f1010140.gpio USB Copy 24: 106 main-interrupt-ctrl ehci_hcd:usb1 25: 2463 main-interrupt-ctrl sata_mv 26: 0 main-interrupt-ctrl f1030000.crypto 27: 2 main-interrupt-ctrl f1060800.xor 28: 2 main-interrupt-ctrl f1060800.xor 29: 71 main-interrupt-ctrl mv64xxx_i2c 30: 2 main-interrupt-ctrl f1060900.xor 31: 2 main-interrupt-ctrl f1060900.xor 32: 41 main-interrupt-ctrl eth0 33: 1317 main-interrupt-ctrl serial 75: 745 main-interrupt-ctrl f1072004.mdio-bus Err: 0 Andrew
diff --git a/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt b/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt new file mode 100644 index 0000000..62bb826 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt @@ -0,0 +1,17 @@ +Marvell Orion SoC timer + +Required properties: +- compatible: shall be "marvell,orion-timer" +- reg: base address of the timer register starting with TIMERS CONTROL register +- interrupt-parent: phandle of the bridge interrupt controller +- interrupts: should contain the interrupts for Timer0 and Timer1 +- clocks: phandle of timer reference clock (tclk) + +Example: + timer: timer { + compatible = "marvell,orion-timer"; + reg = <0x20300 0x20>; + interrupt-parent = <&bridge_intc>; + interrupts = <1>, <2>; + clocks = <&core_clk 0>; + }; diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f151c6c..2404869 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -25,6 +25,11 @@ config DW_APB_TIMER_OF config ARMADA_370_XP_TIMER bool +config ORION_TIMER + select CLKSRC_OF + select CLKSRC_MMIO + bool + config SUN4I_TIMER bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 8d979c7..d1e8d68 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o +obj-$(CONFIG_ORION_TIMER) += time-orion.o obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o obj-$(CONFIG_ARCH_MARCO) += timer-marco.o obj-$(CONFIG_ARCH_MXS) += mxs_timer.o diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c new file mode 100644 index 0000000..ad7df17 --- /dev/null +++ b/drivers/clocksource/time-orion.c @@ -0,0 +1,150 @@ +/* + * Marvell Orion SoC timer handling. + * + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * Timer 0 is used as free-running clocksource, while timer 1 is + * used as clock_event_device. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/clockchips.h> +#include <linux/interrupt.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/spinlock.h> +#include <asm/sched_clock.h> + +#define TIMER_CTRL 0x00 +#define TIMER0_EN BIT(0) +#define TIMER0_RELOAD_EN BIT(1) +#define TIMER1_EN BIT(2) +#define TIMER1_RELOAD_EN BIT(3) +#define TIMER0_RELOAD 0x10 +#define TIMER0_VAL 0x14 +#define TIMER1_RELOAD 0x18 +#define TIMER1_VAL 0x1c + +#define ORION_ONESHOT_MIN 1 +#define ORION_ONESHOT_MAX 0xfffffffe + +static void __iomem *timer_base; +static DEFINE_SPINLOCK(timer_ctrl_lock); + +/* + * Thread-safe access to TIMER_CTRL register + * (shared with watchdog timer) + */ +void orion_timer_ctrl_clrset(u32 clr, u32 set) +{ + spin_lock(&timer_ctrl_lock); + writel((readl(timer_base + TIMER_CTRL) & ~clr) | set, + timer_base + TIMER_CTRL); + spin_unlock(&timer_ctrl_lock); +} +EXPORT_SYMBOL(orion_timer_ctrl_clrset); + +/* + * Free-running clocksource handling. + */ +static u32 notrace orion_read_sched_clock(void) +{ + return ~readl(timer_base + TIMER0_VAL); +} + +/* + * Clockevent handling. + */ +static u32 ticks_per_jiffy; + +static int orion_clkevt_next_event(unsigned long delta, + struct clock_event_device *dev) +{ + /* setup and enable one-shot timer */ + writel(delta, timer_base + TIMER1_VAL); + orion_timer_ctrl_clrset(TIMER1_RELOAD_EN, TIMER1_EN); + + return 0; +} + +static void orion_clkevt_mode(enum clock_event_mode mode, + struct clock_event_device *dev) +{ + if (mode == CLOCK_EVT_MODE_PERIODIC) { + /* setup and enable periodic timer at 1/HZ intervals */ + writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); + writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); + orion_timer_ctrl_clrset(0, TIMER1_RELOAD_EN | TIMER1_EN); + } else { + /* disable timer */ + orion_timer_ctrl_clrset(TIMER1_RELOAD_EN | TIMER1_EN, 0); + } +} + +static struct clock_event_device orion_clkevt = { + .name = "orion_event", + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, + .shift = 32, + .rating = 300, + .set_next_event = orion_clkevt_next_event, + .set_mode = orion_clkevt_mode, +}; + +static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) +{ + orion_clkevt.event_handler(&orion_clkevt); + return IRQ_HANDLED; +} + +static struct irqaction orion_clkevt_irq = { + .name = "orion_event", + .flags = IRQF_TIMER, + .handler = orion_clkevt_irq_handler, +}; + +static void __init orion_timer_init(struct device_node *np) +{ + struct clk *clk; + int irq; + + /* timer registers are shared with watchdog timer */ + timer_base = of_iomap(np, 0); + if (!timer_base) + panic("%s: unable to map resource\n", np->name); + + clk = of_clk_get(np, 0); + if (IS_ERR(clk)) + panic("%s: unable to get clk\n", np->name); + clk_prepare_enable(clk); + + /* we are only interested in timer1 irq */ + irq = irq_of_parse_and_map(np, 1); + if (irq <= 0) + panic("%s: unable to parse timer1 irq\n", np->name); + + /* setup timer0 as free-running clocksource */ + writel(~0, timer_base + TIMER0_VAL); + writel(~0, timer_base + TIMER0_RELOAD); + orion_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | TIMER0_EN); + clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", + clk_get_rate(clk), 300, 32, + clocksource_mmio_readl_down); + setup_sched_clock(orion_read_sched_clock, 32, clk_get_rate(clk)); + + /* setup timer1 as clockevent timer */ + if (setup_irq(irq, &orion_clkevt_irq)) + panic("%s: unable to setup irq\n", np->name); + + ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; + orion_clkevt.cpumask = cpumask_of(0); + orion_clkevt.irq = irq; + clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), + ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); +} +CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);
This patch add a DT enabled driver for timers found on Marvell Orion SoCs (Kirkwood, Dove, Orion5x, and Discovery Innovation). It installs a free- running clocksource on timer0 and a clockevent source on timer1. Corresponding device tree documentation is also added. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> --- Changelog: v3->v4: - export thread-safe access to TIMER_CTRL register to use with watchdog - remove IRQF_DISABLED and add .irq to clock event (Suggested by Daniel Lezcano) Notes: - This is only an update to clocksource driver, the remaining patches are not resent as they have not been changed. - I will not rework orion watchdog driver for this patch set. It is written Kirkwood/Orion5x specific although it will also work on Dove and it is messing with shared registers. It has done it before, so I consider it broken anyway. I (or somebody else) will take care of proper watchdog later. - An updated branch can be found on git://github.com/shesselba/linux-dove.git orion-irqchip-for-v3.11_v4 Cc: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Rob Landley <rob@landley.net> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Russell King <linux@arm.linux.org.uk> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Cc: Gregory Clement <gregory.clement@free-electrons.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-doc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- .../bindings/timer/marvell,orion-timer.txt | 17 +++ drivers/clocksource/Kconfig | 5 + drivers/clocksource/Makefile | 1 + drivers/clocksource/time-orion.c | 150 ++++++++++++++++++++ 4 files changed, 173 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/timer/marvell,orion-timer.txt create mode 100644 drivers/clocksource/time-orion.c