OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [alpha/] [kernel/] [sys_wildfire.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/alpha/kernel/sys_wildfire.c
3
 *
4
 *  Wildfire support.
5
 *
6
 *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
7
 */
8
 
9
#include <linux/kernel.h>
10
#include <linux/types.h>
11
#include <linux/mm.h>
12
#include <linux/sched.h>
13
#include <linux/pci.h>
14
#include <linux/init.h>
15
 
16
#include <asm/ptrace.h>
17
#include <asm/system.h>
18
#include <asm/dma.h>
19
#include <asm/irq.h>
20
#include <asm/bitops.h>
21
#include <asm/mmu_context.h>
22
#include <asm/io.h>
23
#include <asm/pgtable.h>
24
#include <asm/core_wildfire.h>
25
#include <asm/hwrpb.h>
26
 
27
#include "proto.h"
28
#include "irq_impl.h"
29
#include "pci_impl.h"
30
#include "machvec_impl.h"
31
 
32
static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];
33
 
34
spinlock_t wildfire_irq_lock = SPIN_LOCK_UNLOCKED;
35
 
36
static int doing_init_irq_hw = 0;
37
 
38
static void
39
wildfire_update_irq_hw(unsigned int irq)
40
{
41
        int qbbno = (irq >> 8) & (WILDFIRE_MAX_QBB - 1);
42
        int pcano = (irq >> 6) & (WILDFIRE_PCA_PER_QBB - 1);
43
        wildfire_pca *pca;
44
        volatile unsigned long * enable0;
45
 
46
        if (!WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
47
                if (!doing_init_irq_hw) {
48
                        printk(KERN_ERR "wildfire_update_irq_hw:"
49
                               " got irq %d for non-existent PCA %d"
50
                               " on QBB %d.\n",
51
                               irq, pcano, qbbno);
52
                }
53
                return;
54
        }
55
 
56
        pca = WILDFIRE_pca(qbbno, pcano);
57
        enable0 = (unsigned long *) &pca->pca_int[0].enable; /* ??? */
58
 
59
        *enable0 = cached_irq_mask[qbbno * WILDFIRE_PCA_PER_QBB + pcano];
60
        mb();
61
        *enable0;
62
}
63
 
64
static void __init
65
wildfire_init_irq_hw(void)
66
{
67
#if 0
68
        register wildfire_pca * pca = WILDFIRE_pca(0, 0);
69
        volatile unsigned long * enable0, * enable1, * enable2, *enable3;
70
        volatile unsigned long * target0, * target1, * target2, *target3;
71
 
72
        enable0 = (unsigned long *) &pca->pca_int[0].enable;
73
        enable1 = (unsigned long *) &pca->pca_int[1].enable;
74
        enable2 = (unsigned long *) &pca->pca_int[2].enable;
75
        enable3 = (unsigned long *) &pca->pca_int[3].enable;
76
 
77
        target0 = (unsigned long *) &pca->pca_int[0].target;
78
        target1 = (unsigned long *) &pca->pca_int[1].target;
79
        target2 = (unsigned long *) &pca->pca_int[2].target;
80
        target3 = (unsigned long *) &pca->pca_int[3].target;
81
 
82
        *enable0 = *enable1 = *enable2 = *enable3 = 0;
83
 
84
        *target0 = (1UL<<8) | WILDFIRE_QBB(0);
85
        *target1 = *target2 = *target3 = 0;
86
 
87
        mb();
88
 
89
        *enable0; *enable1; *enable2; *enable3;
90
        *target0; *target1; *target2; *target3;
91
 
92
#else
93
        int i;
94
 
95
        doing_init_irq_hw = 1;
96
 
97
        /* Need to update only once for every possible PCA. */
98
        for (i = 0; i < WILDFIRE_NR_IRQS; i+=WILDFIRE_IRQ_PER_PCA)
99
                wildfire_update_irq_hw(i);
100
 
101
        doing_init_irq_hw = 0;
102
#endif
103
}
104
 
105
static void
106
wildfire_enable_irq(unsigned int irq)
107
{
108
        if (irq < 16)
109
                i8259a_enable_irq(irq);
110
 
111
        spin_lock(&wildfire_irq_lock);
112
        set_bit(irq, &cached_irq_mask);
113
        wildfire_update_irq_hw(irq);
114
        spin_unlock(&wildfire_irq_lock);
115
}
116
 
117
static void
118
wildfire_disable_irq(unsigned int irq)
119
{
120
        if (irq < 16)
121
                i8259a_disable_irq(irq);
122
 
123
        spin_lock(&wildfire_irq_lock);
124
        clear_bit(irq, &cached_irq_mask);
125
        wildfire_update_irq_hw(irq);
126
        spin_unlock(&wildfire_irq_lock);
127
}
128
 
