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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [tc/] [tc.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * tc-init: We assume the TURBOchannel to be up and running so
3
 * just probe for Modules and fill in the global data structure
4
 * tc_bus.
5
 *
6
 * This file is subject to the terms and conditions of the GNU General Public
7
 * License.  See the file "COPYING" in the main directory of this archive
8
 * for more details.
9
 *
10
 * Copyright (c) Harald Koerfgen, 1998
11
 * Copyright (c) 2001, 2003  Maciej W. Rozycki
12
 */
13
#include <linux/string.h>
14
#include <linux/init.h>
15
#include <linux/ioport.h>
16
#include <linux/kernel.h>
17
#include <linux/module.h>
18
 
19
#include <asm/addrspace.h>
20
#include <asm/errno.h>
21
#include <asm/dec/machtype.h>
22
#include <asm/dec/prom.h>
23
#include <asm/dec/tcinfo.h>
24
#include <asm/dec/tcmodule.h>
25
#include <asm/dec/interrupts.h>
26
#include <asm/paccess.h>
27
#include <asm/ptrace.h>
28
 
29
#define TC_DEBUG
30
 
31
MODULE_LICENSE("GPL");
32
slot_info tc_bus[MAX_SLOT];
33
static int num_tcslots;
34
static tcinfo *info;
35
 
36
unsigned long system_base;
37
 
38
/*
39
 * Interface to the world. Read comment in include/asm-mips/tc.h.
40
 */
41
 
42
int search_tc_card(const char *name)
43
{
44
        int slot;
45
        slot_info *sip;
46
 
47
        for (slot = 0; slot < num_tcslots; slot++) {
48
                sip = &tc_bus[slot];
49
                if ((sip->flags & FREE) &&
50
                    (strncmp(sip->name, name, strlen(name)) == 0)) {
51
                        return slot;
52
                }
53
        }
54
 
55
        return -ENODEV;
56
}
57
 
58
void claim_tc_card(int slot)
59
{
60
        if (tc_bus[slot].flags & IN_USE) {
61
                printk("claim_tc_card: attempting to claim a card already in use\n");
62
                return;
63
        }
64
        tc_bus[slot].flags &= ~FREE;
65
        tc_bus[slot].flags |= IN_USE;
66
}
67
 
68
void release_tc_card(int slot)
69
{
70
        if (tc_bus[slot].flags & FREE) {
71
                printk("release_tc_card: "
72
                       "attempting to release a card already free\n");
73
                return;
74
        }
75
        tc_bus[slot].flags &= ~IN_USE;
76
        tc_bus[slot].flags |= FREE;
77
}
78
 
79
unsigned long get_tc_base_addr(int slot)
80
{
81
        return tc_bus[slot].base_addr;
82
}
83
 
84
unsigned long get_tc_irq_nr(int slot)
85
{
86
        return tc_bus[slot].interrupt;
87
}
88
 
89
unsigned long get_tc_speed(void)
90
{
91
        return 100000 * (10000 / (unsigned long)info->clk_period);
92
}
93
 
94
/*
95
 * Probing for TURBOchannel modules
96
 */
97
static void __init tc_probe(unsigned long startaddr, unsigned long size,
98
                            int slots)
99
{
100
        int i, slot, err;
101
        long offset;
102
        unsigned char pattern[4];
103
        unsigned char *module;
104
 
105
        for (slot = 0; slot < slots; slot++) {
106
                module = (char *)(startaddr + slot * size);
107
 
108
                offset = OLDCARD;
109
 
110
                err = 0;
111
                err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
112
                err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
113
                err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
114
                err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
115
                if (err)
116
                        continue;
117
 
118
                if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
119
                    pattern[2] != 0xaa || pattern[3] != 0xff) {
120
                        offset = NEWCARD;
121
 
122
                        err = 0;
123
                        err |= get_dbe(pattern[0], module + TC_PATTERN0);
124
                        err |= get_dbe(pattern[1], module + TC_PATTERN1);
125
                        err |= get_dbe(pattern[2], module + TC_PATTERN2);
126
                        err |= get_dbe(pattern[3], module + TC_PATTERN3);
127
                        if (err)
128
                                continue;
129
                }
130
 
131
                if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
132
                    pattern[2] != 0xaa || pattern[3] != 0xff)
133
                        continue;
134
 
135
                tc_bus[slot].base_addr = (unsigned long)module;
136
                for(i = 0; i < 8; i++) {
137
                        tc_bus[slot].firmware[i] =
138
                                module[TC_FIRM_VER + offset + 4 * i];
139
                        tc_bus[slot].vendor[i] =
140
                                module[TC_VENDOR + offset + 4 * i];
141
                        tc_bus[slot].name[i] =
142
                                module[TC_MODULE + offset + 4 * i];
143
                }
144
                tc_bus[slot].firmware[8] = 0;
145
                tc_bus[slot].vendor[8] = 0;
146
                tc_bus[slot].name[8] = 0;
147
                /*
148
                 * Looks unneccesary, but we may change
149
                 * TC? in the future
150
                 */
151
                switch (slot) {
152
                case 0:
153
                        tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
154
                        break;
155
                case 1:
156
                        tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
157
                        break;
158
                case 2:
159
                        tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
160
                        break;
161
                /*
162
                 * Yuck! DS5000/200 onboard devices
163
                 */
164
                case 5:
165
                        tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
166
                        break;
167
                case 6:
168
                        tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
169
                        break;
170
                default:
171
                        tc_bus[slot].interrupt = -1;
172
                        break;
173
                }
174
        }
