cregit-Linux how code gets into the kernel

Release 4.18 drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c

/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "dm_services.h"
#include "include/fixed31_32.h"


static inline unsigned long long abs_i64( long long arg) { if (arg > 0) return (unsigned long long)arg; else return (unsigned long long)(-arg); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland2871.79%150.00%
Anthony Koo1128.21%150.00%
Total39100.00%2100.00%

/* * @brief * result = dividend / divisor * *remainder = dividend % divisor */
static inline unsigned long long complete_integer_division_u64( unsigned long long dividend, unsigned long long divisor, unsigned long long *remainder) { unsigned long long result; ASSERT(divisor); result = div64_u64_rem(dividend, divisor, remainder); return result; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland3469.39%150.00%
Anthony Koo1530.61%150.00%
Total49100.00%2100.00%

#define FRACTIONAL_PART_MASK \ ((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1) #define GET_INTEGER_PART(x) \ ((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART) #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 res; bool arg1_negative = numerator < 0; bool arg2_negative = denominator < 0; unsigned long long arg1_value = arg1_negative ? -numerator : numerator; unsigned long long arg2_value = arg2_negative ? -denominator : denominator; unsigned long long remainder; /* determine integer part */ unsigned long long res_value = complete_integer_division_u64( arg1_value, arg2_value, &remainder); ASSERT(res_value <= LONG_MAX); /* determine fractional part */ { unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART; do { remainder <<= 1; res_value <<= 1; if (remainder >= arg2_value) { res_value |= 1; remainder -= arg2_value; } } while (--i != 0); } /* round up LSB */ { unsigned long long summand = (remainder << 1) >= arg2_value; ASSERT(res_value <= LLONG_MAX - summand); res_value += summand; } res.value = (long long)res_value; if (arg1_negative ^ arg2_negative) res.value = -res.value; return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland16086.49%125.00%
Anthony Koo2312.43%125.00%
Dmytro Laktyushkin10.54%125.00%
Dave Airlie10.54%125.00%
Total185100.00%4100.00%


struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2) { struct fixed31_32 res; bool arg1_negative = arg1.value < 0; bool arg2_negative = arg2.value < 0; unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value; unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value; unsigned long long arg1_int = GET_INTEGER_PART(arg1_value); unsigned long long arg2_int = GET_INTEGER_PART(arg2_value); unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value); unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value); unsigned long long tmp; res.value = arg1_int * arg2_int; ASSERT(res.value <= LONG_MAX); res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; tmp = arg1_int * arg2_fra; ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; tmp = arg2_int * arg1_fra; ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; tmp = arg1_fra * arg2_fra; tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + (tmp >= (unsigned long long)dc_fixpt_half.value); ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; if (arg1_negative ^ arg2_negative) res.value = -res.value; return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland22886.04%125.00%
Anthony Koo3312.45%125.00%
Dave Airlie20.75%125.00%
Dmytro Laktyushkin20.75%125.00%
Total265100.00%4100.00%


struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg) { struct fixed31_32 res; unsigned long long arg_value = abs_i64(arg.value); unsigned long long arg_int = GET_INTEGER_PART(arg_value); unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value); unsigned long long tmp; res.value = arg_int * arg_int; ASSERT(res.value <= LONG_MAX); res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; tmp = arg_int * arg_fra; ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; tmp = arg_fra * arg_fra; tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + (tmp >= (unsigned long long)dc_fixpt_half.value); ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); res.value += tmp; return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland15484.62%125.00%
Anthony Koo2413.19%125.00%
Dmytro Laktyushkin21.10%125.00%
Dave Airlie21.10%125.00%
Total182100.00%4100.00%


struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg) { /* * @note * Good idea to use Newton's method */ ASSERT(arg.value); return dc_fixpt_from_fraction( dc_fixpt_one.value, arg.value); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland2790.00%150.00%
Dmytro Laktyushkin310.00%150.00%
Total30100.00%2100.00%


struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg) { struct fixed31_32 square; struct fixed31_32 res = dc_fixpt_one; int n = 27; struct fixed31_32 arg_norm = arg; if (dc_fixpt_le( dc_fixpt_two_pi, dc_fixpt_abs(arg))) { arg_norm = dc_fixpt_sub( arg_norm, dc_fixpt_mul_int( dc_fixpt_two_pi, (int)div64_s64( arg_norm.value, dc_fixpt_two_pi.value))); } square = dc_fixpt_sqr(arg_norm); do { res = dc_fixpt_sub( dc_fixpt_one, dc_fixpt_div_int( dc_fixpt_mul( square, res), n * (n - 1))); n -= 2; } while (n > 2); if (arg.value != arg_norm.value) res = dc_fixpt_div( dc_fixpt_mul(res, arg_norm), arg); return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland12687.50%133.33%
Dmytro Laktyushkin1611.11%133.33%
Anthony Koo21.39%133.33%
Total144100.00%3100.00%


struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg) { return dc_fixpt_mul( arg, dc_fixpt_sinc(arg)); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland1885.71%150.00%
Dmytro Laktyushkin314.29%150.00%
Total21100.00%2100.00%


struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg) { /* TODO implement argument normalization */ const struct fixed31_32 square = dc_fixpt_sqr(arg); struct fixed31_32 res = dc_fixpt_one; int n = 26; do { res = dc_fixpt_sub( dc_fixpt_one, dc_fixpt_div_int( dc_fixpt_mul( square, res), n * (n - 1))); n -= 2; } while (n != 0); return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland6689.19%133.33%
Dmytro Laktyushkin79.46%133.33%
Anthony Koo11.35%133.33%
Total74100.00%3100.00%

/* * @brief * result = exp(arg), * where abs(arg) < 1 * * Calculated as Taylor series. */
static struct fixed31_32 fixed31_32_exp_from_taylor_series(struct fixed31_32 arg) { unsigned int n = 9; struct fixed31_32 res = dc_fixpt_from_fraction( n + 2, n + 1); /* TODO find correct res */ ASSERT(dc_fixpt_lt(arg, dc_fixpt_one)); do res = dc_fixpt_add( dc_fixpt_one, dc_fixpt_div_int( dc_fixpt_mul( arg, res), n)); while (--n != 1); return dc_fixpt_add( dc_fixpt_one, dc_fixpt_mul( arg, res)); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland7285.71%133.33%
Dmytro Laktyushkin1011.90%133.33%
Anthony Koo22.38%133.33%
Total84100.00%3100.00%


struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg) { /* * @brief * Main equation is: * exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r), * where m = round(x / ln(2)), r = x - m * ln(2) */ if (dc_fixpt_le( dc_fixpt_ln2_div_2, dc_fixpt_abs(arg))) { int m = dc_fixpt_round( dc_fixpt_div( arg, dc_fixpt_ln2)); struct fixed31_32 r = dc_fixpt_sub( arg, dc_fixpt_mul_int( dc_fixpt_ln2, m)); ASSERT(m != 0); ASSERT(dc_fixpt_lt( dc_fixpt_abs(r), dc_fixpt_one)); if (m > 0) return dc_fixpt_shl( fixed31_32_exp_from_taylor_series(r), (unsigned char)m); else return dc_fixpt_div_int( fixed31_32_exp_from_taylor_series(r), 1LL << -m); } else if (arg.value != 0) return fixed31_32_exp_from_taylor_series(arg); else return dc_fixpt_one; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland11085.27%133.33%
Dmytro Laktyushkin1612.40%133.33%
Anthony Koo32.33%133.33%
Total129100.00%3100.00%


struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg) { struct fixed31_32 res = dc_fixpt_neg(dc_fixpt_one); /* TODO improve 1st estimation */ struct fixed31_32 error; ASSERT(arg.value > 0); /* TODO if arg is negative, return NaN */ /* TODO if arg is zero, return -INF */ do { struct fixed31_32 res1 = dc_fixpt_add( dc_fixpt_sub( res, dc_fixpt_one), dc_fixpt_div( arg, dc_fixpt_exp(res))); error = dc_fixpt_sub( res, res1); res = res1; /* TODO determine max_allowed_error based on quality of exp() */ } while (abs_i64(error.value) > 100ULL); return res; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland8290.11%150.00%
Dmytro Laktyushkin99.89%150.00%
Total91100.00%2100.00%

/* this function is a generic helper to translate fixed point value to * specified integer format that will consist of integer_bits integer part and * fractional_bits fractional part. For example it is used in * dc_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional * part in 32 bits. It is used in hw programming (scaler) */
static inline unsigned int ux_dy( long long value, unsigned int integer_bits, unsigned int fractional_bits) { /* 1. create mask of integer part */ unsigned int result = (1 << integer_bits) - 1; /* 2. mask out fractional part */ unsigned int fractional_part = FRACTIONAL_PART_MASK & value; /* 3. shrink fixed point integer part to be of integer_bits width*/ result &= GET_INTEGER_PART(value); /* 4. make space for fractional part to be filled in after integer */ result <<= fractional_bits; /* 5. shrink fixed point fractional part to of fractional_bits width*/ fractional_part >>= FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits; /* 6. merge the result */ return result | fractional_part; }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland5580.88%133.33%
Anthony Koo1217.65%133.33%
Dave Airlie11.47%133.33%
Total68100.00%3100.00%


static inline unsigned int clamp_ux_dy( long long value, unsigned int integer_bits, unsigned int fractional_bits, unsigned int min_clamp) { unsigned int truncated_val = ux_dy(value, integer_bits, fractional_bits); if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART))) return (1 << (integer_bits + fractional_bits)) - 1; else if (truncated_val > min_clamp) return truncated_val; else return min_clamp; }

