mmrm_fixedpoint.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #ifdef _FIXP_ARITH_H
  6. #error "This implementation is meant to override fixp-arith.h, don't use both"
  7. #endif
  8. #ifndef _MMRM_FIXEDPOINT_H_
  9. #define _MMRM_FIXEDPOINT_H_
  10. #include <linux/types.h>
  11. #include <linux/bits.h>
  12. /*
  13. * Normally would typedef'ed, but checkpatch doesn't like typedef.
  14. * Also should be normally typedef'ed to intmax_t but that doesn't seem to be
  15. * available in the kernel
  16. */
  17. #define fp_t size_t
  18. /* (Arbitrarily) make the first 25% of the bits to be the fractional bits */
  19. #define FP_FRACTIONAL_BITS ((sizeof(fp_t) * 8) / 4)
  20. #define FP(__i, __f_n, __f_d) \
  21. ((((fp_t)(__i)) << FP_FRACTIONAL_BITS) + \
  22. (((__f_n) << FP_FRACTIONAL_BITS) / (__f_d)))
  23. #define FP_INT(__i) FP(__i, 0, 1)
  24. #define FP_ONE FP_INT(1)
  25. #define FP_ZERO FP_INT(0)
  26. static inline size_t fp_frac_base(void)
  27. {
  28. return GENMASK(FP_FRACTIONAL_BITS - 1, 0);
  29. }
  30. static inline size_t fp_frac(fp_t a)
  31. {
  32. return a & GENMASK(FP_FRACTIONAL_BITS - 1, 0);
  33. }
  34. static inline size_t fp_int(fp_t a)
  35. {
  36. return a >> FP_FRACTIONAL_BITS;
  37. }
  38. static inline size_t fp_round(fp_t a)
  39. {
  40. /* is the fractional part >= frac_max / 2? */
  41. bool round_up = fp_frac(a) >= fp_frac_base() / 2;
  42. return fp_int(a) + round_up;
  43. }
  44. static inline fp_t fp_mult(fp_t a, fp_t b)
  45. {
  46. return (a * b) >> FP_FRACTIONAL_BITS;
  47. }
  48. static inline fp_t fp_div(fp_t a, fp_t b)
  49. {
  50. return (a << FP_FRACTIONAL_BITS) / b;
  51. }
  52. #endif /* _MMRM_FIXEDPOINT_H_ */