Branch data Line data Source code
1 : : /* SPDX-License-Identifier: MIT */ 2 : : /* 3 : : * Copyright © 2018 Intel Corporation 4 : : */ 5 : : 6 : : #ifndef _I915_FIXED_H_ 7 : : #define _I915_FIXED_H_ 8 : : 9 : : #include <linux/bug.h> 10 : : #include <linux/kernel.h> 11 : : #include <linux/math64.h> 12 : : #include <linux/types.h> 13 : : 14 : : typedef struct { 15 : : u32 val; 16 : : } uint_fixed_16_16_t; 17 : : 18 : : #define FP_16_16_MAX ((uint_fixed_16_16_t){ .val = UINT_MAX }) 19 : : 20 : : static inline bool is_fixed16_zero(uint_fixed_16_16_t val) 21 : : { 22 : : return val.val == 0; 23 : : } 24 : : 25 : 0 : static inline uint_fixed_16_16_t u32_to_fixed16(u32 val) 26 : : { 27 : 0 : uint_fixed_16_16_t fp = { .val = val << 16 }; 28 : : 29 [ # # # # ]: 0 : WARN_ON(val > U16_MAX); 30 : : 31 : 0 : return fp; 32 : : } 33 : : 34 : 0 : static inline u32 fixed16_to_u32_round_up(uint_fixed_16_16_t fp) 35 : : { 36 : 0 : return DIV_ROUND_UP(fp.val, 1 << 16); 37 : : } 38 : : 39 : : static inline u32 fixed16_to_u32(uint_fixed_16_16_t fp) 40 : : { 41 : : return fp.val >> 16; 42 : : } 43 : : 44 : : static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1, 45 : : uint_fixed_16_16_t min2) 46 : : { 47 : : uint_fixed_16_16_t min = { .val = min(min1.val, min2.val) }; 48 : : 49 : : return min; 50 : : } 51 : : 52 : 0 : static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1, 53 : : uint_fixed_16_16_t max2) 54 : : { 55 : 0 : uint_fixed_16_16_t max = { .val = max(max1.val, max2.val) }; 56 : : 57 [ # # ]: 0 : return max; 58 : : } 59 : : 60 : 0 : static inline uint_fixed_16_16_t clamp_u64_to_fixed16(u64 val) 61 : : { 62 : 0 : uint_fixed_16_16_t fp = { .val = (u32)val }; 63 : : 64 : 0 : WARN_ON(val > U32_MAX); 65 : : 66 [ # # # # : 0 : return fp; # # # # ] 67 : : } 68 : : 69 : : static inline u32 div_round_up_fixed16(uint_fixed_16_16_t val, 70 : : uint_fixed_16_16_t d) 71 : : { 72 : : return DIV_ROUND_UP(val.val, d.val); 73 : : } 74 : : 75 : 0 : static inline u32 mul_round_up_u32_fixed16(u32 val, uint_fixed_16_16_t mul) 76 : : { 77 : 0 : u64 tmp; 78 : : 79 [ # # # # ]: 0 : tmp = mul_u32_u32(val, mul.val); 80 : 0 : tmp = DIV_ROUND_UP_ULL(tmp, 1 << 16); 81 [ # # # # ]: 0 : WARN_ON(tmp > U32_MAX); 82 : : 83 : 0 : return (u32)tmp; 84 : : } 85 : : 86 : 0 : static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val, 87 : : uint_fixed_16_16_t mul) 88 : : { 89 : 0 : u64 tmp; 90 : : 91 [ # # ]: 0 : tmp = mul_u32_u32(val.val, mul.val); 92 : 0 : tmp = tmp >> 16; 93 : : 94 [ # # ]: 0 : return clamp_u64_to_fixed16(tmp); 95 : : } 96 : : 97 : 0 : static inline uint_fixed_16_16_t div_fixed16(u32 val, u32 d) 98 : : { 99 : 0 : u64 tmp; 100 : : 101 : 0 : tmp = (u64)val << 16; 102 : 0 : tmp = DIV_ROUND_UP_ULL(tmp, d); 103 : : 104 [ # # # # : 0 : return clamp_u64_to_fixed16(tmp); # # # # # # ] 105 : : } 106 : : 107 : : static inline u32 div_round_up_u32_fixed16(u32 val, uint_fixed_16_16_t d) 108 : : { 109 : : u64 tmp; 110 : : 111 : : tmp = (u64)val << 16; 112 : : tmp = DIV_ROUND_UP_ULL(tmp, d.val); 113 : : WARN_ON(tmp > U32_MAX); 114 : : 115 : : return (u32)tmp; 116 : : } 117 : : 118 : 0 : static inline uint_fixed_16_16_t mul_u32_fixed16(u32 val, uint_fixed_16_16_t mul) 119 : : { 120 : 0 : u64 tmp; 121 : : 122 [ # # # # ]: 0 : tmp = mul_u32_u32(val, mul.val); 123 : : 124 [ # # # # ]: 0 : return clamp_u64_to_fixed16(tmp); 125 : : } 126 : : 127 : : static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1, 128 : : uint_fixed_16_16_t add2) 129 : : { 130 : : u64 tmp; 131 : : 132 : : tmp = (u64)add1.val + add2.val; 133 : : 134 : : return clamp_u64_to_fixed16(tmp); 135 : : } 136 : : 137 : 0 : static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1, 138 : : u32 add2) 139 : : { 140 : 0 : uint_fixed_16_16_t tmp_add2 = u32_to_fixed16(add2); 141 : 0 : u64 tmp; 142 : : 143 : 0 : tmp = (u64)add1.val + tmp_add2.val; 144 : : 145 [ # # ]: 0 : return clamp_u64_to_fixed16(tmp); 146 : : } 147 : : 148 : : #endif /* _I915_FIXED_H_ */