cns21xx: add initial support for the Cavium CNS21xx SoC
[openwrt/staging/yousong.git] / target / linux / cns21xx / patches-2.6.37 / 004-arm-add-fa-time.patch
diff --git a/target/linux/cns21xx/patches-2.6.37/004-arm-add-fa-time.patch b/target/linux/cns21xx/patches-2.6.37/004-arm-add-fa-time.patch
new file mode 100644 (file)
index 0000000..876caeb
--- /dev/null
@@ -0,0 +1,143 @@
+--- /dev/null
++++ b/arch/arm/plat-fa/include/plat/time.h
+@@ -0,0 +1,20 @@
++/*
++ *  Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * 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.
++ */
++
++#ifndef _FA_TIME_H
++#define _FA_TIME_H
++
++#define FA_TIMER1     0
++#define FA_TIMER2     1
++#define FA_TIMER3     2
++
++int __init fa_timer_init(unsigned int mapbase, unsigned int irq,
++                       unsigned int timer, unsigned int freq);
++
++#endif /* _FA_TIME_H */
+--- /dev/null
++++ b/arch/arm/plat-fa/time.c
+@@ -0,0 +1,97 @@
++/*
++ *  Copyright (C) 2001-2006 Storlink, Corp.
++ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
++ *  Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * 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/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/io.h>
++
++#include <asm/mach/time.h>
++#include <plat/time.h>
++
++/*
++ * Register definitions for the timers
++ */
++#define TIMER_COUNT(_base, _tmr)      ((_base) + 0x00 + (_tmr) * 0x10)
++#define TIMER_LOAD(_base, _tmr)               ((_base) + 0x04 + (_tmr) * 0x10)
++#define TIMER_MATCH1(_base, _tmr)     ((_base) + 0x08 + (_tmr) * 0x10)
++#define TIMER_MATCH2(_base, _tmr)     ((_base) + 0x0c + (_tmr) * 0x10)
++
++#define TIMER_CR(_base)                       ((_base) + 0x30)
++#define TIMER_STATUS(_base)           ((_base) + 0x34)
++#define TIMER_MASK(_base)             ((_base) + 0x38)
++
++#define TIMER_SIZE            0x3c
++
++#define TIMER_CR_ENABLE(x)    (1 << ((x) * 3))
++#define TIMER_CR_CLOCK(x)     (1 << ((x) * 3 + 1))
++#define TIMER_CR_INT(x)               (1 << ((x) * 3 + 2))
++#define TIMER_CR_DOWN(x)      (1 << ((x) * 3 + 9))
++
++#define TIMER_MASK_MATCH1(x)  (1 << ((x) * 3))
++#define TIMER_MASK_MATCH2(x)  (1 << ((x) * 3 + 1))
++#define TIMER_MASK_OF(x)      (1 << ((x) * 3 + 2))
++
++#define TIMER_MASK_ALL                0x7ff
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t fa_timer_interrupt(int irq, void *dev_id)
++{
++      timer_tick();
++      return IRQ_HANDLED;
++}
++
++static struct irqaction fa_timer_irq = {
++      .name           = "Timer Tick",
++      .flags          = IRQF_DISABLED | IRQF_TIMER,
++      .handler        = fa_timer_interrupt,
++};
++
++int __init fa_timer_init(unsigned int mapbase, unsigned int irq,
++                       unsigned int timer, unsigned int freq)
++{
++      void __iomem *base;
++
++      base = ioremap(mapbase, TIMER_SIZE);
++      if (!base)
++              return -ENOMEM;
++
++      /* disable timers, clear status and mask all interrupts */
++      __raw_writel(0, TIMER_CR(base));
++      __raw_writel(0, TIMER_STATUS(base));
++      __raw_writel(TIMER_MASK_ALL, TIMER_MASK(base));
++
++      /*
++       * Make irqs happen for the system timer
++       */
++      setup_irq(irq, &fa_timer_irq);
++
++      /* Setup the timer */
++      __raw_writel(freq / HZ, TIMER_COUNT(base, timer));
++      __raw_writel(freq / HZ, TIMER_LOAD(base, timer));
++      __raw_writel(0, TIMER_MATCH1(base, timer));
++      __raw_writel(0, TIMER_MATCH2(base, timer));
++
++      /* Enable interrupt and start the timer */
++      __raw_writel(TIMER_MASK_ALL & ~TIMER_MASK_OF(timer),
++                   TIMER_MASK(base));
++
++      __raw_writel(TIMER_CR_ENABLE(timer) |
++                   TIMER_CR_INT(timer) |
++                   TIMER_CR_DOWN(timer),
++                   TIMER_CR(base));
++
++      iounmap(base);
++
++      return 0;
++}
+--- a/arch/arm/plat-fa/Kconfig
++++ b/arch/arm/plat-fa/Kconfig
+@@ -1,3 +1,6 @@
+ if PLAT_FA
++config PLAT_FA_TIME
++      def_bool n
++
+ endif
+--- a/arch/arm/plat-fa/Makefile
++++ b/arch/arm/plat-fa/Makefile
+@@ -4,6 +4,8 @@
+ obj-y :=
++obj-$(CONFIG_PLAT_FA_TIME)    += time.o
++
+ obj-m :=
+ obj-n :=
+ obj-  :=