summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Felice <tony.felice@timesys.com>2013-11-07 11:55:15 -0500
committerAnthony Felice <tony.felice@timesys.com>2013-11-07 11:55:15 -0500
commit8dbbf996897e1d5878f3f5fd5fff5adedb04f3b8 (patch)
tree7cf8054eb498f5b7dcb3118a9e2bebe311134125
parent498b5774630e0c8ac7dadd72fce5ceb555f741b8 (diff)
Add Global Timer support to fix High Resolution Timer functionality.
This patch was submitted by Yoshihisa Ozawa <ozawa@lineo.co.jp> in ticket #52306.
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S7
-rw-r--r--arch/arm/include/asm/hardirq.h3
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-gic.S12
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/mach-mvf/clock.c12
-rwxr-xr-xarch/arm/plat-mxc/Kconfig2
-rwxr-xr-xarch/arm/plat-mxc/Makefile6
-rwxr-xr-xarch/arm/plat-mxc/include/mach/common.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h5
9 files changed, 49 insertions, 2 deletions
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
index 2da8547de6d6..1b32239a6665 100644
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -33,6 +33,13 @@
bne do_local_timer
#endif
#endif
+
+#if defined(CONFIG_ARCH_MVF) && !defined(CONFIG_MXC_USE_PIT) /* MVF Global Timer Support*/
+ test_for_gtirq r0, r6, r5, lr
+ movne r0, sp
+ adrne lr, BSYM(1b)
+ bne do_global_timer
+#endif
9997:
.endm
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 89ad1805e579..b9f0c62e82c3 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -15,6 +15,9 @@ typedef struct {
#ifdef CONFIG_SMP
unsigned int ipi_irqs[NR_IPI];
#endif
+#if defined(CONFIG_ARCH_MVF) && !defined(CONFIG_MXC_USE_PIT)
+ unsigned int global_timer_irqs;
+#endif
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
index c115b82fe80a..14ea31cda750 100644
--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -73,3 +73,15 @@
streq \irqstat, [\base, #GIC_CPU_EOI]
cmp \tmp, #0
.endm
+
+#if defined(CONFIG_ARCH_MVF) && !defined(CONFIG_MXC_USE_PIT)
+ /* MVF Global Timer Support*/
+ .macro test_for_gtirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #27
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+#endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 83bbad03fcc6..bb2f444fe218 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -62,6 +62,9 @@ int arch_show_interrupts(struct seq_file *p, int prec)
#ifdef CONFIG_LOCAL_TIMERS
show_local_irqs(p, prec);
#endif
+#if defined(CONFIG_ARCH_MVF) && !defined(CONFIG_MXC_USE_PIT)
+ show_global_timer_irqs(p, prec);
+#endif
seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
return 0;
}
diff --git a/arch/arm/mach-mvf/clock.c b/arch/arm/mach-mvf/clock.c
index 5ac0ff1766fb..b37992318170 100644
--- a/arch/arm/mach-mvf/clock.c
+++ b/arch/arm/mach-mvf/clock.c
@@ -1024,6 +1024,12 @@ static struct clk ipg_clk = {
};
+static struct clk scu_clk = {
+ __INIT_CLK_DEBUG(scu_clk)
+ .parent = &periph_clk,
+};
+
+
static int _clk_enet_set_parent(struct clk *clk, struct clk *parent)
{
int mux;
@@ -1897,6 +1903,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk), /* arm core clk */
_REGISTER_CLOCK(NULL, "periph_clk", periph_clk), /* platform bus clk */
_REGISTER_CLOCK(NULL, "ipg_clk", ipg_clk),
+ _REGISTER_CLOCK(NULL, "scu_clk", scu_clk),
_REGISTER_CLOCK(NULL, "audio ext clk", audio_external_clk),
_REGISTER_CLOCK(NULL, "mvf-uart.0", uart_clk[0]),
_REGISTER_CLOCK(NULL, "mvf-uart.1", uart_clk[0]),
@@ -1976,9 +1983,14 @@ int __init mvf_clocks_init(unsigned long ckil, unsigned long osc,
#endif
clk_enable(&pll3_usb_otg_main_clk);
+#ifdef CONFIG_MXC_USE_PIT
base = MVF_IO_ADDRESS(MVF_PIT_BASE_ADDR);
pit_timer_init(&pit_clk, base, MVF_INT_PIT);
+#else
+ base = MVF_IO_ADDRESS(MVF_SCUGIC_BASE_ADDR + 0x200);
+ global_timer_init(&scu_clk, base, MVF_INT_GLOBAL_TIMER);
+#endif
/*clk_set_parent(&enet_clk, &pll5_enet_main_clk);*/
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 9f40120e63e1..d3cf435d6d28 100755
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -138,7 +138,7 @@ config HAVE_PIT
config MXC_USE_PIT
bool "Use PIT"
- depends on HAVE_PIT
+ depends on HAVE_PIT && !HIGH_RES_TIMERS
help
Use PIT as the system timer on systems that have it.
Anyway, on some systems the GPT may be in use such as mvf platform.
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 238788df23da..6bb77052bbf4 100755
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -8,6 +8,11 @@ obj-y := clock.o devices.o cpu.o system.o irq-common.o usb_common.o usb_wakeup.o
ifdef CONFIG_ARCH_MVF
obj-y += gpio-mvf.o
+ ifdef CONFIG_MXC_USE_PIT
+ obj-y += pit.o
+ else
+ obj-y += global_timer.o
+ endif
else
obj-y += gpio.o
obj-y += time.o
@@ -23,7 +28,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
-obj-$(CONFIG_MXC_USE_PIT) += pit.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index fa16fcd74c06..5d71255bc3b2 100755
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -63,6 +63,7 @@ extern void mxc91231_init_irq(void);
extern void pit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
+extern void global_timer_init(struct clk *timer_clk, void __iomem *, int);
extern int mx1_clocks_init(unsigned long fref);
extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
extern int mx25_clocks_init(void);
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 9fce85784a32..844a404b8c4d 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -83,4 +83,9 @@ extern int imx_irq_set_priority(unsigned char irq, unsigned char prio);
/* switch between IRQ and FIQ */
extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type);
+#if defined(CONFIG_ARCH_MVF) && !defined(CONFIG_MXC_USE_PIT)
+struct seq_file;
+extern void show_global_timer_irqs(struct seq_file *, int);
+#endif
+
#endif /* __ASM_ARCH_MXC_IRQS_H__ */