1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CP - include
3 File: divider.h
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:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #ifndef NITRO_CP_DIVIDER_H_
19 #define NITRO_CP_DIVIDER_H_
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 #ifdef SDK_NITRO
26 #include <nitro/ioreg.h>
27 #else
28 #include <twl/ioreg.h>
29 #endif
30
31 //----------------------------------------------------------------
32 #define CP_DIV_32_32BIT_MODE (0UL << REG_CP_DIVCNT_MODE_SHIFT) // 32bit/32bit mode
33 #define CP_DIV_64_32BIT_MODE (1UL << REG_CP_DIVCNT_MODE_SHIFT) // 64bit/32bit mode
34 #define CP_DIV_64_64BIT_MODE (2UL << REG_CP_DIVCNT_MODE_SHIFT) // 64bit/64bit mode
35
36
37 /*---------------------------------------------------------------------------*
38 Name: CP_SetDivControl
39
40 Description: set parameter to divider control register
41
42 Arguments: parameter parameter to set control register
43
44 Returns: None
45 *---------------------------------------------------------------------------*/
CP_SetDivControl(u16 parameter)46 static inline void CP_SetDivControl(u16 parameter)
47 {
48 reg_CP_DIVCNT = parameter;
49 }
50
51 /*---------------------------------------------------------------------------*
52 Name: CP_SetDivImm32_32_NS_
53 CP_SetDivImm64_32_NS_
54 CP_SetDivImm64_64_NS_
55
56 Description: set numerator(dividend) and denominator(divisor).
57 ignore setting mode.
58 non thread safe.
59
60 Arguments: numer : numerator (dividend)
61 denom : denominator(divisor)
62
63 Returns: None
64 *---------------------------------------------------------------------------*/
65 // 32bit / 32bit
CP_SetDivImm32_32_NS_(u32 numer,u32 denom)66 static inline void CP_SetDivImm32_32_NS_(u32 numer, u32 denom)
67 {
68 *(REGType32 *)REG_DIV_NUMER_ADDR = numer;
69 *(REGType64 *)REG_DIV_DENOM_ADDR = denom;
70 }
71
72 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
73 // 64bit / 32bit
CP_SetDivImm64_32_NS_(u64 numer,u32 denom)74 static inline void CP_SetDivImm64_32_NS_(u64 numer, u32 denom)
75 {
76 *(REGType64 *)REG_DIV_NUMER_ADDR = numer;
77 *(REGType64 *)REG_DIV_DENOM_ADDR = denom;
78 }
79
80 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81 // 64bit / 64bit
CP_SetDivImm64_64_NS_(u64 numer,u64 denom)82 static inline void CP_SetDivImm64_64_NS_(u64 numer, u64 denom)
83 {
84 *(REGType64 *)REG_DIV_NUMER_ADDR = numer;
85 *(REGType64 *)REG_DIV_DENOM_ADDR = denom;
86 }
87
88 /*---------------------------------------------------------------------------*
89 Name: CP_SetDivImm32_32
90 CP_SetDivImm64_32
91 CP_SetDivImm64_64
92
93 Description: set numerator(dividend) and denominator(divisor).
94 ignore setting mode.
95 thread safe.
96
97 Arguments: numer : numerator (dividend)
98 denom : denominator(divisor)
99
100 Returns: None
101 *---------------------------------------------------------------------------*/
102 // 32bit / 32bit
CP_SetDivImm32_32(u32 numer,u32 denom)103 static inline void CP_SetDivImm32_32(u32 numer, u32 denom)
104 {
105 CP_SetDivImm32_32_NS_(numer, denom);
106 }
107
108 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
109 // 64bit / 32bit
CP_SetDivImm64_32(u64 numer,u32 denom)110 static inline void CP_SetDivImm64_32(u64 numer, u32 denom)
111 {
112 CP_SetDivImm64_32_NS_(numer, denom);
113 }
114
115 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 // 64bit / 64bit
CP_SetDivImm64_64(u64 numer,u64 denom)117 static inline void CP_SetDivImm64_64(u64 numer, u64 denom)
118 {
119 CP_SetDivImm64_64_NS_(numer, denom);
120 }
121
122 /*---------------------------------------------------------------------------*
123 Name: CP_SetDiv32_32
124 CP_SetDiv64_32
125 CP_SetDiv64_64
126
127 Description: set numerator(dividend) and denominator(divisor).
128 set mode.
129 thread safe.
130
131 Arguments: numer : numerator (dividend)
132 denom : denominator(divisor)
133
134 Returns: None
135 *---------------------------------------------------------------------------*/
136 // 32bit / 32bit
CP_SetDiv32_32(u32 numer,u32 denom)137 static inline void CP_SetDiv32_32(u32 numer, u32 denom)
138 {
139 reg_CP_DIVCNT = CP_DIV_32_32BIT_MODE;
140 CP_SetDivImm32_32_NS_(numer, denom);
141 }
142
143 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
144 // 64bit / 32bit
CP_SetDiv64_32(u64 numer,u32 denom)145 static inline void CP_SetDiv64_32(u64 numer, u32 denom)
146 {
147 reg_CP_DIVCNT = CP_DIV_64_32BIT_MODE;
148 CP_SetDivImm64_32_NS_(numer, denom);
149 }
150
151 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
152 // 64bit / 64bit
CP_SetDiv64_64(u64 numer,u64 denom)153 static inline void CP_SetDiv64_64(u64 numer, u64 denom)
154 {
155 reg_CP_DIVCNT = CP_DIV_64_64BIT_MODE;
156 CP_SetDivImm64_64_NS_(numer, denom);
157 }
158
159 /*---------------------------------------------------------------------------*
160 Name: CP_IsDivBusy
161
162 Description: check whether operation finished
163
164 Arguments: None
165
166 Returns: non-0 if finish, 0 if not
167 *---------------------------------------------------------------------------*/
CP_IsDivBusy()168 static inline s32 CP_IsDivBusy()
169 {
170 return (reg_CP_DIVCNT & REG_CP_DIVCNT_BUSY_MASK);
171 }
172
173 /*---------------------------------------------------------------------------*
174 Name: CP_WaitDiv
175
176 Description: wait to finish operation
177
178 Arguments: None
179
180 Returns: None
181 *---------------------------------------------------------------------------*/
CP_WaitDiv()182 static inline void CP_WaitDiv()
183 {
184 while (CP_IsDivBusy())
185 {
186 }
187 }
188
189 /*---------------------------------------------------------------------------*
190 Name: CP_GetDivResultImm64
191 CP_GetDivResultImm32
192 CP_GetDivResultImm16
193 CP_GetDivResultImm8
194
195 Description: get result(quotient) of division.
196 don't check whether operation finish
197
198 Arguments: None
199
200 Returns: result(quotient) of division
201 *---------------------------------------------------------------------------*/
202 // as 64bit data
CP_GetDivResultImm64()203 static inline s64 CP_GetDivResultImm64()
204 {
205 return (s64)(*(REGType64 *)REG_DIV_RESULT_ADDR);
206 }
207
208 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
209 // as 32bit data
CP_GetDivResultImm32()210 static inline s32 CP_GetDivResultImm32()
211 {
212 return (s32)(*(REGType32 *)REG_DIV_RESULT_ADDR);
213 }
214
215 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 // as 16bit data
CP_GetDivResultImm16()217 static inline s16 CP_GetDivResultImm16()
218 {
219 return (s16)(*(REGType16 *)REG_DIV_RESULT_ADDR);
220 }
221
222 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
223 // as 8bit data
CP_GetDivResultImm8()224 static inline s8 CP_GetDivResultImm8()
225 {
226 return (s8)(*(REGType8 *)REG_DIV_RESULT_ADDR);
227 }
228
229 /*---------------------------------------------------------------------------*
230 Name: CP_GetDivResult64
231 CP_GetDivResult32
232 CP_GetDivResult16
233 CP_GetDivResult8
234
235 Description: get result(quotient) of division.
236 wait till operation finish
237
238 Arguments: None
239
240 Returns: result(quotient) of division
241 *---------------------------------------------------------------------------*/
242 // as 64bit data
CP_GetDivResult64()243 static inline s64 CP_GetDivResult64()
244 {
245 CP_WaitDiv();
246 return CP_GetDivResultImm64();
247 }
248
249 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
250 // as 32bit data
CP_GetDivResult32()251 static inline s32 CP_GetDivResult32()
252 {
253 CP_WaitDiv();
254 return CP_GetDivResultImm32();
255 }
256
257 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
258 // as 16bit data
CP_GetDivResult16()259 static inline s16 CP_GetDivResult16()
260 {
261 CP_WaitDiv();
262 return CP_GetDivResultImm16();
263 }
264
265 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
266 // as 8bit data
CP_GetDivResult8()267 static inline s8 CP_GetDivResult8()
268 {
269 CP_WaitDiv();
270 return CP_GetDivResultImm8();
271 }
272
273 /*---------------------------------------------------------------------------*
274 Name: CP_GetDivRemainderImm64
275 CP_GetDivRemainderImm32
276 CP_GetDivRemainderImm16
277 CP_GetDivRemainderImm8
278
279 Description: get remainder of division.
280 don't check whether operation finish
281
282 Arguments: None
283
284 Returns: remainder of division
285 *---------------------------------------------------------------------------*/
286 // as 64bit data
CP_GetDivRemainderImm64()287 static inline s64 CP_GetDivRemainderImm64()
288 {
289 return (s64)(*(REGType64 *)REG_DIVREM_RESULT_ADDR);
290 }
291
292 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
293 // as 32bit data
CP_GetDivRemainderImm32()294 static inline s32 CP_GetDivRemainderImm32()
295 {
296 return (s32)(*(REGType32 *)REG_DIVREM_RESULT_ADDR);
297 }
298
299 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
300 // as 16bit data
CP_GetDivRemainderImm16()301 static inline s16 CP_GetDivRemainderImm16()
302 {
303 return (s16)(*(REGType16 *)REG_DIVREM_RESULT_ADDR);
304 }
305
306 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
307 // as 8bit data
CP_GetDivRemainderImm8()308 static inline s8 CP_GetDivRemainderImm8()
309 {
310 return (s8)(*(REGType8 *)REG_DIVREM_RESULT_ADDR);
311 }
312
313 /*---------------------------------------------------------------------------*
314 Name: CP_GetDivRemainder64
315 CP_GetDivRemainder32
316 CP_GetDivRemainder16
317 CP_GetDivRemainder8
318
319 Description: get remainder of division.
320 wait till operation finish
321
322 Arguments: None
323
324 Returns: remainder of division
325 *---------------------------------------------------------------------------*/
326 // as 64bit data
CP_GetDivRemainder64()327 static inline s64 CP_GetDivRemainder64()
328 {
329 CP_WaitDiv();
330 return CP_GetDivRemainderImm64();
331 }
332
333 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
334 // as 32bit data
CP_GetDivRemainder32()335 static inline s32 CP_GetDivRemainder32()
336 {
337 CP_WaitDiv();
338 return CP_GetDivRemainderImm32();
339 }
340
341 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
342 // as 16bit data
CP_GetDivRemainder16()343 static inline s16 CP_GetDivRemainder16()
344 {
345 CP_WaitDiv();
346 return CP_GetDivRemainderImm16();
347 }
348
349 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
350 // as 8bit data
CP_GetDivRemainder8()351 static inline s8 CP_GetDivRemainder8()
352 {
353 CP_WaitDiv();
354 return CP_GetDivRemainderImm8();
355 }
356
357 #ifdef __cplusplus
358 } /* extern "C" */
359 #endif
360
361 /* NITRO_CP_DIVIDER_H_ */
362 #endif
363