mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
drm/amd/display: remove dc dependencies from SPL library
[Why] Make SPL library dc-independent so it can be reused by other components [How] Create separate set of fixed31_32 calls in SPL Make all inputs and outputs to SPL use primitive types For ratios and inits, return as uint32 from SPL. So add conversion from uint32 back to fixed point in SPL-to-dc translate function Reviewed-by: Relja Vojvodic <relja.vojvodic@amd.com> Signed-off-by: Jerry Zuo <jerry.zuo@amd.com> Signed-off-by: Samson Tam <samson.tam@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a41d58fb91
commit
f822007034
@ -486,3 +486,30 @@ int dc_fixpt_s4d19(struct fixed31_32 arg)
|
||||
else
|
||||
return ux_dy(arg.value, 4, 19);
|
||||
}
|
||||
|
||||
struct fixed31_32 dc_fixpt_from_ux_dy(unsigned int value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct fixed31_32 fixpt_value = dc_fixpt_zero;
|
||||
struct fixed31_32 fixpt_int_value = dc_fixpt_zero;
|
||||
long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
|
||||
|
||||
fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
frac_mask = frac_mask << fractional_bits;
|
||||
fixpt_int_value.value = value & frac_mask;
|
||||
fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
fixpt_value.value |= fixpt_int_value.value;
|
||||
return fixpt_value;
|
||||
}
|
||||
|
||||
struct fixed31_32 dc_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct fixed31_32 fixpt_value = dc_fixpt_from_int(int_value);
|
||||
|
||||
fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
return fixpt_value;
|
||||
}
|
||||
|
@ -1511,8 +1511,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
|
||||
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
|
||||
spl_out->scl_data.h_active = pipe_ctx->plane_res.scl_data.h_active;
|
||||
spl_out->scl_data.v_active = pipe_ctx->plane_res.scl_data.v_active;
|
||||
|
||||
// Convert pipe_ctx to respective input params for SPL
|
||||
translate_SPL_in_params_from_pipe_ctx(pipe_ctx, spl_in);
|
||||
|
@ -42,26 +42,26 @@ static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality,
|
||||
static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality,
|
||||
const struct spl_taps *spl_scaling_quality)
|
||||
{
|
||||
scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c;
|
||||
scaling_quality->h_taps = spl_scaling_quality->h_taps;
|
||||
scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c;
|
||||
scaling_quality->v_taps = spl_scaling_quality->v_taps;
|
||||
scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c + 1;
|
||||
scaling_quality->h_taps = spl_scaling_quality->h_taps + 1;
|
||||
scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c + 1;
|
||||
scaling_quality->v_taps = spl_scaling_quality->v_taps + 1;
|
||||
}
|
||||
static void populate_ratios_from_splratios(struct scaling_ratios *ratios,
|
||||
const struct spl_ratios *spl_ratios)
|
||||
const struct ratio *spl_ratios)
|
||||
{
|
||||
ratios->horz = spl_ratios->horz;
|
||||
ratios->vert = spl_ratios->vert;
|
||||
ratios->horz_c = spl_ratios->horz_c;
|
||||
ratios->vert_c = spl_ratios->vert_c;
|
||||
ratios->horz = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio >> 5, 3, 19);
|
||||
ratios->vert = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio >> 5, 3, 19);
|
||||
ratios->horz_c = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio_c >> 5, 3, 19);
|
||||
ratios->vert_c = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio_c >> 5, 3, 19);
|
||||
}
|
||||
static void populate_inits_from_splinits(struct scl_inits *inits,
|
||||
const struct spl_inits *spl_inits)
|
||||
const struct init *spl_inits)
|
||||
{
|
||||
inits->h = spl_inits->h;
|
||||
inits->v = spl_inits->v;
|
||||
inits->h_c = spl_inits->h_c;
|
||||
inits->v_c = spl_inits->v_c;
|
||||
inits->h = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int, spl_inits->h_filter_init_frac >> 5, 0, 19);
|
||||
inits->v = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int, spl_inits->v_filter_init_frac >> 5, 0, 19);
|
||||
inits->h_c = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int_c, spl_inits->h_filter_init_frac_c >> 5, 0, 19);
|
||||
inits->v_c = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int_c, spl_inits->v_filter_init_frac_c >> 5, 0, 19);
|
||||
}
|
||||
/// @brief Translate SPL input parameters from pipe context
|
||||
/// @param pipe_ctx
|
||||
@ -170,6 +170,9 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
|
||||
/* Translate transfer function */
|
||||
spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
|
||||
spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
|
||||
|
||||
spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
|
||||
spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
|
||||
/* Check if it is stream is in fullscreen and if its HDR.
|
||||
* Use this to determine sharpness levels
|
||||
*/
|
||||
@ -184,15 +187,15 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
|
||||
void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out)
|
||||
{
|
||||
// Make scaler data recout point to spl output field recout
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->scl_data.recout);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->dscl_prog_data->recout);
|
||||
// Make scaler data ratios point to spl output field ratios
|
||||
populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->scl_data.ratios);
|
||||
populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->dscl_prog_data->ratios);
|
||||
// Make scaler data viewport point to spl output field viewport
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->scl_data.viewport);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->dscl_prog_data->viewport);
|
||||
// Make scaler data viewport_c point to spl output field viewport_c
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->scl_data.viewport_c);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->dscl_prog_data->viewport_c);
|
||||
// Make scaler data taps point to spl output field scaling taps
|
||||
populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->scl_data.taps);
|
||||
populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->dscl_prog_data->taps);
|
||||
// Make scaler data init point to spl output field init
|
||||
populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->scl_data.inits);
|
||||
populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->dscl_prog_data->init);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
# Makefile for the 'spl' sub-component of DAL.
|
||||
# It provides the scaling library interface.
|
||||
|
||||
SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o
|
||||
SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o spl_fixpt31_32.o
|
||||
|
||||
AMD_DAL_SPL = $(addprefix $(AMDDALPATH)/dc/spl/,$(SPL))
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
#include "spl_debug.h"
|
||||
#include "dc_spl_filters.h"
|
||||
#include "dc_spl_isharp_filters.h"
|
||||
|
||||
@ -631,10 +632,10 @@ uint16_t *spl_get_filter_isharp_bs_3tap_64p(void)
|
||||
return filter_isharp_bs_3tap_64p_s1_12;
|
||||
}
|
||||
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct fixed31_32 ratio, enum system_setup setup)
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup)
|
||||
{
|
||||
uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
|
||||
struct fixed31_32 sharp_base, sharp_calc, sharp_level, ratio_level;
|
||||
struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level, ratio_level;
|
||||
int i, j;
|
||||
struct scale_ratio_to_sharpness_level_lookup *setup_lookup_ptr;
|
||||
int num_sharp_ramp_levels;
|
||||
@ -680,12 +681,12 @@ void spl_build_isharp_1dlut_from_reference_curve(struct fixed31_32 ratio, enum s
|
||||
* base scale ratio to sharpness curve
|
||||
*/
|
||||
j = 0;
|
||||
sharp_level = dc_fixpt_zero;
|
||||
sharp_level = spl_fixpt_zero;
|
||||
while (j < num_sharp_ramp_levels) {
|
||||
ratio_level = dc_fixpt_from_fraction(setup_lookup_ptr->ratio_numer,
|
||||
ratio_level = spl_fixpt_from_fraction(setup_lookup_ptr->ratio_numer,
|
||||
setup_lookup_ptr->ratio_denom);
|
||||
if (ratio.value >= ratio_level.value) {
|
||||
sharp_level = dc_fixpt_from_fraction(setup_lookup_ptr->sharpness_numer,
|
||||
sharp_level = spl_fixpt_from_fraction(setup_lookup_ptr->sharpness_numer,
|
||||
setup_lookup_ptr->sharpness_denom);
|
||||
break;
|
||||
}
|
||||
@ -707,12 +708,12 @@ void spl_build_isharp_1dlut_from_reference_curve(struct fixed31_32 ratio, enum s
|
||||
size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
|
||||
memset(byte_ptr_1dlut_dst, 0, size_1dlut);
|
||||
for (j = 0; j < size_1dlut; j++) {
|
||||
sharp_base = dc_fixpt_from_int((int)*byte_ptr_1dlut_src);
|
||||
sharp_calc = dc_fixpt_mul(sharp_base, sharp_level);
|
||||
sharp_calc = dc_fixpt_div(sharp_calc, dc_fixpt_from_int(3));
|
||||
sharp_calc = dc_fixpt_min(dc_fixpt_from_int(255), sharp_calc);
|
||||
sharp_calc = dc_fixpt_add(sharp_calc, dc_fixpt_from_fraction(1, 2));
|
||||
sharp_calc_int = dc_fixpt_floor(sharp_calc);
|
||||
sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
|
||||
sharp_calc = spl_fixpt_mul(sharp_base, sharp_level);
|
||||
sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
|
||||
sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
|
||||
sharp_calc = spl_fixpt_add(sharp_calc, spl_fixpt_from_fraction(1, 2));
|
||||
sharp_calc_int = spl_fixpt_floor(sharp_calc);
|
||||
if (sharp_calc_int > 255)
|
||||
sharp_calc_int = 255;
|
||||
*byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
|
||||
@ -742,7 +743,6 @@ void spl_init_blur_scale_coeffs(void)
|
||||
filter_isharp_bs_4tap_in_6_64p_s1_12, 6);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
||||
uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps)
|
||||
{
|
||||
if (taps == 3)
|
||||
@ -753,7 +753,7 @@ uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps)
|
||||
return spl_get_filter_isharp_bs_4tap_in_6_64p();
|
||||
else {
|
||||
/* should never happen, bug */
|
||||
BREAK_TO_DEBUGGER();
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -767,5 +767,4 @@ void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
|
||||
dscl_prog_data->filter_blur_scale_v =
|
||||
spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -43,6 +43,6 @@ void spl_init_blur_scale_coeffs(void);
|
||||
void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
|
||||
const struct spl_scaler_data *data);
|
||||
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct fixed31_32 ratio, enum system_setup setup);
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup);
|
||||
uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum explicit_sharpness sharpness);
|
||||
#endif /* __DC_SPL_ISHARP_FILTERS_H__ */
|
||||
|
@ -2,6 +2,7 @@
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "spl_debug.h"
|
||||
#include "dc_spl_filters.h"
|
||||
#include "dc_spl_scl_filters.h"
|
||||
#include "dc_spl_scl_easf_filters.h"
|
||||
@ -1406,67 +1407,67 @@ void spl_init_easf_filter_coeffs(void)
|
||||
easf_filter_6tap_64p_ratio_1_00_s1_12, 6);
|
||||
}
|
||||
|
||||
uint16_t *spl_get_easf_filter_3tap_64p(struct fixed31_32 ratio)
|
||||
uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_from_fraction(3, 10).value)
|
||||
if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_30_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_40_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_50_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(6, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_60_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(7, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_70_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(8, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_80_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(9, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
|
||||
return easf_filter_3tap_64p_ratio_0_90_s1_12;
|
||||
else
|
||||
return easf_filter_3tap_64p_ratio_1_00_s1_12;
|
||||
}
|
||||
|
||||
uint16_t *spl_get_easf_filter_4tap_64p(struct fixed31_32 ratio)
|
||||
uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_from_fraction(3, 10).value)
|
||||
if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_30_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_40_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_50_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(6, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_60_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(7, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_70_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(8, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_80_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(9, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
|
||||
return easf_filter_4tap_64p_ratio_0_90_s1_12;
|
||||
else
|
||||
return easf_filter_4tap_64p_ratio_1_00_s1_12;
|
||||
}
|
||||
|
||||
uint16_t *spl_get_easf_filter_6tap_64p(struct fixed31_32 ratio)
|
||||
uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_from_fraction(3, 10).value)
|
||||
if (ratio.value < spl_fixpt_from_fraction(3, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_30_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_40_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_50_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(6, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(6, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_60_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(7, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(7, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_70_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(8, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(8, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_80_s1_12;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(9, 10).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(9, 10).value)
|
||||
return easf_filter_6tap_64p_ratio_0_90_s1_12;
|
||||
else
|
||||
return easf_filter_6tap_64p_ratio_1_00_s1_12;
|
||||
}
|
||||
|
||||
uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
|
||||
uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (taps == 6)
|
||||
return spl_get_easf_filter_6tap_64p(ratio);
|
||||
@ -1476,7 +1477,7 @@ uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
|
||||
return spl_get_easf_filter_3tap_64p(ratio);
|
||||
else {
|
||||
/* should never happen, bug */
|
||||
BREAK_TO_DEBUGGER();
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1517,7 +1518,7 @@ void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t spl_easf_get_scale_ratio_to_reg_value(struct fixed31_32 ratio,
|
||||
static uint32_t spl_easf_get_scale_ratio_to_reg_value(struct spl_fixed31_32 ratio,
|
||||
struct scale_ratio_to_reg_value_lookup *lookup_table_base_ptr,
|
||||
unsigned int num_entries)
|
||||
{
|
||||
@ -1534,7 +1535,7 @@ static uint32_t spl_easf_get_scale_ratio_to_reg_value(struct fixed31_32 ratio,
|
||||
if (lookup_table_index_ptr->numer < 0)
|
||||
break;
|
||||
|
||||
if (ratio.value < dc_fixpt_from_fraction(
|
||||
if (ratio.value < spl_fixpt_from_fraction(
|
||||
lookup_table_index_ptr->numer,
|
||||
lookup_table_index_ptr->denom).value) {
|
||||
value = lookup_table_index_ptr->reg_value;
|
||||
@ -1545,7 +1546,7 @@ static uint32_t spl_easf_get_scale_ratio_to_reg_value(struct fixed31_32 ratio,
|
||||
}
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_v_bf3_mode(struct fixed31_32 ratio)
|
||||
uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries = sizeof(easf_v_bf3_mode_lookup) /
|
||||
@ -1554,7 +1555,7 @@ uint32_t spl_get_v_bf3_mode(struct fixed31_32 ratio)
|
||||
easf_v_bf3_mode_lookup, num_entries);
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_h_bf3_mode(struct fixed31_32 ratio)
|
||||
uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries = sizeof(easf_h_bf3_mode_lookup) /
|
||||
@ -1563,7 +1564,7 @@ uint32_t spl_get_h_bf3_mode(struct fixed31_32 ratio)
|
||||
easf_h_bf3_mode_lookup, num_entries);
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_reducer_gain6(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1582,7 +1583,7 @@ uint32_t spl_get_reducer_gain6(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_reducer_gain4(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1601,7 +1602,7 @@ uint32_t spl_get_reducer_gain4(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_gainRing6(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1620,7 +1621,7 @@ uint32_t spl_get_gainRing6(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_gainRing4(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1639,7 +1640,7 @@ uint32_t spl_get_gainRing4(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1653,7 +1654,7 @@ uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_uptilt_maxval(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1667,7 +1668,7 @@ uint32_t spl_get_3tap_uptilt_maxval(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_dntilt_slope(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1681,7 +1682,7 @@ uint32_t spl_get_3tap_dntilt_slope(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_uptilt1_slope(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1695,7 +1696,7 @@ uint32_t spl_get_3tap_uptilt1_slope(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_uptilt2_slope(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
@ -1709,7 +1710,7 @@ uint32_t spl_get_3tap_uptilt2_slope(int taps, struct fixed31_32 ratio)
|
||||
value = 0;
|
||||
return value;
|
||||
}
|
||||
uint32_t spl_get_3tap_uptilt2_offset(int taps, struct fixed31_32 ratio)
|
||||
uint32_t spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
uint32_t value;
|
||||
unsigned int num_entries;
|
||||
|
@ -14,25 +14,25 @@ struct scale_ratio_to_reg_value_lookup {
|
||||
};
|
||||
|
||||
void spl_init_easf_filter_coeffs(void);
|
||||
uint16_t *spl_get_easf_filter_3tap_64p(struct fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_4tap_64p(struct fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_6tap_64p(struct fixed31_32 ratio);
|
||||
uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
|
||||
void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
|
||||
const struct spl_scaler_data *data, bool enable_easf_v,
|
||||
bool enable_easf_h);
|
||||
|
||||
uint32_t spl_get_v_bf3_mode(struct fixed31_32 ratio);
|
||||
uint32_t spl_get_h_bf3_mode(struct fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain6(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain4(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing6(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing4(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt_maxval(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_slope(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt1_slope(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_slope(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_offset(int taps, struct fixed31_32 ratio);
|
||||
uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio);
|
||||
|
||||
#endif /* __DC_SPL_SCL_EASF_FILTERS_H__ */
|
||||
|
@ -3,6 +3,7 @@
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
#include "spl_debug.h"
|
||||
#include "dc_spl_scl_filters.h"
|
||||
//=========================================
|
||||
// <num_taps> = 2
|
||||
@ -1318,97 +1319,97 @@ static const uint16_t filter_8tap_64p_183[264] = {
|
||||
0x3FD4, 0x3F84, 0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4
|
||||
};
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_3tap_16p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_3tap_16p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_3tap_16p_149;
|
||||
else
|
||||
return filter_3tap_16p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_3tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_3tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_3tap_64p_149;
|
||||
else
|
||||
return filter_3tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_4tap_16p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_4tap_16p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_4tap_16p_149;
|
||||
else
|
||||
return filter_4tap_16p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_4tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_4tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_4tap_64p_149;
|
||||
else
|
||||
return filter_4tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_5tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_5tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_5tap_64p_149;
|
||||
else
|
||||
return filter_5tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_6tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_6tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_6tap_64p_149;
|
||||
else
|
||||
return filter_6tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_7tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_7tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_7tap_64p_149;
|
||||
else
|
||||
return filter_7tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_8tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_8tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_8tap_64p_149;
|
||||
else
|
||||
return filter_8tap_64p_183;
|
||||
@ -1424,7 +1425,7 @@ const uint16_t *spl_get_filter_2tap_64p(void)
|
||||
return filter_2tap_64p;
|
||||
}
|
||||
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (taps == 8)
|
||||
return spl_get_filter_8tap_64p(ratio);
|
||||
@ -1444,7 +1445,7 @@ const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio
|
||||
return NULL;
|
||||
else {
|
||||
/* should never happen, bug */
|
||||
BREAK_TO_DEBUGGER();
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -7,16 +7,16 @@
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_2tap_16p(void);
|
||||
const uint16_t *spl_get_filter_2tap_64p(void);
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio);
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
|
||||
|
||||
#endif /* __DC_SPL_SCL_FILTERS_H__ */
|
||||
|
@ -2,15 +2,15 @@
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "os_types.h"
|
||||
#include "dc_hw_types.h"
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(_bool) (void *)0
|
||||
#endif
|
||||
#include "include/fixed31_32.h" // fixed31_32 and related functions
|
||||
#ifndef __DC_SPL_TYPES_H__
|
||||
#define __DC_SPL_TYPES_H__
|
||||
|
||||
#include "spl_os_types.h" // swap
|
||||
#ifndef SPL_ASSERT
|
||||
#define SPL_ASSERT(_bool) ((void *)0)
|
||||
#endif
|
||||
#include "spl_fixpt31_32.h" // fixed31_32 and related functions
|
||||
|
||||
enum lb_memory_config {
|
||||
/* Enable all 3 pieces of memory */
|
||||
LB_MEMORY_CONFIG_0 = 0,
|
||||
@ -39,16 +39,16 @@ struct spl_rect {
|
||||
};
|
||||
|
||||
struct spl_ratios {
|
||||
struct fixed31_32 horz;
|
||||
struct fixed31_32 vert;
|
||||
struct fixed31_32 horz_c;
|
||||
struct fixed31_32 vert_c;
|
||||
struct spl_fixed31_32 horz;
|
||||
struct spl_fixed31_32 vert;
|
||||
struct spl_fixed31_32 horz_c;
|
||||
struct spl_fixed31_32 vert_c;
|
||||
};
|
||||
struct spl_inits {
|
||||
struct fixed31_32 h;
|
||||
struct fixed31_32 h_c;
|
||||
struct fixed31_32 v;
|
||||
struct fixed31_32 v_c;
|
||||
struct spl_fixed31_32 h;
|
||||
struct spl_fixed31_32 h_c;
|
||||
struct spl_fixed31_32 v;
|
||||
struct spl_fixed31_32 v_c;
|
||||
};
|
||||
|
||||
struct spl_taps {
|
||||
@ -409,10 +409,15 @@ struct dscl_prog_data {
|
||||
};
|
||||
|
||||
/* SPL input and output definitions */
|
||||
// SPL outputs struct
|
||||
struct spl_out {
|
||||
// SPL scratch struct
|
||||
struct spl_scratch {
|
||||
// Pack all SPL outputs in scl_data
|
||||
struct spl_scaler_data scl_data;
|
||||
};
|
||||
|
||||
/* SPL input and output definitions */
|
||||
// SPL outputs struct
|
||||
struct spl_out {
|
||||
// Pack all output need to program hw registers
|
||||
struct dscl_prog_data *dscl_prog_data;
|
||||
};
|
||||
@ -497,6 +502,8 @@ struct spl_in {
|
||||
struct spl_debug debug;
|
||||
bool is_fullscreen;
|
||||
bool is_hdr_on;
|
||||
int h_active;
|
||||
int v_active;
|
||||
};
|
||||
// end of SPL inputs
|
||||
|
||||
|
23
drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
Normal file
23
drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* Copyright © 1997-2004 Advanced Micro Devices, Inc. All rights reserved. */
|
||||
|
||||
#ifndef SPL_DEBUG_H
|
||||
#define SPL_DEBUG_H
|
||||
|
||||
#ifdef SPL_ASSERT
|
||||
#undef SPL_ASSERT
|
||||
#endif
|
||||
#define SPL_ASSERT(b)
|
||||
|
||||
#define SPL_ASSERT_CRITICAL(expr) do {if (expr)/* Do nothing */; } while (0)
|
||||
|
||||
#ifdef SPL_DALMSG
|
||||
#undef SPL_DALMSG
|
||||
#endif
|
||||
#define SPL_DALMSG(b)
|
||||
|
||||
#ifdef SPL_DAL_ASSERT_MSG
|
||||
#undef SPL_DAL_ASSERT_MSG
|
||||
#endif
|
||||
#define SPL_DAL_ASSERT_MSG(b, m)
|
||||
|
||||
#endif // SPL_DEBUG_H
|
518
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
Normal file
518
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
Normal file
@ -0,0 +1,518 @@
|
||||
/*
|
||||
* 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 "spl_fixpt31_32.h"
|
||||
|
||||
static const struct spl_fixed31_32 spl_fixpt_two_pi = { 26986075409LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_ln2 = { 2977044471LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_ln2_div_2 = { 1488522236LL };
|
||||
|
||||
static inline unsigned long long abs_i64(
|
||||
long long arg)
|
||||
{
|
||||
if (arg > 0)
|
||||
return (unsigned long long)arg;
|
||||
else
|
||||
return (unsigned long long)(-arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* @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 = spl_div64_u64_rem(dividend, divisor, remainder);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#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 spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator)
|
||||
{
|
||||
struct spl_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;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_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 long)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)spl_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;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_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 long)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)spl_fixpt_half.value);
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg)
|
||||
{
|
||||
/*
|
||||
* @note
|
||||
* Good idea to use Newton's method
|
||||
*/
|
||||
|
||||
ASSERT(arg.value);
|
||||
|
||||
return spl_fixpt_from_fraction(
|
||||
spl_fixpt_one.value,
|
||||
arg.value);
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 square;
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_one;
|
||||
|
||||
int n = 27;
|
||||
|
||||
struct spl_fixed31_32 arg_norm = arg;
|
||||
|
||||
if (spl_fixpt_le(
|
||||
spl_fixpt_two_pi,
|
||||
spl_fixpt_abs(arg))) {
|
||||
arg_norm = spl_fixpt_sub(
|
||||
arg_norm,
|
||||
spl_fixpt_mul_int(
|
||||
spl_fixpt_two_pi,
|
||||
(int)spl_div64_s64(
|
||||
arg_norm.value,
|
||||
spl_fixpt_two_pi.value)));
|
||||
}
|
||||
|
||||
square = spl_fixpt_sqr(arg_norm);
|
||||
|
||||
do {
|
||||
res = spl_fixpt_sub(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
square,
|
||||
res),
|
||||
n * (n - 1)));
|
||||
|
||||
n -= 2;
|
||||
} while (n > 2);
|
||||
|
||||
if (arg.value != arg_norm.value)
|
||||
res = spl_fixpt_div(
|
||||
spl_fixpt_mul(res, arg_norm),
|
||||
arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return spl_fixpt_mul(
|
||||
arg,
|
||||
spl_fixpt_sinc(arg));
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg)
|
||||
{
|
||||
/* TODO implement argument normalization */
|
||||
|
||||
const struct spl_fixed31_32 square = spl_fixpt_sqr(arg);
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_one;
|
||||
|
||||
int n = 26;
|
||||
|
||||
do {
|
||||
res = spl_fixpt_sub(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
square,
|
||||
res),
|
||||
n * (n - 1)));
|
||||
|
||||
n -= 2;
|
||||
} while (n != 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = exp(arg),
|
||||
* where abs(arg) < 1
|
||||
*
|
||||
* Calculated as Taylor series.
|
||||
*/
|
||||
static struct spl_fixed31_32 fixed31_32_exp_from_taylor_series(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned int n = 9;
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_from_fraction(
|
||||
n + 2,
|
||||
n + 1);
|
||||
/* TODO find correct res */
|
||||
|
||||
ASSERT(spl_fixpt_lt(arg, spl_fixpt_one));
|
||||
|
||||
do
|
||||
res = spl_fixpt_add(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
arg,
|
||||
res),
|
||||
n));
|
||||
while (--n != 1);
|
||||
|
||||
return spl_fixpt_add(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_mul(
|
||||
arg,
|
||||
res));
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_exp(struct spl_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 (spl_fixpt_le(
|
||||
spl_fixpt_ln2_div_2,
|
||||
spl_fixpt_abs(arg))) {
|
||||
int m = spl_fixpt_round(
|
||||
spl_fixpt_div(
|
||||
arg,
|
||||
spl_fixpt_ln2));
|
||||
|
||||
struct spl_fixed31_32 r = spl_fixpt_sub(
|
||||
arg,
|
||||
spl_fixpt_mul_int(
|
||||
spl_fixpt_ln2,
|
||||
m));
|
||||
|
||||
ASSERT(m != 0);
|
||||
|
||||
ASSERT(spl_fixpt_lt(
|
||||
spl_fixpt_abs(r),
|
||||
spl_fixpt_one));
|
||||
|
||||
if (m > 0)
|
||||
return spl_fixpt_shl(
|
||||
fixed31_32_exp_from_taylor_series(r),
|
||||
(unsigned char)m);
|
||||
else
|
||||
return spl_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 spl_fixpt_one;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 res = spl_fixpt_neg(spl_fixpt_one);
|
||||
/* TODO improve 1st estimation */
|
||||
|
||||
struct spl_fixed31_32 error;
|
||||
|
||||
ASSERT(arg.value > 0);
|
||||
/* TODO if arg is negative, return NaN */
|
||||
/* TODO if arg is zero, return -INF */
|
||||
|
||||
do {
|
||||
struct spl_fixed31_32 res1 = spl_fixpt_add(
|
||||
spl_fixpt_sub(
|
||||
res,
|
||||
spl_fixpt_one),
|
||||
spl_fixpt_div(
|
||||
arg,
|
||||
spl_fixpt_exp(res)));
|
||||
|
||||
error = spl_fixpt_sub(
|
||||
res,
|
||||
res1);
|
||||
|
||||
res = res1;
|
||||
/* TODO determine max_allowed_error based on quality of exp() */
|
||||
} while (abs_i64(error.value) > 100ULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
* spl_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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 4, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 3, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 2, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 0, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return clamp_ux_dy(arg.value, 0, 14, 1);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return clamp_ux_dy(arg.value, 0, 10, 1);
|
||||
}
|
||||
|
||||
int spl_fixpt_s4d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
if (arg.value < 0)
|
||||
return -(int)ux_dy(spl_fixpt_abs(arg).value, 4, 19);
|
||||
else
|
||||
return ux_dy(arg.value, 4, 19);
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct spl_fixed31_32 fixpt_value = spl_fixpt_zero;
|
||||
struct spl_fixed31_32 fixpt_int_value = spl_fixpt_zero;
|
||||
long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
|
||||
|
||||
fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
frac_mask = frac_mask << fractional_bits;
|
||||
fixpt_int_value.value = value & frac_mask;
|
||||
fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
fixpt_value.value |= fixpt_int_value.value;
|
||||
return fixpt_value;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct spl_fixed31_32 fixpt_value = spl_fixpt_from_int(int_value);
|
||||
|
||||
fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
return fixpt_value;
|
||||
}
|
546
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
Normal file
546
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SPL_FIXED31_32_H__
|
||||
#define __SPL_FIXED31_32_H__
|
||||
|
||||
#include "os_types.h"
|
||||
#include "spl_os_types.h" // swap
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(_bool) ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 9223372036854775807ll
|
||||
#endif
|
||||
#ifndef LLONG_MIN
|
||||
#define LLONG_MIN (-LLONG_MAX - 1ll)
|
||||
#endif
|
||||
|
||||
#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
|
||||
#ifndef LLONG_MIN
|
||||
#define LLONG_MIN (1LL<<63)
|
||||
#endif
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX (-1LL>>1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Arithmetic operations on real numbers
|
||||
* represented as fixed-point numbers.
|
||||
* There are: 1 bit for sign,
|
||||
* 31 bit for integer part,
|
||||
* 32 bits for fractional part.
|
||||
*
|
||||
* @note
|
||||
* Currently, overflows and underflows are asserted;
|
||||
* no special result returned.
|
||||
*/
|
||||
|
||||
struct spl_fixed31_32 {
|
||||
long long value;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Useful constants
|
||||
*/
|
||||
|
||||
static const struct spl_fixed31_32 spl_fixpt_zero = { 0 };
|
||||
static const struct spl_fixed31_32 spl_fixpt_epsilon = { 1LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_half = { 0x80000000LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_one = { 0x100000000LL };
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Initialization routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = numerator / denominator
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_from_int(int arg)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Unary operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = -arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_neg(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
res.value = -arg.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = abs(arg) := (arg >= 0) ? arg : -arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_abs(struct spl_fixed31_32 arg)
|
||||
{
|
||||
if (arg.value < 0)
|
||||
return spl_fixpt_neg(arg);
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary relational operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 < arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_lt(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value < arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 <= arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_le(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value <= arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 == arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_eq(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value == arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_min(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value <= arg2.value)
|
||||
return arg1;
|
||||
else
|
||||
return arg2;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_max(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value <= arg2.value)
|
||||
return arg2;
|
||||
else
|
||||
return arg1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* | min_value, when arg <= min_value
|
||||
* result = | arg, when min_value < arg < max_value
|
||||
* | max_value, when arg >= max_value
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_clamp(
|
||||
struct spl_fixed31_32 arg,
|
||||
struct spl_fixed31_32 min_value,
|
||||
struct spl_fixed31_32 max_value)
|
||||
{
|
||||
if (spl_fixpt_le(arg, min_value))
|
||||
return min_value;
|
||||
else if (spl_fixpt_le(max_value, arg))
|
||||
return max_value;
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary shift operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg << shift
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned char shift)
|
||||
{
|
||||
ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
|
||||
((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
|
||||
|
||||
arg.value = arg.value << shift;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg >> shift
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned char shift)
|
||||
{
|
||||
bool negative = arg.value < 0;
|
||||
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
arg.value = arg.value >> shift;
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary additive operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 + arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_add(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_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 spl_fixed31_32 spl_fixpt_add_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_add(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 - arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_sub(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_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 spl_fixed31_32 spl_fixpt_sub_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_sub(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary multiplicative operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 * arg2
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2);
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 * arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_mul_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_mul(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = square(arg) := arg * arg
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 / arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_div_int(struct spl_fixed31_32 arg1, long long arg2)
|
||||
{
|
||||
return spl_fixpt_from_fraction(arg1.value, spl_fixpt_from_int((int)arg2).value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 / arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_div(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return spl_fixpt_from_fraction(arg1.value, arg2.value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Reciprocal function
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = reciprocal(arg) := 1 / arg
|
||||
*
|
||||
* @note
|
||||
* No special actions taken in case argument is zero.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Trigonometric functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = sinc(arg) := sin(arg) / arg
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians,
|
||||
* internally it's normalized to [-2pi...2pi] range.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = sin(arg)
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians,
|
||||
* internally it's normalized to [-2pi...2pi] range.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = cos(arg)
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians
|
||||
* and should be in [-2pi...2pi] range -
|
||||
* passing arguments outside that range
|
||||
* will cause incorrect result!
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Transcendent functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = exp(arg)
|
||||
*
|
||||
* @note
|
||||
* Currently, function is verified for abs(arg) <= 1.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = log(arg)
|
||||
*
|
||||
* @note
|
||||
* Currently, abs(arg) should be less than 1.
|
||||
* No normalization is done.
|
||||
* Currently, no special actions taken
|
||||
* in case of invalid argument(s). Take care!
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Power function
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = pow(arg1, arg2)
|
||||
*
|
||||
* @note
|
||||
* Currently, abs(arg1) should be less than 1. Take care!
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_pow(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value == 0)
|
||||
return arg2.value == 0 ? spl_fixpt_one : spl_fixpt_zero;
|
||||
|
||||
return spl_fixpt_exp(
|
||||
spl_fixpt_mul(
|
||||
spl_fixpt_log(arg1),
|
||||
arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Rounding functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = floor(arg) := greatest integer lower than or equal to arg
|
||||
*/
|
||||
static inline int spl_fixpt_floor(struct spl_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
|
||||
*/
|
||||
static inline int spl_fixpt_round(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
|
||||
|
||||
const long long summand = spl_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
|
||||
*/
|
||||
static inline int spl_fixpt_ceil(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
|
||||
|
||||
const long long summand = spl_fixpt_one.value -
|
||||
spl_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
|
||||
* part. The same applies for u0d19, 0 bits from integer part and 19 bits from
|
||||
* fractional
|
||||
*/
|
||||
|
||||
unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg);
|
||||
|
||||
int spl_fixpt_s4d19(struct spl_fixed31_32 arg);
|
||||
|
||||
static inline struct spl_fixed31_32 spl_fixpt_truncate(struct spl_fixed31_32 arg, unsigned int frac_bits)
|
||||
{
|
||||
bool negative = arg.value < 0;
|
||||
|
||||
if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
|
||||
ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
return arg;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
arg.value &= (~0ULL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
return arg;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value, unsigned int integer_bits, unsigned int fractional_bits);
|
||||
struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits);
|
||||
|
||||
#endif
|
77
drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h
Normal file
77
drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
* Copyright 2019 Raptor Engineering, LLC
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SPL_OS_TYPES_H_
|
||||
#define _SPL_OS_TYPES_H_
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* general debug capabilities
|
||||
*
|
||||
*/
|
||||
// TODO: need backport
|
||||
#define SPL_BREAK_TO_DEBUGGER() ASSERT(0)
|
||||
|
||||
static inline uint64_t spl_div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
|
||||
{
|
||||
return div_u64_rem(dividend, divisor, remainder);
|
||||
}
|
||||
|
||||
static inline uint64_t spl_div_u64(uint64_t dividend, uint32_t divisor)
|
||||
{
|
||||
return div_u64(dividend, divisor);
|
||||
}
|
||||
|
||||
static inline uint64_t spl_div64_u64(uint64_t dividend, uint64_t divisor)
|
||||
{
|
||||
return div64_u64(dividend, divisor);
|
||||
}
|
||||
|
||||
static inline uint64_t spl_div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
|
||||
{
|
||||
return div64_u64_rem(dividend, divisor, remainder);
|
||||
}
|
||||
|
||||
static inline int64_t spl_div64_s64(int64_t dividend, int64_t divisor)
|
||||
{
|
||||
return div64_s64(dividend, divisor);
|
||||
}
|
||||
|
||||
#define spl_swap(a, b) \
|
||||
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
|
||||
|
||||
#ifndef spl_min
|
||||
#define spl_min(a, b) (((a) < (b)) ? (a):(b))
|
||||
#endif
|
||||
|
||||
#endif /* _SPL_OS_TYPES_H_ */
|
@ -531,4 +531,10 @@ static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigne
|
||||
return arg;
|
||||
}
|
||||
|
||||
struct fixed31_32 dc_fixpt_from_ux_dy(unsigned int value, unsigned int integer_bits, unsigned int fractional_bits);
|
||||
struct fixed31_32 dc_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user