]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - arch/sparc/include/asm/floppy_32.h
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-eoan-kernel.git] / arch / sparc / include / asm / floppy_32.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
a439fe51 2/* asm/floppy.h: Sparc specific parts of the Floppy driver.
f5e706ad
SR
3 *
4 * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
5 */
6
7#ifndef __ASM_SPARC_FLOPPY_H
8#define __ASM_SPARC_FLOPPY_H
9
454eeb2d
DM
10#include <linux/of.h>
11#include <linux/of_device.h>
12
f5e706ad 13#include <asm/pgtable.h>
f5e706ad 14#include <asm/idprom.h>
f5e706ad
SR
15#include <asm/oplib.h>
16#include <asm/auxio.h>
fbb86383
SR
17#include <asm/setup.h>
18#include <asm/page.h>
f5e706ad
SR
19#include <asm/irq.h>
20
21/* We don't need no stinkin' I/O port allocation crap. */
22#undef release_region
23#undef request_region
24#define release_region(X, Y) do { } while(0)
25#define request_region(X, Y, Z) (1)
26
27/* References:
28 * 1) Netbsd Sun floppy driver.
29 * 2) NCR 82077 controller manual
30 * 3) Intel 82077 controller manual
31 */
32struct sun_flpy_controller {
33 volatile unsigned char status_82072; /* Main Status reg. */
34#define dcr_82072 status_82072 /* Digital Control reg. */
35#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
36
37 volatile unsigned char data_82072; /* Data fifo. */
38#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
39
40 volatile unsigned char dor_82077; /* Digital Output reg. */
41 volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
42
43 volatile unsigned char status_82077; /* Main Status Register. */
44#define drs_82077 status_82077 /* Digital Rate Select reg. */
45
46 volatile unsigned char data_82077; /* Data fifo. */
47 volatile unsigned char ___unused;
48 volatile unsigned char dir_82077; /* Digital Input reg. */
49#define dcr_82077 dir_82077 /* Config Control reg. */
50};
51
52/* You'll only ever find one controller on a SparcStation anyways. */
53static struct sun_flpy_controller *sun_fdc = NULL;
f5e706ad
SR
54
55struct sun_floppy_ops {
56 unsigned char (*fd_inb)(int port);
57 void (*fd_outb)(unsigned char value, int port);
58};
59
60static struct sun_floppy_ops sun_fdops;
61
62#define fd_inb(port) sun_fdops.fd_inb(port)
63#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
64#define fd_enable_dma() sun_fd_enable_dma()
65#define fd_disable_dma() sun_fd_disable_dma()
66#define fd_request_dma() (0) /* nothing... */
67#define fd_free_dma() /* nothing... */
68#define fd_clear_dma_ff() /* nothing... */
69#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
70#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
71#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
72#define fd_enable_irq() /* nothing... */
73#define fd_disable_irq() /* nothing... */
74#define fd_cacheflush(addr, size) /* nothing... */
75#define fd_request_irq() sun_fd_request_irq()
76#define fd_free_irq() /* nothing... */
77#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
78#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
79#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
80#endif
81
82/* XXX This isn't really correct. XXX */
83#define get_dma_residue(x) (0)
84
85#define FLOPPY0_TYPE 4
86#define FLOPPY1_TYPE 0
87
88/* Super paranoid... */
89#undef HAVE_DISABLE_HLT
90
91/* Here is where we catch the floppy driver trying to initialize,
92 * therefore this is where we call the PROM device tree probing
93 * routine etc. on the Sparc.
94 */
95#define FDC1 sun_floppy_init()
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. */
104static void sun_set_dor(unsigned char value, int fdc_82077)
105{
0301a6cb 106 if (fdc_82077)
f5e706ad 107 sun_fdc->dor_82077 = value;
f5e706ad
SR
108}
109
110static unsigned char sun_read_dir(void)
111{
0301a6cb 112 return sun_fdc->dir_82077;
f5e706ad
SR
113}
114
115static unsigned char sun_82072_fd_inb(int port)
116{
117 udelay(5);
118 switch(port & 7) {
119 default:
120 printk("floppy: Asked to read unknown port %d\n", port);
121 panic("floppy: Port bolixed.");
122 case 4: /* FD_STATUS */
123 return sun_fdc->status_82072 & ~STATUS_DMA;
124 case 5: /* FD_DATA */
125 return sun_fdc->data_82072;
126 case 7: /* FD_DIR */
127 return sun_read_dir();
6cb79b3f 128 }
f5e706ad
SR
129 panic("sun_82072_fd_inb: How did I get here?");
130}
131
132static void sun_82072_fd_outb(unsigned char value, int port)
133{
134 udelay(5);
135 switch(port & 7) {
136 default:
137 printk("floppy: Asked to write to unknown port %d\n", port);
138 panic("floppy: Port bolixed.");
139 case 2: /* FD_DOR */
140 sun_set_dor(value, 0);
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;
6cb79b3f 151 }
f5e706ad
SR
152 return;
153}
154
155static unsigned char sun_82077_fd_inb(int port)
156{
157 udelay(5);
158 switch(port & 7) {
159 default:
160 printk("floppy: Asked to read unknown port %d\n", port);
161 panic("floppy: Port bolixed.");
162 case 0: /* FD_STATUS_0 */
163 return sun_fdc->status1_82077;
164 case 1: /* FD_STATUS_1 */
165 return sun_fdc->status2_82077;
166 case 2: /* FD_DOR */
167 return sun_fdc->dor_82077;
168 case 3: /* FD_TDR */
169 return sun_fdc->tapectl_82077;
170 case 4: /* FD_STATUS */
171 return sun_fdc->status_82077 & ~STATUS_DMA;
172 case 5: /* FD_DATA */
173 return sun_fdc->data_82077;
174 case 7: /* FD_DIR */
175 return sun_read_dir();
6cb79b3f 176 }
f5e706ad
SR
177 panic("sun_82077_fd_inb: How did I get here?");
178}
179
180static void sun_82077_fd_outb(unsigned char value, int port)
181{
182 udelay(5);
183 switch(port & 7) {
184 default:
185 printk("floppy: Asked to write to unknown port %d\n", port);
186 panic("floppy: Port bolixed.");
187 case 2: /* FD_DOR */
188 sun_set_dor(value, 1);
189 break;
190 case 5: /* FD_DATA */
191 sun_fdc->data_82077 = value;
192 break;
193 case 7: /* FD_DCR */
194 sun_fdc->dcr_82077 = value;
195 break;
196 case 4: /* FD_STATUS */
197 sun_fdc->status_82077 = value;
198 break;
199 case 3: /* FD_TDR */
200 sun_fdc->tapectl_82077 = value;
201 break;
6cb79b3f 202 }
f5e706ad
SR
203 return;
204}
205
206/* For pseudo-dma (Sun floppy drives have no real DMA available to
207 * them so we must eat the data fifo bytes directly ourselves) we have
208 * three state variables. doing_pdma tells our inline low-level
209 * assembly floppy interrupt entry point whether it should sit and eat
210 * bytes from the fifo or just transfer control up to the higher level
211 * floppy interrupt c-code. I tried very hard but I could not get the
212 * pseudo-dma to work in c-code without getting many overruns and
213 * underruns. If non-zero, doing_pdma encodes the direction of
214 * the transfer for debugging. 1=read 2=write
215 */
f5e706ad
SR
216
217/* Common routines to all controller types on the Sparc. */
218static inline void virtual_dma_init(void)
219{
220 /* nothing... */
221}
222
223static inline void sun_fd_disable_dma(void)
224{
225 doing_pdma = 0;
679bea5e 226 pdma_base = NULL;
f5e706ad
SR
227}
228
229static inline void sun_fd_set_dma_mode(int mode)
230{
231 switch(mode) {
232 case DMA_MODE_READ:
233 doing_pdma = 1;
234 break;
235 case DMA_MODE_WRITE:
236 doing_pdma = 2;
237 break;
238 default:
239 printk("Unknown dma mode %d\n", mode);
240 panic("floppy: Giving up...");
241 }
242}
243
244static inline void sun_fd_set_dma_addr(char *buffer)
245{
246 pdma_vaddr = buffer;
247}
248
249static inline void sun_fd_set_dma_count(int length)
250{
251 pdma_size = length;
252}
253
254static inline void sun_fd_enable_dma(void)
255{
f5e706ad
SR
256 pdma_base = pdma_vaddr;
257 pdma_areasize = pdma_size;
258}
259
f05a6865 260int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
f5e706ad
SR
261
262static int sun_fd_request_irq(void)
263{
264 static int once = 0;
f5e706ad 265
6baa9b20 266 if (!once) {
f5e706ad 267 once = 1;
6baa9b20
SR
268 return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
269 } else {
270 return 0;
271 }
f5e706ad
SR
272}
273
274static struct linux_prom_registers fd_regs[2];
275
276static int sun_floppy_init(void)
277{
6baa9b20
SR
278 struct platform_device *op;
279 struct device_node *dp;
144e988d 280 struct resource r;
f5e706ad 281 char state[128];
144e988d
SR
282 phandle fd_node;
283 phandle tnode;
8d125562 284 int num_regs;
f5e706ad
SR
285
286 use_virtual_dma = 1;
287
f5e706ad
SR
288 /* Forget it if we aren't on a machine that could possibly
289 * ever have a floppy drive.
290 */
58fa4dcb 291 if (sparc_cpu_model != sun4m) {
f5e706ad
SR
292 /* We certainly don't have a floppy controller. */
293 goto no_sun_fdc;
294 }
295 /* Well, try to find one. */
296 tnode = prom_getchild(prom_root_node);
297 fd_node = prom_searchsiblings(tnode, "obio");
144e988d 298 if (fd_node != 0) {
f5e706ad
SR
299 tnode = prom_getchild(fd_node);
300 fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
301 } else {
302 fd_node = prom_searchsiblings(tnode, "fd");
303 }
144e988d 304 if (fd_node == 0) {
f5e706ad
SR
305 goto no_sun_fdc;
306 }
307
308 /* The sun4m lets us know if the controller is actually usable. */
144e988d 309 if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
f5e706ad
SR
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 memset(&r, 0, sizeof(r));
318 r.flags = fd_regs[0].which_io;
319 r.start = fd_regs[0].phys_addr;
144e988d 320 sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
f5e706ad 321
6baa9b20
SR
322 /* Look up irq in platform_device.
323 * We try "SUNW,fdtwo" and "fd"
324 */
918f8322 325 op = NULL;
6baa9b20
SR
326 for_each_node_by_name(dp, "SUNW,fdtwo") {
327 op = of_find_device_by_node(dp);
328 if (op)
329 break;
330 }
331 if (!op) {
332 for_each_node_by_name(dp, "fd") {
333 op = of_find_device_by_node(dp);
334 if (op)
335 break;
336 }
337 }
338 if (!op)
339 goto no_sun_fdc;
340
341 FLOPPY_IRQ = op->archdata.irqs[0];
342
f5e706ad 343 /* Last minute sanity check... */
144e988d 344 if (sun_fdc->status_82072 == 0xff) {
f5e706ad
SR
345 sun_fdc = NULL;
346 goto no_sun_fdc;
347 }
348
349 sun_fdops.fd_inb = sun_82077_fd_inb;
350 sun_fdops.fd_outb = sun_82077_fd_outb;
351 fdc_status = &sun_fdc->status_82077;
352
353 if (sun_fdc->dor_82077 == 0x80) {
354 sun_fdc->dor_82077 = 0x02;
355 if (sun_fdc->dor_82077 == 0x80) {
356 sun_fdops.fd_inb = sun_82072_fd_inb;
357 sun_fdops.fd_outb = sun_82072_fd_outb;
358 fdc_status = &sun_fdc->status_82072;
359 }
360 }
361
362 /* Success... */
363 allowed_drive_mask = 0x01;
364 return (int) sun_fdc;
365
366no_sun_fdc:
367 return -1;
368}
369
370static int sparc_eject(void)
371{
372 set_dor(0x00, 0xff, 0x90);
373 udelay(500);
374 set_dor(0x00, 0x6f, 0x00);
375 udelay(500);
376 return 0;
377}
378
379#define fd_eject(drive) sparc_eject()
380
381#define EXTRA_FLOPPY_PARAMS
382
334ae614
DM
383static DEFINE_SPINLOCK(dma_spin_lock);
384
385#define claim_dma_lock() \
386({ unsigned long flags; \
387 spin_lock_irqsave(&dma_spin_lock, flags); \
388 flags; \
389})
390
391#define release_dma_lock(__flags) \
392 spin_unlock_irqrestore(&dma_spin_lock, __flags);
393
f5e706ad 394#endif /* !(__ASM_SPARC_FLOPPY_H) */