1 /* Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License,
5 * or (at your option) any later version. */
7 #include <linux/interrupt.h>
10 #include <linux/ioport.h>
12 #include <mach/hardware.h>
13 #include <asm/mach/time.h>
15 #define TIMER_1_COUNT(base_addr) (base_addr + 0x00)
16 #define TIMER_1_LOAD(base_addr) (base_addr + 0x04)
17 #define TIMER_1_MATCH1(base_addr) (base_addr + 0x08)
18 #define TIMER_1_MATCH2(base_addr) (base_addr + 0x0C)
20 #define TIMER_2_COUNT(base_addr) (base_addr + 0x10)
21 #define TIMER_2_LOAD(base_addr) (base_addr + 0x14)
22 #define TIMER_2_MATCH1(base_addr) (base_addr + 0x18)
23 #define TIMER_2_MATCH2(base_addr) (base_addr + 0x1C)
25 #define TIMER_3_COUNT(base_addr) (base_addr + 0x20)
26 #define TIMER_3_LOAD(base_addr) (base_addr + 0x24)
27 #define TIMER_3_MATCH1(base_addr) (base_addr + 0x28)
28 #define TIMER_3_MATCH2(base_addr) (base_addr + 0x2C)
30 #define TIMER_CR(base_addr) (base_addr + 0x30)
32 #define TIMER_1_CR_ENABLE(base_addr) (base_addr + 0x30)
33 #define TIMER_1_CR_EXTCLK(base_addr) (base_addr + 0x34)
34 #define TIMER_1_CR_FLOWIN(base_addr) (base_addr + 0x38)
36 #define TIMER_2_CR_ENABLE(base_addr) (base_addr + 0x42)
37 #define TIMER_2_CR_EXTCLK(base_addr) (base_addr + 0x46)
38 #define TIMER_2_CR_FLOWIN(base_addr) (base_addr + 0x50)
40 #define TIMER_3_CR_ENABLE(base_addr) (base_addr + 0x54)
41 #define TIMER_3_CR_EXTCLK(base_addr) (base_addr + 0x58)
42 #define TIMER_3_CR_FLOWIN(base_addr) (base_addr + 0x62)
44 #define TIMER_INTR_STATE(base_addr) (base_addr + 0x34)
46 #define TIMEREG_1_CR_ENABLE (1 << 0)
47 #define TIMEREG_1_CR_CLOCK (1 << 1)
48 #define TIMEREG_1_CR_INT (1 << 2)
49 #define TIMEREG_2_CR_ENABLE (1 << 3)
50 #define TIMEREG_2_CR_CLOCK (1 << 4)
51 #define TIMEREG_2_CR_INT (1 << 5)
52 #define TIMEREG_3_CR_ENABLE (1 << 6)
53 #define TIMEREG_3_CR_CLOCK (1 << 7)
54 #define TIMEREG_3_CR_INT (1 << 8)
55 #define TIMEREG_COUNT_UP (1 << 9)
56 #define TIMEREG_COUNT_DOWN (0 << 9)
58 /* is it needed? (defined to CONFIG_HZ in other drivers)
59 * arch/arm/Kconfig's config HZ is default 100. */
65 #define TIMER1_COUNT 0x0
66 #define TIMER1_LOAD 0x4
67 #define TIMER1_MATCH1 0x8
68 #define TIMER1_MATCH2 0xC
69 #define TIMER2_COUNT 0x10
70 #define TIMER2_LOAD 0x14
71 #define TIMER2_MATCH1 0x18
72 #define TIMER2_MATCH2 0x1C
73 #define TIMER3_COUNT 0x20
74 #define TIMER3_LOAD 0x24
75 #define TIMER3_MATCH1 0x28
76 #define TIMER3_MATCH2 0x2C
77 #define TIMER_INTR_MASK 0x38
79 static irqreturn_t
moxart_timer_interrupt(int irq
, void *dev_id
)
81 /* printk("TIMER moxart_timer_interrupt irq = %d\n", irq); */
82 /* __raw_writel(0, TIMER_INTR_STATE(IO_ADDRESS(MOXART_TIMER1_BASE))); */
89 static struct irqaction moxart_timer_irq
= {
90 .name
= "MOXART Timer Tick",
91 .flags
= IRQF_DISABLED
| IRQF_TIMER
,
92 .handler
= moxart_timer_interrupt
,
95 /*static struct resource timer_resource = {
96 .name = "timer_handler",
97 .start = IO_ADDRESS(MOXART_TIMER_BASE),
98 .end = IO_ADDRESS(TIMER_INTR_STATE(MOXART_TIMER_BASE)) + 4,
101 void __init
moxart_timer_init(void)
103 /* unsigned int t_int; */
105 setup_irq(IRQ_TIMER1
, &moxart_timer_irq
);
107 /*t_int = __raw_readl(TIMER_INTR_STATE(IO_ADDRESS(MOXART_TIMER1_BASE)));
108 printk("TIMER TIMER_INTR_STATE(IO_ADDRESS(MOXART_TIMER1_BASE))"
110 t_int = __raw_readl(TIMER_1_COUNT(IO_ADDRESS(MOXART_TIMER1_BASE)));
111 printk("TIMER TIMER_1_COUNT(IO_ADDRESS(MOXART_TIMER1_BASE))"
114 __raw_writel(APB_CLK
/ HZ
,
115 TIMER_1_COUNT(IO_ADDRESS(MOXART_TIMER_BASE
)));
116 __raw_writel(APB_CLK
/ HZ
,
117 TIMER_1_LOAD(IO_ADDRESS(MOXART_TIMER_BASE
)));
120 __raw_writel(0xffffffff, TIMER_1_MATCH1(IO_ADDRESS(MOXART_TIMER_BASE)));
121 __raw_writel(0xffffffff, TIMER_1_MATCH2(IO_ADDRESS(MOXART_TIMER_BASE)));
125 __raw_writel(TIMER_1_CR_ENABLE | TIMER_1_CR_INT,
126 TIMER_CR(IO_ADDRESS(MOXART_TIMER1_BASE)));
127 __raw_writel((1 << 0) | (1 << 2),
128 TIMER_1_CR_ENABLE(IO_ADDRESS(MOXART_TIMER_BASE)));
129 __raw_writel(0x0000020f,
130 TIMER_1_CR_ENABLE(IO_ADDRESS(MOXART_TIMER_BASE)));
131 __raw_writel(TIMEREG_COUNT_UP | TIMEREG_1_CR_ENABLE |
132 TIMEREG_1_CR_INT | TIMEREG_1_CR_CLOCK,
133 TIMER_1_CR_ENABLE(IO_ADDRESS(MOXART_TIMER_BASE)));
134 __raw_writel(TIMEREG_COUNT_UP | TIMEREG_1_CR_ENABLE |
136 TIMER_1_CR_ENABLE(IO_ADDRESS(MOXART_TIMER_BASE)));
139 __raw_writel(1, TIMER_1_CR_ENABLE(IO_ADDRESS(MOXART_TIMER_BASE
)));
140 __raw_writel(0, TIMER_1_CR_EXTCLK(IO_ADDRESS(MOXART_TIMER_BASE
)));
141 __raw_writel(1, TIMER_1_CR_FLOWIN(IO_ADDRESS(MOXART_TIMER_BASE
)));
143 /*t_int = __raw_readl(TIMER_INTR_STATE(IO_ADDRESS(MOXART_TIMER1_BASE)));
144 printk("TIMER TIMER_INTR_STATE(IO_ADDRESS(MOXART_TIMER1_BASE))"
147 t_int = __raw_readl(TIMER_1_COUNT(IO_ADDRESS(MOXART_TIMER1_BASE)));
148 printk("TIMER TIMER_1_COUNT(IO_ADDRESS(MOXART_TIMER1_BASE))"
150 t_int = __raw_readl(TIMER_1_LOAD(IO_ADDRESS(MOXART_TIMER1_BASE)));
151 printk("TIMER TIMER_1_LOAD(IO_ADDRESS(MOXART_TIMER1_BASE))"
156 "MOXART TIMER: count/load set (APB_CLK=%d / HZ=%d) IRQ=0x%x\n"
157 , APB_CLK
, HZ
, IRQ_TIMER1
);
160 struct sys_timer moxart_timer
= {
161 .init
= moxart_timer_init
,