175
}
176
 
177
/*
178
 * the main entry
179
 */
180
void __init tc_init(void)
181
{
182
        int tc_clock;
183
        int i;
184
        unsigned long slot0addr;
185
        unsigned long slot_size;
186
 
187
        if (!TURBOCHANNEL)
188
                return;
189
 
190
        for (i = 0; i < MAX_SLOT; i++) {
191
                tc_bus[i].base_addr = 0;
192
                tc_bus[i].name[0] = 0;
193
                tc_bus[i].vendor[0] = 0;
194
                tc_bus[i].firmware[0] = 0;
195
                tc_bus[i].interrupt = -1;
196
                tc_bus[i].flags = FREE;
197
        }
198
 
199
        info = (tcinfo *) rex_gettcinfo();
200
        slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
201
 
202
        switch (mips_machtype) {
203
        case MACH_DS5000_200:
204
                num_tcslots = 7;
205
                break;
206
        case MACH_DS5000_1XX:
207
        case MACH_DS5000_2X0:
208
        case MACH_DS5900:
209
                num_tcslots = 3;
210
                break;
211
        case MACH_DS5000_XX:
212
        default:
213
                num_tcslots = 2;
214
                break;
215
        }
216
 
217
        tc_clock = 10000 / info->clk_period;
218
 
219
        if (TURBOCHANNEL && info->slot_size && slot0addr) {
220
                printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
221
                        tc_clock / 10, tc_clock % 10);
222
                printk("(with%s parity)\n", info->parity ? "" : "out");
223
 
224
                slot_size = info->slot_size << 20;
225
 
226
                tc_probe(slot0addr, slot_size, num_tcslots);
227
 
228
                /*
229
                 * All TURBOchannel DECstations have the onboard devices
230
                 * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
231
                 * would be.
232
                 */
233
                if(mips_machtype == MACH_DS5000_XX)
234
                        i = 1;
235
                else
236
                        i = 0;
237
 
238
                system_base = slot0addr + slot_size * (num_tcslots + i);
239
 
240
#ifdef TC_DEBUG
241
                for (i = 0; i < num_tcslots; i++)
242
                        if (tc_bus[i].base_addr) {
243
                                printk("    slot %d: ", i);
244
                                printk("%s %s %s\n", tc_bus[i].vendor,
245
                                        tc_bus[i].name, tc_bus[i].firmware);
246
                        }
247
#endif
248
                ioport_resource.end = KSEG2 - 1;
249
        }
250
}
251
 
252
EXPORT_SYMBOL(search_tc_card);
253
EXPORT_SYMBOL(claim_tc_card);
254
EXPORT_SYMBOL(release_tc_card);
255
EXPORT_SYMBOL(get_tc_base_addr);
256
EXPORT_SYMBOL(get_tc_irq_nr);
257
EXPORT_SYMBOL(get_tc_speed);
258
EXPORT_SYMBOL(system_base);

powered by: WebSVN 2.1.0

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