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