Linux Audio

Check our new training course

Loading...
  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
 14typedef 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
 20static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
 21{
 22	return val.val == 0;
 23}
 24
 25static inline uint_fixed_16_16_t u32_to_fixed16(u32 val)
 26{
 27	uint_fixed_16_16_t fp = { .val = val << 16 };
 28
 29	WARN_ON(val > U16_MAX);
 30
 31	return fp;
 32}
 33
 34static inline u32 fixed16_to_u32_round_up(uint_fixed_16_16_t fp)
 35{
 36	return DIV_ROUND_UP(fp.val, 1 << 16);
 37}
 38
 39static inline u32 fixed16_to_u32(uint_fixed_16_16_t fp)
 40{
 41	return fp.val >> 16;
 42}
 43
 44static 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
 52static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1,
 53					     uint_fixed_16_16_t max2)
 54{
 55	uint_fixed_16_16_t max = { .val = max(max1.val, max2.val) };
 56
 57	return max;
 58}
 59
 60static inline uint_fixed_16_16_t clamp_u64_to_fixed16(u64 val)
 61{
 62	uint_fixed_16_16_t fp = { .val = (u32)val };
 63
 64	WARN_ON(val > U32_MAX);
 65
 66	return fp;
 67}
 68
 69static 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
 75static inline u32 mul_round_up_u32_fixed16(u32 val, uint_fixed_16_16_t mul)
 76{
 77	u64 tmp;
 78
 79	tmp = mul_u32_u32(val, mul.val);
 80	tmp = DIV_ROUND_UP_ULL(tmp, 1 << 16);
 81	WARN_ON(tmp > U32_MAX);
 82
 83	return (u32)tmp;
 84}
 85
 86static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val,
 87					     uint_fixed_16_16_t mul)
 88{
 89	u64 tmp;
 90
 91	tmp = mul_u32_u32(val.val, mul.val);
 92	tmp = tmp >> 16;
 93
 94	return clamp_u64_to_fixed16(tmp);
 95}
 96
 97static inline uint_fixed_16_16_t div_fixed16(u32 val, u32 d)
 98{
 99	u64 tmp;
100
101	tmp = (u64)val << 16;
102	tmp = DIV_ROUND_UP_ULL(tmp, d);
103
104	return clamp_u64_to_fixed16(tmp);
105}
106
107static 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
118static inline uint_fixed_16_16_t mul_u32_fixed16(u32 val, uint_fixed_16_16_t mul)
119{
120	u64 tmp;
121
122	tmp = mul_u32_u32(val, mul.val);
123
124	return clamp_u64_to_fixed16(tmp);
125}
126
127static 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
137static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1,
138						 u32 add2)
139{
140	uint_fixed_16_16_t tmp_add2 = u32_to_fixed16(add2);
141	u64 tmp;
142
143	tmp = (u64)add1.val + tmp_add2.val;
144
145	return clamp_u64_to_fixed16(tmp);
146}
147
148#endif /* _I915_FIXED_H_ */