From f70459e5afc5e1e9211465631a819568cef894e8 Mon Sep 17 00:00:00 2001 From: Anthony Felice Date: Thu, 7 Nov 2013 11:55:15 -0500 Subject: Add Global Timer support to fix High Resolution Timer functionality. This patch was submitted by Yoshihisa Ozawa in ticket #52306. --- arch/arm/include/asm/entry-macro-multi.S | 7 +++++++ arch/arm/include/asm/hardirq.h | 3 +++ arch/arm/include/asm/hardware/entry-macro-gic.S | 12 ++++++++++++ arch/arm/kernel/irq.c | 3 +++ arch/arm/mach-mvf/clock.c | 12 ++++++++++++ arch/arm/plat-mxc/Kconfig | 2 +- arch/arm/plat-mxc/Makefile | 6 +++++- arch/arm/plat-mxc/include/mach/common.h | 1 + arch/arm/plat-mxc/include/mach/irqs.h | 5 +++++ 9 files changed, 49 insertions(+), 2 deletions(-) (limited to 'arch') 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 /* 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 @@ -61,6 +61,9 @@ int arch_show_interrupts(struct seq_file *p, int prec) #endif #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 49645099cdc8..624ba73c85fc 100644 --- a/arch/arm/mach-mvf/clock.c +++ b/arch/arm/mach-mvf/clock.c @@ -1026,6 +1026,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; @@ -1939,6 +1945,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]), @@ -2018,9 +2025,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 4edd8d91c57d..96d219c0f8f0 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h @@ -90,4 +90,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__ */ -- cgit v1.2.3