1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MI
3   File:     mi_dma.c
4 
5   Copyright 2003-2008 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-11-24#$
14   $Rev: 11187 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include <nitro.h>
19 #include "../include/mi_dma.h"
20 
21 #ifdef SDK_ARM9
22 #include <nitro/itcm_begin.h>
23 //================================================================================
24 //          setting DMA
25 //================================================================================
MIi_DmaSetParameters(u32 dmaNo,u32 src,u32 dest,u32 ctrl,u32 mode)26 void MIi_DmaSetParameters(u32 dmaNo, u32 src, u32 dest, u32 ctrl, u32 mode)
27 {
28 	OSIntrMode enabled;
29     vu32 *p;
30 
31 	if ( ! (mode & MIi_DMA_MODE_NOINT) )
32 	{
33 		enabled = OS_DisableInterrupts();
34 	}
35 
36     p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_SAD_WOFFSET );
37 
38 	if ( mode & MIi_DMA_MODE_SRC32 )
39 	{
40 		MIiDmaClearSrc *srcp = (MIiDmaClearSrc *) ((u32)MIi_DMA_CLEAR_DATA_BUF + dmaNo * 4);
41 		srcp->b32 = src;
42 		src = (u32)srcp;
43 	}
44 	else if ( mode & MIi_DMA_MODE_SRC16 )
45 	{
46 		MIiDmaClearSrc *srcp = (MIiDmaClearSrc *) ((u32)MIi_DMA_CLEAR_DATA_BUF + dmaNo * 4);
47 		srcp->b16 = (u16)src;
48 		src = (u32)srcp;
49 	}
50 
51     *p = (vu32)src;
52     *(p + 1) = (vu32)dest;
53     *(p + 2) = (vu32)ctrl;
54 
55 	if ( mode & MIi_DMA_MODE_WAIT )
56 	{
57 		//---- ARM9 must wait 2 cycle (load is 1/2 cycle)
58 		{
59 			u32     dummy = reg_MI_DMA0SAD;
60 		}
61 		{
62 			u32     dummy = reg_MI_DMA0SAD;
63 		}
64 
65 		if ( ! (mode & MIi_DMA_MODE_NOCLEAR) )
66 		{
67 			//---- for multiple DMA problem in DMA0
68 			if (dmaNo == MIi_DUMMY_DMA_NO)
69 			{
70 				*p = (vu32)MIi_DUMMY_SRC;
71 				*(p + 1) = (vu32)MIi_DUMMY_DEST;
72 				*(p + 2) = (vu32)MIi_DUMMY_CNT;
73 			}
74 		}
75 	}
76 
77 	if ( ! (mode & MIi_DMA_MODE_NOINT) )
78 	{
79 		(void)OS_RestoreInterrupts(enabled);
80 	}
81 
82 	if ( mode & MIi_DMA_MODE_WAIT )
83 	{
84 		//---- ARM9 must wait 2 cycle (load is 1/2 cycle)
85 		{
86 			u32     dummy = reg_MI_DMA0SAD;
87 		}
88 		{
89 			u32     dummy = reg_MI_DMA0SAD;
90 		}
91 	}
92 }
93 #include <nitro/itcm_end.h>
94 #else // ifdef SDK_ARM9
MIi_DmaSetParameters(u32 dmaNo,u32 src,u32 dest,u32 ctrl,u32 mode)95 void MIi_DmaSetParameters(u32 dmaNo, u32 src, u32 dest, u32 ctrl, u32 mode)
96 {
97 	OSIntrMode enabled;
98     vu32 *p;
99 
100 	if ( ! (mode & MIi_DMA_MODE_NOINT) )
101 	{
102 		enabled = OS_DisableInterrupts();
103 	}
104 
105     p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_SAD_WOFFSET );
106 
107 	if ( mode & MIi_DMA_MODE_SRC32 )
108 	{
109 		MIiDmaClearSrc *srcp = (MIiDmaClearSrc *) ((u32)MIi_DMA_CLEAR_DATA_BUF + dmaNo * 4);
110 		srcp->b32 = src;
111 		src = (u32)srcp;
112 	}
113 	else if ( mode & MIi_DMA_MODE_SRC16 )
114 	{
115 		MIiDmaClearSrc *srcp = (MIiDmaClearSrc *) ((u32)MIi_DMA_CLEAR_DATA_BUF + dmaNo * 4);
116 		srcp->b16 = (u16)src;
117 		src = (u32)srcp;
118 	}
119 
120     *p = (vu32)src;
121     *(p + 1) = (vu32)dest;
122     *(p + 2) = (vu32)ctrl;
123 
124 	if ( mode & MIi_DMA_MODE_WAIT )
125 	{
126 		// ARM7 must wait 2 cycle (load is 3 cycle)
127         u32     dummy = reg_MI_DMA0SAD;
128 	}
129 
130 	if ( ! (mode & MIi_DMA_MODE_NOINT) )
131 	{
132 		(void)OS_RestoreInterrupts(enabled);
133 	}
134 }
135 #endif
136 
137 //================================================================================
138 //            memory oparation using DMA (sync)
139 //================================================================================
140 /*---------------------------------------------------------------------------*
141   Name:         MI_DmaFill32
142 
143   Description:  fill memory with specified data.
144                 sync 32bit version
145 
146   Arguments:    dmaNo : DMA channel No.
147                 dest  : destination address
148                 data  : fill data
149                 size  : size (byte)
150 
151   Returns:      None
152  *---------------------------------------------------------------------------*/
MIi_DmaFill32(u32 dmaNo,void * dest,u32 data,u32 size,BOOL dmaEnable)153 void MIi_DmaFill32(u32 dmaNo, void *dest, u32 data, u32 size, BOOL dmaEnable)
154 {
155     vu32   *dmaCntp;
156 
157     MIi_ASSERT_DMANO(dmaNo);
158     MIi_ASSERT_MUL4(size);
159     MIi_ASSERT_SIZE(dmaNo, size / 4);
160     MIi_ASSERT_DEST_ALIGN4(dest);
161     MIi_WARNING_ADDRINTCM(dest, size);
162 
163     if (size > 0)
164     {
165 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
166 		if ( dmaEnable )
167 		{
168 			MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size),
169 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_SRC32 );
170 		}
171 		else
172 		{
173 			MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR32(size),
174 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_SRC32 | MIi_DMA_MODE_NOCLEAR );
175 		}
176 		MIi_Wait_AfterDMA(dmaCntp);
177 	}
178 }
179 
180 /*---------------------------------------------------------------------------*
181   Name:         MI_DmaCopy32
182 
183   Description:  copy memory with DMA
184                 sync 32bit version
185 
186   Arguments:    dmaNo : DMA channel No.
187                 src   : source address
188                 dest  : destination address
189                 size  : size (byte)
190 
191   Returns:      None
192  *---------------------------------------------------------------------------*/
MIi_DmaCopy32(u32 dmaNo,const void * src,void * dest,u32 size,BOOL dmaEnable)193 void MIi_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size, BOOL dmaEnable)
194 {
195     vu32   *dmaCntp;
196 
197     MIi_ASSERT_DMANO(dmaNo);
198     MIi_ASSERT_MUL4(size);
199     MIi_ASSERT_SIZE(dmaNo, size / 4);
200     MIi_ASSERT_SRC_ALIGN4(src);
201     MIi_ASSERT_DEST_ALIGN4(dest);
202     MIi_WARNING_ADDRINTCM(src, size);
203     MIi_WARNING_ADDRINTCM(dest, size);
204 
205     if (size > 0)
206     {
207 		//---- check DMA0 source address
208 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
209 
210 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
211 		if ( dmaEnable )
212 		{
213 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size),
214 							  MIi_DMA_MODE_WAIT );
215 		}
216 		else
217 		{
218 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY32(size),
219 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
220 		}
221 		MIi_Wait_AfterDMA(dmaCntp);
222 	}
223 }
224 
225 /*---------------------------------------------------------------------------*
226   Name:         MI_DmaSend32
227 
228   Description:  send u32 data to fixed address
229                 sync 32bit version
230 
231   Arguments:    dmaNo : DMA channel No.
232                 src   : data stream to send
233                 dest  : destination address. not incremented
234                 size  : size (byte)
235 
236   Returns:      None
237  *---------------------------------------------------------------------------*/
MIi_DmaSend32(u32 dmaNo,const void * src,volatile void * dest,u32 size,BOOL dmaEnable)238 void MIi_DmaSend32(u32 dmaNo, const void *src, volatile void *dest, u32 size, BOOL dmaEnable)
239 {
240     vu32   *dmaCntp;
241 
242     MIi_ASSERT_DMANO(dmaNo);
243     MIi_ASSERT_MUL4(size);
244     MIi_ASSERT_SIZE(dmaNo, size / 4);
245     MIi_ASSERT_SRC_ALIGN4(src);
246     MIi_ASSERT_DEST_ALIGN4(dest);
247     MIi_WARNING_ADDRINTCM(src, size);
248     MIi_WARNING_ADDRINTCM(dest, 0);
249 
250     if (size > 0)
251     {
252 		//---- check DMA0 source address
253 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
254 
255 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
256 		if ( dmaEnable )
257 		{
258 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND32(size),
259 							  MIi_DMA_MODE_WAIT );
260 		}
261 		else
262 		{
263 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND32(size),
264 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
265 		}
266 		MIi_Wait_AfterDMA(dmaCntp);
267 	}
268 }
269 
270 /*---------------------------------------------------------------------------*
271   Name:         MI_DmaRecv32
272 
273   Description:  receive u32 data from fixed address
274                 sync 32bit version
275 
276   Arguments:    dmaNo : DMA channel No.
277                 src   : source address. not incremented
278                 dest  : data buffer to receive
279                 size  : size (byte)
280 
281   Returns:      None
282  *---------------------------------------------------------------------------*/
MIi_DmaRecv32(u32 dmaNo,volatile const void * src,void * dest,u32 size,BOOL dmaEnable)283 void MIi_DmaRecv32(u32 dmaNo, volatile const void *src, void *dest, u32 size, BOOL dmaEnable)
284 {
285     vu32   *dmaCntp;
286 
287     MIi_ASSERT_DMANO(dmaNo);
288     MIi_ASSERT_MUL4(size);
289     MIi_ASSERT_SIZE(dmaNo, size / 4);
290     MIi_ASSERT_SRC_ALIGN4(src);
291     MIi_ASSERT_DEST_ALIGN4(dest);
292     MIi_WARNING_ADDRINTCM(src, 0);
293     MIi_WARNING_ADDRINTCM(dest, size);
294 
295     if (size > 0)
296     {
297 		//---- check DMA0 source address
298 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
299 
300 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
301 		if ( dmaEnable )
302 		{
303 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV32(size),
304 							  MIi_DMA_MODE_WAIT );
305 		}
306 		else
307 		{
308 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV32(size),
309 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
310 		}
311 		MIi_Wait_AfterDMA(dmaCntp);
312 	}
313 }
314 
315 /*---------------------------------------------------------------------------*
316   Name:         MI_DmaPipe32
317 
318   Description:  pipe data from fixed address to fixed address.
319                 sync 32bit version
320 
321   Arguments:    dmaNo : DMA channel No.
322                 src   : source address. not incremented
323                 dest  : destination address. not incremented
324                 size  : size (byte)
325 
326   Returns:      None
327  *---------------------------------------------------------------------------*/
MIi_DmaPipe32(u32 dmaNo,volatile const void * src,volatile void * dest,u32 size,BOOL dmaEnable)328 void MIi_DmaPipe32(u32 dmaNo, volatile const void *src, volatile void *dest, u32 size, BOOL dmaEnable)
329 {
330     vu32   *dmaCntp;
331 
332     MIi_ASSERT_DMANO(dmaNo);
333     MIi_ASSERT_MUL4(size);
334     MIi_ASSERT_SIZE(dmaNo, size / 4);
335     MIi_ASSERT_SRC_ALIGN4(src);
336     MIi_ASSERT_DEST_ALIGN4(dest);
337     MIi_WARNING_ADDRINTCM(src, 0);
338     MIi_WARNING_ADDRINTCM(dest, 0);
339 
340     if (size > 0)
341     {
342 		//---- check DMA0 source address
343 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
344 
345 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
346 		if ( dmaEnable )
347 		{
348 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE32(size),
349 							  MIi_DMA_MODE_WAIT );
350 		}
351 		else
352 		{
353 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE32(size),
354 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
355 		}
356 		MIi_Wait_AfterDMA(dmaCntp);
357 	}
358 }
359 
360 /*---------------------------------------------------------------------------*
361   Name:         MI_DmaFill16
362 
363   Description:  fill memory with specified data.
364                 sync 16bit version
365 
366   Arguments:    dmaNo : DMA channel No.
367                 dest  : destination address
368                 data  : fill data
369                 size  : size (byte)
370 
371   Returns:      None
372  *---------------------------------------------------------------------------*/
MIi_DmaFill16(u32 dmaNo,void * dest,u16 data,u32 size,BOOL dmaEnable)373 void MIi_DmaFill16(u32 dmaNo, void *dest, u16 data, u32 size, BOOL dmaEnable)
374 {
375     vu32   *dmaCntp;
376 
377     MIi_ASSERT_DMANO(dmaNo);
378     MIi_ASSERT_MUL2(size);
379     MIi_ASSERT_SIZE(dmaNo, size / 2);
380     MIi_ASSERT_DEST_ALIGN2(dest);
381     MIi_WARNING_ADDRINTCM(dest, size);
382 
383     if (size > 0)
384     {
385 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
386 		if ( dmaEnable )
387 		{
388 			MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR16(size),
389 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_SRC16 );
390 		}
391 		else
392 		{
393 			MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR16(size),
394 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_SRC16 | MIi_DMA_MODE_NOCLEAR );
395 		}
396 		MIi_Wait_AfterDMA(dmaCntp);
397 	}
398 }
399 
400 /*---------------------------------------------------------------------------*
401   Name:         MI_DmaCopy16
402 
403   Description:  copy memory with DMA
404                 sync 16bit version
405 
406   Arguments:    dmaNo : DMA channel No.
407                 src   : source address
408                 dest  : destination address
409                 size  : size (byte)
410 
411   Returns:      None
412  *---------------------------------------------------------------------------*/
MIi_DmaCopy16(u32 dmaNo,const void * src,void * dest,u32 size,BOOL dmaEnable)413 void MIi_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size, BOOL dmaEnable)
414 {
415     vu32   *dmaCntp;
416 
417     MIi_ASSERT_DMANO(dmaNo);
418     MIi_ASSERT_MUL2(size);
419     MIi_ASSERT_SIZE(dmaNo, size / 2);
420     MIi_ASSERT_SRC_ALIGN2(src);
421     MIi_ASSERT_DEST_ALIGN2(dest);
422     MIi_WARNING_ADDRINTCM(src, size);
423     MIi_WARNING_ADDRINTCM(dest, size);
424 
425     if (size > 0)
426     {
427 		//---- check DMA0 source address
428 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
429 
430 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
431 		if ( dmaEnable )
432 		{
433 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY16(size),
434 							  MIi_DMA_MODE_WAIT );
435 		}
436 		else
437 		{
438 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY16(size),
439 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
440 		}
441 		MIi_Wait_AfterDMA(dmaCntp);
442 	}
443 }
444 
445 /*---------------------------------------------------------------------------*
446   Name:         MI_DmaSend16
447 
448   Description:  send u16 data to fixed address
449                 sync 16bit version
450 
451   Arguments:    dmaNo : DMA channel No.
452                 src   : data stream to send
453                 dest  : destination address. not incremented
454                 size  : size (byte)
455 
456   Returns:      None
457  *---------------------------------------------------------------------------*/
MIi_DmaSend16(u32 dmaNo,const void * src,volatile void * dest,u32 size,BOOL dmaEnable)458 void MIi_DmaSend16(u32 dmaNo, const void *src, volatile void *dest, u32 size, BOOL dmaEnable)
459 {
460     vu32   *dmaCntp;
461 
462     MIi_ASSERT_DMANO(dmaNo);
463     MIi_ASSERT_MUL2(size);
464     MIi_ASSERT_SIZE(dmaNo, size / 2);
465     MIi_ASSERT_SRC_ALIGN2(src);
466     MIi_ASSERT_DEST_ALIGN2(dest);
467     MIi_WARNING_ADDRINTCM(src, size);
468     MIi_WARNING_ADDRINTCM(dest, 0);
469 
470     if (size > 0)
471     {
472 		//---- check DMA0 source address
473 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
474 
475 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
476 		if ( dmaEnable )
477 		{
478 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND16(size),
479 							  MIi_DMA_MODE_WAIT );
480 		}
481 		else
482 		{
483 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND16(size),
484 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
485 		}
486 		MIi_Wait_AfterDMA(dmaCntp);
487 	}
488 }
489 
490 /*---------------------------------------------------------------------------*
491   Name:         MI_DmaRecv16
492 
493   Description:  send u16 data to fixed address
494                 sync 16bit version
495 
496   Arguments:    dmaNo : DMA channel No.
497                 src   : source address. not incremented
498                 dest  : data buffer to receive
499                 size  : size (byte)
500 
501   Returns:      None
502  *---------------------------------------------------------------------------*/
MIi_DmaRecv16(u32 dmaNo,volatile const void * src,void * dest,u32 size,BOOL dmaEnable)503 void MIi_DmaRecv16(u32 dmaNo, volatile const void *src, void *dest, u32 size, BOOL dmaEnable)
504 {
505     vu32   *dmaCntp;
506 
507     MIi_ASSERT_DMANO(dmaNo);
508     MIi_ASSERT_MUL2(size);
509     MIi_ASSERT_SIZE(dmaNo, size / 2);
510     MIi_ASSERT_SRC_ALIGN2(src);
511     MIi_ASSERT_DEST_ALIGN2(dest);
512     MIi_WARNING_ADDRINTCM(src, 0);
513     MIi_WARNING_ADDRINTCM(dest, size);
514 
515     if (size > 0)
516     {
517 		//---- check DMA0 source address
518 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
519 
520 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
521 		if ( dmaEnable )
522 		{
523 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV16(size),
524 							  MIi_DMA_MODE_WAIT );
525 		}
526 		else
527 		{
528 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV16(size),
529 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
530 		}
531 		MIi_Wait_AfterDMA(dmaCntp);
532 	}
533 }
534 
535 /*---------------------------------------------------------------------------*
536   Name:         MI_DmaPipe16
537 
538   Description:  pipe data from fixed address to fixed address.
539                 sync 16bit version
540 
541   Arguments:    dmaNo : DMA channel No.
542                 src   : source address. not incremented
543                 dest  : destination address. not incremented
544                 size  : size (byte)
545 
546   Returns:      None
547  *---------------------------------------------------------------------------*/
MIi_DmaPipe16(u32 dmaNo,volatile const void * src,volatile void * dest,u32 size,BOOL dmaEnable)548 void MIi_DmaPipe16(u32 dmaNo, volatile const void *src, volatile void *dest, u32 size, BOOL dmaEnable)
549 {
550     vu32   *dmaCntp;
551 
552     MIi_ASSERT_DMANO(dmaNo);
553     MIi_ASSERT_MUL2(size);
554     MIi_ASSERT_SIZE(dmaNo, size / 2);
555     MIi_ASSERT_SRC_ALIGN2(src);
556     MIi_ASSERT_DEST_ALIGN2(dest);
557     MIi_WARNING_ADDRINTCM(src, 0);
558     MIi_WARNING_ADDRINTCM(dest, 0);
559 
560     if (size > 0)
561     {
562 		//---- check DMA0 source address
563 		MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
564 
565 		MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
566 		if ( dmaEnable )
567 		{
568 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE16(size),
569 							  MIi_DMA_MODE_WAIT );
570 		}
571 		else
572 		{
573 			MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE16(size),
574 							  MIi_DMA_MODE_WAIT | MIi_DMA_MODE_NOCLEAR );
575 		}
576 		MIi_Wait_AfterDMA(dmaCntp);
577 	}
578 }
579 
580 //================================================================================
581 //            memory oparation using DMA (async)
582 //================================================================================
583 /*---------------------------------------------------------------------------*
584   Name:         MI_DmaFill32Async
585 
586   Description:  fill memory with specified data.
587                 async 32bit version
588 
589   Arguments:    dmaNo : DMA channel No.
590                 dest  : destination address
591                 data  : fill data
592                 size  : size (byte)
593                 callback : callback function called finish DMA
594                 arg      : callback argument
595 
596   Returns:      None
597  *---------------------------------------------------------------------------*/
MIi_DmaFill32Async(u32 dmaNo,void * dest,u32 data,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)598 void MIi_DmaFill32Async(u32 dmaNo, void *dest, u32 data, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
599 {
600     MIi_ASSERT_DMANO(dmaNo);
601     MIi_ASSERT_MUL4(size);
602     MIi_ASSERT_SIZE(dmaNo, size / 4);
603     MIi_ASSERT_DEST_ALIGN4(dest);
604     MIi_WARNING_ADDRINTCM(dest, size);
605 
606     if (size == 0)
607     {
608         MIi_CallCallback(callback, arg);
609     }
610     else
611     {
612         MI_WaitDma(dmaNo);
613 
614         if (callback)
615         {
616             OSi_EnterDmaCallback(dmaNo, callback, arg);
617 			if ( dmaEnable )
618 			{
619 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR32_IF(size), MIi_DMA_MODE_SRC32 );
620 			}
621 			else
622 			{
623 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR32_IF(size), MIi_DMA_MODE_SRC32 | MIi_DMA_MODE_NOCLEAR );
624 			}
625         }
626         else
627         {
628 			if ( dmaEnable )
629 			{
630 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size), MIi_DMA_MODE_SRC32 );
631 			}
632 			else
633 			{
634 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR32(size), MIi_DMA_MODE_SRC32 | MIi_DMA_MODE_NOCLEAR );
635 			}
636         }
637     }
638 }
639 
640 /*---------------------------------------------------------------------------*
641   Name:         MI_DmaCopy32Async
642 
643   Description:  copy memory with DMA
644                 async 32bit version
645 
646   Arguments:    dmaNo : DMA channel No.
647                 src   : source address
648                 dest  : destination address
649                 size  : size (byte)
650                 callback : callback function called finish DMA
651                 arg      : callback argument
652 
653   Returns:      None
654  *---------------------------------------------------------------------------*/
MIi_DmaCopy32Async(u32 dmaNo,const void * src,void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)655 void MIi_DmaCopy32Async(u32 dmaNo, const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
656 {
657     MIi_ASSERT_DMANO(dmaNo);
658     MIi_ASSERT_MUL4(size);
659     MIi_ASSERT_SIZE(dmaNo, size / 4);
660     MIi_ASSERT_SRC_ALIGN4(src);
661     MIi_ASSERT_DEST_ALIGN4(dest);
662     MIi_WARNING_ADDRINTCM(src, size);
663     MIi_WARNING_ADDRINTCM(dest, size);
664 
665     //---- check DMA0 source address
666     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
667 
668     if (size == 0)
669     {
670         MIi_CallCallback(callback, arg);
671     }
672     else
673     {
674         MI_WaitDma(dmaNo);
675 
676         if (callback)
677         {
678             OSi_EnterDmaCallback(dmaNo, callback, arg);
679 			if ( dmaEnable )
680 			{
681 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32_IF(size), 0 );
682 			}
683 			else
684 			{
685 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY32_IF(size), MIi_DMA_MODE_NOCLEAR );
686 			}
687         }
688         else
689         {
690 			if ( dmaEnable )
691 			{
692 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size), 0 );
693 			}
694 			else
695 			{
696 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY32(size), MIi_DMA_MODE_NOCLEAR );
697 			}
698         }
699     }
700 }
701 
702 /*---------------------------------------------------------------------------*
703   Name:         MI_DmaSend32Async
704 
705   Description:  send u32 data to fixed address
706                 async 32bit version
707 
708   Arguments:    dmaNo : DMA channel No.
709                 src   : data stream to send
710                 dest  : destination address. not incremented
711                 size  : size (byte)
712                 callback : callback function called finish DMA
713                 arg      : callback argument
714 
715   Returns:      None
716  *---------------------------------------------------------------------------*/
MIi_DmaSend32Async(u32 dmaNo,const void * src,volatile void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)717 void MIi_DmaSend32Async(u32 dmaNo, const void *src, volatile void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
718 {
719     MIi_ASSERT_DMANO(dmaNo);
720     MIi_ASSERT_MUL4(size);
721     MIi_ASSERT_SIZE(dmaNo, size / 4);
722     MIi_ASSERT_SRC_ALIGN4(src);
723     MIi_ASSERT_DEST_ALIGN4(dest);
724     MIi_WARNING_ADDRINTCM(src, size);
725     MIi_WARNING_ADDRINTCM(dest, size);
726 
727     //---- check DMA0 source address
728     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
729 
730     if (size == 0)
731     {
732         MIi_CallCallback(callback, arg);
733     }
734     else
735     {
736         MI_WaitDma(dmaNo);
737 
738         if (callback)
739         {
740             OSi_EnterDmaCallback(dmaNo, callback, arg);
741 			if ( dmaEnable )
742 			{
743 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND32_IF(size), 0 );
744 			}
745 			else
746 			{
747 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND32_IF(size), MIi_DMA_MODE_NOCLEAR );
748 			}
749         }
750         else
751         {
752 			if ( dmaEnable )
753 			{
754 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND32(size), 0 );
755 			}
756 			else
757 			{
758 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND32(size), MIi_DMA_MODE_NOCLEAR );
759 			}
760         }
761     }
762 }
763 
764 /*---------------------------------------------------------------------------*
765   Name:         MI_DmaRecv32Async
766 
767   Description:  send u32 data to fixed address
768                 async 32bit version
769 
770   Arguments:    dmaNo : DMA channel No.
771                 src   : data stream to send
772                 dest  : destination address. not incremented
773                 size  : size (byte)
774                 callback : callback function called finish DMA
775                 arg      : callback argument
776 
777   Returns:      None
778  *---------------------------------------------------------------------------*/
MIi_DmaRecv32Async(u32 dmaNo,volatile const void * src,void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)779 void MIi_DmaRecv32Async(u32 dmaNo, volatile const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
780 {
781     MIi_ASSERT_DMANO(dmaNo);
782     MIi_ASSERT_MUL4(size);
783     MIi_ASSERT_SIZE(dmaNo, size / 4);
784     MIi_ASSERT_SRC_ALIGN4(src);
785     MIi_ASSERT_DEST_ALIGN4(dest);
786     MIi_WARNING_ADDRINTCM(src, size);
787     MIi_WARNING_ADDRINTCM(dest, size);
788 
789     //---- check DMA0 source address
790     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
791 
792     if (size == 0)
793     {
794         MIi_CallCallback(callback, arg);
795     }
796     else
797     {
798         MI_WaitDma(dmaNo);
799 
800         if (callback)
801         {
802             OSi_EnterDmaCallback(dmaNo, callback, arg);
803 			if ( dmaEnable )
804 			{
805 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV32_IF(size), 0 );
806 			}
807 			else
808 			{
809 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV32_IF(size), MIi_DMA_MODE_NOCLEAR );
810 			}
811         }
812         else
813         {
814 			if ( dmaEnable )
815 			{
816 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV32(size), 0 );
817 			}
818 			else
819 			{
820 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV32(size), MIi_DMA_MODE_NOCLEAR );
821 			}
822         }
823     }
824 }
825 
826 /*---------------------------------------------------------------------------*
827   Name:         MI_DmaPipe32Async
828 
829   Description:  pipe data from fixed address to fixed address.
830                 async 32bit version
831 
832   Arguments:    dmaNo : DMA channel No.
833                 src   : source address. not incremented
834                 dest  : destination address. not incremented
835                 size  : size (byte)
836                 callback : callback function called finish DMA
837                 arg      : callback argument
838 
839   Returns:      None
840  *---------------------------------------------------------------------------*/
MIi_DmaPipe32Async(u32 dmaNo,volatile const void * src,volatile void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)841 void MIi_DmaPipe32Async(u32 dmaNo, volatile const void *src, volatile void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
842 {
843     MIi_ASSERT_DMANO(dmaNo);
844     MIi_ASSERT_MUL4(size);
845     MIi_ASSERT_SIZE(dmaNo, size / 4);
846     MIi_ASSERT_SRC_ALIGN4(src);
847     MIi_ASSERT_DEST_ALIGN4(dest);
848     MIi_WARNING_ADDRINTCM(src, 0);
849     MIi_WARNING_ADDRINTCM(dest, 0);
850 
851     //---- check DMA0 source address
852     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
853 
854     if (size == 0)
855     {
856         MIi_CallCallback(callback, arg);
857     }
858     else
859     {
860         MI_WaitDma(dmaNo);
861 
862         if (callback)
863         {
864             OSi_EnterDmaCallback(dmaNo, callback, arg);
865 			if ( dmaEnable )
866 			{
867 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE32_IF(size), 0 );
868 			}
869 			else
870 			{
871 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE32_IF(size), MIi_DMA_MODE_NOCLEAR );
872 			}
873         }
874         else
875         {
876 			if ( dmaEnable )
877 			{
878 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE32(size), 0 );
879 			}
880 			else
881 			{
882 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE32(size), MIi_DMA_MODE_NOCLEAR );
883 			}
884         }
885     }
886 }
887 
888 /*---------------------------------------------------------------------------*
889   Name:         MI_DmaFill16Async
890 
891   Description:  fill memory with specified data.
892                 async 16bit version
893 
894   Arguments:    dmaNo : DMA channel No.
895                 dest  : destination address
896                 data  : fill data
897                 size  : size (byte)
898                 callback : callback function called finish DMA
899                 arg      : callback argument
900 
901   Returns:      None
902  *---------------------------------------------------------------------------*/
MIi_DmaFill16Async(u32 dmaNo,void * dest,u16 data,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)903 void MIi_DmaFill16Async(u32 dmaNo, void *dest, u16 data, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
904 {
905     MIi_ASSERT_DMANO(dmaNo);
906     MIi_ASSERT_MUL2(size);
907     MIi_ASSERT_SIZE(dmaNo, size / 2);
908     MIi_ASSERT_DEST_ALIGN2(dest);
909     MIi_WARNING_ADDRINTCM(dest, size);
910 
911     if (size == 0)
912     {
913         MIi_CallCallback(callback, arg);
914     }
915     else
916     {
917         MI_WaitDma(dmaNo);
918 
919         if (callback)
920         {
921             OSi_EnterDmaCallback(dmaNo, callback, arg);
922 			if ( dmaEnable )
923 			{
924 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR16_IF(size), MIi_DMA_MODE_SRC16 );
925 			}
926 			else
927 			{
928 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR16_IF(size), MIi_DMA_MODE_SRC16 | MIi_DMA_MODE_NOCLEAR );
929 			}
930         }
931         else
932         {
933 			if ( dmaEnable )
934 			{
935 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_CLEAR16(size), MIi_DMA_MODE_SRC16 );
936 			}
937 			else
938 			{
939 				MIi_DmaSetParameters(dmaNo, data, (u32)dest, MI_CNT_SET_CLEAR16(size), MIi_DMA_MODE_SRC16 | MIi_DMA_MODE_NOCLEAR );
940 			}
941         }
942     }
943 }
944 
945 /*---------------------------------------------------------------------------*
946   Name:         MI_DmaCopy16Async
947 
948   Description:  copy memory with DMA
949                 async 16bit version
950 
951   Arguments:    dmaNo : DMA channel No.
952                 src   : source address
953                 dest  : destination address
954                 size  : size (byte)
955                 callback : callback function called finish DMA
956                 arg      : callback argument
957 
958   Returns:      None
959  *---------------------------------------------------------------------------*/
MIi_DmaCopy16Async(u32 dmaNo,const void * src,void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)960 void MIi_DmaCopy16Async(u32 dmaNo, const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
961 {
962     MIi_ASSERT_DMANO(dmaNo);
963     MIi_ASSERT_MUL2(size);
964     MIi_ASSERT_SIZE(dmaNo, size / 2);
965     MIi_ASSERT_SRC_ALIGN2(src);
966     MIi_ASSERT_DEST_ALIGN2(dest);
967     MIi_WARNING_ADDRINTCM(src, size);
968     MIi_WARNING_ADDRINTCM(dest, size);
969 
970     //---- check DMA0 source address
971     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
972 
973     if (size == 0)
974     {
975         MIi_CallCallback(callback, arg);
976     }
977     else
978     {
979         MI_WaitDma(dmaNo);
980 
981         if (callback)
982         {
983             OSi_EnterDmaCallback(dmaNo, callback, arg);
984 			if ( dmaEnable )
985 			{
986 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY16_IF(size), 0 );
987 			}
988 			else
989 			{
990 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY16_IF(size), MIi_DMA_MODE_NOCLEAR );
991 			}
992         }
993         else
994         {
995 			if ( dmaEnable )
996 			{
997 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY16(size), 0 );
998 			}
999 			else
1000 			{
1001 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_COPY16(size), MIi_DMA_MODE_NOCLEAR );
1002 			}
1003         }
1004     }
1005 }
1006 
1007 /*---------------------------------------------------------------------------*
1008   Name:         MI_DmaSend16Async
1009 
1010   Description:  send u16 data to fixed address
1011                 async 16bit version
1012 
1013   Arguments:    dmaNo : DMA channel No.
1014                 src   : data stream to send
1015                 dest  : destination address. not incremented
1016                 size  : size (byte)
1017                 callback : callback function called finish DMA
1018                 arg      : callback argument
1019 
1020   Returns:      None
1021  *---------------------------------------------------------------------------*/
MIi_DmaSend16Async(u32 dmaNo,const void * src,volatile void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)1022 void MIi_DmaSend16Async(u32 dmaNo, const void *src, volatile void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
1023 {
1024     MIi_ASSERT_DMANO(dmaNo);
1025     MIi_ASSERT_MUL2(size);
1026     MIi_ASSERT_SIZE(dmaNo, size / 2);
1027     MIi_ASSERT_SRC_ALIGN2(src);
1028     MIi_ASSERT_DEST_ALIGN2(dest);
1029     MIi_WARNING_ADDRINTCM(src, size);
1030     MIi_WARNING_ADDRINTCM(dest, size);
1031 
1032     //---- check DMA0 source address
1033     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
1034 
1035     if (size == 0)
1036     {
1037         MIi_CallCallback(callback, arg);
1038     }
1039     else
1040     {
1041         MI_WaitDma(dmaNo);
1042 
1043         if (callback)
1044         {
1045             OSi_EnterDmaCallback(dmaNo, callback, arg);
1046 			if ( dmaEnable )
1047 			{
1048 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND16_IF(size), 0 );
1049 			}
1050 			else
1051 			{
1052 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND16_IF(size), MIi_DMA_MODE_NOCLEAR );
1053 			}
1054         }
1055         else
1056         {
1057 			if ( dmaEnable )
1058 			{
1059 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SEND16(size), 0 );
1060 			}
1061 			else
1062 			{
1063 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_SEND16(size), MIi_DMA_MODE_NOCLEAR );
1064 			}
1065         }
1066     }
1067 }
1068 
1069 /*---------------------------------------------------------------------------*
1070   Name:         MI_DmaRecv16Async
1071 
1072   Description:  send u16 data to fixed address
1073                 async 16bit version
1074 
1075   Arguments:    dmaNo : DMA channel No.
1076                 src   : data stream to send
1077                 dest  : destination address. not incremented
1078                 size  : size (byte)
1079                 callback : callback function called finish DMA
1080                 arg      : callback argument
1081 
1082   Returns:      None
1083  *---------------------------------------------------------------------------*/
MIi_DmaRecv16Async(u32 dmaNo,volatile const void * src,void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)1084 void MIi_DmaRecv16Async(u32 dmaNo, volatile const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
1085 {
1086     MIi_ASSERT_DMANO(dmaNo);
1087     MIi_ASSERT_MUL2(size);
1088     MIi_ASSERT_SIZE(dmaNo, size / 2);
1089     MIi_ASSERT_SRC_ALIGN2(src);
1090     MIi_ASSERT_DEST_ALIGN2(dest);
1091     MIi_WARNING_ADDRINTCM(src, size);
1092     MIi_WARNING_ADDRINTCM(dest, size);
1093 
1094     //---- check DMA0 source address
1095     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
1096 
1097     if (size == 0)
1098     {
1099         MIi_CallCallback(callback, arg);
1100     }
1101     else
1102     {
1103         MI_WaitDma(dmaNo);
1104 
1105         if (callback)
1106         {
1107             OSi_EnterDmaCallback(dmaNo, callback, arg);
1108 			if ( dmaEnable )
1109 			{
1110 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV16_IF(size), 0 );
1111 			}
1112 			else
1113 			{
1114 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV16_IF(size), MIi_DMA_MODE_NOCLEAR );
1115 			}
1116         }
1117         else
1118         {
1119 			if ( dmaEnable )
1120 			{
1121 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_RECV16(size), 0 );
1122 			}
1123 			else
1124 			{
1125 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_RECV16(size), MIi_DMA_MODE_NOCLEAR );
1126 			}
1127         }
1128     }
1129 }
1130 
1131 /*---------------------------------------------------------------------------*
1132   Name:         MI_DmaPipe16Async
1133 
1134   Description:  receive u16 data from fixed address
1135                 async 16bit version
1136 
1137   Arguments:    dmaNo : DMA channel No.
1138                 src   : source address. not incremented
1139                 dest  : destination address. not incremented
1140                 size  : size (byte)
1141                 callback : callback function called finish DMA
1142                 arg      : callback argument
1143 
1144   Returns:      None
1145  *---------------------------------------------------------------------------*/
MIi_DmaPipe16Async(u32 dmaNo,volatile const void * src,volatile void * dest,u32 size,MIDmaCallback callback,void * arg,BOOL dmaEnable)1146 void MIi_DmaPipe16Async(u32 dmaNo, volatile const void *src, volatile void *dest, u32 size, MIDmaCallback callback, void *arg, BOOL dmaEnable)
1147 {
1148     MIi_ASSERT_DMANO(dmaNo);
1149     MIi_ASSERT_MUL2(size);
1150     MIi_ASSERT_SIZE(dmaNo, size / 2);
1151     MIi_ASSERT_SRC_ALIGN2(src);
1152     MIi_ASSERT_DEST_ALIGN2(dest);
1153     MIi_WARNING_ADDRINTCM(src, 0);
1154     MIi_WARNING_ADDRINTCM(dest, 0);
1155 
1156     //---- check DMA0 source address
1157     MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
1158 
1159     if (size == 0)
1160     {
1161         MIi_CallCallback(callback, arg);
1162     }
1163     else
1164     {
1165         MI_WaitDma(dmaNo);
1166 
1167         if (callback)
1168         {
1169             OSi_EnterDmaCallback(dmaNo, callback, arg);
1170 			if ( dmaEnable )
1171 			{
1172 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE16_IF(size), 0 );
1173 			}
1174 			else
1175 			{
1176 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE16_IF(size), MIi_DMA_MODE_NOCLEAR );
1177 			}
1178         }
1179         else
1180         {
1181 			if ( dmaEnable )
1182 			{
1183 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_PIPE16(size), 0 );
1184 			}
1185 			else
1186 			{
1187 				MIi_DmaSetParameters(dmaNo, (u32)src, (u32)dest, MI_CNT_SET_PIPE16(size), MIi_DMA_MODE_NOCLEAR );
1188 			}
1189         }
1190     }
1191 }
1192 
1193 //================================================================================
1194 //       DMA WAIT/STOP
1195 //================================================================================
1196 /*---------------------------------------------------------------------------*
1197   Name:         MI_IsDmaBusy
1198 
1199   Description:  check whether DMA is busy or not
1200 
1201   Arguments:    dmaNo : DMA channel No.
1202 
1203   Returns:      TRUE if DMA is busy, FALSE if not
1204  *---------------------------------------------------------------------------*/
MI_IsDmaBusy(u32 dmaNo)1205 BOOL MI_IsDmaBusy(u32 dmaNo)
1206 {
1207     vu32 *dmaCntp = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_CNT_WOFFSET );
1208 
1209     MIi_ASSERT_DMANO(dmaNo);
1210     return (BOOL)((*(vu32 *)dmaCntp & REG_MI_DMA0CNT_E_MASK) >> REG_MI_DMA0CNT_E_SHIFT);
1211 }
1212 
1213 /*---------------------------------------------------------------------------*
1214   Name:         MI_WaitDma
1215 
1216   Description:  wait while DMA is busy
1217 
1218   Arguments:    dmaNo : DMA channel No.
1219 
1220   Returns:      None
1221  *---------------------------------------------------------------------------*/
MI_WaitDma(u32 dmaNo)1222 void MI_WaitDma(u32 dmaNo)
1223 {
1224     OSIntrMode enabled = OS_DisableInterrupts();
1225     vu32 *dmaCntp = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_CNT_WOFFSET );
1226 
1227     MIi_ASSERT_DMANO(dmaNo);
1228     while (*dmaCntp & REG_MI_DMA0CNT_E_MASK)
1229     {
1230     }
1231 
1232     //---- for multiple DMA problem in DMA0
1233     if (dmaNo == MIi_DUMMY_DMA_NO)
1234     {
1235         vu32   *p = MI_DMA_REGADDR( dmaNo, MI_DMA_REG_SAD_WOFFSET );
1236         *p = (vu32)MIi_DUMMY_SRC;
1237         *(p + 1) = (vu32)MIi_DUMMY_DEST;
1238         *(p + 2) = (vu32)MIi_DUMMY_CNT;
1239     }
1240 
1241     (void)OS_RestoreInterrupts(enabled);
1242 }
1243 
1244 /*---------------------------------------------------------------------------*
1245   Name:         MI_StopDma
1246 
1247   Description:  stop DMA
1248 
1249   Arguments:    dmaNo : DMA channel No.
1250 
1251   Returns:      None
1252  *---------------------------------------------------------------------------*/
MI_StopDma(u32 dmaNo)1253 void MI_StopDma(u32 dmaNo)
1254 {
1255     OSIntrMode enabled = OS_DisableInterrupts();
1256     vu32   *dmaCntp = (vu32*)MI_DMA_REGADDR(dmaNo, MI_DMA_REG_CNT_WOFFSET);
1257 
1258     MIi_ASSERT_DMANO(dmaNo);
1259 
1260     *dmaCntp &= ~(MI_DMA_TIMING_MASK | MI_DMA_CONTINUOUS_ON);
1261     *dmaCntp &= ~MI_DMA_ENABLE;
1262 
1263     //---- ARM9 must wait 2 cycle (load is 1/2 cycle)
1264     {
1265         u32     dummy = dmaCntp[0];
1266     }
1267     {
1268         u32     dummy = dmaCntp[0];
1269     }
1270 
1271     //---- for multiple DMA problem in DMA0
1272     if (dmaNo == MIi_DUMMY_DMA_NO)
1273     {
1274         vu32   *p = (vu32 *)MI_DMA_REGADDR(dmaNo, MI_DMA_REG_SAD_WOFFSET);
1275         *p = (vu32)MIi_DUMMY_SRC;
1276         *(p + 1) = (vu32)MIi_DUMMY_DEST;
1277         *(p + 2) = (vu32)MIi_DUMMY_CNT;
1278     }
1279 
1280     (void)OS_RestoreInterrupts(enabled);
1281 }
1282 
1283 /*---------------------------------------------------------------------------*
1284   Name:         MI_StopAllDma
1285 
1286   Description:  stop all DMA
1287 
1288   Arguments:    None
1289 
1290   Returns:      None
1291  *---------------------------------------------------------------------------*/
MI_StopAllDma(void)1292 void    MI_StopAllDma(void)
1293 {
1294 	MI_StopDma(0);
1295 	MI_StopDma(1);
1296 	MI_StopDma(2);
1297 	MI_StopDma(3);
1298 }
1299 
1300 //================================================================================
1301 //        restart DMA
1302 //================================================================================
1303 /*---------------------------------------------------------------------------*
1304   Name:         MI_DmaRestart
1305 
1306   Description:  restart DMA
1307                 Just set the enable bit.
1308 
1309   Arguments:    ndmaNo : DMA channel	MI_NDMA_REG( ndmaNo, MI_NDMA_REG_CNT_WOFFSET ) |= MI_DMA_ENABLE;
1310  No.
1311 
1312   Returns:      None
1313  *---------------------------------------------------------------------------*/
MI_DmaRestart(u32 dmaNo)1314 void MI_DmaRestart(u32 dmaNo)
1315 {
1316     vu32   *dmaCntp = (vu32*)MI_DMA_REGADDR(dmaNo, MI_DMA_REG_CNT_WOFFSET);
1317 
1318 	MIi_ASSERT_DMANO(dmaNo);
1319     *dmaCntp |= MI_DMA_ENABLE;
1320 }
1321 
1322 //================================================================================
1323 //           for avoid multiple auto start DMA
1324 //================================================================================
1325 #ifdef SDK_ARM9
1326 /*---------------------------------------------------------------------------*
1327   Name:         MIi_CheckAnotherAutoDMA
1328 
1329   Description:  check whether other auto DMA is running.
1330                 (however, HBlankDMA and VBlankDMA are permit to
1331                  run at the same time.)
1332 
1333   Arguments:    dmaNo   : DMA channel No.
1334                 dmaType : DMA type
1335                 src     : source address
1336                 size    : DMA size
1337                 dir     : source direction (MI_DMA_SRC_INC/DEC/FIX)
1338 
1339   Returns:      None
1340  *---------------------------------------------------------------------------*/
MIi_CheckAnotherAutoDMA(u32 dmaNo,u32 dmaType)1341 void MIi_CheckAnotherAutoDMA(u32 dmaNo, u32 dmaType)
1342 {
1343     int     n;
1344     u32     dmaCnt;
1345     u32     timing;
1346 
1347     for (n = 0; n < MI_DMA_MAX_NUM; n++)
1348     {
1349         if (n == dmaNo)
1350         {
1351             continue;
1352         }
1353 
1354         dmaCnt = *(REGType32v *)(REG_DMA0CNT_ADDR + n * 12);
1355 
1356         //---- not used
1357         if ((dmaCnt & MI_DMA_ENABLE) == 0)
1358         {
1359             continue;
1360         }
1361 
1362         timing = dmaCnt & MI_DMA_TIMING_MASK;
1363 
1364         //---- if two DMAs are same, or HDMA and VDMA, it is allowed
1365         if (timing == dmaType
1366             || (timing == MI_DMA_TIMING_V_BLANK && dmaType == MI_DMA_TIMING_H_BLANK)
1367             || (timing == MI_DMA_TIMING_H_BLANK && dmaType == MI_DMA_TIMING_V_BLANK))
1368         {
1369             continue;
1370         }
1371 
1372         //---- check other auto DMA running
1373         if (timing == MI_DMA_TIMING_DISP
1374             || timing == MI_DMA_TIMING_DISP_MMEM
1375             || timing == MI_DMA_TIMING_CARD
1376             || timing == MI_DMA_TIMING_CARTRIDGE
1377             || timing == MI_DMA_TIMING_GXFIFO
1378             || timing == MI_DMA_TIMING_V_BLANK || timing == MI_DMA_TIMING_H_BLANK)
1379         {
1380             OS_TPanic("cannot start auto DMA at the same time.");
1381         }
1382     }
1383 }
1384 
1385 #endif // ifdef SDK_ARM9
1386 
1387 /*---------------------------------------------------------------------------*
1388   Name:         MIi_CheckDma0SourceAddress
1389 
1390   Description:  IN case of using DMA0, check source address.
1391                 Source address which is in I/O register or cartridge bus
1392                 is not available.
1393 
1394   Arguments:    dmaNo   : DMA channel No.
1395                 src     : source address
1396                 size    : DMA size
1397                 dir     : source direction (MI_DMA_SRC_INC/DEC/FIX)
1398 
1399   Returns:      None
1400  *---------------------------------------------------------------------------*/
MIi_CheckDma0SourceAddress(u32 dmaNo,u32 src,u32 size,u32 dir)1401 void MIi_CheckDma0SourceAddress(u32 dmaNo, u32 src, u32 size, u32 dir)
1402 {
1403 #ifdef SDK_TWL
1404     //---- If DMAC is fixed, not check here. (only on TWL)
1405     if ( OS_IsRunOnTwl() && SCFG_IsDmacFixed() )
1406     {
1407         return;
1408     }
1409 #endif
1410 
1411     //---- only in case of DMA0
1412     if (dmaNo == 0)
1413     {
1414         u32     addStart;
1415         u32     addEnd;
1416 
1417         //---- start address of souce
1418         addStart = src & 0xff000000;
1419 
1420         //---- end address of source
1421         switch (dir)
1422         {
1423         case MI_DMA_SRC_INC:
1424             addEnd = src + size;
1425             break;
1426         case MI_DMA_SRC_DEC:
1427             addEnd = src - size;
1428             break;
1429         default:
1430             addEnd = src;
1431             break;
1432         }
1433         addEnd &= 0xff000000;
1434 
1435         //---- check start and end address of source
1436         if (addStart == 0x04000000 || addStart >= 0x08000000 ||
1437             addEnd == 0x04000000 || addEnd >= 0x08000000)
1438         {
1439             OS_TPanic("illegal DMA0 source address.");
1440         }
1441     }
1442 }
1443 
1444 //================================================================================
1445 //           check if area is in TCM
1446 //================================================================================
1447 /*---------------------------------------------------------------------------*
1448   Name:         MIi_CheckAddressInTCM
1449 
1450   Description:  Check if specified area (from address to address+size)
1451                 is in ITCM/DTCM.
1452 
1453   Arguments:    addr  : start address
1454                 size  : size
1455 
1456   Returns:      None
1457  *---------------------------------------------------------------------------*/
1458 #if defined( SDK_ARM9 ) && defined( SDK_DEBUG )
MIi_CheckAddressInTCM(u32 addr,u32 size)1459 void MIi_CheckAddressInTCM(u32 addr, u32 size)
1460 {
1461     u32     itcm = HW_ITCM;            // ITCM fixed to HW_ITCM (=0x01ff8000)
1462     u32     dtcm = OS_GetDTCMAddress();
1463 
1464     SDK_WARNING(itcm >= addr + size
1465                 || addr >= itcm + HW_ITCM_SIZE, "intend to do DMA in ITCM area (%x)", addr);
1466     SDK_WARNING(dtcm >= addr + size
1467                 || addr >= dtcm + HW_DTCM_SIZE, "intend to do DMA in DTCM area (%x)", addr);
1468 }
1469 #endif
1470 
1471 //================================================================================
1472 //		 setting each register directly (internal)
1473 //================================================================================
MIi_SetDmaSrc16(u32 dmaNo,void * src)1474 void MIi_SetDmaSrc16( u32 dmaNo, void *src )
1475 {
1476 	vu32 *p;
1477 
1478     MIi_ASSERT_SRC_ALIGN2(src);
1479     MIi_WARNING_ADDRINTCM(src, 0); // size is unknown
1480 
1481 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_SAD_WOFFSET );
1482 	*p = (vu32)src;
1483 }
MIi_SetDmaSrc32(u32 dmaNo,void * src)1484 void MIi_SetDmaSrc32( u32 dmaNo, void *src )
1485 {
1486 	vu32 *p;
1487 
1488     MIi_ASSERT_SRC_ALIGN4(src);
1489     MIi_WARNING_ADDRINTCM(src, 0); // size is unknown
1490 
1491 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_SAD_WOFFSET );
1492 	*p = (vu32)src;
1493 }
MIi_SetDmaDest16(u32 dmaNo,void * dest)1494 void MIi_SetDmaDest16( u32 dmaNo, void *dest )
1495 {
1496 	vu32 *p;
1497 
1498     MIi_ASSERT_SRC_ALIGN2(dest);
1499     MIi_WARNING_ADDRINTCM(dest, 0); // size is unknown
1500 
1501 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_DAD_WOFFSET );
1502 	*p = (vu32)dest;
1503 }
MIi_SetDmaDest32(u32 dmaNo,void * dest)1504 void MIi_SetDmaDest32( u32 dmaNo, void *dest )
1505 {
1506 	vu32 *p;
1507 
1508     MIi_ASSERT_SRC_ALIGN4(dest);
1509     MIi_WARNING_ADDRINTCM(dest, 0); // size is unknown
1510 
1511 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_DAD_WOFFSET );
1512 	*p = (vu32)dest;
1513 }
1514 
MIi_SetDmaSize16(u32 dmaNo,u32 size)1515 void MIi_SetDmaSize16( u32 dmaNo, u32 size )
1516 {
1517 	vu32 *p;
1518 
1519     MIi_ASSERT_MUL2(size);
1520     MIi_ASSERT_SIZE(dmaNo, size / 2);
1521 
1522 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_CNT_WOFFSET );
1523 	*p = (*p & ~REG_MI_DMA0CNT_WORDCNT_MASK) | (size/2);
1524 }
1525 
MIi_SetDmaSize32(u32 dmaNo,u32 size)1526 void MIi_SetDmaSize32( u32 dmaNo, u32 size )
1527 {
1528 	vu32 *p;
1529 
1530     MIi_ASSERT_MUL4(size);
1531     MIi_ASSERT_SIZE(dmaNo, size / 4);
1532 
1533 	p = (vu32*)MI_DMA_REGADDR( dmaNo, MI_DMA_REG_CNT_WOFFSET );
1534 	*p = (*p & ~REG_MI_DMA0CNT_WORDCNT_MASK) | (size/4);
1535 }
1536