129
static void
130
wildfire_mask_and_ack_irq(unsigned int irq)
131
{
132
        if (irq < 16)
133
                i8259a_mask_and_ack_irq(irq);
134
 
135
        spin_lock(&wildfire_irq_lock);
136
        clear_bit(irq, &cached_irq_mask);
137
        wildfire_update_irq_hw(irq);
138
        spin_unlock(&wildfire_irq_lock);
139
}
140
 
141
static unsigned int
142
wildfire_startup_irq(unsigned int irq)
143
{
144
        wildfire_enable_irq(irq);
145
        return 0; /* never anything pending */
146
}
147
 
148
static void
149
wildfire_end_irq(unsigned int irq)
150
{
151
#if 0
152
        if (!irq_desc[irq].action)
153
                printk("got irq %d\n", irq);
154
#endif
155
        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
156
                wildfire_enable_irq(irq);
157
}
158
 
159
static struct hw_interrupt_type wildfire_irq_type = {
160
        typename:       "WILDFIRE",
161
        startup:        wildfire_startup_irq,
162
        shutdown:       wildfire_disable_irq,
163
        enable:         wildfire_enable_irq,
164
        disable:        wildfire_disable_irq,
165
        ack:            wildfire_mask_and_ack_irq,
166
        end:            wildfire_end_irq,
167
};
168
 
169
static void __init
170
wildfire_init_irq_per_pca(int qbbno, int pcano)
171
{
172
        int i, irq_bias;
173
        unsigned long io_bias;
174
        static struct irqaction isa_enable = {
175
                handler:        no_action,
176
                name:           "isa_enable",
177
        };
178
 
179
        irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
180
                 + pcano * WILDFIRE_IRQ_PER_PCA;
181
 
182
        /* Only need the following for first PCI bus per PCA. */
183
        io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS;
184
 
185
#if 0
186
        outb(0, DMA1_RESET_REG + io_bias);
187
        outb(0, DMA2_RESET_REG + io_bias);
188
        outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias);
189
        outb(0, DMA2_MASK_REG + io_bias);
190
#endif
191
 
192
#if 0
193
        /* ??? Not sure how to do this, yet... */
194
        init_i8259a_irqs(); /* ??? */
195
#endif
196
 
197
        for (i = 0; i < 16; ++i) {
198
                if (i == 2)
199
                        continue;
200
                irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
201
                irq_desc[i+irq_bias].handler = &wildfire_irq_type;
202
        }
203
 
204
        irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
205
        irq_desc[36+irq_bias].handler = &wildfire_irq_type;
206
        for (i = 40; i < 64; ++i) {
207
                irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
208
                irq_desc[i+irq_bias].handler = &wildfire_irq_type;
209
        }
210
 
211
        setup_irq(32+irq_bias, &isa_enable);
212
}
213
 
214
static void __init
215
wildfire_init_irq(void)
216
{
217
        int qbbno, pcano;
218
 
219
#if 1
220
        wildfire_init_irq_hw();
221
        init_i8259a_irqs();
222
#endif
223
 
224
        for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
225
          if (WILDFIRE_QBB_EXISTS(qbbno)) {
226
            for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
227
              if (WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
228
                wildfire_init_irq_per_pca(qbbno, pcano);
229
              }
230
            }
231
          }
232
        }
233
}
234
 
235
static void
236
wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs)
237
{
238
        int irq;
239
 
240
        irq = (vector - 0x800) >> 4;
241
 
242
        /*
243
         * bits 10-8:   source QBB ID
244
         * bits 7-6:    PCA
245
         * bits 5-0:    irq in PCA
246
         */
247
 
248
        handle_irq(irq, regs);
249
        return;
250
}
251
 