Contributors

PersonTokensPropCommitsCommitProp
Dmytro Laktyushkin6684.62%150.00%
Anthony Koo1215.38%150.00%
Total78100.00%2100.00%


unsigned int dc_fixpt_u3d19(struct fixed31_32 arg) { return ux_dy(arg.value, 3, 19); }

Contributors

PersonTokensPropCommitsCommitProp
Dmytro Laktyushkin22100.00%1100.00%
Total22100.00%1100.00%


unsigned int dc_fixpt_u2d19(struct fixed31_32 arg) { return ux_dy(arg.value, 2, 19); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland1986.36%133.33%
Anthony Koo29.09%133.33%
Dmytro Laktyushkin14.55%133.33%
Total22100.00%3100.00%


unsigned int dc_fixpt_u0d19(struct fixed31_32 arg) { return ux_dy(arg.value, 0, 19); }

Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland1986.36%133.33%
Anthony Koo29.09%133.33%
Dmytro Laktyushkin14.55%133.33%
Total22100.00%3100.00%


unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg) { return clamp_ux_dy(arg.value, 0, 14, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Prosyak1770.83%125.00%
Dmytro Laktyushkin520.83%250.00%
Anthony Koo28.33%125.00%
Total24100.00%4100.00%


unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg) { return clamp_ux_dy(arg.value, 0, 10, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Prosyak1770.83%125.00%
Dmytro Laktyushkin520.83%250.00%
Anthony Koo28.33%125.00%
Total24100.00%4100.00%


int dc_fixpt_s4d19(struct fixed31_32 arg) { if (arg.value < 0) return -(int)ux_dy(dc_fixpt_abs(arg).value, 4, 19); else return ux_dy(arg.value, 4, 19); }

Contributors

PersonTokensPropCommitsCommitProp
Ken Chalmers4591.84%133.33%
Anthony Koo24.08%133.33%
Dmytro Laktyushkin24.08%133.33%
Total49100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Harry Wentland122675.08%112.50%
Dmytro Laktyushkin17210.53%337.50%
Anthony Koo1489.06%112.50%
Ken Chalmers452.76%112.50%
Vitaly Prosyak342.08%112.50%
Dave Airlie80.49%112.50%
Total1633100.00%8100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.