From f3ba7a2fd1ebffe7fc6a9c524754db05dcd0c0e4 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 18 Apr 2018 13:54:24 -0400 Subject: [PATCH] drm/amd/display: inline more of fixed point code Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/basics/fixpt31_32.c | 156 ++----------- .../gpu/drm/amd/display/include/fixed31_32.h | 207 ++++++++++-------- .../amd/display/modules/color/color_gamma.c | 8 +- 3 files changed, 135 insertions(+), 236 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c index e398ecdf742c..e61dd97d0928 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c +++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c @@ -64,9 +64,7 @@ static inline unsigned long long complete_integer_division_u64( #define GET_FRACTIONAL_PART(x) \ (FRACTIONAL_PART_MASK & (x)) -struct fixed31_32 dc_fixpt_from_fraction( - long long numerator, - long long denominator) +struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator) { struct fixed31_32 res; @@ -118,63 +116,7 @@ struct fixed31_32 dc_fixpt_from_fraction( return res; } -struct fixed31_32 dc_fixpt_from_int_nonconst( - long long arg) -{ - struct fixed31_32 res; - - ASSERT((LONG_MIN <= arg) && (arg <= LONG_MAX)); - - res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART; - - return res; -} - -struct fixed31_32 dc_fixpt_shl( - struct fixed31_32 arg, - unsigned char shift) -{ - struct fixed31_32 res; - - ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) || - ((arg.value < 0) && (arg.value >= LLONG_MIN >> shift))); - - res.value = arg.value << shift; - - return res; -} - -struct fixed31_32 dc_fixpt_add( - struct fixed31_32 arg1, - struct fixed31_32 arg2) -{ - struct fixed31_32 res; - - ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) || - ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value))); - - res.value = arg1.value + arg2.value; - - return res; -} - -struct fixed31_32 dc_fixpt_sub( - struct fixed31_32 arg1, - struct fixed31_32 arg2) -{ - struct fixed31_32 res; - - ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) || - ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value))); - - res.value = arg1.value - arg2.value; - - return res; -} - -struct fixed31_32 dc_fixpt_mul( - struct fixed31_32 arg1, - struct fixed31_32 arg2) +struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2) { struct fixed31_32 res; @@ -225,8 +167,7 @@ struct fixed31_32 dc_fixpt_mul( return res; } -struct fixed31_32 dc_fixpt_sqr( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg) { struct fixed31_32 res; @@ -266,8 +207,7 @@ struct fixed31_32 dc_fixpt_sqr( return res; } -struct fixed31_32 dc_fixpt_recip( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg) { /* * @note @@ -281,8 +221,7 @@ struct fixed31_32 dc_fixpt_recip( arg.value); } -struct fixed31_32 dc_fixpt_sinc( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg) { struct fixed31_32 square; @@ -326,16 +265,14 @@ struct fixed31_32 dc_fixpt_sinc( return res; } -struct fixed31_32 dc_fixpt_sin( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg) { return dc_fixpt_mul( arg, dc_fixpt_sinc(arg)); } -struct fixed31_32 dc_fixpt_cos( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg) { /* TODO implement argument normalization */ @@ -367,8 +304,7 @@ struct fixed31_32 dc_fixpt_cos( * * Calculated as Taylor series. */ -static struct fixed31_32 fixed31_32_exp_from_taylor_series( - struct fixed31_32 arg) +static struct fixed31_32 fixed31_32_exp_from_taylor_series(struct fixed31_32 arg) { unsigned int n = 9; @@ -396,8 +332,7 @@ static struct fixed31_32 fixed31_32_exp_from_taylor_series( res)); } -struct fixed31_32 dc_fixpt_exp( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg) { /* * @brief @@ -440,8 +375,7 @@ struct fixed31_32 dc_fixpt_exp( return dc_fixpt_one; } -struct fixed31_32 dc_fixpt_log( - struct fixed31_32 arg) +struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg) { struct fixed31_32 res = dc_fixpt_neg(dc_fixpt_one); /* TODO improve 1st estimation */ @@ -472,61 +406,6 @@ struct fixed31_32 dc_fixpt_log( return res; } -struct fixed31_32 dc_fixpt_pow( - struct fixed31_32 arg1, - struct fixed31_32 arg2) -{ - return dc_fixpt_exp( - dc_fixpt_mul( - dc_fixpt_log(arg1), - arg2)); -} - -int dc_fixpt_floor( - struct fixed31_32 arg) -{ - unsigned long long arg_value = abs_i64(arg.value); - - if (arg.value >= 0) - return (int)GET_INTEGER_PART(arg_value); - else - return -(int)GET_INTEGER_PART(arg_value); -} - -int dc_fixpt_round( - struct fixed31_32 arg) -{ - unsigned long long arg_value = abs_i64(arg.value); - - const long long summand = dc_fixpt_half.value; - - ASSERT(LLONG_MAX - (long long)arg_value >= summand); - - arg_value += summand; - - if (arg.value >= 0) - return (int)GET_INTEGER_PART(arg_value); - else - return -(int)GET_INTEGER_PART(arg_value); -} - -int dc_fixpt_ceil( - struct fixed31_32 arg) -{ - unsigned long long arg_value = abs_i64(arg.value); - - const long long summand = dc_fixpt_one.value - - dc_fixpt_epsilon.value; - - ASSERT(LLONG_MAX - (long long)arg_value >= summand); - - arg_value += summand; - - if (arg.value >= 0) - return (int)GET_INTEGER_PART(arg_value); - else - return -(int)GET_INTEGER_PART(arg_value); -} /* this function is a generic helper to translate fixed point value to * specified integer format that will consist of integer_bits integer part and @@ -570,32 +449,27 @@ static inline unsigned int clamp_ux_dy( return min_clamp; } -unsigned int dc_fixpt_u2d19( - struct fixed31_32 arg) +unsigned int dc_fixpt_u2d19(struct fixed31_32 arg) { return ux_dy(arg.value, 2, 19); } -unsigned int dc_fixpt_u0d19( - struct fixed31_32 arg) +unsigned int dc_fixpt_u0d19(struct fixed31_32 arg) { return ux_dy(arg.value, 0, 19); } -unsigned int dc_fixpt_clamp_u0d14( - struct fixed31_32 arg) +unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg) { return clamp_ux_dy(arg.value, 0, 14, 1); } -unsigned int dc_fixpt_clamp_u0d10( - struct fixed31_32 arg) +unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg) { return clamp_ux_dy(arg.value, 0, 10, 1); } -int dc_fixpt_s4d19( - struct fixed31_32 arg) +int dc_fixpt_s4d19(struct fixed31_32 arg) { if (arg.value < 0) return -(int)ux_dy(dc_fixpt_abs(arg).value, 4, 19); diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h index b5b8d7dea373..ebfd33e91ee8 100644 --- a/drivers/gpu/drm/amd/display/include/fixed31_32.h +++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h @@ -70,24 +70,19 @@ static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL }; * @brief * result = numerator / denominator */ -struct fixed31_32 dc_fixpt_from_fraction( - long long numerator, - long long denominator); +struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator); /* * @brief * result = arg */ -struct fixed31_32 dc_fixpt_from_int_nonconst(long long arg); -static inline struct fixed31_32 dc_fixpt_from_int(long long arg) +static inline struct fixed31_32 dc_fixpt_from_int(int arg) { - if (__builtin_constant_p(arg)) { - struct fixed31_32 res; - BUILD_BUG_ON((LONG_MIN > arg) || (arg > LONG_MAX)); - res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART; - return res; - } else - return dc_fixpt_from_int_nonconst(arg); + struct fixed31_32 res; + + res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART; + + return res; } /* @@ -129,8 +124,7 @@ static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg) * @brief * result = arg1 < arg2 */ -static inline bool dc_fixpt_lt(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline bool dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2) { return arg1.value < arg2.value; } @@ -139,8 +133,7 @@ static inline bool dc_fixpt_lt(struct fixed31_32 arg1, * @brief * result = arg1 <= arg2 */ -static inline bool dc_fixpt_le(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2) { return arg1.value <= arg2.value; } @@ -149,8 +142,7 @@ static inline bool dc_fixpt_le(struct fixed31_32 arg1, * @brief * result = arg1 == arg2 */ -static inline bool dc_fixpt_eq(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2) { return arg1.value == arg2.value; } @@ -159,8 +151,7 @@ static inline bool dc_fixpt_eq(struct fixed31_32 arg1, * @brief * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2 */ -static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2) { if (arg1.value <= arg2.value) return arg1; @@ -172,8 +163,7 @@ static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, * @brief * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1 */ -static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2) { if (arg1.value <= arg2.value) return arg2; @@ -209,17 +199,23 @@ static inline struct fixed31_32 dc_fixpt_clamp( * @brief * result = arg << shift */ -struct fixed31_32 dc_fixpt_shl( - struct fixed31_32 arg, - unsigned char shift); +static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift) +{ + struct fixed31_32 res; + + ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) || + ((arg.value < 0) && (arg.value >= LLONG_MIN >> shift))); + + res.value = arg.value << shift; + + return res; +} /* * @brief * result = arg >> shift */ -static inline struct fixed31_32 dc_fixpt_shr( - struct fixed31_32 arg, - unsigned char shift) +static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift) { struct fixed31_32 res; res.value = arg.value >> shift; @@ -235,38 +231,50 @@ static inline struct fixed31_32 dc_fixpt_shr( * @brief * result = arg1 + arg2 */ -struct fixed31_32 dc_fixpt_add( - struct fixed31_32 arg1, - struct fixed31_32 arg2); +static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2) +{ + struct fixed31_32 res; + + ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) || + ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value))); + + res.value = arg1.value + arg2.value; + + return res; +} /* * @brief * result = arg1 + arg2 */ -static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, - int arg2) +static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2) { - return dc_fixpt_add(arg1, - dc_fixpt_from_int(arg2)); + return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2)); } /* * @brief * result = arg1 - arg2 */ -struct fixed31_32 dc_fixpt_sub( - struct fixed31_32 arg1, - struct fixed31_32 arg2); +static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2) +{ + struct fixed31_32 res; + + ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) || + ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value))); + + res.value = arg1.value - arg2.value; + + return res; +} /* * @brief * result = arg1 - arg2 */ -static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, - int arg2) +static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2) { - return dc_fixpt_sub(arg1, - dc_fixpt_from_int(arg2)); + return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2)); } @@ -279,49 +287,40 @@ static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, * @brief * result = arg1 * arg2 */ -struct fixed31_32 dc_fixpt_mul( - struct fixed31_32 arg1, - struct fixed31_32 arg2); +struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2); /* * @brief * result = arg1 * arg2 */ -static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, - int arg2) +static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2) { - return dc_fixpt_mul(arg1, - dc_fixpt_from_int(arg2)); + return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2)); } /* * @brief * result = square(arg) := arg * arg */ -struct fixed31_32 dc_fixpt_sqr( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg); /* * @brief * result = arg1 / arg2 */ -static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, - long long arg2) +static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2) { - return dc_fixpt_from_fraction(arg1.value, - dc_fixpt_from_int(arg2).value); + return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int(arg2).value); } /* * @brief * result = arg1 / arg2 */ -static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, - struct fixed31_32 arg2) +static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2) { - return dc_fixpt_from_fraction(arg1.value, - arg2.value); + return dc_fixpt_from_fraction(arg1.value, arg2.value); } /* @@ -336,8 +335,7 @@ static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, * @note * No special actions taken in case argument is zero. */ -struct fixed31_32 dc_fixpt_recip( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg); /* * @brief @@ -352,8 +350,7 @@ struct fixed31_32 dc_fixpt_recip( * Argument specified in radians, * internally it's normalized to [-2pi...2pi] range. */ -struct fixed31_32 dc_fixpt_sinc( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg); /* * @brief @@ -363,8 +360,7 @@ struct fixed31_32 dc_fixpt_sinc( * Argument specified in radians, * internally it's normalized to [-2pi...2pi] range. */ -struct fixed31_32 dc_fixpt_sin( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg); /* * @brief @@ -376,8 +372,7 @@ struct fixed31_32 dc_fixpt_sin( * passing arguments outside that range * will cause incorrect result! */ -struct fixed31_32 dc_fixpt_cos( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg); /* * @brief @@ -391,8 +386,7 @@ struct fixed31_32 dc_fixpt_cos( * @note * Currently, function is verified for abs(arg) <= 1. */ -struct fixed31_32 dc_fixpt_exp( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg); /* * @brief @@ -404,8 +398,7 @@ struct fixed31_32 dc_fixpt_exp( * Currently, no special actions taken * in case of invalid argument(s). Take care! */ -struct fixed31_32 dc_fixpt_log( - struct fixed31_32 arg); +struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg); /* * @brief @@ -419,9 +412,13 @@ struct fixed31_32 dc_fixpt_log( * @note * Currently, abs(arg1) should be less than 1. Take care! */ -struct fixed31_32 dc_fixpt_pow( - struct fixed31_32 arg1, - struct fixed31_32 arg2); +static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2) +{ + return dc_fixpt_exp( + dc_fixpt_mul( + dc_fixpt_log(arg1), + arg2)); +} /* * @brief @@ -432,22 +429,56 @@ struct fixed31_32 dc_fixpt_pow( * @brief * result = floor(arg) := greatest integer lower than or equal to arg */ -int dc_fixpt_floor( - struct fixed31_32 arg); +static inline int dc_fixpt_floor(struct fixed31_32 arg) +{ + unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; + + if (arg.value >= 0) + return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); + else + return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); +} /* * @brief * result = round(arg) := integer nearest to arg */ -int dc_fixpt_round( - struct fixed31_32 arg); +static inline int dc_fixpt_round(struct fixed31_32 arg) +{ + unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; + + const long long summand = dc_fixpt_half.value; + + ASSERT(LLONG_MAX - (long long)arg_value >= summand); + + arg_value += summand; + + if (arg.value >= 0) + return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); + else + return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); +} /* * @brief * result = ceil(arg) := lowest integer greater than or equal to arg */ -int dc_fixpt_ceil( - struct fixed31_32 arg); +static inline int dc_fixpt_ceil(struct fixed31_32 arg) +{ + unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; + + const long long summand = dc_fixpt_one.value - + dc_fixpt_epsilon.value; + + ASSERT(LLONG_MAX - (long long)arg_value >= summand); + + arg_value += summand; + + if (arg.value >= 0) + return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); + else + return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); +} /* the following two function are used in scaler hw programming to convert fixed * point value to format 2 bits from integer part and 19 bits from fractional @@ -455,20 +486,14 @@ int dc_fixpt_ceil( * fractional */ -unsigned int dc_fixpt_u2d19( - struct fixed31_32 arg); +unsigned int dc_fixpt_u2d19(struct fixed31_32 arg); -unsigned int dc_fixpt_u0d19( - struct fixed31_32 arg); +unsigned int dc_fixpt_u0d19(struct fixed31_32 arg); +unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg); -unsigned int dc_fixpt_clamp_u0d14( - struct fixed31_32 arg); +unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg); -unsigned int dc_fixpt_clamp_u0d10( - struct fixed31_32 arg); - -int dc_fixpt_s4d19( - struct fixed31_32 arg); +int dc_fixpt_s4d19(struct fixed31_32 arg); #endif diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index 29d2ec82b924..e803b375e835 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -913,7 +913,7 @@ static void apply_lut_1d( struct fixed31_32 lut2; const int max_lut_index = 4095; const struct fixed31_32 max_lut_index_f = - dc_fixpt_from_int_nonconst(max_lut_index); + dc_fixpt_from_int(max_lut_index); int32_t index = 0, index_next = 0; struct fixed31_32 index_f; struct fixed31_32 delta_lut; @@ -934,7 +934,7 @@ static void apply_lut_1d( norm_y = dc_fixpt_mul(max_lut_index_f, *regamma_y); index = dc_fixpt_floor(norm_y); - index_f = dc_fixpt_from_int_nonconst(index); + index_f = dc_fixpt_from_int(index); if (index < 0 || index > max_lut_index) continue; @@ -1094,7 +1094,7 @@ static void interpolate_user_regamma(uint32_t hw_points_num, struct fixed31_32 *tf_point; struct fixed31_32 hw_x; struct fixed31_32 norm_factor = - dc_fixpt_from_int_nonconst(255); + dc_fixpt_from_int(255); struct fixed31_32 norm_x; struct fixed31_32 index_f; struct fixed31_32 lut1; @@ -1134,7 +1134,7 @@ static void interpolate_user_regamma(uint32_t hw_points_num, if (index < 0 || index > 255) continue; - index_f = dc_fixpt_from_int_nonconst(index); + index_f = dc_fixpt_from_int(index); index_next = (index == 255) ? index : index + 1; if (color == 0) {