1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/arch/arm/mach-rpc/dma.c
5 * Copyright (C) 1998 Russell King
7 * DMA functions specific to RiscPC architecture
9 #include <linux/mman.h>
10 #include <linux/init.h>
11 #include <linux/interrupt.h>
12 #include <linux/dma-mapping.h>
19 #include <mach/hardware.h>
20 #include <linux/uaccess.h>
22 #include <asm/mach/dma.h>
23 #include <asm/hardware/iomd.h>
26 struct dma_struct dma
;
27 void __iomem
*base
; /* Controller base address */
28 int irq
; /* Controller IRQ */
45 #define TRANSFER_SIZE 2
48 #define ENDA (IOMD_IO0ENDA - IOMD_IO0CURA)
49 #define CURB (IOMD_IO0CURB - IOMD_IO0CURA)
50 #define ENDB (IOMD_IO0ENDB - IOMD_IO0CURA)
51 #define CR (IOMD_IO0CR - IOMD_IO0CURA)
52 #define ST (IOMD_IO0ST - IOMD_IO0CURA)
54 static void iomd_get_next_sg(struct iomd_dma
*idma
)
56 unsigned long end
, offset
, flags
= 0;
59 idma
->cur_addr
= idma
->dma_addr
;
60 offset
= idma
->cur_addr
& ~PAGE_MASK
;
62 end
= offset
+ idma
->dma_len
;
67 if (offset
+ TRANSFER_SIZE
>= end
)
70 idma
->cur_len
= end
- TRANSFER_SIZE
;
72 idma
->dma_len
-= end
- offset
;
73 idma
->dma_addr
+= end
- offset
;
75 if (idma
->dma_len
== 0) {
76 if (idma
->dma
.sgcount
> 1) {
77 idma
->dma
.sg
= sg_next(idma
->dma
.sg
);
78 idma
->dma_addr
= idma
->dma
.sg
->dma_address
;
79 idma
->dma_len
= idma
->dma
.sg
->length
;
87 flags
= DMA_END_S
| DMA_END_L
;
92 idma
->cur_len
|= flags
;
95 static irqreturn_t
iomd_dma_handle(int irq
, void *dev_id
)
97 struct iomd_dma
*idma
= dev_id
;
98 void __iomem
*base
= idma
->base
;
99 unsigned int state
= idma
->state
;
100 unsigned int status
, cur
, end
;
103 status
= readb(base
+ ST
);
104 if (!(status
& DMA_ST_INT
))
107 if ((state
^ status
) & DMA_ST_AB
)
108 iomd_get_next_sg(idma
);
110 // This efficiently implements state = OFL != AB ? AB : 0
111 state
= ((status
>> 2) ^ status
) & DMA_ST_AB
;
119 writel(idma
->cur_addr
, base
+ cur
);
120 writel(idma
->cur_len
, base
+ end
);
122 if (status
& DMA_ST_OFL
&&
123 idma
->cur_len
== (DMA_END_S
|DMA_END_L
))
128 disable_irq_nosync(irq
);
134 static int iomd_request_dma(unsigned int chan
, dma_t
*dma
)
136 struct iomd_dma
*idma
= container_of(dma
, struct iomd_dma
, dma
);
138 return request_irq(idma
->irq
, iomd_dma_handle
,
139 0, idma
->dma
.device_id
, idma
);
142 static void iomd_free_dma(unsigned int chan
, dma_t
*dma
)
144 struct iomd_dma
*idma
= container_of(dma
, struct iomd_dma
, dma
);
146 free_irq(idma
->irq
, idma
);
149 static struct device isa_dma_dev
= {
150 .init_name
= "fallback device",
151 .coherent_dma_mask
= ~(dma_addr_t
)0,
152 .dma_mask
= &isa_dma_dev
.coherent_dma_mask
,
155 static void iomd_enable_dma(unsigned int chan
, dma_t
*dma
)
157 struct iomd_dma
*idma
= container_of(dma
, struct iomd_dma
, dma
);
158 void __iomem
*base
= idma
->base
;
159 unsigned int ctrl
= TRANSFER_SIZE
| DMA_CR_E
;
161 if (idma
->dma
.invalid
) {
162 idma
->dma
.invalid
= 0;
165 * Cope with ISA-style drivers which expect cache
169 idma
->dma
.sg
= &idma
->dma
.buf
;
170 idma
->dma
.sgcount
= 1;
171 idma
->dma
.buf
.length
= idma
->dma
.count
;
172 idma
->dma
.buf
.dma_address
= dma_map_single(&isa_dma_dev
,
173 idma
->dma
.addr
, idma
->dma
.count
,
174 idma
->dma
.dma_mode
== DMA_MODE_READ
?
175 DMA_FROM_DEVICE
: DMA_TO_DEVICE
);
178 idma
->dma_addr
= idma
->dma
.sg
->dma_address
;
179 idma
->dma_len
= idma
->dma
.sg
->length
;
181 writeb(DMA_CR_C
, base
+ CR
);
182 idma
->state
= DMA_ST_AB
;
185 if (idma
->dma
.dma_mode
== DMA_MODE_READ
)
188 writeb(ctrl
, base
+ CR
);
189 enable_irq(idma
->irq
);
192 static void iomd_disable_dma(unsigned int chan
, dma_t
*dma
)
194 struct iomd_dma
*idma
= container_of(dma
, struct iomd_dma
, dma
);
195 void __iomem
*base
= idma
->base
;
198 local_irq_save(flags
);
199 if (idma
->state
!= ~DMA_ST_AB
)
200 disable_irq(idma
->irq
);
201 writeb(0, base
+ CR
);
202 local_irq_restore(flags
);
205 static int iomd_set_dma_speed(unsigned int chan
, dma_t
*dma
, int cycle
)
211 else if (cycle
<= 250)
213 else if (cycle
< 438)
218 tcr
= iomd_readb(IOMD_DMATCR
);
223 tcr
= (tcr
& ~0x03) | speed
;
227 tcr
= (tcr
& ~0x0c) | (speed
<< 2);
231 tcr
= (tcr
& ~0x30) | (speed
<< 4);
235 tcr
= (tcr
& ~0xc0) | (speed
<< 6);
242 iomd_writeb(tcr
, IOMD_DMATCR
);
247 static struct dma_ops iomd_dma_ops
= {
249 .request
= iomd_request_dma
,
250 .free
= iomd_free_dma
,
251 .enable
= iomd_enable_dma
,
252 .disable
= iomd_disable_dma
,
253 .setspeed
= iomd_set_dma_speed
,
256 static struct fiq_handler fh
= {
261 struct dma_struct dma
;
265 static void floppy_enable_dma(unsigned int chan
, dma_t
*dma
)
267 struct floppy_dma
*fdma
= container_of(dma
, struct floppy_dma
, dma
);
268 void *fiqhandler_start
;
269 unsigned int fiqhandler_length
;
275 if (fdma
->dma
.dma_mode
== DMA_MODE_READ
) {
276 extern unsigned char floppy_fiqin_start
, floppy_fiqin_end
;
277 fiqhandler_start
= &floppy_fiqin_start
;
278 fiqhandler_length
= &floppy_fiqin_end
- &floppy_fiqin_start
;
280 extern unsigned char floppy_fiqout_start
, floppy_fiqout_end
;
281 fiqhandler_start
= &floppy_fiqout_start
;
282 fiqhandler_length
= &floppy_fiqout_end
- &floppy_fiqout_start
;
285 regs
.ARM_r9
= fdma
->dma
.count
;
286 regs
.ARM_r10
= (unsigned long)fdma
->dma
.addr
;
287 regs
.ARM_fp
= (unsigned long)FLOPPYDMA_BASE
;
289 if (claim_fiq(&fh
)) {
290 printk("floppydma: couldn't claim FIQ.\n");
294 set_fiq_handler(fiqhandler_start
, fiqhandler_length
);
296 enable_fiq(fdma
->fiq
);
299 static void floppy_disable_dma(unsigned int chan
, dma_t
*dma
)
301 struct floppy_dma
*fdma
= container_of(dma
, struct floppy_dma
, dma
);
302 disable_fiq(fdma
->fiq
);
306 static int floppy_get_residue(unsigned int chan
, dma_t
*dma
)
313 static struct dma_ops floppy_dma_ops
= {
315 .enable
= floppy_enable_dma
,
316 .disable
= floppy_disable_dma
,
317 .residue
= floppy_get_residue
,
321 * This is virtual DMA - we don't need anything here.
323 static void sound_enable_disable_dma(unsigned int chan
, dma_t
*dma
)
327 static struct dma_ops sound_dma_ops
= {
329 .enable
= sound_enable_disable_dma
,
330 .disable
= sound_enable_disable_dma
,
333 static struct iomd_dma iomd_dma
[6];
335 static struct floppy_dma floppy_dma
= {
337 .d_ops
= &floppy_dma_ops
,
339 .fiq
= FIQ_FLOPPYDATA
,
342 static dma_t sound_dma
= {
343 .d_ops
= &sound_dma_ops
,
346 static int __init
rpc_dma_init(void)
351 iomd_writeb(0, IOMD_IO0CR
);
352 iomd_writeb(0, IOMD_IO1CR
);
353 iomd_writeb(0, IOMD_IO2CR
);
354 iomd_writeb(0, IOMD_IO3CR
);
356 iomd_writeb(0xa0, IOMD_DMATCR
);
359 * Setup DMA channels 2,3 to be for podules
360 * and channels 0,1 for internal devices
362 iomd_writeb(DMA_EXT_IO3
|DMA_EXT_IO2
, IOMD_DMAEXT
);
364 iomd_dma
[DMA_0
].base
= IOMD_BASE
+ IOMD_IO0CURA
;
365 iomd_dma
[DMA_0
].irq
= IRQ_DMA0
;
366 iomd_dma
[DMA_1
].base
= IOMD_BASE
+ IOMD_IO1CURA
;
367 iomd_dma
[DMA_1
].irq
= IRQ_DMA1
;
368 iomd_dma
[DMA_2
].base
= IOMD_BASE
+ IOMD_IO2CURA
;
369 iomd_dma
[DMA_2
].irq
= IRQ_DMA2
;
370 iomd_dma
[DMA_3
].base
= IOMD_BASE
+ IOMD_IO3CURA
;
371 iomd_dma
[DMA_3
].irq
= IRQ_DMA3
;
372 iomd_dma
[DMA_S0
].base
= IOMD_BASE
+ IOMD_SD0CURA
;
373 iomd_dma
[DMA_S0
].irq
= IRQ_DMAS0
;
374 iomd_dma
[DMA_S1
].base
= IOMD_BASE
+ IOMD_SD1CURA
;
375 iomd_dma
[DMA_S1
].irq
= IRQ_DMAS1
;
377 for (i
= DMA_0
; i
<= DMA_S1
; i
++) {
378 iomd_dma
[i
].dma
.d_ops
= &iomd_dma_ops
;
380 ret
= isa_dma_add(i
, &iomd_dma
[i
].dma
);
382 printk("IOMDDMA%u: unable to register: %d\n", i
, ret
);
385 ret
= isa_dma_add(DMA_VIRTUAL_FLOPPY
, &floppy_dma
.dma
);
387 printk("IOMDFLOPPY: unable to register: %d\n", ret
);
388 ret
= isa_dma_add(DMA_VIRTUAL_SOUND
, &sound_dma
);
390 printk("IOMDSOUND: unable to register: %d\n", ret
);
393 core_initcall(rpc_dma_init
);