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