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