LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dml/calcs - bw_fixed.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 63 67 94.0 %
Date: 2022-12-09 01:23:36 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  * Authors: AMD
      23             :  *
      24             :  */
      25             : #include "dm_services.h"
      26             : #include "bw_fixed.h"
      27             : 
      28             : #define MAX_I64 \
      29             :         ((int64_t)((1ULL << 63) - 1))
      30             : 
      31             : #define MIN_I64 \
      32             :         (-MAX_I64 - 1)
      33             : 
      34             : #define FRACTIONAL_PART_MASK \
      35             :         ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1)
      36             : 
      37             : #define GET_FRACTIONAL_PART(x) \
      38             :         (FRACTIONAL_PART_MASK & (x))
      39             : 
      40             : static uint64_t abs_i64(int64_t arg)
      41             : {
      42          94 :         if (arg >= 0)
      43          75 :                 return (uint64_t)(arg);
      44             :         else
      45          12 :                 return (uint64_t)(-arg);
      46             : }
      47             : 
      48           5 : struct bw_fixed bw_int_to_fixed_nonconst(int64_t value)
      49             : {
      50             :         struct bw_fixed res;
      51             : 
      52           5 :         ASSERT(value < BW_FIXED_MAX_I32 && value > BW_FIXED_MIN_I32);
      53           5 :         res.value = value << BW_FIXED_BITS_PER_FRACTIONAL_PART;
      54           5 :         return res;
      55             : }
      56             : 
      57          24 : struct bw_fixed bw_frc_to_fixed(int64_t numerator, int64_t denominator)
      58             : {
      59             :         struct bw_fixed res;
      60          24 :         bool arg1_negative = numerator < 0;
      61          24 :         bool arg2_negative = denominator < 0;
      62             :         uint64_t arg1_value;
      63             :         uint64_t arg2_value;
      64             :         uint64_t remainder;
      65             : 
      66             :         /* determine integer part */
      67             :         uint64_t res_value;
      68             : 
      69          24 :         ASSERT(denominator != 0);
      70             : 
      71          24 :         arg1_value = abs_i64(numerator);
      72          24 :         arg2_value = abs_i64(denominator);
      73          24 :         res_value = div64_u64_rem(arg1_value, arg2_value, &remainder);
      74             : 
      75          24 :         ASSERT(res_value <= BW_FIXED_MAX_I32);
      76             : 
      77             :         /* determine fractional part */
      78             :         {
      79             :                 uint32_t i = BW_FIXED_BITS_PER_FRACTIONAL_PART;
      80             : 
      81             :                 do {
      82         576 :                         remainder <<= 1;
      83             : 
      84         576 :                         res_value <<= 1;
      85             : 
      86         576 :                         if (remainder >= arg2_value) {
      87         153 :                                 res_value |= 1;
      88         153 :                                 remainder -= arg2_value;
      89             :                         }
      90         576 :                 } while (--i != 0);
      91             :         }
      92             : 
      93             :         /* round up LSB */
      94             :         {
      95          24 :                 uint64_t summand = (remainder << 1) >= arg2_value;
      96             : 
      97          24 :                 ASSERT(res_value <= MAX_I64 - summand);
      98             : 
      99          24 :                 res_value += summand;
     100             :         }
     101             : 
     102          24 :         res.value = (int64_t)(res_value);
     103             : 
     104          24 :         if (arg1_negative ^ arg2_negative)
     105           3 :                 res.value = -res.value;
     106          24 :         return res;
     107             : }
     108             : 
     109           8 : struct bw_fixed bw_floor2(
     110             :         const struct bw_fixed arg,
     111             :         const struct bw_fixed significance)
     112             : {
     113             :         struct bw_fixed result;
     114             :         int64_t multiplicand;
     115             : 
     116          24 :         multiplicand = div64_s64(arg.value, abs_i64(significance.value));
     117           8 :         result.value = abs_i64(significance.value) * multiplicand;
     118          24 :         ASSERT(abs_i64(result.value) <= abs_i64(arg.value));
     119           8 :         return result;
     120             : }
     121             : 
     122           0 : struct bw_fixed bw_ceil2(
     123             :         const struct bw_fixed arg,
     124             :         const struct bw_fixed significance)
     125             : {
     126             :         struct bw_fixed result;
     127             :         int64_t multiplicand;
     128             : 
     129           8 :         multiplicand = div64_s64(arg.value, abs_i64(significance.value));
     130           8 :         result.value = abs_i64(significance.value) * multiplicand;
     131           8 :         if (abs_i64(result.value) < abs_i64(arg.value)) {
     132           0 :                 if (arg.value < 0)
     133           0 :                         result.value -= abs_i64(significance.value);
     134             :                 else
     135           2 :                         result.value += abs_i64(significance.value);
     136             :         }
     137           0 :         return result;
     138             : }
     139             : 
     140          11 : struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
     141             : {
     142             :         struct bw_fixed res;
     143             : 
     144          11 :         bool arg1_negative = arg1.value < 0;
     145          11 :         bool arg2_negative = arg2.value < 0;
     146             : 
     147          22 :         uint64_t arg1_value = abs_i64(arg1.value);
     148          22 :         uint64_t arg2_value = abs_i64(arg2.value);
     149             : 
     150          11 :         uint64_t arg1_int = BW_FIXED_GET_INTEGER_PART(arg1_value);
     151          11 :         uint64_t arg2_int = BW_FIXED_GET_INTEGER_PART(arg2_value);
     152             : 
     153          11 :         uint64_t arg1_fra = GET_FRACTIONAL_PART(arg1_value);
     154          11 :         uint64_t arg2_fra = GET_FRACTIONAL_PART(arg2_value);
     155             : 
     156             :         uint64_t tmp;
     157             : 
     158          11 :         res.value = arg1_int * arg2_int;
     159             : 
     160          11 :         ASSERT(res.value <= BW_FIXED_MAX_I32);
     161             : 
     162          11 :         res.value <<= BW_FIXED_BITS_PER_FRACTIONAL_PART;
     163             : 
     164          11 :         tmp = arg1_int * arg2_fra;
     165             : 
     166          11 :         ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
     167             : 
     168          11 :         res.value += tmp;
     169             : 
     170          11 :         tmp = arg2_int * arg1_fra;
     171             : 
     172          11 :         ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
     173             : 
     174          11 :         res.value += tmp;
     175             : 
     176          11 :         tmp = arg1_fra * arg2_fra;
     177             : 
     178          22 :         tmp = (tmp >> BW_FIXED_BITS_PER_FRACTIONAL_PART) +
     179          11 :                 (tmp >= (uint64_t)(bw_frc_to_fixed(1, 2).value));
     180             : 
     181          11 :         ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
     182             : 
     183          11 :         res.value += tmp;
     184             : 
     185          11 :         if (arg1_negative ^ arg2_negative)
     186           4 :                 res.value = -res.value;
     187          11 :         return res;
     188             : }
     189             : 
     190             : #if IS_ENABLED(CONFIG_DCE_KUNIT_TEST)
     191             : #include "../../../tests/dc/dml/calcs/bw_fixed_test.c"
     192             : #endif

Generated by: LCOV version 1.14