~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-rpc/dma.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/mach-rpc/dma.c (Version linux-6.12-rc7) and /arch/ppc/mach-rpc/dma.c (Version linux-5.2.21)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  *  linux/arch/arm/mach-rpc/dma.c                 
  4  *                                                
  5  *  Copyright (C) 1998 Russell King               
  6  *                                                
  7  *  DMA functions specific to RiscPC architect    
  8  */                                               
  9 #include <linux/mman.h>                           
 10 #include <linux/init.h>                           
 11 #include <linux/interrupt.h>                      
 12 #include <linux/dma-mapping.h>                    
 13 #include <linux/io.h>                             
 14                                                   
 15 #include <asm/page.h>                             
 16 #include <asm/dma.h>                              
 17 #include <asm/fiq.h>                              
 18 #include <asm/irq.h>                              
 19 #include <mach/hardware.h>                        
 20 #include <linux/uaccess.h>                        
 21                                                   
 22 #include <asm/mach/dma.h>                         
 23 #include <asm/hardware/iomd.h>                    
 24                                                   
 25 struct iomd_dma {                                 
 26         struct dma_struct       dma;              
 27         void __iomem            *base;            
 28         int                     irq;              
 29         unsigned int            state;            
 30         dma_addr_t              cur_addr;         
 31         unsigned int            cur_len;          
 32         dma_addr_t              dma_addr;         
 33         unsigned int            dma_len;          
 34 };                                                
 35                                                   
 36 #if 0                                             
 37 typedef enum {                                    
 38         dma_size_8      = 1,                      
 39         dma_size_16     = 2,                      
 40         dma_size_32     = 4,                      
 41         dma_size_128    = 16                      
 42 } dma_size_t;                                     
 43 #endif                                            
 44                                                   
 45 #define TRANSFER_SIZE   2                         
 46                                                   
 47 #define CURA    (0)                               
 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)       
 53                                                   
 54 static void iomd_get_next_sg(struct iomd_dma *    
 55 {                                                 
 56         unsigned long end, offset, flags = 0;     
 57                                                   
 58         if (idma->dma.sg) {                       
 59                 idma->cur_addr = idma->dma_add    
 60                 offset = idma->cur_addr & ~PAG    
 61                                                   
 62                 end = offset + idma->dma_len;     
 63                                                   
 64                 if (end > PAGE_SIZE)              
 65                         end = PAGE_SIZE;          
 66                                                   
 67                 if (offset + TRANSFER_SIZE >=     
 68                         flags |= DMA_END_L;       
 69                                                   
 70                 idma->cur_len = end - TRANSFER    
 71                                                   
 72                 idma->dma_len -= end - offset;    
 73                 idma->dma_addr += end - offset    
 74                                                   
 75                 if (idma->dma_len == 0) {         
 76                         if (idma->dma.sgcount     
 77                                 idma->dma.sg =    
 78                                 idma->dma_addr    
 79                                 idma->dma_len     
 80                                 idma->dma.sgco    
 81                         } else {                  
 82                                 idma->dma.sg =    
 83                                 flags |= DMA_E    
 84                         }                         
 85                 }                                 
 86         } else {                                  
 87                 flags = DMA_END_S | DMA_END_L;    
 88                 idma->cur_addr = 0;               
 89                 idma->cur_len = 0;                
 90         }                                         
 91                                                   
 92         idma->cur_len |= flags;                   
 93 }                                                 
 94                                                   
 95 static irqreturn_t iomd_dma_handle(int irq, vo    
 96 {                                                 
 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;            
101                                                   
102         do {                                      
103                 status = readb(base + ST);        
104                 if (!(status & DMA_ST_INT))       
105                         goto out;                 
106                                                   
107                 if ((state ^ status) & DMA_ST_    
108                         iomd_get_next_sg(idma)    
109                                                   
110                 // This efficiently implements    
111                 state = ((status >> 2) ^ statu    
112                 if (state) {                      
113                         cur = CURA;               
114                         end = ENDA;               
115                 } else {                          
116                         cur = CURB;               
117                         end = ENDB;               
118                 }                                 
119                 writel(idma->cur_addr, base +     
120                 writel(idma->cur_len, base + e    
121                                                   
122                 if (status & DMA_ST_OFL &&        
123                     idma->cur_len == (DMA_END_    
124                         break;                    
125         } while (1);                              
126                                                   
127         state = ~DMA_ST_AB;                       
128         disable_irq_nosync(irq);                  
129 out:                                              
130         idma->state = state;                      
131         return IRQ_HANDLED;                       
132 }                                                 
133                                                   
134 static int iomd_request_dma(unsigned int chan,    
135 {                                                 
136         struct iomd_dma *idma = container_of(d    
137                                                   
138         return request_irq(idma->irq, iomd_dma    
139                            0, idma->dma.device    
140 }                                                 
141                                                   
142 static void iomd_free_dma(unsigned int chan, d    
143 {                                                 
144         struct iomd_dma *idma = container_of(d    
145                                                   
146         free_irq(idma->irq, idma);                
147 }                                                 
148                                                   
149 static struct device isa_dma_dev = {              
150         .init_name              = "fallback de    
151         .coherent_dma_mask      = ~(dma_addr_t    
152         .dma_mask               = &isa_dma_dev    
153 };                                                
154                                                   
155 static void iomd_enable_dma(unsigned int chan,    
156 {                                                 
157         struct iomd_dma *idma = container_of(d    
158         void __iomem *base = idma->base;          
159         unsigned int ctrl = TRANSFER_SIZE | DM    
160                                                   
161         if (idma->dma.invalid) {                  
162                 idma->dma.invalid = 0;            
163                                                   
164                 /*                                
165                  * Cope with ISA-style drivers    
166                  * coherence.                     
167                  */                               
168                 if (!idma->dma.sg) {              
169                         idma->dma.sg = &idma->    
170                         idma->dma.sgcount = 1;    
171                         idma->dma.buf.length =    
172                         idma->dma.buf.dma_addr    
173                                 idma->dma.addr    
174                                 idma->dma.dma_    
175                                 DMA_FROM_DEVIC    
176                 }                                 
177                                                   
178                 idma->dma_addr = idma->dma.sg-    
179                 idma->dma_len = idma->dma.sg->    
180                                                   
181                 writeb(DMA_CR_C, base + CR);      
182                 idma->state = DMA_ST_AB;          
183         }                                         
184                                                   
185         if (idma->dma.dma_mode == DMA_MODE_REA    
186                 ctrl |= DMA_CR_D;                 
187                                                   
188         writeb(ctrl, base + CR);                  
189         enable_irq(idma->irq);                    
190 }                                                 
191                                                   
192 static void iomd_disable_dma(unsigned int chan    
193 {                                                 
194         struct iomd_dma *idma = container_of(d    
195         void __iomem *base = idma->base;          
196         unsigned long flags;                      
197                                                   
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);                 
203 }                                                 
204                                                   
205 static int iomd_set_dma_speed(unsigned int cha    
206 {                                                 
207         int tcr, speed;                           
208                                                   
209         if (cycle < 188)                          
210                 speed = 3;                        
211         else if (cycle <= 250)                    
212                 speed = 2;                        
213         else if (cycle < 438)                     
214                 speed = 1;                        
215         else                                      
216                 speed = 0;                        
217                                                   
218         tcr = iomd_readb(IOMD_DMATCR);            
219         speed &= 3;                               
220                                                   
221         switch (chan) {                           
222         case DMA_0:                               
223                 tcr = (tcr & ~0x03) | speed;      
224                 break;                            
225                                                   
226         case DMA_1:                               
227                 tcr = (tcr & ~0x0c) | (speed <    
228                 break;                            
229                                                   
230         case DMA_2:                               
231                 tcr = (tcr & ~0x30) | (speed <    
232                 break;                            
233                                                   
234         case DMA_3:                               
235                 tcr = (tcr & ~0xc0) | (speed <    
236                 break;                            
237                                                   
238         default:                                  
239                 break;                            
240         }                                         
241                                                   
242         iomd_writeb(tcr, IOMD_DMATCR);            
243                                                   
244         return speed;                             
245 }                                                 
246                                                   
247 static struct dma_ops iomd_dma_ops = {            
248         .type           = "IOMD",                 
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,     
254 };                                                
255                                                   
256 static struct fiq_handler fh = {                  
257         .name   = "floppydma"                     
258 };                                                
259                                                   
260 struct floppy_dma {                               
261         struct dma_struct       dma;              
262         unsigned int            fiq;              
263 };                                                
264                                                   
265 static void floppy_enable_dma(unsigned int cha    
266 {                                                 
267         struct floppy_dma *fdma = container_of    
268         void *fiqhandler_start;                   
269         unsigned int fiqhandler_length;           
270         struct pt_regs regs;                      
271                                                   
272         if (fdma->dma.sg)                         
273                 BUG();                            
274                                                   
275         if (fdma->dma.dma_mode == DMA_MODE_REA    
276                 extern unsigned char floppy_fi    
277                 fiqhandler_start = &floppy_fiq    
278                 fiqhandler_length = &floppy_fi    
279         } else {                                  
280                 extern unsigned char floppy_fi    
281                 fiqhandler_start = &floppy_fiq    
282                 fiqhandler_length = &floppy_fi    
283         }                                         
284                                                   
285         regs.ARM_r9  = fdma->dma.count;           
286         regs.ARM_r10 = (unsigned long)fdma->dm    
287         regs.ARM_fp  = (unsigned long)FLOPPYDM    
288                                                   
289         if (claim_fiq(&fh)) {                     
290                 printk("floppydma: couldn't cl    
291                 return;                           
292         }                                         
293                                                   
294         set_fiq_handler(fiqhandler_start, fiqh    
295         set_fiq_regs(&regs);                      
296         enable_fiq(fdma->fiq);                    
297 }                                                 
298                                                   
299 static void floppy_disable_dma(unsigned int ch    
300 {                                                 
301         struct floppy_dma *fdma = container_of    
302         disable_fiq(fdma->fiq);                   
303         release_fiq(&fh);                         
304 }                                                 
305                                                   
306 static int floppy_get_residue(unsigned int cha    
307 {                                                 
308         struct pt_regs regs;                      
309         get_fiq_regs(&regs);                      
310         return regs.ARM_r9;                       
311 }                                                 
312                                                   
313 static struct dma_ops floppy_dma_ops = {          
314         .type           = "FIQDMA",               
315         .enable         = floppy_enable_dma,      
316         .disable        = floppy_disable_dma,     
317         .residue        = floppy_get_residue,     
318 };                                                
319                                                   
320 /*                                                
321  * This is virtual DMA - we don't need anythin    
322  */                                               
323 static void sound_enable_disable_dma(unsigned     
324 {                                                 
325 }                                                 
326                                                   
327 static struct dma_ops sound_dma_ops = {           
328         .type           = "VIRTUAL",              
329         .enable         = sound_enable_disable    
330         .disable        = sound_enable_disable    
331 };                                                
332                                                   
333 static struct iomd_dma iomd_dma[6];               
334                                                   
335 static struct floppy_dma floppy_dma = {           
336         .dma            = {                       
337                 .d_ops  = &floppy_dma_ops,        
338         },                                        
339         .fiq            = FIQ_FLOPPYDATA,         
340 };                                                
341                                                   
342 static dma_t sound_dma = {                        
343         .d_ops          = &sound_dma_ops,         
344 };                                                
345                                                   
346 static int __init rpc_dma_init(void)              
347 {                                                 
348         unsigned int i;                           
349         int ret;                                  
350                                                   
351         iomd_writeb(0, IOMD_IO0CR);               
352         iomd_writeb(0, IOMD_IO1CR);               
353         iomd_writeb(0, IOMD_IO2CR);               
354         iomd_writeb(0, IOMD_IO3CR);               
355                                                   
356         iomd_writeb(0xa0, IOMD_DMATCR);           
357                                                   
358         /*                                        
359          * Setup DMA channels 2,3 to be for po    
360          * and channels 0,1 for internal devic    
361          */                                       
362         iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, I    
363                                                   
364         iomd_dma[DMA_0].base    = IOMD_BASE +     
365         iomd_dma[DMA_0].irq     = IRQ_DMA0;       
366         iomd_dma[DMA_1].base    = IOMD_BASE +     
367         iomd_dma[DMA_1].irq     = IRQ_DMA1;       
368         iomd_dma[DMA_2].base    = IOMD_BASE +     
369         iomd_dma[DMA_2].irq     = IRQ_DMA2;       
370         iomd_dma[DMA_3].base    = IOMD_BASE +     
371         iomd_dma[DMA_3].irq     = IRQ_DMA3;       
372         iomd_dma[DMA_S0].base   = IOMD_BASE +     
373         iomd_dma[DMA_S0].irq    = IRQ_DMAS0;      
374         iomd_dma[DMA_S1].base   = IOMD_BASE +     
375         iomd_dma[DMA_S1].irq    = IRQ_DMAS1;      
376                                                   
377         for (i = DMA_0; i <= DMA_S1; i++) {       
378                 iomd_dma[i].dma.d_ops = &iomd_    
379                                                   
380                 ret = isa_dma_add(i, &iomd_dma    
381                 if (ret)                          
382                         printk("IOMDDMA%u: una    
383         }                                         
384                                                   
385         ret = isa_dma_add(DMA_VIRTUAL_FLOPPY,     
386         if (ret)                                  
387                 printk("IOMDFLOPPY: unable to     
388         ret = isa_dma_add(DMA_VIRTUAL_SOUND, &    
389         if (ret)                                  
390                 printk("IOMDSOUND: unable to r    
391         return 0;                                 
392 }                                                 
393 core_initcall(rpc_dma_init);                      
394                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php