1 /*
2  *  linux/arch/arm/mach-sa1100/dma-sa1111.c
3  *
4  *  Copyright (C) 2000 John Dorsey
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 as
8  *  published by the Free Software Foundation.
9  *
10  *  4 September 2000 - created.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/sched.h>
16 #include <linux/delay.h>
17 #include <linux/spinlock.h>
18 #include <linux/errno.h>
19 
20 #include <asm/system.h>
21 #include <asm/irq.h>
22 #include <asm/hardware.h>
23 #include <asm/io.h>
24 #include <asm/dma.h>
25 #include <asm/hardware/sa1111.h>
26 
27 // #define DEBUG
28 #ifdef DEBUG
29 #define DPRINTK( s, arg... )  printk( "dma<%s>: " s, dma->device_id , ##arg )
30 #else
31 #define DPRINTK( x... )
32 #endif
33 
34 
35 /*
36  * Control register structure for the SA1111 SAC DMA
37  */
38 
39 typedef struct {
40 	volatile u_long SAD_CS;
41 	volatile dma_addr_t SAD_SA;
42 	volatile u_long SAD_CA;
43 	volatile dma_addr_t SAD_SB;
44 	volatile u_long SAD_CB;
45 } dma_regs_t;
46 
47 #include "dma.h"
48 
49 
sa1111_reset_sac_dma(dmach_t channel)50 void sa1111_reset_sac_dma(dmach_t channel)
51 {
52 	sa1100_dma_t *dma = &dma_chan[channel];
53 	dma->regs->SAD_CS = 0;
54 	mdelay(1);
55 	dma->dma_a = dma->dma_b = 0;
56 }
57 
58 
start_sa1111_sac_dma(sa1100_dma_t * dma,dma_addr_t dma_ptr,size_t size)59 int start_sa1111_sac_dma(sa1100_dma_t *dma, dma_addr_t dma_ptr, size_t size)
60 {
61   	dma_regs_t *sac_regs = dma->regs;
62 
63 	DPRINTK(" SAC DMA %cCS %02x at %08x (%d)\n",
64 		(sac_regs==&SADTCS)?'T':'R', sac_regs->SAD_CS, dma_ptr, size);
65 
66 	/* The minimum transfer length requirement has not yet been
67 	 * verified:
68 	 */
69 	if( size < SA1111_SAC_DMA_MIN_XFER )
70 	  printk(KERN_WARNING "Warning: SAC xfers below %u bytes may be buggy!"
71 		 " (%u bytes)\n", SA1111_SAC_DMA_MIN_XFER, size);
72 
73 	if( dma->dma_a && dma->dma_b ){
74 	  	DPRINTK("  neither engine available! (A %d, B %d)\n",
75 			dma->dma_a, dma->dma_b);
76 	  	return -1;
77 	}
78 
79 	if( sa1111_check_dma_bug(dma_ptr) )
80 	  	printk(KERN_WARNING "Warning: DMA address %08x is buggy!\n",
81 		       dma_ptr);
82 
83 	if( (dma->last_dma || dma->dma_b) && dma->dma_a == 0 ){
84 	  	if( sac_regs->SAD_CS & SAD_CS_DBDB ){
85 		  	DPRINTK("  awaiting \"done B\" interrupt, not starting\n");
86 			return -1;
87 		}
88 		sac_regs->SAD_SA = SA1111_DMA_ADDR((u_int)dma_ptr);
89 		sac_regs->SAD_CA = size;
90 		sac_regs->SAD_CS = SAD_CS_DSTA | SAD_CS_DEN;
91 		++dma->dma_a;
92 		DPRINTK("  with A [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,
93 			sac_regs->SAD_SA, sac_regs->SAD_CA);
94 	} else {
95 	  	if( sac_regs->SAD_CS & SAD_CS_DBDA ){
96 		  	DPRINTK("  awaiting \"done A\" interrupt, not starting\n");
97 			return -1;
98 		}
99 		sac_regs->SAD_SB = SA1111_DMA_ADDR((u_int)dma_ptr);
100 		sac_regs->SAD_CB = size;
101 		sac_regs->SAD_CS = SAD_CS_DSTB | SAD_CS_DEN;
102 		++dma->dma_b;
103 		DPRINTK("  with B [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,
104 			sac_regs->SAD_SB, sac_regs->SAD_CB);
105 	}
106 
107 	/* Additional delay to avoid DMA engine lockup during record: */
108 	if( sac_regs == (dma_regs_t*)&SADRCS )
109 	  	mdelay(1);	/* NP : wouuuh! ugly... */
110 
111 	return 0;
112 }
113 
114 
sa1111_sac_dma_irq(int irq,void * dev_id,struct pt_regs * regs)115 static void sa1111_sac_dma_irq(int irq, void *dev_id, struct pt_regs *regs)
116 {
117   	sa1100_dma_t *dma = (sa1100_dma_t *) dev_id;
118 
119 	DPRINTK("irq %d, last DMA serviced was %c, CS %02x\n", irq,
120 		dma->last_dma?'B':'A', dma->regs->SAD_CS);
121 
122 	/* Occasionally, one of the DMA engines (A or B) will
123 	 * lock up. We try to deal with this by quietly kicking
124 	 * the control register for the afflicted transfer
125 	 * direction.
126 	 *
127 	 * Note for the debugging-inclined: we currently aren't
128 	 * properly flushing the DMA engines during channel
129 	 * shutdown. A slight hiccup at the beginning of playback
130 	 * after a channel has been stopped can be heard as
131 	 * evidence of this. Programmatically, this shows up
132 	 * as either a locked engine, or a spurious interrupt. -jd
133 	 */
134 
135 	if(irq==AUDXMTDMADONEA || irq==AUDRCVDMADONEA){
136 
137 	  	if(dma->last_dma == 0){
138 		  	DPRINTK("DMA B has locked up!\n");
139 			dma->regs->SAD_CS = 0;
140 			mdelay(1);
141 			dma->dma_a = dma->dma_b = 0;
142 		} else {
143 		  	if(dma->dma_a == 0)
144 			  	DPRINTK("spurious SAC IRQ %d\n", irq);
145 			else {
146 			  	--dma->dma_a;
147 
148 				/* Servicing the SAC DMA engines too quickly
149 				 * after they issue a DONE interrupt causes
150 				 * them to lock up.
151 				 */
152 				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)
153 				  	mdelay(1);
154 			}
155 		}
156 
157 		dma->regs->SAD_CS = SAD_CS_DBDA | SAD_CS_DEN; /* w1c */
158 		dma->last_dma = 0;
159 
160 	} else {
161 
162 	  	if(dma->last_dma == 1){
163 		  	DPRINTK("DMA A has locked up!\n");
164 			dma->regs->SAD_CS = 0;
165 			mdelay(1);
166 			dma->dma_a = dma->dma_b = 0;
167 		} else {
168 		  	if(dma->dma_b == 0)
169 			  	DPRINTK("spurious SAC IRQ %d\n", irq);
170 			else {
171 			  	--dma->dma_b;
172 
173 				/* See lock-up note above. */
174 				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)
175 				  	mdelay(1);
176 			}
177 		}
178 
179 		dma->regs->SAD_CS = SAD_CS_DBDB | SAD_CS_DEN; /* w1c */
180 		dma->last_dma = 1;
181 
182 	}
183 
184 	/* NP: maybe this shouldn't be called in all cases? */
185 	sa1100_dma_done (dma);
186 }
187 
188 
sa1111_sac_request_dma(dmach_t * channel,const char * device_id,unsigned int direction)189 int sa1111_sac_request_dma(dmach_t *channel, const char *device_id,
190 			   unsigned int direction)
191 {
192 	sa1100_dma_t *dma = NULL;
193 	int ch, irq, err;
194 
195 	*channel = -1;		/* to be sure we catch the freeing of a misregistered channel */
196 
197 	ch = SA1111_SAC_DMA_BASE + direction;
198 
199 	if (!channel_is_sa1111_sac(ch)) {
200 	  	printk(KERN_ERR "%s: invalid SA-1111 SAC DMA channel (%d)\n",
201 		       device_id, ch);
202 		return -1;
203 	}
204 
205 	dma = &dma_chan[ch];
206 
207 	if (xchg(&dma->in_use, 1) == 1) {
208 	  	printk(KERN_ERR "%s: SA-1111 SAC DMA channel %d in use\n",
209 		       device_id, ch);
210 		return -EBUSY;
211 	}
212 
213 	irq = AUDXMTDMADONEA + direction;
214 	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,
215 			  device_id, (void *) dma);
216 	if (err) {
217 		printk(KERN_ERR
218 		       "%s: unable to request IRQ %d for DMA channel %d (A)\n",
219 		       device_id, irq, ch);
220 		dma->in_use = 0;
221 		return err;
222 	}
223 
224 	irq = AUDXMTDMADONEB + direction;
225 	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,
226 			  device_id, (void *) dma);
227 	if (err) {
228 		printk(KERN_ERR
229 		       "%s: unable to request IRQ %d for DMA channel %d (B)\n",
230 		       device_id, irq, ch);
231 		dma->in_use = 0;
232 		return err;
233 	}
234 
235 	*channel = ch;
236 	dma->device_id = device_id;
237 	dma->callback = NULL;
238 	dma->spin_size = 0;
239 
240 	return 0;
241 }
242 
243 
244 /* FIXME:  need to complete the three following functions */
245 
sa1111_dma_get_current(dmach_t channel,void ** buf_id,dma_addr_t * addr)246 int sa1111_dma_get_current(dmach_t channel, void **buf_id, dma_addr_t *addr)
247 {
248 	sa1100_dma_t *dma = &dma_chan[channel];
249 	int flags, ret;
250 
251 	local_irq_save(flags);
252 	if (dma->curr && dma->spin_ref <= 0) {
253 		dma_buf_t *buf = dma->curr;
254 		if (buf_id)
255 			*buf_id = buf->id;
256 		/* not fully accurate but still... */
257 		*addr = buf->dma_ptr;
258 		ret = 0;
259 	} else {
260 		if (buf_id)
261 			*buf_id = NULL;
262 		*addr = 0;
263 		ret = -ENXIO;
264 	}
265 	local_irq_restore(flags);
266 	return ret;
267 }
268 
sa1111_dma_stop(dmach_t channel)269 int sa1111_dma_stop(dmach_t channel)
270 {
271 	return 0;
272 }
273 
sa1111_dma_resume(dmach_t channel)274 int sa1111_dma_resume(dmach_t channel)
275 {
276 	return 0;
277 }
278 
279 
sa1111_cleanup_sac_dma(dmach_t channel)280 void sa1111_cleanup_sac_dma(dmach_t channel)
281 {
282 	sa1100_dma_t *dma = &dma_chan[channel];
283 	free_irq(AUDXMTDMADONEA + (channel - SA1111_SAC_DMA_BASE), (void*) dma);
284 	free_irq(AUDXMTDMADONEB + (channel - SA1111_SAC_DMA_BASE), (void*) dma);
285 }
286 
287 
288 /* According to the "Intel StrongARM SA-1111 Microprocessor Companion
289  * Chip Specification Update" (June 2000), erratum #7, there is a
290  * significant bug in Serial Audio Controller DMA. If the SAC is
291  * accessing a region of memory above 1MB relative to the bank base,
292  * it is important that address bit 10 _NOT_ be asserted. Depending
293  * on the configuration of the RAM, bit 10 may correspond to one
294  * of several different (processor-relative) address bits.
295  *
296  * This routine only identifies whether or not a given DMA address
297  * is susceptible to the bug.
298  */
sa1111_check_dma_bug(dma_addr_t addr)299 int sa1111_check_dma_bug(dma_addr_t addr){
300 	unsigned int physaddr=SA1111_DMA_ADDR((unsigned int)addr);
301 
302 	/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module
303 	 * User's Guide" mentions that jumpers R51 and R52 control the
304 	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
305 	 * SDRAM bank 1 on Neponset). The default configuration selects
306 	 * Assabet, so any address in bank 1 is necessarily invalid.
307 	 */
308 	if((machine_is_assabet() || machine_is_pfs168() ||
309             machine_is_graphicsmaster() || machine_is_adsagc()) && addr >= 0xc8000000)
310 	  	return -1;
311 
312 	/* The bug only applies to buffers located more than one megabyte
313 	 * above the start of the target bank:
314 	 */
315 	if(physaddr<(1<<20))
316 	  	return 0;
317 
318 	switch(FExtr(SBI_SMCR, SMCR_DRAC)){
319 	case 01: /* 10 row + bank address bits, A<20> must not be set */
320 	  	if(physaddr & (1<<20))
321 		  	return -1;
322 		break;
323 	case 02: /* 11 row + bank address bits, A<23> must not be set */
324 	  	if(physaddr & (1<<23))
325 		  	return -1;
326 		break;
327 	case 03: /* 12 row + bank address bits, A<24> must not be set */
328 	  	if(physaddr & (1<<24))
329 		  	return -1;
330 		break;
331 	case 04: /* 13 row + bank address bits, A<25> must not be set */
332 	  	if(physaddr & (1<<25))
333 		  	return -1;
334 		break;
335 	case 05: /* 14 row + bank address bits, A<20> must not be set */
336 	  	if(physaddr & (1<<20))
337 		  	return -1;
338 		break;
339 	case 06: /* 15 row + bank address bits, A<20> must not be set */
340 	  	if(physaddr & (1<<20))
341 		  	return -1;
342 		break;
343 	default:
344 	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n",
345 		       __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));
346 		return -1;
347 	}
348 
349 	return 0;
350 }
351 
352 
353 EXPORT_SYMBOL(sa1111_sac_request_dma);
354 EXPORT_SYMBOL(sa1111_check_dma_bug);
355 
356 
sa1111_init_sac_dma(void)357 static int __init sa1111_init_sac_dma(void)
358 {
359 	int channel = SA1111_SAC_DMA_BASE;
360 	dma_chan[channel++].regs = (dma_regs_t *) &SADTCS;
361 	dma_chan[channel++].regs = (dma_regs_t *) &SADRCS;
362 	return 0;
363 }
364 
365 __initcall(sa1111_init_sac_dma);
366