amdgpu/dc: allow inlining constant int to fixed a lot better.
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / include / fixed31_32.h
CommitLineData
4562236b
HW
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#include "os_types.h"
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
44struct fixed31_32 {
45 int64_t value;
46};
47
48/*
49 * @brief
50 * Useful constants
51 */
52
53static const struct fixed31_32 dal_fixed31_32_zero = { 0 };
54static const struct fixed31_32 dal_fixed31_32_epsilon = { 1LL };
55static const struct fixed31_32 dal_fixed31_32_half = { 0x80000000LL };
56static const struct fixed31_32 dal_fixed31_32_one = { 0x100000000LL };
57
58static const struct fixed31_32 dal_fixed31_32_pi = { 13493037705LL };
59static const struct fixed31_32 dal_fixed31_32_two_pi = { 26986075409LL };
60static const struct fixed31_32 dal_fixed31_32_e = { 11674931555LL };
61static const struct fixed31_32 dal_fixed31_32_ln2 = { 2977044471LL };
62static const struct fixed31_32 dal_fixed31_32_ln2_div_2 = { 1488522236LL };
63
64/*
65 * @brief
66 * Initialization routines
67 */
68
69/*
70 * @brief
71 * result = numerator / denominator
72 */
73struct fixed31_32 dal_fixed31_32_from_fraction(
74 int64_t numerator,
75 int64_t denominator);
76
77/*
78 * @brief
79 * result = arg
80 */
81struct fixed31_32 dal_fixed31_32_from_int(
82 int64_t arg);
83
84/*
85 * @brief
86 * Unary operators
87 */
88
89/*
90 * @brief
91 * result = -arg
92 */
204de25f
DA
93static inline struct fixed31_32 dal_fixed31_32_neg(struct fixed31_32 arg)
94{
95 struct fixed31_32 res;
96
97 res.value = -arg.value;
98
99 return res;
100}
4562236b
HW
101
102/*
103 * @brief
104 * result = abs(arg) := (arg >= 0) ? arg : -arg
105 */
204de25f
DA
106static inline struct fixed31_32 dal_fixed31_32_abs(struct fixed31_32 arg)
107{
108 if (arg.value < 0)
109 return dal_fixed31_32_neg(arg);
110 else
111 return arg;
112}
4562236b
HW
113
114/*
115 * @brief
116 * Binary relational operators
117 */
118
119/*
120 * @brief
121 * result = arg1 < arg2
122 */
204de25f
DA
123static inline bool dal_fixed31_32_lt(struct fixed31_32 arg1,
124 struct fixed31_32 arg2)
125{
126 return arg1.value < arg2.value;
127}
4562236b
HW
128
129/*
130 * @brief
131 * result = arg1 <= arg2
132 */
204de25f
DA
133static inline bool dal_fixed31_32_le(struct fixed31_32 arg1,
134 struct fixed31_32 arg2)
135{
136 return arg1.value <= arg2.value;
137}
4562236b
HW
138
139/*
140 * @brief
141 * result = arg1 == arg2
142 */
204de25f
DA
143static inline bool dal_fixed31_32_eq(struct fixed31_32 arg1,
144 struct fixed31_32 arg2)
145{
146 return arg1.value == arg2.value;
147}
4562236b
HW
148
149/*
150 * @brief
151 * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
152 */
204de25f
DA
153static inline struct fixed31_32 dal_fixed31_32_min(struct fixed31_32 arg1,
154 struct fixed31_32 arg2)
155{
156 if (arg1.value <= arg2.value)
157 return arg1;
158 else
159 return arg2;
160}
4562236b
HW
161
162/*
163 * @brief
164 * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
165 */
204de25f
DA
166static inline struct fixed31_32 dal_fixed31_32_max(struct fixed31_32 arg1,
167 struct fixed31_32 arg2)
168{
169 if (arg1.value <= arg2.value)
170 return arg2;
171 else
172 return arg1;
173}
4562236b
HW
174
175/*
176 * @brief
177 * | min_value, when arg <= min_value
178 * result = | arg, when min_value < arg < max_value
179 * | max_value, when arg >= max_value
180 */
204de25f 181static inline struct fixed31_32 dal_fixed31_32_clamp(
4562236b
HW
182 struct fixed31_32 arg,
183 struct fixed31_32 min_value,
204de25f
DA
184 struct fixed31_32 max_value)
185{
186 if (dal_fixed31_32_le(arg, min_value))
187 return min_value;
188 else if (dal_fixed31_32_le(max_value, arg))
189 return max_value;
190 else
191 return arg;
192}
4562236b
HW
193
194/*
195 * @brief
196 * Binary shift operators
197 */
198
199/*
200 * @brief
201 * result = arg << shift
202 */
203struct fixed31_32 dal_fixed31_32_shl(
204 struct fixed31_32 arg,
205 uint8_t shift);
206
207/*
208 * @brief
209 * result = arg >> shift
210 */
204de25f 211static inline struct fixed31_32 dal_fixed31_32_shr(
4562236b 212 struct fixed31_32 arg,
204de25f
DA
213 uint8_t shift)
214{
215 struct fixed31_32 res;
216 res.value = arg.value >> shift;
217 return res;
218}
4562236b
HW
219
220/*
221 * @brief
222 * Binary additive operators
223 */
224
225/*
226 * @brief
227 * result = arg1 + arg2
228 */
229struct fixed31_32 dal_fixed31_32_add(
230 struct fixed31_32 arg1,
231 struct fixed31_32 arg2);
232
fcd2f4bf
AZ
233/*
234 * @brief
235 * result = arg1 + arg2
236 */
204de25f
DA
237static inline struct fixed31_32 dal_fixed31_32_add_int(struct fixed31_32 arg1,
238 int32_t arg2)
239{
240 return dal_fixed31_32_add(arg1,
241 dal_fixed31_32_from_int(arg2));
242}
fcd2f4bf 243
4562236b
HW
244/*
245 * @brief
246 * result = arg1 - arg2
247 */
204de25f 248struct fixed31_32 dal_fixed31_32_sub(
4562236b 249 struct fixed31_32 arg1,
204de25f 250 struct fixed31_32 arg2);
4562236b
HW
251
252/*
253 * @brief
254 * result = arg1 - arg2
255 */
204de25f
DA
256static inline struct fixed31_32 dal_fixed31_32_sub_int(struct fixed31_32 arg1,
257 int32_t arg2)
258{
259 return dal_fixed31_32_sub(arg1,
260 dal_fixed31_32_from_int(arg2));
261}
262
4562236b
HW
263
264/*
265 * @brief
266 * Binary multiplicative operators
267 */
268
269/*
270 * @brief
271 * result = arg1 * arg2
272 */
204de25f 273struct fixed31_32 dal_fixed31_32_mul(
4562236b 274 struct fixed31_32 arg1,
204de25f
DA
275 struct fixed31_32 arg2);
276
4562236b
HW
277
278/*
279 * @brief
280 * result = arg1 * arg2
281 */
204de25f
DA
282static inline struct fixed31_32 dal_fixed31_32_mul_int(struct fixed31_32 arg1,
283 int32_t arg2)
284{
285 return dal_fixed31_32_mul(arg1,
286 dal_fixed31_32_from_int(arg2));
287}
4562236b
HW
288
289/*
290 * @brief
291 * result = square(arg) := arg * arg
292 */
293struct fixed31_32 dal_fixed31_32_sqr(
294 struct fixed31_32 arg);
295
296/*
297 * @brief
298 * result = arg1 / arg2
299 */
300struct fixed31_32 dal_fixed31_32_div_int(
301 struct fixed31_32 arg1,
302 int64_t arg2);
303
304/*
305 * @brief
306 * result = arg1 / arg2
307 */
204de25f
DA
308static inline struct fixed31_32 dal_fixed31_32_div(struct fixed31_32 arg1,
309 struct fixed31_32 arg2)
310{
311 return dal_fixed31_32_from_fraction(arg1.value,
312 arg2.value);
313}
4562236b
HW
314
315/*
316 * @brief
317 * Reciprocal function
318 */
319
320/*
321 * @brief
322 * result = reciprocal(arg) := 1 / arg
323 *
324 * @note
325 * No special actions taken in case argument is zero.
326 */
327struct fixed31_32 dal_fixed31_32_recip(
328 struct fixed31_32 arg);
329
330/*
331 * @brief
332 * Trigonometric functions
333 */
334
335/*
336 * @brief
337 * result = sinc(arg) := sin(arg) / arg
338 *
339 * @note
340 * Argument specified in radians,
341 * internally it's normalized to [-2pi...2pi] range.
342 */
343struct fixed31_32 dal_fixed31_32_sinc(
344 struct fixed31_32 arg);
345
346/*
347 * @brief
348 * result = sin(arg)
349 *
350 * @note
351 * Argument specified in radians,
352 * internally it's normalized to [-2pi...2pi] range.
353 */
354struct fixed31_32 dal_fixed31_32_sin(
355 struct fixed31_32 arg);
356
357/*
358 * @brief
359 * result = cos(arg)
360 *
361 * @note
362 * Argument specified in radians
363 * and should be in [-2pi...2pi] range -
364 * passing arguments outside that range
365 * will cause incorrect result!
366 */
367struct fixed31_32 dal_fixed31_32_cos(
368 struct fixed31_32 arg);
369
370/*
371 * @brief
372 * Transcendent functions
373 */
374
375/*
376 * @brief
377 * result = exp(arg)
378 *
379 * @note
380 * Currently, function is verified for abs(arg) <= 1.
381 */
382struct fixed31_32 dal_fixed31_32_exp(
383 struct fixed31_32 arg);
384
385/*
386 * @brief
387 * result = log(arg)
388 *
389 * @note
390 * Currently, abs(arg) should be less than 1.
391 * No normalization is done.
392 * Currently, no special actions taken
393 * in case of invalid argument(s). Take care!
394 */
395struct fixed31_32 dal_fixed31_32_log(
396 struct fixed31_32 arg);
397
398/*
399 * @brief
400 * Power function
401 */
402
403/*
404 * @brief
405 * result = pow(arg1, arg2)
406 *
407 * @note
408 * Currently, abs(arg1) should be less than 1. Take care!
409 */
410struct fixed31_32 dal_fixed31_32_pow(
411 struct fixed31_32 arg1,
412 struct fixed31_32 arg2);
413
414/*
415 * @brief
416 * Rounding functions
417 */
418
419/*
420 * @brief
421 * result = floor(arg) := greatest integer lower than or equal to arg
422 */
423int32_t dal_fixed31_32_floor(
424 struct fixed31_32 arg);
425
426/*
427 * @brief
428 * result = round(arg) := integer nearest to arg
429 */
430int32_t dal_fixed31_32_round(
431 struct fixed31_32 arg);
432
433/*
434 * @brief
435 * result = ceil(arg) := lowest integer greater than or equal to arg
436 */
437int32_t dal_fixed31_32_ceil(
438 struct fixed31_32 arg);
439
440/* the following two function are used in scaler hw programming to convert fixed
441 * point value to format 2 bits from integer part and 19 bits from fractional
442 * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
443 * fractional
444 */
445
446uint32_t dal_fixed31_32_u2d19(
447 struct fixed31_32 arg);
448
449uint32_t dal_fixed31_32_u0d19(
450 struct fixed31_32 arg);
451
452#endif