Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: MIT */
0002 /*
0003  * Copyright © 2018 Intel Corporation
0004  */
0005 
0006 #ifndef _I915_FIXED_H_
0007 #define _I915_FIXED_H_
0008 
0009 #include <linux/bug.h>
0010 #include <linux/kernel.h>
0011 #include <linux/math64.h>
0012 #include <linux/types.h>
0013 
0014 typedef struct {
0015     u32 val;
0016 } uint_fixed_16_16_t;
0017 
0018 #define FP_16_16_MAX ((uint_fixed_16_16_t){ .val = UINT_MAX })
0019 
0020 static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
0021 {
0022     return val.val == 0;
0023 }
0024 
0025 static inline uint_fixed_16_16_t u32_to_fixed16(u32 val)
0026 {
0027     uint_fixed_16_16_t fp = { .val = val << 16 };
0028 
0029     WARN_ON(val > U16_MAX);
0030 
0031     return fp;
0032 }
0033 
0034 static inline u32 fixed16_to_u32_round_up(uint_fixed_16_16_t fp)
0035 {
0036     return DIV_ROUND_UP(fp.val, 1 << 16);
0037 }
0038 
0039 static inline u32 fixed16_to_u32(uint_fixed_16_16_t fp)
0040 {
0041     return fp.val >> 16;
0042 }
0043 
0044 static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1,
0045                          uint_fixed_16_16_t min2)
0046 {
0047     uint_fixed_16_16_t min = { .val = min(min1.val, min2.val) };
0048 
0049     return min;
0050 }
0051 
0052 static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1,
0053                          uint_fixed_16_16_t max2)
0054 {
0055     uint_fixed_16_16_t max = { .val = max(max1.val, max2.val) };
0056 
0057     return max;
0058 }
0059 
0060 static inline uint_fixed_16_16_t clamp_u64_to_fixed16(u64 val)
0061 {
0062     uint_fixed_16_16_t fp = { .val = (u32)val };
0063 
0064     WARN_ON(val > U32_MAX);
0065 
0066     return fp;
0067 }
0068 
0069 static inline u32 div_round_up_fixed16(uint_fixed_16_16_t val,
0070                        uint_fixed_16_16_t d)
0071 {
0072     return DIV_ROUND_UP(val.val, d.val);
0073 }
0074 
0075 static inline u32 mul_round_up_u32_fixed16(u32 val, uint_fixed_16_16_t mul)
0076 {
0077     u64 tmp;
0078 
0079     tmp = mul_u32_u32(val, mul.val);
0080     tmp = DIV_ROUND_UP_ULL(tmp, 1 << 16);
0081     WARN_ON(tmp > U32_MAX);
0082 
0083     return (u32)tmp;
0084 }
0085 
0086 static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val,
0087                          uint_fixed_16_16_t mul)
0088 {
0089     u64 tmp;
0090 
0091     tmp = mul_u32_u32(val.val, mul.val);
0092     tmp = tmp >> 16;
0093 
0094     return clamp_u64_to_fixed16(tmp);
0095 }
0096 
0097 static inline uint_fixed_16_16_t div_fixed16(u32 val, u32 d)
0098 {
0099     u64 tmp;
0100 
0101     tmp = (u64)val << 16;
0102     tmp = DIV_ROUND_UP_ULL(tmp, d);
0103 
0104     return clamp_u64_to_fixed16(tmp);
0105 }
0106 
0107 static inline u32 div_round_up_u32_fixed16(u32 val, uint_fixed_16_16_t d)
0108 {
0109     u64 tmp;
0110 
0111     tmp = (u64)val << 16;
0112     tmp = DIV_ROUND_UP_ULL(tmp, d.val);
0113     WARN_ON(tmp > U32_MAX);
0114 
0115     return (u32)tmp;
0116 }
0117 
0118 static inline uint_fixed_16_16_t mul_u32_fixed16(u32 val, uint_fixed_16_16_t mul)
0119 {
0120     u64 tmp;
0121 
0122     tmp = mul_u32_u32(val, mul.val);
0123 
0124     return clamp_u64_to_fixed16(tmp);
0125 }
0126 
0127 static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1,
0128                          uint_fixed_16_16_t add2)
0129 {
0130     u64 tmp;
0131 
0132     tmp = (u64)add1.val + add2.val;
0133 
0134     return clamp_u64_to_fixed16(tmp);
0135 }
0136 
0137 static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1,
0138                          u32 add2)
0139 {
0140     uint_fixed_16_16_t tmp_add2 = u32_to_fixed16(add2);
0141     u64 tmp;
0142 
0143     tmp = (u64)add1.val + tmp_add2.val;
0144 
0145     return clamp_u64_to_fixed16(tmp);
0146 }
0147 
0148 #endif /* _I915_FIXED_H_ */