Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-footbridge/common.c
26295 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* linux/arch/arm/mach-footbridge/common.c
4
*
5
* Copyright (C) 1998-2000 Russell King, Dave Gilbert.
6
*/
7
#include <linux/module.h>
8
#include <linux/types.h>
9
#include <linux/mm.h>
10
#include <linux/ioport.h>
11
#include <linux/list.h>
12
#include <linux/init.h>
13
#include <linux/io.h>
14
#include <linux/spinlock.h>
15
#include <linux/dma-direct.h>
16
#include <video/vga.h>
17
18
#include <asm/page.h>
19
#include <asm/irq.h>
20
#include <asm/mach-types.h>
21
#include <asm/setup.h>
22
#include <asm/system_misc.h>
23
#include <asm/hardware/dec21285.h>
24
25
#include <asm/mach/irq.h>
26
#include <asm/mach/map.h>
27
#include <asm/mach/pci.h>
28
29
#include "common.h"
30
31
#include <mach/hardware.h>
32
#include <mach/irqs.h>
33
#include <asm/hardware/dec21285.h>
34
35
static int dc21285_get_irq(void)
36
{
37
void __iomem *irqstatus = (void __iomem *)CSR_IRQ_STATUS;
38
u32 mask = readl(irqstatus);
39
40
if (mask & IRQ_MASK_SDRAMPARITY)
41
return IRQ_SDRAMPARITY;
42
43
if (mask & IRQ_MASK_UART_RX)
44
return IRQ_CONRX;
45
46
if (mask & IRQ_MASK_DMA1)
47
return IRQ_DMA1;
48
49
if (mask & IRQ_MASK_DMA2)
50
return IRQ_DMA2;
51
52
if (mask & IRQ_MASK_IN0)
53
return IRQ_IN0;
54
55
if (mask & IRQ_MASK_IN1)
56
return IRQ_IN1;
57
58
if (mask & IRQ_MASK_IN2)
59
return IRQ_IN2;
60
61
if (mask & IRQ_MASK_IN3)
62
return IRQ_IN3;
63
64
if (mask & IRQ_MASK_PCI)
65
return IRQ_PCI;
66
67
if (mask & IRQ_MASK_DOORBELLHOST)
68
return IRQ_DOORBELLHOST;
69
70
if (mask & IRQ_MASK_I2OINPOST)
71
return IRQ_I2OINPOST;
72
73
if (mask & IRQ_MASK_TIMER1)
74
return IRQ_TIMER1;
75
76
if (mask & IRQ_MASK_TIMER2)
77
return IRQ_TIMER2;
78
79
if (mask & IRQ_MASK_TIMER3)
80
return IRQ_TIMER3;
81
82
if (mask & IRQ_MASK_UART_TX)
83
return IRQ_CONTX;
84
85
if (mask & IRQ_MASK_PCI_ABORT)
86
return IRQ_PCI_ABORT;
87
88
if (mask & IRQ_MASK_PCI_SERR)
89
return IRQ_PCI_SERR;
90
91
if (mask & IRQ_MASK_DISCARD_TIMER)
92
return IRQ_DISCARD_TIMER;
93
94
if (mask & IRQ_MASK_PCI_DPERR)
95
return IRQ_PCI_DPERR;
96
97
if (mask & IRQ_MASK_PCI_PERR)
98
return IRQ_PCI_PERR;
99
100
return 0;
101
}
102
103
static void dc21285_handle_irq(struct pt_regs *regs)
104
{
105
int irq;
106
do {
107
irq = dc21285_get_irq();
108
if (!irq)
109
break;
110
111
generic_handle_irq(irq);
112
} while (1);
113
}
114
115
116
unsigned int mem_fclk_21285 = 50000000;
117
118
EXPORT_SYMBOL(mem_fclk_21285);
119
120
static int __init early_fclk(char *arg)
121
{
122
mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
123
return 0;
124
}
125
126
early_param("mem_fclk_21285", early_fclk);
127
128
static int __init parse_tag_memclk(const struct tag *tag)
129
{
130
mem_fclk_21285 = tag->u.memclk.fmemclk;
131
return 0;
132
}
133
134
__tagtable(ATAG_MEMCLK, parse_tag_memclk);
135
136
/*
137
* Footbridge IRQ translation table
138
* Converts from our IRQ numbers into FootBridge masks
139
*/
140
static const int fb_irq_mask[] = {
141
IRQ_MASK_UART_RX, /* 0 */
142
IRQ_MASK_UART_TX, /* 1 */
143
IRQ_MASK_TIMER1, /* 2 */
144
IRQ_MASK_TIMER2, /* 3 */
145
IRQ_MASK_TIMER3, /* 4 */
146
IRQ_MASK_IN0, /* 5 */
147
IRQ_MASK_IN1, /* 6 */
148
IRQ_MASK_IN2, /* 7 */
149
IRQ_MASK_IN3, /* 8 */
150
IRQ_MASK_DOORBELLHOST, /* 9 */
151
IRQ_MASK_DMA1, /* 10 */
152
IRQ_MASK_DMA2, /* 11 */
153
IRQ_MASK_PCI, /* 12 */
154
IRQ_MASK_SDRAMPARITY, /* 13 */
155
IRQ_MASK_I2OINPOST, /* 14 */
156
IRQ_MASK_PCI_ABORT, /* 15 */
157
IRQ_MASK_PCI_SERR, /* 16 */
158
IRQ_MASK_DISCARD_TIMER, /* 17 */
159
IRQ_MASK_PCI_DPERR, /* 18 */
160
IRQ_MASK_PCI_PERR, /* 19 */
161
};
162
163
static void fb_mask_irq(struct irq_data *d)
164
{
165
*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(d->irq)];
166
}
167
168
static void fb_unmask_irq(struct irq_data *d)
169
{
170
*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(d->irq)];
171
}
172
173
static struct irq_chip fb_chip = {
174
.irq_ack = fb_mask_irq,
175
.irq_mask = fb_mask_irq,
176
.irq_unmask = fb_unmask_irq,
177
};
178
179
static void __init __fb_init_irq(void)
180
{
181
unsigned int irq;
182
183
/*
184
* setup DC21285 IRQs
185
*/
186
*CSR_IRQ_DISABLE = -1;
187
*CSR_FIQ_DISABLE = -1;
188
189
for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
190
irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq);
191
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
192
}
193
}
194
195
void __init footbridge_init_irq(void)
196
{
197
set_handle_irq(dc21285_handle_irq);
198
199
__fb_init_irq();
200
201
if (machine_is_ebsa285())
202
/* The following is dependent on which slot
203
* you plug the Southbridge card into. We
204
* currently assume that you plug it into
205
* the right-hand most slot.
206
*/
207
isa_init_irq(IRQ_PCI);
208
209
if (machine_is_netwinder())
210
isa_init_irq(IRQ_IN3);
211
}
212
213
/*
214
* Common mapping for all systems. Note that the outbound write flush is
215
* commented out since there is a "No Fix" problem with it. Not mapping
216
* it means that we have extra bullet protection on our feet.
217
*/
218
static struct map_desc ebsa285_host_io_desc[] __initdata = {
219
{
220
.virtual = ARMCSR_BASE,
221
.pfn = __phys_to_pfn(DC21285_ARMCSR_BASE),
222
.length = ARMCSR_SIZE,
223
.type = MT_DEVICE,
224
},
225
{
226
.virtual = PCIMEM_BASE,
227
.pfn = __phys_to_pfn(DC21285_PCI_MEM),
228
.length = PCIMEM_SIZE,
229
.type = MT_DEVICE,
230
}, {
231
.virtual = PCICFG0_BASE,
232
.pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
233
.length = PCICFG0_SIZE,
234
.type = MT_DEVICE,
235
}, {
236
.virtual = PCICFG1_BASE,
237
.pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
238
.length = PCICFG1_SIZE,
239
.type = MT_DEVICE,
240
}, {
241
.virtual = PCIIACK_BASE,
242
.pfn = __phys_to_pfn(DC21285_PCI_IACK),
243
.length = PCIIACK_SIZE,
244
.type = MT_DEVICE,
245
},
246
};
247
248
void __init footbridge_map_io(void)
249
{
250
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
251
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
252
vga_base = PCIMEM_BASE;
253
}
254
255
void footbridge_restart(enum reboot_mode mode, const char *cmd)
256
{
257
if (mode == REBOOT_SOFT) {
258
/* Jump into the ROM */
259
soft_restart(0x41000000);
260
} else {
261
/*
262
* Force the watchdog to do a CPU reset.
263
*
264
* After making sure that the watchdog is disabled
265
* (so we can change the timer registers) we first
266
* enable the timer to autoreload itself. Next, the
267
* timer interval is set really short and any
268
* current interrupt request is cleared (so we can
269
* see an edge transition). Finally, TIMER4 is
270
* enabled as the watchdog.
271
*/
272
*CSR_SA110_CNTL &= ~(1 << 13);
273
*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
274
TIMER_CNTL_AUTORELOAD |
275
TIMER_CNTL_DIV16;
276
*CSR_TIMER4_LOAD = 0x2;
277
*CSR_TIMER4_CLR = 0;
278
*CSR_SA110_CNTL |= (1 << 13);
279
}
280
}
281
282