Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i.MXC family: Adding timer support

This patch adds timer support for the i.MX machine family. This code can
be used on the following machs:

- i.MX1 (tested)
- i.MX2 (i.MX21 (to be tested), i.MX27 (tested))
- i.MX3 (i.MX31 (tested))

TODO: It seems impossible to build a kernel for more than one CPU because the
timer do not follow the platform device rules. So it does only work if
timer 1 can be accessed on all CPUs at the same address.

Signed-off-by: Juergen Beisert <j.beisert@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

authored by

Juergen Beisert and committed by
Robert Schwebel
d0f349fb 90292ea6

+418 -251
+2
arch/arm/Kconfig
··· 367 367 368 368 config ARCH_MXC 369 369 bool "Freescale MXC/iMX-based" 370 + select GENERIC_TIME 371 + select GENERIC_CLOCKEVENTS 370 372 select ARCH_MTD_XIP 371 373 select GENERIC_GPIO 372 374 select HAVE_GPIO_LIB
+1 -1
arch/arm/mach-mx3/Makefile
··· 4 4 5 5 # Object file lists. 6 6 7 - obj-y := mm.o time.o clock.o devices.o iomux.o 7 + obj-y := mm.o clock.o devices.o iomux.o 8 8 obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
+12 -1
arch/arm/mach-mx3/mx31ads.c
··· 26 26 #include <asm/hardware.h> 27 27 #include <asm/mach-types.h> 28 28 #include <asm/mach/arch.h> 29 + #include <asm/mach/time.h> 29 30 #include <asm/memory.h> 30 31 #include <asm/mach/map.h> 31 32 #include <asm/arch/common.h> ··· 128 127 mxc_init_extuart(); 129 128 } 130 129 130 + static void __init mx31ads_timer_init(void) 131 + { 132 + mxc_clocks_init(26000000); 133 + mxc_timer_init("ipg_clk.0"); 134 + } 135 + 136 + struct sys_timer mx31ads_timer = { 137 + .init = mx31ads_timer_init, 138 + }; 139 + 131 140 /* 132 141 * The following uses standard kernel macros defined in arch.h in order to 133 142 * initialize __mach_desc_MX31ADS data structure. ··· 150 139 .map_io = mx31ads_map_io, 151 140 .init_irq = mxc_init_irq, 152 141 .init_machine = mxc_board_init, 153 - .timer = &mxc_timer, 142 + .timer = &mx31ads_timer, 154 143 MACHINE_END
-148
arch/arm/mach-mx3/time.c
··· 1 - /* 2 - * System Timer Interrupt reconfigured to run in free-run mode. 3 - * Author: Vitaly Wool 4 - * Copyright 2004 MontaVista Software Inc. 5 - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 6 - */ 7 - 8 - /* 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation. 12 - */ 13 - 14 - /*! 15 - * @file time.c 16 - * @brief This file contains OS tick and wdog timer implementations. 17 - * 18 - * This file contains OS tick and wdog timer implementations. 19 - * 20 - * @ingroup Timers 21 - */ 22 - 23 - #include <linux/module.h> 24 - #include <linux/init.h> 25 - #include <linux/interrupt.h> 26 - #include <linux/irq.h> 27 - #include <asm/hardware.h> 28 - #include <asm/mach/time.h> 29 - #include <asm/io.h> 30 - #include <asm/arch/common.h> 31 - 32 - /*! 33 - * This is the timer interrupt service routine to do required tasks. 34 - * It also services the WDOG timer at the frequency of twice per WDOG 35 - * timeout value. For example, if the WDOG's timeout value is 4 (2 36 - * seconds since the WDOG runs at 0.5Hz), it will be serviced once 37 - * every 2/2=1 second. 38 - * 39 - * @param irq GPT interrupt source number (not used) 40 - * @param dev_id this parameter is not used 41 - * @return always returns \b IRQ_HANDLED as defined in 42 - * include/linux/interrupt.h. 43 - */ 44 - static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) 45 - { 46 - unsigned int next_match; 47 - 48 - if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { 49 - do { 50 - timer_tick(); 51 - next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH; 52 - __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR); 53 - __raw_writel(next_match, MXC_GPT_GPTOCR1); 54 - } while ((signed long)(next_match - 55 - __raw_readl(MXC_GPT_GPTCNT)) <= 0); 56 - } 57 - 58 - return IRQ_HANDLED; 59 - } 60 - 61 - /*! 62 - * This function is used to obtain the number of microseconds since the last 63 - * timer interrupt. Note that interrupts is disabled by do_gettimeofday(). 64 - * 65 - * @return the number of microseconds since the last timer interrupt. 66 - */ 67 - static unsigned long mxc_gettimeoffset(void) 68 - { 69 - unsigned long ticks_to_match, elapsed, usec, tick_usec, i; 70 - 71 - /* Get ticks before next timer match */ 72 - ticks_to_match = 73 - __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT); 74 - 75 - /* We need elapsed ticks since last match */ 76 - elapsed = LATCH - ticks_to_match; 77 - 78 - /* Now convert them to usec */ 79 - /* Insure no overflow when calculating the usec below */ 80 - for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) { 81 - tick_usec /= i; 82 - if ((0xFFFFFFFF / tick_usec) > elapsed) 83 - break; 84 - } 85 - usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i); 86 - 87 - return usec; 88 - } 89 - 90 - /*! 91 - * The OS tick timer interrupt structure. 92 - */ 93 - static struct irqaction timer_irq = { 94 - .name = "MXC Timer Tick", 95 - .flags = IRQF_DISABLED | IRQF_TIMER, 96 - .handler = mxc_timer_interrupt 97 - }; 98 - 99 - /*! 100 - * This function is used to initialize the GPT to produce an interrupt 101 - * based on HZ. It is called by start_kernel() during system startup. 102 - */ 103 - void __init mxc_init_time(void) 104 - { 105 - u32 reg, v; 106 - reg = __raw_readl(MXC_GPT_GPTCR); 107 - reg &= ~GPTCR_ENABLE; 108 - __raw_writel(reg, MXC_GPT_GPTCR); 109 - reg |= GPTCR_SWR; 110 - __raw_writel(reg, MXC_GPT_GPTCR); 111 - 112 - while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0) 113 - cpu_relax(); 114 - 115 - reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ; 116 - __raw_writel(reg, MXC_GPT_GPTCR); 117 - 118 - /* TODO: get timer rate from clk driver */ 119 - v = 66500000; 120 - 121 - __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR); 122 - 123 - if ((v % CLOCK_TICK_RATE) != 0) { 124 - pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n", 125 - CLOCK_TICK_RATE); 126 - } 127 - pr_info("Actual CLOCK_TICK_RATE is %d Hz\n", 128 - v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1)); 129 - 130 - reg = __raw_readl(MXC_GPT_GPTCNT); 131 - reg += LATCH; 132 - __raw_writel(reg, MXC_GPT_GPTOCR1); 133 - 134 - setup_irq(MXC_INT_GPT, &timer_irq); 135 - 136 - reg = __raw_readl(MXC_GPT_GPTCR); 137 - reg = 138 - GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN | 139 - GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE; 140 - __raw_writel(reg, MXC_GPT_GPTCR); 141 - 142 - __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR); 143 - } 144 - 145 - struct sys_timer mxc_timer = { 146 - .init = mxc_init_time, 147 - .offset = mxc_gettimeoffset, 148 - };
+1 -1
arch/arm/plat-mxc/Makefile
··· 3 3 # 4 4 5 5 # Common support 6 - obj-y := irq.o clock.o gpio.o 6 + obj-y := irq.o clock.o gpio.o time.o
+228
arch/arm/plat-mxc/time.c
··· 1 + /* 2 + * linux/arch/arm/plat-mxc/time.c 3 + * 4 + * Copyright (C) 2000-2001 Deep Blue Solutions 5 + * Copyright (C) 2002 Shane Nay (shane@minirl.com) 6 + * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) 7 + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * as published by the Free Software Foundation; either version 2 12 + * of the License, or (at your option) any later version. 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 + * MA 02110-1301, USA. 22 + */ 23 + 24 + #include <linux/interrupt.h> 25 + #include <linux/irq.h> 26 + #include <linux/clockchips.h> 27 + #include <linux/clk.h> 28 + 29 + #include <asm/hardware.h> 30 + #include <asm/mach/time.h> 31 + #include <asm/arch/common.h> 32 + #include <asm/arch/mxc_timer.h> 33 + 34 + static struct clock_event_device clockevent_mxc; 35 + static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; 36 + 37 + /* clock source for the timer */ 38 + static struct clk *timer_clk; 39 + 40 + /* clock source */ 41 + 42 + static cycle_t mxc_get_cycles(void) 43 + { 44 + return __raw_readl(TIMER_BASE + MXC_TCN); 45 + } 46 + 47 + static struct clocksource clocksource_mxc = { 48 + .name = "mxc_timer1", 49 + .rating = 200, 50 + .read = mxc_get_cycles, 51 + .mask = CLOCKSOURCE_MASK(32), 52 + .shift = 20, 53 + .flags = CLOCK_SOURCE_IS_CONTINUOUS, 54 + }; 55 + 56 + static int __init mxc_clocksource_init(void) 57 + { 58 + unsigned int clock; 59 + 60 + clock = clk_get_rate(timer_clk); 61 + 62 + clocksource_mxc.mult = clocksource_hz2mult(clock, 63 + clocksource_mxc.shift); 64 + clocksource_register(&clocksource_mxc); 65 + 66 + return 0; 67 + } 68 + 69 + /* clock event */ 70 + 71 + static int mxc_set_next_event(unsigned long evt, 72 + struct clock_event_device *unused) 73 + { 74 + unsigned long tcmp; 75 + 76 + tcmp = __raw_readl(TIMER_BASE + MXC_TCN) + evt; 77 + __raw_writel(tcmp, TIMER_BASE + MXC_TCMP); 78 + 79 + return (int)(tcmp - __raw_readl(TIMER_BASE + MXC_TCN)) < 0 ? 80 + -ETIME : 0; 81 + } 82 + 83 + #ifdef DEBUG 84 + static const char *clock_event_mode_label[] = { 85 + [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", 86 + [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", 87 + [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", 88 + [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED" 89 + }; 90 + #endif /* DEBUG */ 91 + 92 + static void mxc_set_mode(enum clock_event_mode mode, 93 + struct clock_event_device *evt) 94 + { 95 + unsigned long flags; 96 + 97 + /* 98 + * The timer interrupt generation is disabled at least 99 + * for enough time to call mxc_set_next_event() 100 + */ 101 + local_irq_save(flags); 102 + 103 + /* Disable interrupt in GPT module */ 104 + gpt_irq_disable(); 105 + 106 + if (mode != clockevent_mode) { 107 + /* Set event time into far-far future */ 108 + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCN) - 3, 109 + TIMER_BASE + MXC_TCMP); 110 + /* Clear pending interrupt */ 111 + gpt_irq_acknowledge(); 112 + } 113 + 114 + #ifdef DEBUG 115 + printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", 116 + clock_event_mode_label[clockevent_mode], 117 + clock_event_mode_label[mode]); 118 + #endif /* DEBUG */ 119 + 120 + /* Remember timer mode */ 121 + clockevent_mode = mode; 122 + local_irq_restore(flags); 123 + 124 + switch (mode) { 125 + case CLOCK_EVT_MODE_PERIODIC: 126 + printk(KERN_ERR"mxc_set_mode: Periodic mode is not " 127 + "supported for i.MX\n"); 128 + break; 129 + case CLOCK_EVT_MODE_ONESHOT: 130 + /* 131 + * Do not put overhead of interrupt enable/disable into 132 + * mxc_set_next_event(), the core has about 4 minutes 133 + * to call mxc_set_next_event() or shutdown clock after 134 + * mode switching 135 + */ 136 + local_irq_save(flags); 137 + gpt_irq_enable(); 138 + local_irq_restore(flags); 139 + break; 140 + case CLOCK_EVT_MODE_SHUTDOWN: 141 + case CLOCK_EVT_MODE_UNUSED: 142 + case CLOCK_EVT_MODE_RESUME: 143 + /* Left event sources disabled, no more interrupts appear */ 144 + break; 145 + } 146 + } 147 + 148 + /* 149 + * IRQ handler for the timer 150 + */ 151 + static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) 152 + { 153 + struct clock_event_device *evt = &clockevent_mxc; 154 + uint32_t tstat; 155 + 156 + tstat = __raw_readl(TIMER_BASE + MXC_TSTAT); 157 + 158 + gpt_irq_acknowledge(); 159 + 160 + evt->event_handler(evt); 161 + 162 + return IRQ_HANDLED; 163 + } 164 + 165 + static struct irqaction mxc_timer_irq = { 166 + .name = "i.MX Timer Tick", 167 + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 168 + .handler = mxc_timer_interrupt, 169 + }; 170 + 171 + static struct clock_event_device clockevent_mxc = { 172 + .name = "mxc_timer1", 173 + .features = CLOCK_EVT_FEAT_ONESHOT, 174 + .shift = 32, 175 + .set_mode = mxc_set_mode, 176 + .set_next_event = mxc_set_next_event, 177 + .rating = 200, 178 + }; 179 + 180 + static int __init mxc_clockevent_init(void) 181 + { 182 + unsigned int clock; 183 + 184 + clock = clk_get_rate(timer_clk); 185 + 186 + clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC, 187 + clockevent_mxc.shift); 188 + clockevent_mxc.max_delta_ns = 189 + clockevent_delta2ns(0xfffffffe, &clockevent_mxc); 190 + clockevent_mxc.min_delta_ns = 191 + clockevent_delta2ns(0xff, &clockevent_mxc); 192 + 193 + clockevent_mxc.cpumask = cpumask_of_cpu(0); 194 + 195 + clockevents_register_device(&clockevent_mxc); 196 + 197 + return 0; 198 + } 199 + 200 + void __init mxc_timer_init(const char *clk_timer) 201 + { 202 + timer_clk = clk_get(NULL, clk_timer); 203 + if (!timer_clk) { 204 + printk(KERN_ERR"Cannot determine timer clock. Giving up.\n"); 205 + return; 206 + } 207 + 208 + clk_enable(timer_clk); 209 + 210 + /* 211 + * Initialise to a known state (all timers off, and timing reset) 212 + */ 213 + __raw_writel(0, TIMER_BASE + MXC_TCTL); 214 + __raw_writel(0, TIMER_BASE + MXC_TPRER); /* see datasheet note */ 215 + 216 + __raw_writel(TCTL_FRR | /* free running */ 217 + TCTL_VAL | /* set clocksource and arch specific bits */ 218 + TCTL_TEN, /* start the timer */ 219 + TIMER_BASE + MXC_TCTL); 220 + 221 + /* init and register the timer to the framework */ 222 + mxc_clocksource_init(); 223 + mxc_clockevent_init(); 224 + 225 + /* Make irqs happen */ 226 + setup_irq(TIMER_INTERRUPT, &mxc_timer_irq); 227 + } 228 +
+1 -3
include/asm-arm/arch-mxc/common.h
··· 11 11 #ifndef __ASM_ARCH_MXC_COMMON_H__ 12 12 #define __ASM_ARCH_MXC_COMMON_H__ 13 13 14 - struct sys_timer; 15 - 16 14 extern void mxc_map_io(void); 17 15 extern void mxc_init_irq(void); 18 - extern struct sys_timer mxc_timer; 16 + extern void mxc_timer_init(const char *clk_timer); 19 17 extern int mxc_clocks_init(unsigned long fref); 20 18 extern int mxc_register_gpios(void); 21 19
+15 -97
include/asm-arm/arch-mxc/mxc.h
··· 1 1 /* 2 2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 3 - */ 4 - 5 - /* 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 3 + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 + * MA 02110-1301, USA. 9 18 */ 10 19 11 20 #ifndef __ASM_ARCH_MXC_H__ ··· 28 19 #ifndef CONFIG_ARCH_MX3 29 20 # define cpu_is_mx31() (0) 30 21 #endif 31 - 32 - /* 33 - ***************************************** 34 - * GPT Register definitions * 35 - ***************************************** 36 - */ 37 - #define MXC_GPT_GPTCR IO_ADDRESS(GPT1_BASE_ADDR + 0x00) 38 - #define MXC_GPT_GPTPR IO_ADDRESS(GPT1_BASE_ADDR + 0x04) 39 - #define MXC_GPT_GPTSR IO_ADDRESS(GPT1_BASE_ADDR + 0x08) 40 - #define MXC_GPT_GPTIR IO_ADDRESS(GPT1_BASE_ADDR + 0x0C) 41 - #define MXC_GPT_GPTOCR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x10) 42 - #define MXC_GPT_GPTOCR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x14) 43 - #define MXC_GPT_GPTOCR3 IO_ADDRESS(GPT1_BASE_ADDR + 0x18) 44 - #define MXC_GPT_GPTICR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x1C) 45 - #define MXC_GPT_GPTICR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x20) 46 - #define MXC_GPT_GPTCNT IO_ADDRESS(GPT1_BASE_ADDR + 0x24) 47 - 48 - /* GPT Control register bit definitions */ 49 - #define GPTCR_FO3 (1 << 31) 50 - #define GPTCR_FO2 (1 << 30) 51 - #define GPTCR_FO1 (1 << 29) 52 - 53 - #define GPTCR_OM3_SHIFT 26 54 - #define GPTCR_OM3_MASK (7 << GPTCR_OM3_SHIFT) 55 - #define GPTCR_OM3_DISCONNECTED (0 << GPTCR_OM3_SHIFT) 56 - #define GPTCR_OM3_TOGGLE (1 << GPTCR_OM3_SHIFT) 57 - #define GPTCR_OM3_CLEAR (2 << GPTCR_OM3_SHIFT) 58 - #define GPTCR_OM3_SET (3 << GPTCR_OM3_SHIFT) 59 - #define GPTCR_OM3_GENERATE_LOW (7 << GPTCR_OM3_SHIFT) 60 - 61 - #define GPTCR_OM2_SHIFT 23 62 - #define GPTCR_OM2_MASK (7 << GPTCR_OM2_SHIFT) 63 - #define GPTCR_OM2_DISCONNECTED (0 << GPTCR_OM2_SHIFT) 64 - #define GPTCR_OM2_TOGGLE (1 << GPTCR_OM2_SHIFT) 65 - #define GPTCR_OM2_CLEAR (2 << GPTCR_OM2_SHIFT) 66 - #define GPTCR_OM2_SET (3 << GPTCR_OM2_SHIFT) 67 - #define GPTCR_OM2_GENERATE_LOW (7 << GPTCR_OM2_SHIFT) 68 - 69 - #define GPTCR_OM1_SHIFT 20 70 - #define GPTCR_OM1_MASK (7 << GPTCR_OM1_SHIFT) 71 - #define GPTCR_OM1_DISCONNECTED (0 << GPTCR_OM1_SHIFT) 72 - #define GPTCR_OM1_TOGGLE (1 << GPTCR_OM1_SHIFT) 73 - #define GPTCR_OM1_CLEAR (2 << GPTCR_OM1_SHIFT) 74 - #define GPTCR_OM1_SET (3 << GPTCR_OM1_SHIFT) 75 - #define GPTCR_OM1_GENERATE_LOW (7 << GPTCR_OM1_SHIFT) 76 - 77 - #define GPTCR_IM2_SHIFT 18 78 - #define GPTCR_IM2_MASK (3 << GPTCR_IM2_SHIFT) 79 - #define GPTCR_IM2_CAPTURE_DISABLE (0 << GPTCR_IM2_SHIFT) 80 - #define GPTCR_IM2_CAPTURE_RISING (1 << GPTCR_IM2_SHIFT) 81 - #define GPTCR_IM2_CAPTURE_FALLING (2 << GPTCR_IM2_SHIFT) 82 - #define GPTCR_IM2_CAPTURE_BOTH (3 << GPTCR_IM2_SHIFT) 83 - 84 - #define GPTCR_IM1_SHIFT 16 85 - #define GPTCR_IM1_MASK (3 << GPTCR_IM1_SHIFT) 86 - #define GPTCR_IM1_CAPTURE_DISABLE (0 << GPTCR_IM1_SHIFT) 87 - #define GPTCR_IM1_CAPTURE_RISING (1 << GPTCR_IM1_SHIFT) 88 - #define GPTCR_IM1_CAPTURE_FALLING (2 << GPTCR_IM1_SHIFT) 89 - #define GPTCR_IM1_CAPTURE_BOTH (3 << GPTCR_IM1_SHIFT) 90 - 91 - #define GPTCR_SWR (1 << 15) 92 - #define GPTCR_FRR (1 << 9) 93 - 94 - #define GPTCR_CLKSRC_SHIFT 6 95 - #define GPTCR_CLKSRC_MASK (7 << GPTCR_CLKSRC_SHIFT) 96 - #define GPTCR_CLKSRC_NOCLOCK (0 << GPTCR_CLKSRC_SHIFT) 97 - #define GPTCR_CLKSRC_HIGHFREQ (2 << GPTCR_CLKSRC_SHIFT) 98 - #define GPTCR_CLKSRC_CLKIN (3 << GPTCR_CLKSRC_SHIFT) 99 - #define GPTCR_CLKSRC_CLK32K (7 << GPTCR_CLKSRC_SHIFT) 100 - 101 - #define GPTCR_STOPEN (1 << 5) 102 - #define GPTCR_DOZEN (1 << 4) 103 - #define GPTCR_WAITEN (1 << 3) 104 - #define GPTCR_DBGEN (1 << 2) 105 - 106 - #define GPTCR_ENMOD (1 << 1) 107 - #define GPTCR_ENABLE (1 << 0) 108 - 109 - #define GPTSR_OF1 (1 << 0) 110 - #define GPTSR_OF2 (1 << 1) 111 - #define GPTSR_OF3 (1 << 2) 112 - #define GPTSR_IF1 (1 << 3) 113 - #define GPTSR_IF2 (1 << 4) 114 - #define GPTSR_ROV (1 << 5) 115 - 116 - #define GPTIR_OF1IE GPTSR_OF1 117 - #define GPTIR_OF2IE GPTSR_OF2 118 - #define GPTIR_OF3IE GPTSR_OF3 119 - #define GPTIR_IF1IE GPTSR_IF1 120 - #define GPTIR_IF2IE GPTSR_IF2 121 - #define GPTIR_ROVIE GPTSR_ROV 122 22 123 23 /* 124 24 *****************************************
+158
include/asm-arm/arch-mxc/mxc_timer.h
··· 1 + /* 2 + * mxc_timer.h 3 + * 4 + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) 5 + * 6 + * Platform independent (i.MX1, i.MX2, i.MX3) definition for timer handling. 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * as published by the Free Software Foundation; either version 2 11 + * of the License, or (at your option) any later version. 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 + * Boston, MA 02110-1301, USA. 21 + */ 22 + 23 + #ifndef __PLAT_MXC_TIMER_H 24 + #define __PLAT_MXC_TIMER_H 25 + 26 + #include <linux/clk.h> 27 + #include <asm/hardware.h> 28 + 29 + #ifdef CONFIG_ARCH_IMX 30 + #define TIMER_BASE IO_ADDRESS(TIM1_BASE_ADDR) 31 + #define TIMER_INTERRUPT TIM1_INT 32 + 33 + #define TCTL_VAL TCTL_CLK_PCLK1 34 + #define TCTL_IRQEN (1<<4) 35 + #define TCTL_FRR (1<<8) 36 + #define TCTL_CLK_PCLK1 (1<<1) 37 + #define TCTL_CLK_PCLK1_4 (2<<1) 38 + #define TCTL_CLK_TIN (3<<1) 39 + #define TCTL_CLK_32 (4<<1) 40 + 41 + #define MXC_TCTL 0x00 42 + #define MXC_TPRER 0x04 43 + #define MXC_TCMP 0x08 44 + #define MXC_TCR 0x0c 45 + #define MXC_TCN 0x10 46 + #define MXC_TSTAT 0x14 47 + #define TSTAT_CAPT (1<<1) 48 + #define TSTAT_COMP (1<<0) 49 + 50 + static inline void gpt_irq_disable(void) 51 + { 52 + unsigned int tmp; 53 + 54 + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); 55 + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); 56 + } 57 + 58 + static inline void gpt_irq_enable(void) 59 + { 60 + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, 61 + TIMER_BASE + MXC_TCTL); 62 + } 63 + 64 + static void gpt_irq_acknowledge(void) 65 + { 66 + __raw_writel(0, TIMER_BASE + MXC_TSTAT); 67 + } 68 + #endif /* CONFIG_ARCH_IMX */ 69 + 70 + #ifdef CONFIG_ARCH_MX2 71 + #define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) 72 + #define TIMER_INTERRUPT MXC_INT_GPT1 73 + 74 + #define MXC_TCTL 0x00 75 + #define TCTL_VAL TCTL_CLK_PCLK1 76 + #define TCTL_CLK_PCLK1 (1<<1) 77 + #define TCTL_CLK_PCLK1_4 (2<<1) 78 + #define TCTL_IRQEN (1<<4) 79 + #define TCTL_FRR (1<<8) 80 + #define MXC_TPRER 0x04 81 + #define MXC_TCMP 0x08 82 + #define MXC_TCR 0x0c 83 + #define MXC_TCN 0x10 84 + #define MXC_TSTAT 0x14 85 + #define TSTAT_CAPT (1<<1) 86 + #define TSTAT_COMP (1<<0) 87 + 88 + static inline void gpt_irq_disable(void) 89 + { 90 + unsigned int tmp; 91 + 92 + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); 93 + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); 94 + } 95 + 96 + static inline void gpt_irq_enable(void) 97 + { 98 + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, 99 + TIMER_BASE + MXC_TCTL); 100 + } 101 + 102 + static void gpt_irq_acknowledge(void) 103 + { 104 + __raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT); 105 + } 106 + #endif /* CONFIG_ARCH_MX2 */ 107 + 108 + #ifdef CONFIG_ARCH_MX3 109 + #define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) 110 + #define TIMER_INTERRUPT MXC_INT_GPT 111 + 112 + #define MXC_TCTL 0x00 113 + #define TCTL_VAL (TCTL_CLK_IPG | TCTL_WAITEN) 114 + #define TCTL_CLK_IPG (1<<6) 115 + #define TCTL_FRR (1<<9) 116 + #define TCTL_WAITEN (1<<3) 117 + 118 + #define MXC_TPRER 0x04 119 + #define MXC_TSTAT 0x08 120 + #define TSTAT_OF1 (1<<0) 121 + #define TSTAT_OF2 (1<<1) 122 + #define TSTAT_OF3 (1<<2) 123 + #define TSTAT_IF1 (1<<3) 124 + #define TSTAT_IF2 (1<<4) 125 + #define TSTAT_ROV (1<<5) 126 + #define MXC_IR 0x0c 127 + #define MXC_TCMP 0x10 128 + #define MXC_TCMP2 0x14 129 + #define MXC_TCMP3 0x18 130 + #define MXC_TCR 0x1c 131 + #define MXC_TCN 0x24 132 + 133 + static inline void gpt_irq_disable(void) 134 + { 135 + __raw_writel(0, TIMER_BASE + MXC_IR); 136 + } 137 + 138 + static inline void gpt_irq_enable(void) 139 + { 140 + __raw_writel(1<<0, TIMER_BASE + MXC_IR); 141 + } 142 + 143 + static inline void gpt_irq_acknowledge(void) 144 + { 145 + __raw_writel(TSTAT_OF1, TIMER_BASE + MXC_TSTAT); 146 + } 147 + #endif /* CONFIG_ARCH_MX3 */ 148 + 149 + #define TCTL_SWR (1<<15) 150 + #define TCTL_CC (1<<10) 151 + #define TCTL_OM (1<<9) 152 + #define TCTL_CAP_RIS (1<<6) 153 + #define TCTL_CAP_FAL (2<<6) 154 + #define TCTL_CAP_RIS_FAL (3<<6) 155 + #define TCTL_CAP_ENA (1<<5) 156 + #define TCTL_TEN (1<<0) 157 + 158 + #endif