252
/*
253
 * PCI Fixup configuration.
254
 *
255
 * Summary per PCA (2 PCI or HIPPI buses):
256
 *
257
 * Bit      Meaning
258
 * 0-15     ISA
259
 *
260
 *32        ISA summary
261
 *33        SMI
262
 *34        NMI
263
 *36        builtin QLogic SCSI (or slot 0 if no IO module)
264
 *40        Interrupt Line A from slot 2 PCI0
265
 *41        Interrupt Line B from slot 2 PCI0
266
 *42        Interrupt Line C from slot 2 PCI0
267
 *43        Interrupt Line D from slot 2 PCI0
268
 *44        Interrupt Line A from slot 3 PCI0
269
 *45        Interrupt Line B from slot 3 PCI0
270
 *46        Interrupt Line C from slot 3 PCI0
271
 *47        Interrupt Line D from slot 3 PCI0
272
 *
273
 *48        Interrupt Line A from slot 4 PCI1
274
 *49        Interrupt Line B from slot 4 PCI1
275
 *50        Interrupt Line C from slot 4 PCI1
276
 *51        Interrupt Line D from slot 4 PCI1
277
 *52        Interrupt Line A from slot 5 PCI1
278
 *53        Interrupt Line B from slot 5 PCI1
279
 *54        Interrupt Line C from slot 5 PCI1
280
 *55        Interrupt Line D from slot 5 PCI1
281
 *56        Interrupt Line A from slot 6 PCI1
282
 *57        Interrupt Line B from slot 6 PCI1
283
 *58        Interrupt Line C from slot 6 PCI1
284
 *50        Interrupt Line D from slot 6 PCI1
285
 *60        Interrupt Line A from slot 7 PCI1
286
 *61        Interrupt Line B from slot 7 PCI1
287
 *62        Interrupt Line C from slot 7 PCI1
288
 *63        Interrupt Line D from slot 7 PCI1
289
 *
290
 *
291
 * IdSel
292
 *   0   Cypress Bridge I/O (ISA summary interrupt)
293
 *   1   64 bit PCI 0 option slot 1 (SCSI QLogic builtin)
294
 *   2   64 bit PCI 0 option slot 2
295
 *   3   64 bit PCI 0 option slot 3
296
 *   4   64 bit PCI 1 option slot 4
297
 *   5   64 bit PCI 1 option slot 5
298
 *   6   64 bit PCI 1 option slot 6
299
 *   7   64 bit PCI 1 option slot 7
300
 */
301
 
302
static int __init
303
wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
304
{
305
        static char irq_tab[8][5] __initdata = {
306
                /*INT    INTA   INTB   INTC   INTD */
307
                { -1,    -1,    -1,    -1,    -1}, /* IdSel 0 ISA Bridge */
308
                { 36,    36,    36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
309
                { 40,    40,    40+1, 40+2, 40+3}, /* IdSel 2 PCI 0 slot 2 */
310
                { 44,    44,    44+1, 44+2, 44+3}, /* IdSel 3 PCI 0 slot 3 */
311
                { 48,    48,    48+1, 48+2, 48+3}, /* IdSel 4 PCI 1 slot 4 */
312
                { 52,    52,    52+1, 52+2, 52+3}, /* IdSel 5 PCI 1 slot 5 */
313
                { 56,    56,    56+1, 56+2, 56+3}, /* IdSel 6 PCI 1 slot 6 */
314
                { 60,    60,    60+1, 60+2, 60+3}, /* IdSel 7 PCI 1 slot 7 */
315
        };
316
        const long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;
317
 
318
        struct pci_controller *hose = dev->sysdata;
319
        int irq = COMMON_TABLE_LOOKUP;
320
 
321
        if (irq > 0) {
322
                int qbbno = hose->index >> 3;
323
                int pcano = (hose->index >> 1) & 3;
324
                irq += (qbbno << 8) + (pcano << 6);
325
        }
326
        return irq;
327
}
328
 
329
 
330
/*
331
 * The System Vectors
332
 */
333
 
334
struct alpha_machine_vector wildfire_mv __initmv = {
335
        vector_name:            "WILDFIRE",
336
        DO_EV6_MMU,
337
        DO_DEFAULT_RTC,
338
        DO_WILDFIRE_IO,
339
        DO_WILDFIRE_BUS,
340
        machine_check:          wildfire_machine_check,
341
        max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
342
        min_io_address:         DEFAULT_IO_BASE,
343
        min_mem_address:        DEFAULT_MEM_BASE,
344
 
345
        nr_irqs:                WILDFIRE_NR_IRQS,
346
        device_interrupt:       wildfire_device_interrupt,
347
 
348
        init_arch:              wildfire_init_arch,
349
        init_irq:               wildfire_init_irq,
350
        init_rtc:               common_init_rtc,
351
        init_pci:               common_init_pci,
352
        kill_arch:              wildfire_kill_arch,
353
        pci_map_irq:            wildfire_map_irq,
354
        pci_swizzle:            common_swizzle,
355
 
356
        pa_to_nid:              wildfire_pa_to_nid,
357
        cpuid_to_nid:           wildfire_cpuid_to_nid,
358
        node_mem_start:         wildfire_node_mem_start,
359
        node_mem_size:          wildfire_node_mem_size,
360
};
361
ALIAS_MV(wildfire)

powered by: WebSVN 2.1.0

© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.