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