b5b8d7dea3734903317ff1bd448afce9c3f5e753
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / amd / display / include / fixed31_32.h
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #ifndef __DAL_FIXED31_32_H__
27 #define __DAL_FIXED31_32_H__
28
29 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
30
31 /*
32  * @brief
33  * Arithmetic operations on real numbers
34  * represented as fixed-point numbers.
35  * There are: 1 bit for sign,
36  * 31 bit for integer part,
37  * 32 bits for fractional part.
38  *
39  * @note
40  * Currently, overflows and underflows are asserted;
41  * no special result returned.
42  */
43
44 struct fixed31_32 {
45         long long value;
46 };
47
48 /*
49  * @brief
50  * Useful constants
51  */
52
53 static const struct fixed31_32 dc_fixpt_zero = { 0 };
54 static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
55 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
56 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
57
58 static const struct fixed31_32 dc_fixpt_pi = { 13493037705LL };
59 static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
60 static const struct fixed31_32 dc_fixpt_e = { 11674931555LL };
61 static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
62 static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
63
64 /*
65  * @brief
66  * Initialization routines
67  */
68
69 /*
70  * @brief
71  * result = numerator / denominator
72  */
73 struct fixed31_32 dc_fixpt_from_fraction(
74         long long numerator,
75         long long denominator);
76
77 /*
78  * @brief
79  * result = arg
80  */
81 struct fixed31_32 dc_fixpt_from_int_nonconst(long long arg);
82 static inline struct fixed31_32 dc_fixpt_from_int(long long arg)
83 {
84         if (__builtin_constant_p(arg)) {
85                 struct fixed31_32 res;
86                 BUILD_BUG_ON((LONG_MIN > arg) || (arg > LONG_MAX));
87                 res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
88                 return res;
89         } else
90                 return dc_fixpt_from_int_nonconst(arg);
91 }
92
93 /*
94  * @brief
95  * Unary operators
96  */
97
98 /*
99  * @brief
100  * result = -arg
101  */
102 static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
103 {
104         struct fixed31_32 res;
105
106         res.value = -arg.value;
107
108         return res;
109 }
110
111 /*
112  * @brief
113  * result = abs(arg) := (arg >= 0) ? arg : -arg
114  */
115 static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
116 {
117         if (arg.value < 0)
118                 return dc_fixpt_neg(arg);
119         else
120                 return arg;
121 }
122
123 /*
124  * @brief
125  * Binary relational operators
126  */
127
128 /*
129  * @brief
130  * result = arg1 < arg2
131  */
132 static inline bool dc_fixpt_lt(struct fixed31_32 arg1,
133                                      struct fixed31_32 arg2)
134 {
135         return arg1.value < arg2.value;
136 }
137
138 /*
139  * @brief
140  * result = arg1 <= arg2
141  */
142 static inline bool dc_fixpt_le(struct fixed31_32 arg1,
143                                      struct fixed31_32 arg2)
144 {
145         return arg1.value <= arg2.value;
146 }
147
148 /*
149  * @brief
150  * result = arg1 == arg2
151  */
152 static inline bool dc_fixpt_eq(struct fixed31_32 arg1,
153                                      struct fixed31_32 arg2)
154 {
155         return arg1.value == arg2.value;
156 }
157
158 /*
159  * @brief
160  * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
161  */
162 static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1,
163                                                    struct fixed31_32 arg2)
164 {
165         if (arg1.value <= arg2.value)
166                 return arg1;
167         else
168                 return arg2;
169 }
170
171 /*
172  * @brief
173  * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
174  */
175 static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1,
176                                                    struct fixed31_32 arg2)
177 {
178         if (arg1.value <= arg2.value)
179                 return arg2;
180         else
181                 return arg1;
182 }
183
184 /*
185  * @brief
186  *          | min_value, when arg <= min_value
187  * result = | arg, when min_value < arg < max_value
188  *          | max_value, when arg >= max_value
189  */
190 static inline struct fixed31_32 dc_fixpt_clamp(
191         struct fixed31_32 arg,
192         struct fixed31_32 min_value,
193         struct fixed31_32 max_value)
194 {
195         if (dc_fixpt_le(arg, min_value))
196                 return min_value;
197         else if (dc_fixpt_le(max_value, arg))
198                 return max_value;
199         else
200                 return arg;
201 }
202
203 /*
204  * @brief
205  * Binary shift operators
206  */
207
208 /*
209  * @brief
210  * result = arg << shift
211  */
212 struct fixed31_32 dc_fixpt_shl(
213         struct fixed31_32 arg,
214         unsigned char shift);
215
216 /*
217  * @brief
218  * result = arg >> shift
219  */
220 static inline struct fixed31_32 dc_fixpt_shr(
221         struct fixed31_32 arg,
222         unsigned char shift)
223 {
224         struct fixed31_32 res;
225         res.value = arg.value >> shift;
226         return res;
227 }
228
229 /*
230  * @brief
231  * Binary additive operators
232  */
233
234 /*
235  * @brief
236  * result = arg1 + arg2
237  */
238 struct fixed31_32 dc_fixpt_add(
239         struct fixed31_32 arg1,
240         struct fixed31_32 arg2);
241
242 /*
243  * @brief
244  * result = arg1 + arg2
245  */
246 static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1,
247                                                        int arg2)
248 {
249         return dc_fixpt_add(arg1,
250                                   dc_fixpt_from_int(arg2));
251 }
252
253 /*
254  * @brief
255  * result = arg1 - arg2
256  */
257 struct fixed31_32 dc_fixpt_sub(
258         struct fixed31_32 arg1,
259         struct fixed31_32 arg2);
260
261 /*
262  * @brief
263  * result = arg1 - arg2
264  */
265 static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1,
266                                                        int arg2)
267 {
268         return dc_fixpt_sub(arg1,
269                                   dc_fixpt_from_int(arg2));
270 }
271
272
273 /*
274  * @brief
275  * Binary multiplicative operators
276  */
277
278 /*
279  * @brief
280  * result = arg1 * arg2
281  */
282 struct fixed31_32 dc_fixpt_mul(
283         struct fixed31_32 arg1,
284         struct fixed31_32 arg2);
285
286
287 /*
288  * @brief
289  * result = arg1 * arg2
290  */
291 static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1,
292                                                        int arg2)
293 {
294         return dc_fixpt_mul(arg1,
295                                   dc_fixpt_from_int(arg2));
296 }
297
298 /*
299  * @brief
300  * result = square(arg) := arg * arg
301  */
302 struct fixed31_32 dc_fixpt_sqr(
303         struct fixed31_32 arg);
304
305 /*
306  * @brief
307  * result = arg1 / arg2
308  */
309 static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1,
310                                                        long long arg2)
311 {
312         return dc_fixpt_from_fraction(arg1.value,
313                                             dc_fixpt_from_int(arg2).value);
314 }
315
316 /*
317  * @brief
318  * result = arg1 / arg2
319  */
320 static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1,
321                                                    struct fixed31_32 arg2)
322 {
323         return dc_fixpt_from_fraction(arg1.value,
324                                             arg2.value);
325 }
326
327 /*
328  * @brief
329  * Reciprocal function
330  */
331
332 /*
333  * @brief
334  * result = reciprocal(arg) := 1 / arg
335  *
336  * @note
337  * No special actions taken in case argument is zero.
338  */
339 struct fixed31_32 dc_fixpt_recip(
340         struct fixed31_32 arg);
341
342 /*
343  * @brief
344  * Trigonometric functions
345  */
346
347 /*
348  * @brief
349  * result = sinc(arg) := sin(arg) / arg
350  *
351  * @note
352  * Argument specified in radians,
353  * internally it's normalized to [-2pi...2pi] range.
354  */
355 struct fixed31_32 dc_fixpt_sinc(
356         struct fixed31_32 arg);
357
358 /*
359  * @brief
360  * result = sin(arg)
361  *
362  * @note
363  * Argument specified in radians,
364  * internally it's normalized to [-2pi...2pi] range.
365  */
366 struct fixed31_32 dc_fixpt_sin(
367         struct fixed31_32 arg);
368
369 /*
370  * @brief
371  * result = cos(arg)
372  *
373  * @note
374  * Argument specified in radians
375  * and should be in [-2pi...2pi] range -
376  * passing arguments outside that range
377  * will cause incorrect result!
378  */
379 struct fixed31_32 dc_fixpt_cos(
380         struct fixed31_32 arg);
381
382 /*
383  * @brief
384  * Transcendent functions
385  */
386
387 /*
388  * @brief
389  * result = exp(arg)
390  *
391  * @note
392  * Currently, function is verified for abs(arg) <= 1.
393  */
394 struct fixed31_32 dc_fixpt_exp(
395         struct fixed31_32 arg);
396
397 /*
398  * @brief
399  * result = log(arg)
400  *
401  * @note
402  * Currently, abs(arg) should be less than 1.
403  * No normalization is done.
404  * Currently, no special actions taken
405  * in case of invalid argument(s). Take care!
406  */
407 struct fixed31_32 dc_fixpt_log(
408         struct fixed31_32 arg);
409
410 /*
411  * @brief
412  * Power function
413  */
414
415 /*
416  * @brief
417  * result = pow(arg1, arg2)
418  *
419  * @note
420  * Currently, abs(arg1) should be less than 1. Take care!
421  */
422 struct fixed31_32 dc_fixpt_pow(
423         struct fixed31_32 arg1,
424         struct fixed31_32 arg2);
425
426 /*
427  * @brief
428  * Rounding functions
429  */
430
431 /*
432  * @brief
433  * result = floor(arg) := greatest integer lower than or equal to arg
434  */
435 int dc_fixpt_floor(
436         struct fixed31_32 arg);
437
438 /*
439  * @brief
440  * result = round(arg) := integer nearest to arg
441  */
442 int dc_fixpt_round(
443         struct fixed31_32 arg);
444
445 /*
446  * @brief
447  * result = ceil(arg) := lowest integer greater than or equal to arg
448  */
449 int dc_fixpt_ceil(
450         struct fixed31_32 arg);
451
452 /* the following two function are used in scaler hw programming to convert fixed
453  * point value to format 2 bits from integer part and 19 bits from fractional
454  * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
455  * fractional
456  */
457
458 unsigned int dc_fixpt_u2d19(
459         struct fixed31_32 arg);
460
461 unsigned int dc_fixpt_u0d19(
462         struct fixed31_32 arg);
463
464
465 unsigned int dc_fixpt_clamp_u0d14(
466         struct fixed31_32 arg);
467
468 unsigned int dc_fixpt_clamp_u0d10(
469         struct fixed31_32 arg);
470
471 int dc_fixpt_s4d19(
472         struct fixed31_32 arg);
473
474 #endif