1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CARD - libraries
3 File: card_dma.c
4
5 Copyright 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:: 2008-04-21#$
14 $Rev: 5625 $
15 $Author: yosizaki $
16
17 *---------------------------------------------------------------------------*/
18
19
20 #include <nitro.h>
21
22 #include "../include/card_utility.h"
23
24
25 /*---------------------------------------------------------------------------*/
26 /* Constants */
27
28 static const CARDDmaInterface CARDiDmaUsingFormer =
29 {
30 MIi_CardDmaCopy32,
31 MI_StopDma,
32 };
33 #ifdef SDK_TWL
34 #include <twl/ltdmain_begin.h>
35 static CARDDmaInterface CARDiDmaUsingNew =
36 {
37 MI_Card_A_NDmaCopy,
38 MI_StopNDma,
39 };
40 #include <twl/ltdmain_end.h>
41 #endif
42
43 /*---------------------------------------------------------------------------*/
44 /* Functions */
45
46 /*---------------------------------------------------------------------------*
47 Name: CARDi_GetDmaInterface
48
49 Description: Determines appropriately from the DMA channel, and get either the new or the old DMA command interface.
50
51
52 Arguments: channel: DMA channel
53 The range from 0 to MI_DMA_MAX_NUM; if MI_DMA_USING_NEW is valid, indicates that it is a new DMA.
54
55
56 Returns: Either the corresponding new or old DMA interface
57 *---------------------------------------------------------------------------*/
CARDi_GetDmaInterface(u32 channel)58 const CARDDmaInterface* CARDi_GetDmaInterface(u32 channel)
59 {
60 const CARDDmaInterface *retval = NULL;
61 // Use DMA from the valid channel range.
62 BOOL isNew = ((channel & MI_DMA_USING_NEW) != 0);
63 channel &= ~MI_DMA_USING_NEW;
64 if (channel <= MI_DMA_MAX_NUM)
65 {
66 // Existing DMA
67 if (!isNew)
68 {
69 retval = &CARDiDmaUsingFormer;
70 }
71 // New DMA can be used only when running in TWL environments
72 else if (!OS_IsRunOnTwl())
73 {
74 OS_TPanic("NDMA can use only TWL!");
75 }
76 #ifdef SDK_TWL
77 else
78 {
79 retval = &CARDiDmaUsingNew;
80 }
81 #endif
82 }
83 return retval;
84 }
85
86 #ifdef SDK_ARM9
87
88 /*---------------------------------------------------------------------------*
89 Name: CARDi_ICInvalidateSmart
90
91 Description: Selects either the IC_InvalidateAll or IC_InvalidateRange function based on the threshold value.
92
93 Arguments: buffer: Buffer to be invalidated
94 length: Size to be invalidated
95 threshold: Threshold value that switches processes
96
97 Returns: None.
98 *---------------------------------------------------------------------------*/
CARDi_ICInvalidateSmart(void * buffer,u32 length,u32 threshold)99 void CARDi_ICInvalidateSmart(void *buffer, u32 length, u32 threshold)
100 {
101 if (length >= threshold)
102 {
103 IC_InvalidateAll();
104 }
105 else
106 {
107 IC_InvalidateRange((void *)buffer, length);
108 }
109 }
110
111 /*---------------------------------------------------------------------------*
112 Name: CARDi_DCInvalidateSmart
113
114 Description: Selects either the DC_FlushAll or DC_InvalidateRange function based on the threshold value.
115 If the buffer is not aligned with the cache line, the Store operation also is automatic only for the beginning or end.
116
117
118 Arguments: buffer: Buffer to be invalidated
119 length: Size to be invalidated
120 threshold: Threshold value that switches processes
121
122 Returns: None.
123 *---------------------------------------------------------------------------*/
CARDi_DCInvalidateSmart(void * buffer,u32 length,u32 threshold)124 void CARDi_DCInvalidateSmart(void *buffer, u32 length, u32 threshold)
125 {
126 if (length >= threshold)
127 {
128 DC_FlushAll();
129 }
130 else
131 {
132 u32 len = length;
133 u32 pos = (u32)buffer;
134 u32 mod = (pos & (HW_CACHE_LINE_SIZE - 1));
135 if (mod)
136 {
137 pos -= mod;
138 DC_StoreRange((void *)(pos), HW_CACHE_LINE_SIZE);
139 DC_StoreRange((void *)(pos + length), HW_CACHE_LINE_SIZE);
140 length += HW_CACHE_LINE_SIZE;
141 }
142 DC_InvalidateRange((void *)pos, length);
143 DC_WaitWriteBufferEmpty();
144 }
145 }
146
147 #endif // SDK_ARM9
148