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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-sparc/] [floppy.h] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
2
 *
3
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
4
 */
5
 
6
#ifndef __ASM_SPARC_FLOPPY_H
7
#define __ASM_SPARC_FLOPPY_H
8
 
9
#include <asm/page.h>
10
#include <asm/pgtable.h>
11
#include <asm/system.h>
12
#include <asm/idprom.h>
13
#include <asm/machines.h>
14
#include <asm/oplib.h>
15
#include <asm/auxio.h>
16
#include <asm/irq.h>
17
 
18
/* References:
19
 * 1) Netbsd Sun floppy driver.
20
 * 2) NCR 82077 controller manual
21
 * 3) Intel 82077 controller manual
22
 */
23
struct sun_flpy_controller {
24
        volatile unsigned char status_82072;  /* Main Status reg. */
25
#define dcr_82072              status_82072   /* Digital Control reg. */
26
#define status1_82077          status_82072   /* Auxiliary Status reg. 1 */
27
 
28
        volatile unsigned char data_82072;    /* Data fifo. */
29
#define status2_82077          data_82072     /* Auxiliary Status reg. 2 */
30
 
31
        volatile unsigned char dor_82077;     /* Digital Output reg. */
32
        volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
33
 
34
        volatile unsigned char status_82077;  /* Main Status Register. */
35
#define drs_82077              status_82077   /* Digital Rate Select reg. */
36
 
37
        volatile unsigned char data_82077;    /* Data fifo. */
38
        volatile unsigned char ___unused;
39
        volatile unsigned char dir_82077;     /* Digital Input reg. */
40
#define dcr_82077              dir_82077      /* Config Control reg. */
41
};
42
 
43
/* You'll only ever find one controller on a SparcStation anyways. */
44
static struct sun_flpy_controller *sun_fdc = NULL;
45
volatile unsigned char *fdc_status;
46
 
47
struct sun_floppy_ops {
48
        unsigned char (*fd_inb)(int port);
49
        void (*fd_outb)(unsigned char value, int port);
50
};
51
 
52
static struct sun_floppy_ops sun_fdops;
53
 
54
#define fd_inb(port)              sun_fdops.fd_inb(port)
55
#define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
56
#define fd_enable_dma()           sun_fd_enable_dma()
57
#define fd_disable_dma()          sun_fd_disable_dma()
58
#define fd_request_dma()          (0) /* nothing... */
59
#define fd_free_dma()             /* nothing... */
60
#define fd_clear_dma_ff()         /* nothing... */
61
#define fd_set_dma_mode(mode)     sun_fd_set_dma_mode(mode)
62
#define fd_set_dma_addr(addr)     sun_fd_set_dma_addr(addr)
63
#define fd_set_dma_count(count)   sun_fd_set_dma_count(count)
64
#define fd_enable_irq()           /* nothing... */
65
#define fd_disable_irq()          /* nothing... */
66
#define fd_cacheflush(addr, size) /* nothing... */
67
#define fd_request_irq()          sun_fd_request_irq()
68
#define fd_free_irq()             /* nothing... */
69
#if 0  /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
70
#define fd_dma_mem_alloc(size)    ((unsigned long) vmalloc(size))
71
#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
72
#endif
73
 
74
#define FLOPPY_MOTOR_MASK         0x10
75
 
76
/* It's all the same... */
77
#define virt_to_bus(x)            (x)
78
#define bus_to_virt(x)            (x)
79
 
80
/* XXX This isn't really correct. XXX */
81
#define get_dma_residue(x)        (0)
82
 
83
#define FLOPPY0_TYPE  4
84
#define FLOPPY1_TYPE  0
85
 
86
/* Super paranoid... */
87
#undef HAVE_DISABLE_HLT
88
 
89
/* Here is where we catch the floppy driver trying to initialize,
90
 * therefore this is where we call the PROM device tree probing
91
 * routine etc. on the Sparc.
92
 */
93
#define FDC1                      sun_floppy_init()
94
 
95
static int FDC2=-1;
96
 
97
#define N_FDC    1
98
#define N_DRIVE  8
99
 
100
/* No 64k boundary crossing problems on the Sparc. */
101
#define CROSS_64KB(a,s) (0)
102
 
