root/drivers/gpu/drm/amd/display/dc/basics/conversion.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fixed_point_to_int_frac
  2. convert_float_matrix

   1 /*
   2  * Copyright 2012-15 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 
  26 #include "dm_services.h"
  27 
  28 #define DIVIDER 10000
  29 
  30 /* S2D13 value in [-3.00...0.9999] */
  31 #define S2D13_MIN (-3 * DIVIDER)
  32 #define S2D13_MAX (3 * DIVIDER)
  33 
  34 uint16_t fixed_point_to_int_frac(
  35         struct fixed31_32 arg,
  36         uint8_t integer_bits,
  37         uint8_t fractional_bits)
  38 {
  39         int32_t numerator;
  40         int32_t divisor = 1 << fractional_bits;
  41 
  42         uint16_t result;
  43 
  44         uint16_t d = (uint16_t)dc_fixpt_floor(
  45                 dc_fixpt_abs(
  46                         arg));
  47 
  48         if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
  49                 numerator = (uint16_t)dc_fixpt_round(
  50                         dc_fixpt_mul_int(
  51                                 arg,
  52                                 divisor));
  53         else {
  54                 numerator = dc_fixpt_floor(
  55                         dc_fixpt_sub(
  56                                 dc_fixpt_from_int(
  57                                         1LL << integer_bits),
  58                                 dc_fixpt_recip(
  59                                         dc_fixpt_from_int(
  60                                                 divisor))));
  61         }
  62 
  63         if (numerator >= 0)
  64                 result = (uint16_t)numerator;
  65         else
  66                 result = (uint16_t)(
  67                 (1 << (integer_bits + fractional_bits + 1)) + numerator);
  68 
  69         if ((result != 0) && dc_fixpt_lt(
  70                 arg, dc_fixpt_zero))
  71                 result |= 1 << (integer_bits + fractional_bits);
  72 
  73         return result;
  74 }
  75 /**
  76 * convert_float_matrix
  77 * This converts a double into HW register spec defined format S2D13.
  78 * @param :
  79 * @return None
  80 */
  81 void convert_float_matrix(
  82         uint16_t *matrix,
  83         struct fixed31_32 *flt,
  84         uint32_t buffer_size)
  85 {
  86         const struct fixed31_32 min_2_13 =
  87                 dc_fixpt_from_fraction(S2D13_MIN, DIVIDER);
  88         const struct fixed31_32 max_2_13 =
  89                 dc_fixpt_from_fraction(S2D13_MAX, DIVIDER);
  90         uint32_t i;
  91 
  92         for (i = 0; i < buffer_size; ++i) {
  93                 uint32_t reg_value =
  94                                 fixed_point_to_int_frac(
  95                                         dc_fixpt_clamp(
  96                                                 flt[i],
  97                                                 min_2_13,
  98                                                 max_2_13),
  99                                                 2,
 100                                                 13);
 101 
 102                 matrix[i] = (uint16_t)reg_value;
 103         }
 104 }

/* [<][>][^][v][top][bottom][index][help] */