root/drivers/gpu/drm/amd/display/include/fixed31_32.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. dc_fixpt_from_int
  2. dc_fixpt_neg
  3. dc_fixpt_abs
  4. dc_fixpt_lt
  5. dc_fixpt_le
  6. dc_fixpt_eq
  7. dc_fixpt_min
  8. dc_fixpt_max
  9. dc_fixpt_clamp
  10. dc_fixpt_shl
  11. dc_fixpt_shr
  12. dc_fixpt_add
  13. dc_fixpt_add_int
  14. dc_fixpt_sub
  15. dc_fixpt_sub_int
  16. dc_fixpt_mul_int
  17. dc_fixpt_div_int
  18. dc_fixpt_div
  19. dc_fixpt_pow
  20. dc_fixpt_floor
  21. dc_fixpt_round
  22. dc_fixpt_ceil
  23. dc_fixpt_truncate

   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 #ifndef LLONG_MAX
  30 #define LLONG_MAX 9223372036854775807ll
  31 #endif
  32 #ifndef LLONG_MIN
  33 #define LLONG_MIN (-LLONG_MAX - 1ll)
  34 #endif
  35 
  36 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
  37 #ifndef LLONG_MIN
  38 #define LLONG_MIN (1LL<<63)
  39 #endif
  40 #ifndef LLONG_MAX
  41 #define LLONG_MAX (-1LL>>1)
  42 #endif
  43 
  44 /*
  45  * @brief
  46  * Arithmetic operations on real numbers
  47  * represented as fixed-point numbers.
  48  * There are: 1 bit for sign,
  49  * 31 bit for integer part,
  50  * 32 bits for fractional part.
  51  *
  52  * @note
  53  * Currently, overflows and underflows are asserted;
  54  * no special result returned.
  55  */
  56 
  57 struct fixed31_32 {
  58         long long value;
  59 };
  60 
  61 
  62 /*
  63  * @brief
  64  * Useful constants
  65  */
  66 
  67 static const struct fixed31_32 dc_fixpt_zero = { 0 };
  68 static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
  69 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
  70 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
  71 
  72 static const struct fixed31_32 dc_fixpt_pi = { 13493037705LL };
  73 static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
  74 static const struct fixed31_32 dc_fixpt_e = { 11674931555LL };
  75 static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
  76 static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
  77 
  78 /*
  79  * @brief
  80  * Initialization routines
  81  */
  82 
  83 /*
  84  * @brief
  85  * result = numerator / denominator
  86  */
  87 struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
  88 
  89 /*
  90  * @brief
  91  * result = arg
  92  */
  93 static inline struct fixed31_32 dc_fixpt_from_int(int arg)
  94 {
  95         struct fixed31_32 res;
  96 
  97         res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
  98 
  99         return res;
 100 }
 101 
 102 /*
 103  * @brief
 104  * Unary operators
 105  */
 106 
 107 /*
 108  * @brief
 109  * result = -arg
 110  */
 111 static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
 112 {
 113         struct fixed31_32 res;
 114 
 115         res.value = -arg.value;
 116 
 117         return res;
 118 }
 119 
 120 /*
 121  * @brief
 122  * result = abs(arg) := (arg >= 0) ? arg : -arg
 123  */
 124 static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
 125 {
 126         if (arg.value < 0)
 127                 return dc_fixpt_neg(arg);
 128         else
 129                 return arg;
 130 }
 131 
 132 /*
 133  * @brief
 134  * Binary relational operators
 135  */
 136 
 137 /*
 138  * @brief
 139  * result = arg1 < arg2
 140  */
 141 static inline bool dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
 142 {
 143         return arg1.value < arg2.value;
 144 }
 145 
 146 /*
 147  * @brief
 148  * result = arg1 <= arg2
 149  */
 150 static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
 151 {
 152         return arg1.value <= arg2.value;
 153 }
 154 
 155 /*
 156  * @brief
 157  * result = arg1 == arg2
 158  */
 159 static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
 160 {
 161         return arg1.value == arg2.value;
 162 }
 163 
 164 /*
 165  * @brief
 166  * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
 167  */
 168 static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
 169 {
 170         if (arg1.value <= arg2.value)
 171                 return arg1;
 172         else
 173                 return arg2;
 174 }
 175 
 176 /*
 177  * @brief
 178  * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
 179  */
 180 static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
 181 {
 182         if (arg1.value <= arg2.value)
 183                 return arg2;
 184         else
 185                 return arg1;
 186 }
 187 
 188 /*
 189  * @brief
 190  *          | min_value, when arg <= min_value
 191  * result = | arg, when min_value < arg < max_value
 192  *          | max_value, when arg >= max_value
 193  */
 194 static inline struct fixed31_32 dc_fixpt_clamp(
 195         struct fixed31_32 arg,
 196         struct fixed31_32 min_value,
 197         struct fixed31_32 max_value)
 198 {
 199         if (dc_fixpt_le(arg, min_value))
 200                 return min_value;
 201         else if (dc_fixpt_le(max_value, arg))
 202                 return max_value;
 203         else
 204                 return arg;
 205 }
 206 
 207 /*
 208  * @brief
 209  * Binary shift operators
 210  */
 211 
 212 /*
 213  * @brief
 214  * result = arg << shift
 215  */
 216 static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
 217 {
 218         ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
 219                 ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
 220 
 221         arg.value = arg.value << shift;
 222 
 223         return arg;
 224 }
 225 
 226 /*
 227  * @brief
 228  * result = arg >> shift
 229  */
 230 static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
 231 {
 232         bool negative = arg.value < 0;
 233 
 234         if (negative)
 235                 arg.value = -arg.value;
 236         arg.value = arg.value >> shift;
 237         if (negative)
 238                 arg.value = -arg.value;
 239         return arg;
 240 }
 241 
 242 /*
 243  * @brief
 244  * Binary additive operators
 245  */
 246 
 247 /*
 248  * @brief
 249  * result = arg1 + arg2
 250  */
 251 static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
 252 {
 253         struct fixed31_32 res;
 254 
 255         ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
 256                 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
 257 
 258         res.value = arg1.value + arg2.value;
 259 
 260         return res;
 261 }
 262 
 263 /*
 264  * @brief
 265  * result = arg1 + arg2
 266  */
 267 static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
 268 {
 269         return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
 270 }
 271 
 272 /*
 273  * @brief
 274  * result = arg1 - arg2
 275  */
 276 static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
 277 {
 278         struct fixed31_32 res;
 279 
 280         ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
 281                 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
 282 
 283         res.value = arg1.value - arg2.value;
 284 
 285         return res;
 286 }
 287 
 288 /*
 289  * @brief
 290  * result = arg1 - arg2
 291  */
 292 static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
 293 {
 294         return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2));
 295 }
 296 
 297 
 298 /*
 299  * @brief
 300  * Binary multiplicative operators
 301  */
 302 
 303 /*
 304  * @brief
 305  * result = arg1 * arg2
 306  */
 307 struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
 308 
 309 
 310 /*
 311  * @brief
 312  * result = arg1 * arg2
 313  */
 314 static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
 315 {
 316         return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
 317 }
 318 
 319 /*
 320  * @brief
 321  * result = square(arg) := arg * arg
 322  */
 323 struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
 324 
 325 /*
 326  * @brief
 327  * result = arg1 / arg2
 328  */
 329 static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
 330 {
 331         return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int(arg2).value);
 332 }
 333 
 334 /*
 335  * @brief
 336  * result = arg1 / arg2
 337  */
 338 static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
 339 {
 340         return dc_fixpt_from_fraction(arg1.value, arg2.value);
 341 }
 342 
 343 /*
 344  * @brief
 345  * Reciprocal function
 346  */
 347 
 348 /*
 349  * @brief
 350  * result = reciprocal(arg) := 1 / arg
 351  *
 352  * @note
 353  * No special actions taken in case argument is zero.
 354  */
 355 struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg);
 356 
 357 /*
 358  * @brief
 359  * Trigonometric functions
 360  */
 361 
 362 /*
 363  * @brief
 364  * result = sinc(arg) := sin(arg) / arg
 365  *
 366  * @note
 367  * Argument specified in radians,
 368  * internally it's normalized to [-2pi...2pi] range.
 369  */
 370 struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg);
 371 
 372 /*
 373  * @brief
 374  * result = sin(arg)
 375  *
 376  * @note
 377  * Argument specified in radians,
 378  * internally it's normalized to [-2pi...2pi] range.
 379  */
 380 struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg);
 381 
 382 /*
 383  * @brief
 384  * result = cos(arg)
 385  *
 386  * @note
 387  * Argument specified in radians
 388  * and should be in [-2pi...2pi] range -
 389  * passing arguments outside that range
 390  * will cause incorrect result!
 391  */
 392 struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg);
 393 
 394 /*
 395  * @brief
 396  * Transcendent functions
 397  */
 398 
 399 /*
 400  * @brief
 401  * result = exp(arg)
 402  *
 403  * @note
 404  * Currently, function is verified for abs(arg) <= 1.
 405  */
 406 struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg);
 407 
 408 /*
 409  * @brief
 410  * result = log(arg)
 411  *
 412  * @note
 413  * Currently, abs(arg) should be less than 1.
 414  * No normalization is done.
 415  * Currently, no special actions taken
 416  * in case of invalid argument(s). Take care!
 417  */
 418 struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg);
 419 
 420 /*
 421  * @brief
 422  * Power function
 423  */
 424 
 425 /*
 426  * @brief
 427  * result = pow(arg1, arg2)
 428  *
 429  * @note
 430  * Currently, abs(arg1) should be less than 1. Take care!
 431  */
 432 static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
 433 {
 434         return dc_fixpt_exp(
 435                 dc_fixpt_mul(
 436                         dc_fixpt_log(arg1),
 437                         arg2));
 438 }
 439 
 440 /*
 441  * @brief
 442  * Rounding functions
 443  */
 444 
 445 /*
 446  * @brief
 447  * result = floor(arg) := greatest integer lower than or equal to arg
 448  */
 449 static inline int dc_fixpt_floor(struct fixed31_32 arg)
 450 {
 451         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
 452 
 453         if (arg.value >= 0)
 454                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 455         else
 456                 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 457 }
 458 
 459 /*
 460  * @brief
 461  * result = round(arg) := integer nearest to arg
 462  */
 463 static inline int dc_fixpt_round(struct fixed31_32 arg)
 464 {
 465         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
 466 
 467         const long long summand = dc_fixpt_half.value;
 468 
 469         ASSERT(LLONG_MAX - (long long)arg_value >= summand);
 470 
 471         arg_value += summand;
 472 
 473         if (arg.value >= 0)
 474                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 475         else
 476                 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 477 }
 478 
 479 /*
 480  * @brief
 481  * result = ceil(arg) := lowest integer greater than or equal to arg
 482  */
 483 static inline int dc_fixpt_ceil(struct fixed31_32 arg)
 484 {
 485         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
 486 
 487         const long long summand = dc_fixpt_one.value -
 488                 dc_fixpt_epsilon.value;
 489 
 490         ASSERT(LLONG_MAX - (long long)arg_value >= summand);
 491 
 492         arg_value += summand;
 493 
 494         if (arg.value >= 0)
 495                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 496         else
 497                 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
 498 }
 499 
 500 /* the following two function are used in scaler hw programming to convert fixed
 501  * point value to format 2 bits from integer part and 19 bits from fractional
 502  * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
 503  * fractional
 504  */
 505 
 506 unsigned int dc_fixpt_u4d19(struct fixed31_32 arg);
 507 
 508 unsigned int dc_fixpt_u3d19(struct fixed31_32 arg);
 509 
 510 unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
 511 
 512 unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
 513 
 514 unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
 515 
 516 unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
 517 
 518 int dc_fixpt_s4d19(struct fixed31_32 arg);
 519 
 520 static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
 521 {
 522         bool negative = arg.value < 0;
 523 
 524         if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
 525                 ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
 526                 return arg;
 527         }
 528 
 529         if (negative)
 530                 arg.value = -arg.value;
 531         arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
 532         if (negative)
 533                 arg.value = -arg.value;
 534         return arg;
 535 }
 536 
 537 #endif

/* [<][>][^][v][top][bottom][index][help] */