103
/* Routines unique to each controller type on a Sun. */
104
static unsigned char sun_82072_fd_inb(int port)
105
{
106
        switch(port & 7) {
107
        default:
108
                printk("floppy: Asked to read unknown port %d\n", port);
109
                panic("floppy: Port bolixed.");
110
        case 4: /* FD_STATUS */
111
                return sun_fdc->status_82072 & ~STATUS_DMA;
112
        case 5: /* FD_DATA */
113
                return sun_fdc->data_82072;
114
        case 7: /* FD_DIR */
115
                return (*AUXREG & AUXIO_FLPY_DCHG)? 0x80: 0;
116
        };
117
        panic("sun_82072_fd_inb: How did I get here?");
118
}
119
 
120
static void sun_82072_fd_outb(unsigned char value, int port)
121
{
122
        switch(port & 7) {
123
        default:
124
                printk("floppy: Asked to write to unknown port %d\n", port);
125
                panic("floppy: Port bolixed.");
126
        case 2: /* FD_DOR */
127
                /* Oh geese, 82072 on the Sun has no DOR register,
128
                 * the functionality is implemented via the AUXIO
129
                 * I/O register.  So we must emulate the behavior.
130
                 *
131
                 * ASSUMPTIONS:  There will only ever be one floppy
132
                 *               drive attached to a Sun controller
133
                 *               and it will be at drive zero.
134
                 */
135
                {
136
                        unsigned bits = 0;
137
                        if (value & 0x10) bits |= AUXIO_FLPY_DSEL;
138
                        if ((value & 0x80) == 0) bits |= AUXIO_FLPY_EJCT;
139
                        set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
140
                }
141
                break;
142
        case 5: /* FD_DATA */
143
                sun_fdc->data_82072 = value;
144
                break;
145
        case 7: /* FD_DCR */
146
                sun_fdc->dcr_82072 = value;
147
                break;
148
        case 4: /* FD_STATUS */
149
                sun_fdc->status_82072 = value;
150
                break;
151
        };
152
        return;
153
}
154
 
155
static unsigned char sun_82077_fd_inb(int port)
156
{
157
        switch(port & 7) {
158
        default:
159
                printk("floppy: Asked to read unknown port %d\n", port);
160
                panic("floppy: Port bolixed.");
161
        case 4: /* FD_STATUS */
162
                return sun_fdc->status_82077 & ~STATUS_DMA;
163
        case 5: /* FD_DATA */
164
                return sun_fdc->data_82077;
165
        case 7: /* FD_DIR */
166
                /* XXX: Is DCL on 0x80 in sun4m? */
167
                return sun_fdc->dir_82077;
168
        };
169
        panic("sun_82072_fd_inb: How did I get here?");
170
}
171
 
172
static void sun_82077_fd_outb(unsigned char value, int port)
173
{
174
        switch(port & 7) {
175
        default:
176
                printk("floppy: Asked to write to unknown port %d\n", port);
177
                panic("floppy: Port bolixed.");
178
        case 2: /* FD_DOR */
179
                /* Happily, the 82077 has a real DOR register. */
180
                sun_fdc->dor_82077 = value;
181
                break;
182
        case 5: /* FD_DATA */
183
                sun_fdc->data_82077 = value;
184
                break;
185
        case 7: /* FD_DCR */
186
                sun_fdc->dcr_82077 = value;
187
                break;
188
        case 4: /* FD_STATUS */
189
                sun_fdc->status_82077 = value;
190
                break;
191
        };
192
        return;
193
}
194
 
195
/* For pseudo-dma (Sun floppy drives have no real DMA available to
196
 * them so we must eat the data fifo bytes directly ourselves) we have
197
 * three state variables.  doing_pdma tells our inline low-level
198
 * assembly floppy interrupt entry point whether it should sit and eat
199
 * bytes from the fifo or just transfer control up to the higher level
200
 * floppy interrupt c-code.  I tried very hard but I could not get the
201
 * pseudo-dma to work in c-code without getting many overruns and
202
 * underruns.  If non-zero, doing_pdma encodes the direction of
203
 * the transfer for debugging.  1=read 2=write
204
 */
205
char *pdma_vaddr;
206
unsigned long pdma_size;
207
volatile int doing_pdma = 0;
208
 
209
/* This is software state */
210
char *pdma_base = 0;
211
unsigned long pdma_areasize;
212
 
213
/* Common routines to all controller types on the Sparc. */
214
static inline void virtual_dma_init(void)
215
{
216
        /* nothing... */
217
}
218
 
219
static inline void sun_fd_disable_dma(void)
220
{
221
        doing_pdma = 0;
222
        if (pdma_base) {
223
                mmu_unlockarea(pdma_base, pdma_areasize);
224
                pdma_base = 0;
225
        }
226
}
227
 
