blob: 86c5149b1721250e4ea7add3e89dcf750c5c98dc [file] [log] [blame]
Bellido Nicolas038c5b62005-06-20 18:51:05 +01001/*
2 * linux/arch/arm/mach-aaec2000/core.c
3 *
4 * Code common to all AAEC-2000 machines
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
Bellido Nicolas4a91ca22005-10-28 16:51:42 +010016#include <linux/device.h>
Bellido Nicolas038c5b62005-06-20 18:51:05 +010017#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/interrupt.h>
20#include <linux/timex.h>
21#include <linux/signal.h>
22
23#include <asm/hardware.h>
24#include <asm/irq.h>
25
Bellido Nicolas4a91ca22005-10-28 16:51:42 +010026#include <asm/mach/flash.h>
Bellido Nicolas038c5b62005-06-20 18:51:05 +010027#include <asm/mach/irq.h>
28#include <asm/mach/time.h>
29#include <asm/mach/map.h>
30
31/*
32 * Common I/O mapping:
33 *
34 * Static virtual address mappings are as follow:
35 *
36 * 0xf8000000-0xf8001ffff: Devices connected to APB bus
37 * 0xf8002000-0xf8003ffff: Devices connected to AHB bus
38 *
39 * Below 0xe8000000 is reserved for vm allocation.
40 *
41 * The machine specific code must provide the extra mapping beside the
42 * default mapping provided here.
43 */
44static struct map_desc standard_io_desc[] __initdata = {
Deepak Saxenaf70cd652005-10-28 15:18:56 +010045 {
46 .virtual = VIO_APB_BASE,
47 .physical = __phys_to_pfn(PIO_APB_BASE),
48 .length = IO_APB_LENGTH,
49 .type = MT_DEVICE
50 }, {
51 .virtual = VIO_AHB_BASE,
52 .physical = __phys_to_pfn(PIO_AHB_BASE),
53 .length = IO_AHB_LENGTH,
54 .type = MT_DEVICE
55 }
Bellido Nicolas038c5b62005-06-20 18:51:05 +010056};
57
58void __init aaec2000_map_io(void)
59{
60 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
61}
62
63/*
64 * Interrupt handling routines
65 */
66static void aaec2000_int_ack(unsigned int irq)
67{
68 IRQ_INTSR = 1 << irq;
69}
70
71static void aaec2000_int_mask(unsigned int irq)
72{
73 IRQ_INTENC |= (1 << irq);
74}
75
76static void aaec2000_int_unmask(unsigned int irq)
77{
78 IRQ_INTENS |= (1 << irq);
79}
80
81static struct irqchip aaec2000_irq_chip = {
82 .ack = aaec2000_int_ack,
83 .mask = aaec2000_int_mask,
84 .unmask = aaec2000_int_unmask,
85};
86
87void __init aaec2000_init_irq(void)
88{
89 unsigned int i;
90
91 for (i = 0; i < NR_IRQS; i++) {
92 set_irq_handler(i, do_level_IRQ);
93 set_irq_chip(i, &aaec2000_irq_chip);
94 set_irq_flags(i, IRQF_VALID);
95 }
96
97 /* Disable all interrupts */
98 IRQ_INTENC = 0xffffffff;
99
100 /* Clear any pending interrupts */
101 IRQ_INTSR = IRQ_INTSR;
102}
103
104/*
105 * Time keeping
106 */
107/* IRQs are disabled before entering here from do_gettimeofday() */
108static unsigned long aaec2000_gettimeoffset(void)
109{
110 unsigned long ticks_to_match, elapsed, usec;
111
112 /* Get ticks before next timer match */
113 ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
114
115 /* We need elapsed ticks since last match */
116 elapsed = LATCH - ticks_to_match;
117
118 /* Now, convert them to usec */
119 usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
120
121 return usec;
122}
123
124/* We enter here with IRQs enabled */
125static irqreturn_t
126aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
127{
128 /* TODO: Check timer accuracy */
129 write_seqlock(&xtime_lock);
130
131 timer_tick(regs);
132 TIMER1_CLEAR = 1;
133
134 write_sequnlock(&xtime_lock);
135
136 return IRQ_HANDLED;
137}
138
139static struct irqaction aaec2000_timer_irq = {
140 .name = "AAEC-2000 Timer Tick",
Russell King09b8b5f2005-06-26 17:06:36 +0100141 .flags = SA_INTERRUPT | SA_TIMER,
142 .handler = aaec2000_timer_interrupt,
Bellido Nicolas038c5b62005-06-20 18:51:05 +0100143};
144
145static void __init aaec2000_timer_init(void)
146{
147 /* Disable timer 1 */
148 TIMER1_CTRL = 0;
149
150 /* We have somehow to generate a 100Hz clock.
151 * We then use the 508KHz timer in periodic mode.
152 */
153 TIMER1_LOAD = LATCH;
154 TIMER1_CLEAR = 1; /* Clear interrupt */
155
156 setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
157
158 TIMER1_CTRL = TIMER_CTRL_ENABLE |
159 TIMER_CTRL_PERIODIC |
160 TIMER_CTRL_CLKSEL_508K;
161}
162
163struct sys_timer aaec2000_timer = {
164 .init = aaec2000_timer_init,
165 .offset = aaec2000_gettimeoffset,
166};
167
Bellido Nicolas4a91ca22005-10-28 16:51:42 +0100168static struct flash_platform_data aaec2000_flash_data = {
169 .map_name = "cfi_probe",
170 .width = 4,
171};
172
173static struct resource aaec2000_flash_resource = {
174 .start = AAEC_FLASH_BASE,
175 .end = AAEC_FLASH_BASE + AAEC_FLASH_SIZE,
176 .flags = IORESOURCE_MEM,
177};
178
179static struct platform_device aaec2000_flash_device = {
180 .name = "armflash",
181 .id = 0,
182 .dev = {
183 .platform_data = &aaec2000_flash_data,
184 },
185 .num_resources = 1,
186 .resource = &aaec2000_flash_resource,
187};
188
189static int __init aaec2000_init(void)
190{
191 platform_device_register(&aaec2000_flash_device);
192
193 return 0;
194};
195arch_initcall(aaec2000_init);
196