228
static inline void sun_fd_set_dma_mode(int mode)
229
{
230
        switch(mode) {
231
        case DMA_MODE_READ:
232
                doing_pdma = 1;
233
                break;
234
        case DMA_MODE_WRITE:
235
                doing_pdma = 2;
236
                break;
237
        default:
238
                printk("Unknown dma mode %d\n", mode);
239
                panic("floppy: Giving up...");
240
        }
241
}
242
 
243
static inline void sun_fd_set_dma_addr(char *buffer)
244
{
245
        pdma_vaddr = buffer;
246
}
247
 
248
static inline void sun_fd_set_dma_count(int length)
249
{
250
        pdma_size = length;
251
}
252
 
253
static inline void sun_fd_enable_dma(void)
254
{
255
        pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
256
        pdma_base = pdma_vaddr;
257
        pdma_areasize = pdma_size;
258
}
259
 
260
/* Our low-level entry point in arch/sparc/kernel/entry.S */
261
extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs);
262
 
263
static int sun_fd_request_irq(void)
264
{
265
        static int once = 0;
266
        int error;
267
 
268
        if(!once) {
269
                once = 1;
270
                error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy");
271
                return ((error == 0) ? 0 : -1);
272
        } else return 0;
273
}
274
 
275
static struct linux_prom_registers fd_regs[2];
276
 
277
static int sun_floppy_init(void)
278
{
279
        char state[128];
280
        int tnode, fd_node, num_regs;
281
 
282
        use_virtual_dma = 1;
283
 
284
        FLOPPY_IRQ = 11;
285
        /* Forget it if we aren't on a machine that could possibly
286
         * ever have a floppy drive.
287
         */
288
        if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
289
           ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
290
            (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
291
                /* We certainly don't have a floppy controller. */
292
                goto no_sun_fdc;
293
        }
294
        /* Well, try to find one. */
295
        tnode = prom_getchild(prom_root_node);
296
        fd_node = prom_searchsiblings(tnode, "obio");
297
        if(fd_node != 0) {
298
                tnode = prom_getchild(fd_node);
299
                fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
300
        } else {
301
                fd_node = prom_searchsiblings(tnode, "fd");
302
        }
303
        if(fd_node == 0) {
304
                goto no_sun_fdc;
305
        }
306
 
307
        /* The sun4m lets us know if the controller is actually usable. */
308
        if(sparc_cpu_model == sun4m) {
309
                prom_getproperty(fd_node, "status", state, sizeof(state));
310
                if(!strcmp(state, "disabled")) {
311
                        goto no_sun_fdc;
312
                }
313
        }
314
        num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
315
        num_regs = (num_regs / sizeof(fd_regs[0]));
316
        prom_apply_obio_ranges(fd_regs, num_regs);
317
        sun_fdc = (struct sun_flpy_controller *) sparc_alloc_io(fd_regs[0].phys_addr,
318
                                                                0x0,
319
                                                                fd_regs[0].reg_size,
320
                                                                "floppy",
321
                                                                fd_regs[0].which_io,
322
                                                                0x0);
323
        /* Last minute sanity check... */
324
        if(sun_fdc->status_82072 == 0xff) {
325
                sun_fdc = NULL;
326
                goto no_sun_fdc;
327
        }
328
 
329
        if(sparc_cpu_model == sun4c) {
330
                sun_fdops.fd_inb = sun_82072_fd_inb;
331
                sun_fdops.fd_outb = sun_82072_fd_outb;
332
                fdc_status = &sun_fdc->status_82072;
333
                /* printk("AUXIO @0x%p\n", auxio_register); */ /* P3 */
334
        } else {
335
                sun_fdops.fd_inb = sun_82077_fd_inb;
336
                sun_fdops.fd_outb = sun_82077_fd_outb;
337
                fdc_status = &sun_fdc->status_82077;
338
                /* printk("DOR @0x%p\n", &sun_fdc->dor_82077); */ /* P3 */
339
        }
340
 
341
        /* Success... */
342
        return (int) sun_fdc;
343
 
344
no_sun_fdc:
345
        return -1;
346
}
347
 
348
static int sparc_eject(void)
349
{
350
        set_dor(0, ~0, 0x90);
351
        udelay(500);
352
        set_dor(0, ~0x90, 0);
353
        udelay(500);
354
        return 0;
355
}
356
 
357
#define fd_eject(drive) sparc_eject()
358
 
359
#endif /* !(__ASM_SPARC_FLOPPY_H) */

powered by: WebSVN 2.1.0

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