Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,150 @@
#
# Copyright 2017 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.
#
#
# Makefile for the 'utils' sub-component of DAL.
# It provides the general basic services required by other DAL
# subcomponents.
dml_ccflags := $(CC_FLAGS_FPU)
dml_rcflags := $(CC_FLAGS_NO_FPU)
ifneq ($(CONFIG_FRAME_WARN),0)
ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y)
ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_COMPILE_TEST),yy)
frame_warn_limit := 4096
else
frame_warn_limit := 3072
endif
else
frame_warn_limit := 2048
endif
ifeq ($(call test-lt, $(CONFIG_FRAME_WARN), $(frame_warn_limit)),y)
frame_warn_flag := -Wframe-larger-than=$(frame_warn_limit)
endif
endif
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn314/display_mode_vba_314.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn314/display_rq_dlg_calc_314.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn314/dcn314_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_32.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_rq_dlg_calc_32.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn35/dcn35_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn351/dcn351_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn303/dcn303_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calcs.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_auto.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_ccflags) -Wno-tautological-compare
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dml1_frl_cap_chk.o := $(dml_ccflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_32.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn32/display_rq_dlg_calc_32.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn314/display_mode_vba_314.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn314/display_rq_dlg_calc_314.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn314/display_mode_vba_314.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn314/display_rq_dlg_calc_314.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn314/dcn314_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn35/dcn35_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn351/dcn351_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn303/dcn303_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_rcflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calcs.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_auto.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dml1_frl_cap_chk.o := $(dml_rcflags)
ifdef CONFIG_DRM_AMD_DC_FP
DML += display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o
DML += dml1_frl_cap_chk.o
DML += dcn10/dcn10_fpu.o
DML += dcn20/dcn20_fpu.o
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
DML += dcn30/dcn30_fpu.o dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o
DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o
DML += dcn314/display_mode_vba_314.o dcn314/display_rq_dlg_calc_314.o
DML += dcn32/display_mode_vba_32.o dcn32/display_rq_dlg_calc_32.o dcn32/display_mode_vba_util_32.o
DML += dcn31/dcn31_fpu.o
DML += dcn32/dcn32_fpu.o
DML += dcn321/dcn321_fpu.o
DML += dcn301/dcn301_fpu.o
DML += dcn302/dcn302_fpu.o
DML += dcn303/dcn303_fpu.o
DML += dcn314/dcn314_fpu.o
DML += dcn35/dcn35_fpu.o
DML += dcn351/dcn351_fpu.o
DML += dsc/rc_calc_fpu.o
DML += calcs/dcn_calcs.o calcs/dcn_calc_math.o calcs/dcn_calc_auto.o
endif
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
AMD_DISPLAY_FILES += $(AMD_DAL_DML)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,38 @@
/*
* Copyright 2017 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 _DCN_CALC_AUTO_H_
#define _DCN_CALC_AUTO_H_
#include "dc.h"
#include "dcn_calcs.h"
void scaler_settings_calculation(struct dcn_bw_internal_vars *v);
void mode_support_and_system_configuration(struct dcn_bw_internal_vars *v);
void display_pipe_configuration(struct dcn_bw_internal_vars *v);
void dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(
struct dcn_bw_internal_vars *v);
#endif /* _DCN_CALC_AUTO_H_ */
@@ -0,0 +1,145 @@
/*
* Copyright 2017 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 "os_types.h"
#include "dcn_calc_math.h"
#define isNaN(number) ((number) != (number))
/*
* NOTE:
* This file is gcc-parseable HW gospel, coming straight from HW engineers.
*
* It doesn't adhere to Linux kernel style and sometimes will do things in odd
* ways. Unless there is something clearly wrong with it the code should
* remain as-is as it provides us with a guarantee from HW that it is correct.
*/
float dcn_bw_mod(const float arg1, const float arg2)
{
if (isNaN(arg1))
return arg2;
if (isNaN(arg2))
return arg1;
return arg1 - arg1 * ((int) (arg1 / arg2));
}
float dcn_bw_min2(const float arg1, const float arg2)
{
if (isNaN(arg1))
return arg2;
if (isNaN(arg2))
return arg1;
return arg1 < arg2 ? arg1 : arg2;
}
unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_max2(const float arg1, const float arg2)
{
if (isNaN(arg1))
return arg2;
if (isNaN(arg2))
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_floor2(const float arg, const float significance)
{
ASSERT(significance != 0);
return ((int) (arg / significance)) * significance;
}
float dcn_bw_floor(const float arg)
{
return (float)((int)(arg));
}
float dcn_bw_ceil(const float arg)
{
return (float)((int)(arg + 0.99999f));
}
float dcn_bw_ceil2(const float arg, const float significance)
{
ASSERT(significance != 0);
return ((int) (arg / significance + 0.99999)) * significance;
}
float dcn_bw_max3(float v1, float v2, float v3)
{
return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
}
float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
{
return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
}
float dcn_bw_pow(float a, float exp)
{
float temp;
/*ASSERT(exp == (int)exp);*/
if ((int)exp == 0)
return 1;
temp = dcn_bw_pow(a, (float)((int)(exp / 2)));
if (((int)exp % 2) == 0) {
return temp * temp;
} else {
if ((int)exp > 0)
return a * temp * temp;
else
return (temp * temp) / a;
}
}
double dcn_bw_fabs(double a)
{
if (a > 0)
return (a);
else
return (-a);
}
float dcn_bw_log(float a, float b)
{
int * const exp_ptr = (int *)(&a);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
a = ((-1.0f / 3) * a + 2) * a - 2.0f / 3;
if (b > 2.00001 || b < 1.99999)
return (a + log_2) / dcn_bw_log(b, 2);
else
return (a + log_2);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,566 @@
/*
* Copyright 2017 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 __DC_FEATURES_H__
#define __DC_FEATURES_H__
// local features
#define DC__PRESENT 1
#define DC__PRESENT__1 1
#define DC__NUM_DPP 4
/**
* @DC__VOLTAGE_STATES:
*
* Define the maximum amount of states supported by the ASIC. Every ASIC has a
* specific number of states; this macro defines the maximum number of states.
*/
#define DC__VOLTAGE_STATES 40
#define DC__NUM_DPP__4 1
#define DC__NUM_DPP__0_PRESENT 1
#define DC__NUM_DPP__1_PRESENT 1
#define DC__NUM_DPP__2_PRESENT 1
#define DC__NUM_DPP__3_PRESENT 1
#define DC__NUM_DPP__MAX 8
#define DC__NUM_DPP__MAX__8 1
#define DC__PIPE_10BIT 0
#define DC__PIPE_10BIT__0 1
#define DC__PIPE_10BIT__MAX 1
#define DC__PIPE_10BIT__MAX__1 1
#define DC__NUM_OPP 4
#define DC__NUM_OPP__4 1
#define DC__NUM_OPP__0_PRESENT 1
#define DC__NUM_OPP__1_PRESENT 1
#define DC__NUM_OPP__2_PRESENT 1
#define DC__NUM_OPP__3_PRESENT 1
#define DC__NUM_OPP__MAX 6
#define DC__NUM_OPP__MAX__6 1
#define DC__NUM_DSC 0
#define DC__NUM_DSC__0 1
#define DC__NUM_DSC__MAX 6
#define DC__NUM_DSC__MAX__6 1
#define DC__NUM_ABM 1
#define DC__NUM_ABM__1 1
#define DC__NUM_ABM__0_PRESENT 1
#define DC__NUM_ABM__MAX 2
#define DC__NUM_ABM__MAX__2 1
#define DC__ODM_PRESENT 0
#define DC__ODM_PRESENT__0 1
#define DC__NUM_OTG 4
#define DC__NUM_OTG__4 1
#define DC__NUM_OTG__0_PRESENT 1
#define DC__NUM_OTG__1_PRESENT 1
#define DC__NUM_OTG__2_PRESENT 1
#define DC__NUM_OTG__3_PRESENT 1
#define DC__NUM_OTG__MAX 6
#define DC__NUM_OTG__MAX__6 1
#define DC__NUM_DWB 2
#define DC__NUM_DWB__2 1
#define DC__NUM_DWB__0_PRESENT 1
#define DC__NUM_DWB__1_PRESENT 1
#define DC__NUM_DWB__MAX 2
#define DC__NUM_DWB__MAX__2 1
#define DC__NUM_DIG 4
#define DC__NUM_DIG__4 1
#define DC__NUM_DIG__0_PRESENT 1
#define DC__NUM_DIG__1_PRESENT 1
#define DC__NUM_DIG__2_PRESENT 1
#define DC__NUM_DIG__3_PRESENT 1
#define DC__NUM_DIG__MAX 6
#define DC__NUM_DIG__MAX__6 1
#define DC__NUM_AUX 4
#define DC__NUM_AUX__4 1
#define DC__NUM_AUX__0_PRESENT 1
#define DC__NUM_AUX__1_PRESENT 1
#define DC__NUM_AUX__2_PRESENT 1
#define DC__NUM_AUX__3_PRESENT 1
#define DC__NUM_AUX__MAX 6
#define DC__NUM_AUX__MAX__6 1
#define DC__NUM_AUDIO_STREAMS 4
#define DC__NUM_AUDIO_STREAMS__4 1
#define DC__NUM_AUDIO_STREAMS__0_PRESENT 1
#define DC__NUM_AUDIO_STREAMS__1_PRESENT 1
#define DC__NUM_AUDIO_STREAMS__2_PRESENT 1
#define DC__NUM_AUDIO_STREAMS__3_PRESENT 1
#define DC__NUM_AUDIO_STREAMS__MAX 8
#define DC__NUM_AUDIO_STREAMS__MAX__8 1
#define DC__NUM_AUDIO_ENDPOINTS 6
#define DC__NUM_AUDIO_ENDPOINTS__6 1
#define DC__NUM_AUDIO_ENDPOINTS__0_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__1_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__2_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__3_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__4_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__5_PRESENT 1
#define DC__NUM_AUDIO_ENDPOINTS__MAX 8
#define DC__NUM_AUDIO_ENDPOINTS__MAX__8 1
#define DC__NUM_AUDIO_INPUT_STREAMS 0
#define DC__NUM_AUDIO_INPUT_STREAMS__0 1
#define DC__NUM_AUDIO_INPUT_STREAMS__MAX 8
#define DC__NUM_AUDIO_INPUT_STREAMS__MAX__8 1
#define DC__NUM_AUDIO_INPUT_ENDPOINTS 0
#define DC__NUM_AUDIO_INPUT_ENDPOINTS__0 1
#define DC__NUM_AUDIO_INPUT_ENDPOINTS__MAX 8
#define DC__NUM_AUDIO_INPUT_ENDPOINTS__MAX__8 1
#define DC__NUM_CURSOR 1
#define DC__NUM_CURSOR__1 1
#define DC__NUM_CURSOR__0_PRESENT 1
#define DC__NUM_CURSOR__MAX 2
#define DC__NUM_CURSOR__MAX__2 1
#define DC__DIGITAL_BYPASS_PRESENT 0
#define DC__DIGITAL_BYPASS_PRESENT__0 1
#define DC__HCID_HWMAJVER 1
#define DC__HCID_HWMAJVER__1 1
#define DC__HCID_HWMINVER 0
#define DC__HCID_HWMINVER__0 1
#define DC__HCID_HWREV 0
#define DC__HCID_HWREV__0 1
#define DC__ROMSTRAP_PRESENT 0
#define DC__ROMSTRAP_PRESENT__0 1
#define DC__NUM_RBBMIF_DECODES 30
#define DC__NUM_RBBMIF_DECODES__30 1
#define DC__NUM_DBG_REGS 36
#define DC__NUM_DBG_REGS__36 1
#define DC__NUM_PIPES_UNDERLAY 0
#define DC__NUM_PIPES_UNDERLAY__0 1
#define DC__NUM_PIPES_UNDERLAY__MAX 2
#define DC__NUM_PIPES_UNDERLAY__MAX__2 1
#define DC__NUM_VCE_ENGINE 1
#define DC__NUM_VCE_ENGINE__1 1
#define DC__NUM_VCE_ENGINE__0_PRESENT 1
#define DC__NUM_VCE_ENGINE__MAX 2
#define DC__NUM_VCE_ENGINE__MAX__2 1
#define DC__OTG_EXTERNAL_SYNC_PRESENT 0
#define DC__OTG_EXTERNAL_SYNC_PRESENT__0 1
#define DC__OTG_CRC_PRESENT 1
#define DC__OTG_CRC_PRESENT__1 1
#define DC__VIP_PRESENT 0
#define DC__VIP_PRESENT__0 1
#define DC__DTMTEST_PRESENT 0
#define DC__DTMTEST_PRESENT__0 1
#define DC__POWER_GATE_PRESENT 1
#define DC__POWER_GATE_PRESENT__1 1
#define DC__MEM_PG 1
#define DC__MEM_PG__1 1
#define DC__FMT_SRC_SEL_PRESENT 0
#define DC__FMT_SRC_SEL_PRESENT__0 1
#define DC__DIG_FEATURES__HDMI_PRESENT 1
#define DC__DIG_FEATURES__HDMI_PRESENT__1 1
#define DC__DIG_FEATURES__DP_PRESENT 1
#define DC__DIG_FEATURES__DP_PRESENT__1 1
#define DC__DIG_FEATURES__DP_MST_PRESENT 1
#define DC__DIG_FEATURES__DP_MST_PRESENT__1 1
#define DC__DIG_LP_FEATURES__HDMI_PRESENT 0
#define DC__DIG_LP_FEATURES__HDMI_PRESENT__0 1
#define DC__DIG_LP_FEATURES__DP_PRESENT 1
#define DC__DIG_LP_FEATURES__DP_PRESENT__1 1
#define DC__DIG_LP_FEATURES__DP_MST_PRESENT 0
#define DC__DIG_LP_FEATURES__DP_MST_PRESENT__0 1
#define DC__DIG_RESYNC_FIFO_SIZE 14
#define DC__DIG_RESYNC_FIFO_SIZE__14 1
#define DC__DIG_RESYNC_FIFO_SIZE__0_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__1_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__2_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__3_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__4_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__5_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__6_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__7_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__8_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__9_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__10_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__11_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__12_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__13_PRESENT 1
#define DC__DIG_RESYNC_FIFO_SIZE__MAX 16
#define DC__DIG_RESYNC_FIFO_SIZE__MAX__16 1
#define DC__DAC_RESYNC_FIFO_SIZE 12
#define DC__DAC_RESYNC_FIFO_SIZE__12 1
#define DC__DAC_RESYNC_FIFO_SIZE__0_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__1_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__2_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__3_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__4_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__5_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__6_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__7_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__8_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__9_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__10_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__11_PRESENT 1
#define DC__DAC_RESYNC_FIFO_SIZE__MAX 16
#define DC__DAC_RESYNC_FIFO_SIZE__MAX__16 1
#define DC__DVO_RESYNC_FIFO_SIZE 12
#define DC__DVO_RESYNC_FIFO_SIZE__12 1
#define DC__DVO_RESYNC_FIFO_SIZE__0_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__1_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__2_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__3_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__4_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__5_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__6_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__7_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__8_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__9_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__10_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__11_PRESENT 1
#define DC__DVO_RESYNC_FIFO_SIZE__MAX 16
#define DC__DVO_RESYNC_FIFO_SIZE__MAX__16 1
#define DC__MEM_CDC_PRESENT 1
#define DC__MEM_CDC_PRESENT__1 1
#define DC__NUM_HPD 4
#define DC__NUM_HPD__4 1
#define DC__NUM_HPD__0_PRESENT 1
#define DC__NUM_HPD__1_PRESENT 1
#define DC__NUM_HPD__2_PRESENT 1
#define DC__NUM_HPD__3_PRESENT 1
#define DC__NUM_HPD__MAX 6
#define DC__NUM_HPD__MAX__6 1
#define DC__NUM_DDC_PAIRS 4
#define DC__NUM_DDC_PAIRS__4 1
#define DC__NUM_DDC_PAIRS__0_PRESENT 1
#define DC__NUM_DDC_PAIRS__1_PRESENT 1
#define DC__NUM_DDC_PAIRS__2_PRESENT 1
#define DC__NUM_DDC_PAIRS__3_PRESENT 1
#define DC__NUM_DDC_PAIRS__MAX 6
#define DC__NUM_DDC_PAIRS__MAX__6 1
#define DC__NUM_AUDIO_PLL 0
#define DC__NUM_AUDIO_PLL__0 1
#define DC__NUM_AUDIO_PLL__MAX 2
#define DC__NUM_AUDIO_PLL__MAX__2 1
#define DC__NUM_PIXEL_PLL 1
#define DC__NUM_PIXEL_PLL__1 1
#define DC__NUM_PIXEL_PLL__0_PRESENT 1
#define DC__NUM_PIXEL_PLL__MAX 4
#define DC__NUM_PIXEL_PLL__MAX__4 1
#define DC__NUM_CASCADED_PLL 0
#define DC__NUM_CASCADED_PLL__0 1
#define DC__NUM_CASCADED_PLL__MAX 3
#define DC__NUM_CASCADED_PLL__MAX__3 1
#define DC__PIXCLK_FROM_PHYPLL 1
#define DC__PIXCLK_FROM_PHYPLL__1 1
#define DC__NB_STUTTER_MODE_PRESENT 0
#define DC__NB_STUTTER_MODE_PRESENT__0 1
#define DC__I2S0_AND_SPDIF0_PRESENT 0
#define DC__I2S0_AND_SPDIF0_PRESENT__0 1
#define DC__I2S1_PRESENT 0
#define DC__I2S1_PRESENT__0 1
#define DC__SPDIF1_PRESENT 0
#define DC__SPDIF1_PRESENT__0 1
#define DC__DSI_PRESENT 0
#define DC__DSI_PRESENT__0 1
#define DC__DACA_PRESENT 0
#define DC__DACA_PRESENT__0 1
#define DC__DACB_PRESENT 0
#define DC__DACB_PRESENT__0 1
#define DC__NUM_PIPES 4
#define DC__NUM_PIPES__4 1
#define DC__NUM_PIPES__0_PRESENT 1
#define DC__NUM_PIPES__1_PRESENT 1
#define DC__NUM_PIPES__2_PRESENT 1
#define DC__NUM_PIPES__3_PRESENT 1
#define DC__NUM_PIPES__MAX 6
#define DC__NUM_PIPES__MAX__6 1
#define DC__NUM_DIG_LP 0
#define DC__NUM_DIG_LP__0 1
#define DC__NUM_DIG_LP__MAX 2
#define DC__NUM_DIG_LP__MAX__2 1
#define DC__DPDEBUG_PRESENT 0
#define DC__DPDEBUG_PRESENT__0 1
#define DC__DISPLAY_WB_PRESENT 1
#define DC__DISPLAY_WB_PRESENT__1 1
#define DC__NUM_CWB 0
#define DC__NUM_CWB__0 1
#define DC__NUM_CWB__MAX 2
#define DC__NUM_CWB__MAX__2 1
#define DC__MVP_PRESENT 0
#define DC__MVP_PRESENT__0 1
#define DC__DVO_PRESENT 0
#define DC__DVO_PRESENT__0 1
#define DC__ABM_PRESENT 0
#define DC__ABM_PRESENT__0 1
#define DC__BPHYC_PLL_PRESENT 0
#define DC__BPHYC_PLL_PRESENT__0 1
#define DC__BPHYC_UNIPHY_PRESENT 0
#define DC__BPHYC_UNIPHY_PRESENT__0 1
#define DC__PHY_BROADCAST_PRESENT 0
#define DC__PHY_BROADCAST_PRESENT__0 1
#define DC__NUM_OF_DCRX_SD 0
#define DC__NUM_OF_DCRX_SD__0 1
#define DC__DVO_17BIT_MAPPING 0
#define DC__DVO_17BIT_MAPPING__0 1
#define DC__AVSYNC_PRESENT 0
#define DC__AVSYNC_PRESENT__0 1
#define DC__NUM_OF_DCRX_PORTS 0
#define DC__NUM_OF_DCRX_PORTS__0 1
#define DC__NUM_OF_DCRX_PORTS__MAX 1
#define DC__NUM_OF_DCRX_PORTS__MAX__1 1
#define DC__NUM_PHY 4
#define DC__NUM_PHY__4 1
#define DC__NUM_PHY__0_PRESENT 1
#define DC__NUM_PHY__1_PRESENT 1
#define DC__NUM_PHY__2_PRESENT 1
#define DC__NUM_PHY__3_PRESENT 1
#define DC__NUM_PHY__MAX 7
#define DC__NUM_PHY__MAX__7 1
#define DC__NUM_PHY_LP 0
#define DC__NUM_PHY_LP__0 1
#define DC__NUM_PHY_LP__MAX 2
#define DC__NUM_PHY_LP__MAX__2 1
#define DC__SYNC_CELL vid_sync_gf14lpp
#define DC__SYNC_CELL__VID_SYNC_GF14LPP 1
#define DC__USE_NEW_VSS 1
#define DC__USE_NEW_VSS__1 1
#define DC__SYNC_CELL_DISPCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DISPCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DVOCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DVOCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_PIXCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_PIXCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_SYMCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_SYMCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DPPCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DPPCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DPREFCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DPREFCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_REFCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_REFCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_PCIE_REFCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_PCIE_REFCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_MVPCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_MVPCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_SCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_SCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DCEFCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DCEFCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_AMCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_AMCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DSICLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DSICLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_BYTECLK_NUM_LATCHES 6
#define DC__SYNC_CELL_BYTECLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_ESCCLK_NUM_LATCHES 6
#define DC__SYNC_CELL_ESCCLK_NUM_LATCHES__6 1
#define DC__SYNC_CELL_DB_CLK_NUM_LATCHES 6
#define DC__SYNC_CELL_DB_CLK_NUM_LATCHES__6 1
#define UNIPHYA_PRESENT 1
#define UNIPHYA_PRESENT__1 1
#define DC__UNIPHYA_PRESENT 1
#define DC__UNIPHYA_PRESENT__1 1
#define UNIPHYB_PRESENT 1
#define UNIPHYB_PRESENT__1 1
#define DC__UNIPHYB_PRESENT 1
#define DC__UNIPHYB_PRESENT__1 1
#define UNIPHYC_PRESENT 1
#define UNIPHYC_PRESENT__1 1
#define DC__UNIPHYC_PRESENT 1
#define DC__UNIPHYC_PRESENT__1 1
#define UNIPHYD_PRESENT 1
#define UNIPHYD_PRESENT__1 1
#define DC__UNIPHYD_PRESENT 1
#define DC__UNIPHYD_PRESENT__1 1
#define UNIPHYE_PRESENT 0
#define UNIPHYE_PRESENT__0 1
#define DC__UNIPHYE_PRESENT 0
#define DC__UNIPHYE_PRESENT__0 1
#define UNIPHYF_PRESENT 0
#define UNIPHYF_PRESENT__0 1
#define DC__UNIPHYF_PRESENT 0
#define DC__UNIPHYF_PRESENT__0 1
#define UNIPHYG_PRESENT 0
#define UNIPHYG_PRESENT__0 1
#define DC__UNIPHYG_PRESENT 0
#define DC__UNIPHYG_PRESENT__0 1
#define DC__TMDS_LINK tmds_link_dual
#define DC__TMDS_LINK__TMDS_LINK_DUAL 1
#define DC__WBSCL_PIXBW 8
#define DC__WBSCL_PIXBW__8 1
#define DC__DWB_CSC_PRESENT 0
#define DC__DWB_CSC_PRESENT__0 1
#define DC__DWB_LUMA_SCL_PRESENT 0
#define DC__DWB_LUMA_SCL_PRESENT__0 1
#define DC__DENTIST_INTERFACE_PRESENT 1
#define DC__DENTIST_INTERFACE_PRESENT__1 1
#define DC__GENERICA_PRESENT 1
#define DC__GENERICA_PRESENT__1 1
#define DC__GENERICB_PRESENT 1
#define DC__GENERICB_PRESENT__1 1
#define DC__GENERICC_PRESENT 0
#define DC__GENERICC_PRESENT__0 1
#define DC__GENERICD_PRESENT 0
#define DC__GENERICD_PRESENT__0 1
#define DC__GENERICE_PRESENT 0
#define DC__GENERICE_PRESENT__0 1
#define DC__GENERICF_PRESENT 0
#define DC__GENERICF_PRESENT__0 1
#define DC__GENERICG_PRESENT 0
#define DC__GENERICG_PRESENT__0 1
#define DC__UNIPHY_VOLTAGE_MODE 1
#define DC__UNIPHY_VOLTAGE_MODE__1 1
#define DC__BLON_TYPE dedicated
#define DC__BLON_TYPE__DEDICATED 1
#define DC__UNIPHY_STAGGER_CH_PRESENT 1
#define DC__UNIPHY_STAGGER_CH_PRESENT__1 1
#define DC__XDMA_PRESENT 0
#define DC__XDMA_PRESENT__0 1
#define XDMA__PRESENT 0
#define XDMA__PRESENT__0 1
#define DC__DP_MEM_PG 0
#define DC__DP_MEM_PG__0 1
#define DP__MEM_PG 0
#define DP__MEM_PG__0 1
#define DC__AFMT_MEM_PG 0
#define DC__AFMT_MEM_PG__0 1
#define AFMT__MEM_PG 0
#define AFMT__MEM_PG__0 1
#define DC__HDMI_MEM_PG 0
#define DC__HDMI_MEM_PG__0 1
#define HDMI__MEM_PG 0
#define HDMI__MEM_PG__0 1
#define DC__I2C_MEM_PG 0
#define DC__I2C_MEM_PG__0 1
#define I2C__MEM_PG 0
#define I2C__MEM_PG__0 1
#define DC__DSCL_MEM_PG 0
#define DC__DSCL_MEM_PG__0 1
#define DSCL__MEM_PG 0
#define DSCL__MEM_PG__0 1
#define DC__CM_MEM_PG 0
#define DC__CM_MEM_PG__0 1
#define CM__MEM_PG 0
#define CM__MEM_PG__0 1
#define DC__OBUF_MEM_PG 0
#define DC__OBUF_MEM_PG__0 1
#define OBUF__MEM_PG 0
#define OBUF__MEM_PG__0 1
#define DC__WBIF_MEM_PG 1
#define DC__WBIF_MEM_PG__1 1
#define WBIF__MEM_PG 1
#define WBIF__MEM_PG__1 1
#define DC__VGA_MEM_PG 0
#define DC__VGA_MEM_PG__0 1
#define VGA__MEM_PG 0
#define VGA__MEM_PG__0 1
#define DC__FMT_MEM_PG 0
#define DC__FMT_MEM_PG__0 1
#define FMT__MEM_PG 0
#define FMT__MEM_PG__0 1
#define DC__ODM_MEM_PG 0
#define DC__ODM_MEM_PG__0 1
#define ODM__MEM_PG 0
#define ODM__MEM_PG__0 1
#define DC__DSI_MEM_PG 0
#define DC__DSI_MEM_PG__0 1
#define DSI__MEM_PG 0
#define DSI__MEM_PG__0 1
#define DC__AZ_MEM_PG 1
#define DC__AZ_MEM_PG__1 1
#define AZ__MEM_PG 1
#define AZ__MEM_PG__1 1
#define DC__WBSCL_MEM1P1024X64QS_MEM_PG 1
#define DC__WBSCL_MEM1P1024X64QS_MEM_PG__1 1
#define WBSCL_MEM1P1024X64QS__MEM_PG 1
#define WBSCL_MEM1P1024X64QS__MEM_PG__1 1
#define DC__WBSCL_MEM1P528X64QS_MEM_PG 1
#define DC__WBSCL_MEM1P528X64QS_MEM_PG__1 1
#define WBSCL_MEM1P528X64QS__MEM_PG 1
#define WBSCL_MEM1P528X64QS__MEM_PG__1 1
#define DC__DMCU_MEM1P1024X32BQS_MEM_PG 1
#define DC__DMCU_MEM1P1024X32BQS_MEM_PG__1 1
#define DMCU_MEM1P1024X32BQS__MEM_PG 1
#define DMCU_MEM1P1024X32BQS__MEM_PG__1 1
#define DC__HUBBUB_SDP_TAG_INT_MEM_PG 0
#define DC__HUBBUB_SDP_TAG_INT_MEM_PG__0 1
#define HUBBUB_SDP_TAG_INT__MEM_PG 0
#define HUBBUB_SDP_TAG_INT__MEM_PG__0 1
#define DC__HUBBUB_SDP_TAG_EXT_MEM_PG 0
#define DC__HUBBUB_SDP_TAG_EXT_MEM_PG__0 1
#define HUBBUB_SDP_TAG_EXT__MEM_PG 0
#define HUBBUB_SDP_TAG_EXT__MEM_PG__0 1
#define DC__HUBBUB_RET_ZERO_MEM_PG 0
#define DC__HUBBUB_RET_ZERO_MEM_PG__0 1
#define HUBBUB_RET_ZERO__MEM_PG 0
#define HUBBUB_RET_ZERO__MEM_PG__0 1
#define DC__HUBBUB_RET_ROB_MEM_PG 0
#define DC__HUBBUB_RET_ROB_MEM_PG__0 1
#define HUBBUB_RET_ROB__MEM_PG 0
#define HUBBUB_RET_ROB__MEM_PG__0 1
#define DC__HUBPRET_CUR_ROB_MEM_PG 0
#define DC__HUBPRET_CUR_ROB_MEM_PG__0 1
#define HUBPRET_CUR_ROB__MEM_PG 0
#define HUBPRET_CUR_ROB__MEM_PG__0 1
#define DC__HUBPRET_CUR_CDC_MEM_PG 0
#define DC__HUBPRET_CUR_CDC_MEM_PG__0 1
#define HUBPRET_CUR_CDC__MEM_PG 0
#define HUBPRET_CUR_CDC__MEM_PG__0 1
#define DC__HUBPREQ_MPTE_MEM_PG 0
#define DC__HUBPREQ_MPTE_MEM_PG__0 1
#define HUBPREQ_MPTE__MEM_PG 0
#define HUBPREQ_MPTE__MEM_PG__0 1
#define DC__HUBPREQ_META_MEM_PG 0
#define DC__HUBPREQ_META_MEM_PG__0 1
#define HUBPREQ_META__MEM_PG 0
#define HUBPREQ_META__MEM_PG__0 1
#define DC__HUBPREQ_DPTE_MEM_PG 0
#define DC__HUBPREQ_DPTE_MEM_PG__0 1
#define HUBPREQ_DPTE__MEM_PG 0
#define HUBPREQ_DPTE__MEM_PG__0 1
#define DC__HUBPRET_DET_MEM_PG 0
#define DC__HUBPRET_DET_MEM_PG__0 1
#define HUBPRET_DET__MEM_PG 0
#define HUBPRET_DET__MEM_PG__0 1
#define DC__HUBPRET_PIX_CDC_MEM_PG 0
#define DC__HUBPRET_PIX_CDC_MEM_PG__0 1
#define HUBPRET_PIX_CDC__MEM_PG 0
#define HUBPRET_PIX_CDC__MEM_PG__0 1
#define DC__TOP_BLKS__DCCG 1
#define DC__TOP_BLKS__DCHUBBUB 1
#define DC__TOP_BLKS__DCHUBP 1
#define DC__TOP_BLKS__HDA 1
#define DC__TOP_BLKS__DIO 1
#define DC__TOP_BLKS__DCIO 1
#define DC__TOP_BLKS__DMU 1
#define DC__TOP_BLKS__DPP 1
#define DC__TOP_BLKS__MPC 1
#define DC__TOP_BLKS__OPP 1
#define DC__TOP_BLKS__OPTC 1
#define DC__TOP_BLKS__MMHUBBUB 1
#define DC__TOP_BLKS__WB 1
#define DC__TOP_BLKS__MAX 13
#define DC__TOP_BLKS__MAX__13 1
#define DC__DCHUBP_DPP_SF_PIXEL_CREDITS 9
#define DC__DCHUBP_DPP_SF_PIXEL_CREDITS__9 1
#define DC__DPP_MPC_SF_PIXEL_CREDITS 9
#define DC__DPP_MPC_SF_PIXEL_CREDITS__9 1
#define DC__MPC_OPP_SF_PIXEL_CREDITS 8
#define DC__MPC_OPP_SF_PIXEL_CREDITS__8 1
#define DC__OPP_OPTC_SF_PIXEL_CREDITS 8
#define DC__OPP_OPTC_SF_PIXEL_CREDITS__8 1
#define DC__SFR_SFT_ROUND_TRIP_DELAY 5
#define DC__SFR_SFT_ROUND_TRIP_DELAY__5 1
#define DC__REPEATER_PROJECT_MAX 8
#define DC__REPEATER_PROJECT_MAX__8 1
#define DC__SURFACE_422_CAPABLE 0
#define DC__SURFACE_422_CAPABLE__0 1
#endif
@@ -0,0 +1,159 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2021 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 "dcn10/dcn10_resource.h"
#include "dcn10_fpu.h"
#include "resource.h"
#include "amdgpu_dm/dc_fpu.h"
/**
* DOC: DCN10 FPU manipulation Overview
*
* The DCN architecture relies on FPU operations, which require special
* compilation flags and the use of kernel_fpu_begin/end functions; ideally, we
* want to avoid spreading FPU access across multiple files. With this idea in
* mind, this file aims to centralize DCN10 functions that require FPU access
* in a single place. Code in this file follows the following code pattern:
*
* 1. Functions that use FPU operations should be isolated in static functions.
* 2. The FPU functions should have the noinline attribute to ensure anything
* that deals with FP register is contained within this call.
* 3. All function that needs to be accessed outside this file requires a
* public interface that not uses any FPU reference.
* 4. Developers **must not** use DC_FP_START/END in this file, but they need
* to ensure that the caller invokes it before access any function available
* in this file. For this reason, public functions in this file must invoke
* dc_assert_fp_enabled();
*
* Let's expand a little bit more the idea in the code pattern. To fully
* isolate FPU operations in a single place, we must avoid situations where
* compilers spill FP values to registers due to FP enable in a specific C
* file. Note that even if we isolate all FPU functions in a single file and
* call its interface from other files, the compiler might enable the use of
* FPU before we call DC_FP_START. Nevertheless, it is the programmer's
* responsibility to invoke DC_FP_START/END in the correct place. To highlight
* situations where developers forgot to use the FP protection before calling
* the DC FPU interface functions, we introduce a helper that checks if the
* function is invoked under FP protection. If not, it will trigger a kernel
* warning.
*/
struct _vcs_dpi_ip_params_st dcn1_0_ip = {
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = 164,
.dpte_buffer_size_in_pte_reqs_luma = 42,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.pte_enable = 1,
.pte_chunk_size_kbytes = 2,
.meta_chunk_size_kbytes = 2,
.writeback_chunk_size_kbytes = 2,
.line_buffer_size_bits = 589824,
.max_line_buffer_lines = 12,
.IsLineBufferBppFixed = 0,
.LineBufferFixedBpp = (unsigned int)-1,
.writeback_luma_buffer_size_kbytes = 12,
.writeback_chroma_buffer_size_kbytes = 8,
.max_num_dpp = 4,
.max_num_wb = 2,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 4,
.max_vscl_ratio = 4,
.hscl_mults = 4,
.vscl_mults = 4,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dispclk_ramp_margin_percent = 1,
.underscan_factor = 1.10,
.min_vblank_lines = 14,
.dppclk_delay_subtotal = 90,
.dispclk_delay_subtotal = 42,
.dcfclk_cstate_latency = 10,
.max_inter_dcn_tile_repeaters = 8,
.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0,
.bug_forcing_LC_req_same_size_fixed = 0,
};
struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = {
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.urgent_latency_us = 4.0,
.writeback_latency_us = 12.0,
.ideal_dram_bw_after_urgent_percent = 80.0,
.max_request_size_bytes = 256,
.downspread_percent = 0.5,
.dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192,
.round_trip_ping_latency_dcfclk_cycles = 128,
.urgent_out_of_order_return_per_channel_bytes = 256,
.channel_interleave_bytes = 256,
.num_banks = 8,
.num_chans = 2,
.vmm_page_size_bytes = 4096,
.dram_clock_change_latency_us = 17.0,
.writeback_dram_clock_change_latency_us = 23.0,
.return_bus_width_bytes = 64,
};
void dcn10_resource_construct_fp(struct dc *dc)
{
dc_assert_fp_enabled();
if (dc->ctx->dce_version == DCN_VERSION_1_01) {
struct dcn_soc_bounding_box *dcn_soc = dc->dcn_soc;
struct dcn_ip_params *dcn_ip = dc->dcn_ip;
struct display_mode_lib *dml = &dc->dml;
dml->ip.max_num_dpp = 3;
/* TODO how to handle 23.84? */
dcn_soc->dram_clock_change_latency = 23;
dcn_ip->max_num_dpp = 3;
}
if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev)) {
dc->dcn_soc->urgent_latency = 3;
dc->debug.disable_dmcu = true;
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 41.60f;
}
dc->dcn_soc->number_of_channels = dc->ctx->asic_id.vram_width / ddr4_dram_width;
ASSERT(dc->dcn_soc->number_of_channels < 3);
if (dc->dcn_soc->number_of_channels == 0)/*old sbios bug*/
dc->dcn_soc->number_of_channels = 2;
if (dc->dcn_soc->number_of_channels == 1) {
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 19.2f;
dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = 17.066f;
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = 14.933f;
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 12.8f;
if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev))
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 20.80f;
}
}
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2021 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 __DCN10_FPU_H__
#define __DCN10_FPU_H__
void dcn10_resource_construct_fp(struct dc *dc);
#endif /* __DCN10_FPU_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2021 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 "core_types.h"
#ifndef __DCN20_FPU_H__
#define __DCN20_FPU_H__
void dcn20_populate_dml_writeback_from_context(struct dc *dc,
struct resource_context *res_ctx,
display_e2e_pipe_params_st *pipes);
void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt, int i);
void dcn20_calculate_dlg_params(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
int dcn20_populate_dml_pipes_from_context(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
void dcn20_calculate_wm(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *out_pipe_cnt,
int *pipe_split_from,
int vlevel,
enum dc_validate_mode validate_mode);
void dcn20_cap_soc_clocks(struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table max_clocks);
void dcn20_update_bounding_box(struct dc *dc,
struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table *max_clocks,
unsigned int *uclk_states,
unsigned int num_states);
void dcn20_patch_bounding_box(struct dc *dc,
struct _vcs_dpi_soc_bounding_box_st *bb);
bool dcn20_validate_bandwidth_fp(struct dc *dc, struct dc_state *context,
enum dc_validate_mode validate_mode, display_e2e_pipe_params_st *pipes);
void dcn20_fpu_set_wm_ranges(int i,
struct pp_smu_wm_range_sets *ranges,
struct _vcs_dpi_soc_bounding_box_st *loaded_bb);
void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,
int vlevel,
int max_mpc_comb,
int pipe_idx,
bool is_validating_bw);
int dcn21_populate_dml_pipes_from_context(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
bool dcn21_validate_bandwidth_fp(struct dc *dc, struct dc_state *context, enum
dc_validate_mode, display_e2e_pipe_params_st *pipes);
void dcn21_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params);
void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc,
struct resource_context *res_ctx,
display_e2e_pipe_params_st *pipes);
#endif /* __DCN20_FPU_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/*
* Copyright 2018 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 _DCN20_DISPLAY_MODE_VBA_H_
#define _DCN20_DISPLAY_MODE_VBA_H_
void dml20_recalculate(struct display_mode_lib *mode_lib);
void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/*
* Copyright 2018 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 _DCN20V2_DISPLAY_MODE_VBA_H_
#define _DCN20V2_DISPLAY_MODE_VBA_H_
void dml20v2_recalculate(struct display_mode_lib *mode_lib);
void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,73 @@
/*
* Copyright 2018 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 __DML20_DISPLAY_RQ_DLG_CALC_H__
#define __DML20_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml20_rq_dlg_get_rq_reg(
struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml20_rq_dlg_get_dlg_reg(
struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,73 @@
/*
* Copyright 2018 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 __DML20V2_DISPLAY_RQ_DLG_CALC_H__
#define __DML20V2_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml20v2_rq_dlg_get_rq_reg(
struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml20v2_rq_dlg_get_dlg_reg(
struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/*
* Copyright 2017 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 __DML21_DISPLAY_MODE_VBA_H__
#define __DML21_DISPLAY_MODE_VBA_H__
void dml21_recalculate(struct display_mode_lib *mode_lib);
void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
#endif /* _DML21_DISPLAY_MODE_VBA_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,73 @@
/*
* Copyright 2017 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 __DML21_DISPLAY_RQ_DLG_CALC_H__
#define __DML21_DISPLAY_RQ_DLG_CALC_H__
#include "dm_services.h"
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml21_rq_dlg_get_rq_reg(
struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml21_rq_dlg_get_dlg_reg(
struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
@@ -0,0 +1,870 @@
/*
* Copyright 2020-2021 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 "resource.h"
#include "clk_mgr.h"
#include "reg_helper.h"
#include "dcn_calc_math.h"
#include "dcn20/dcn20_resource.h"
#include "dcn30/dcn30_resource.h"
#include "clk_mgr/dcn30/dcn30_smu11_driver_if.h"
#include "display_mode_vba_30.h"
#include "dcn30_fpu.h"
#include "../dml1_frl_cap_chk.h"
#define REG(reg)\
optc1->tg_regs->reg
#define CTX \
optc1->base.ctx
#undef FN
#define FN(reg_name, field_name) \
optc1->tg_shift->field_name, optc1->tg_mask->field_name
struct _vcs_dpi_ip_params_st dcn3_0_ip = {
.use_min_dcfclk = 0,
.clamp_min_dcfclk = 0,
.odm_capable = 1,
.gpuvm_enable = 0,
.hostvm_enable = 0,
.gpuvm_max_page_table_levels = 4,
.hostvm_max_page_table_levels = 4,
.hostvm_cached_page_table_levels = 0,
.pte_group_size_bytes = 2048,
.num_dsc = 6,
.rob_buffer_size_kbytes = 184,
.det_buffer_size_kbytes = 184,
.dpte_buffer_size_in_pte_reqs_luma = 84,
.pde_proc_buffer_size_64k_reqs = 48,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.pte_enable = 1,
.max_page_table_levels = 2,
.pte_chunk_size_kbytes = 2, // ?
.meta_chunk_size_kbytes = 2,
.writeback_chunk_size_kbytes = 8,
.line_buffer_size_bits = 789504,
.is_line_buffer_bpp_fixed = 0, // ?
.line_buffer_fixed_bpp = 0, // ?
.dcc_supported = true,
.writeback_interface_buffer_size_kbytes = 90,
.writeback_line_buffer_buffer_size = 0,
.max_line_buffer_lines = 12,
.writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
.writeback_chroma_buffer_size_kbytes = 8,
.writeback_chroma_line_buffer_width_pixels = 4,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.writeback_line_buffer_luma_buffer_size = 0,
.writeback_line_buffer_chroma_buffer_size = 14643,
.cursor_buffer_size = 8,
.cursor_chunk_size = 2,
.max_num_otg = 6,
.max_num_dpp = 6,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.hscl_mults = 4,
.vscl_mults = 4,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dispclk_ramp_margin_percent = 1,
.underscan_factor = 1.11,
.min_vblank_lines = 32,
.dppclk_delay_subtotal = 46,
.dynamic_metadata_vm_enabled = true,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_scl = 50,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dcfclk_cstate_latency = 5.2, // SRExitTime
.max_inter_dcn_tile_repeaters = 8,
.max_num_hdmi_frl_outputs = 1,
.odm_combine_4to1_supported = true,
.xfc_supported = false,
.xfc_fill_bw_overhead_percent = 10.0,
.xfc_fill_constant_bytes = 0,
.gfx7_compat_tiling_supported = 0,
.number_of_cursors = 1,
};
struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = {
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 562.0,
.dppclk_mhz = 300.0,
.phyclk_mhz = 300.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 405.6,
.dtbclk_mhz = 1217.0,
},
},
.min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
.num_states = 1,
.sr_exit_time_us = 15.5,
.sr_enter_plus_exit_time_us = 20,
.urgent_latency_us = 4.0,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 40.0,
.writeback_latency_us = 12.0,
.max_request_size_bytes = 256,
.fabric_datapath_to_dcn_data_return_bytes = 64,
.dcn_downspread_percent = 0.5,
.downspread_percent = 0.38,
.dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192,
.round_trip_ping_latency_dcfclk_cycles = 191,
.urgent_out_of_order_return_per_channel_bytes = 4096,
.channel_interleave_bytes = 256,
.num_banks = 8,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.dram_clock_change_latency_us = 404,
.dummy_pstate_latency_us = 5,
.writeback_dram_clock_change_latency_us = 23.0,
.return_bus_width_bytes = 64,
.dispclk_dppclk_vco_speed_mhz = 3650,
.xfc_bus_transport_time_us = 20, // ?
.xfc_xbuf_latency_tolerance_us = 4, // ?
.use_urgent_burst_bw = 1, // ?
.do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
};
void dcn30_fpu_populate_dml_writeback_from_context(
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
{
int pipe_cnt;
unsigned int i, j;
double max_calc_writeback_dispclk;
double writeback_dispclk;
struct writeback_st dout_wb = {0};
dc_assert_fp_enabled();
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream;
if (!stream)
continue;
max_calc_writeback_dispclk = 0;
/* Set writeback information */
pipes[pipe_cnt].dout.wb_enable = 0;
pipes[pipe_cnt].dout.num_active_wb = 0;
for (j = 0; j < stream->num_wb_info; j++) {
struct dc_writeback_info *wb_info = &stream->writeback_info[j];
if (wb_info->wb_enabled && wb_info->writeback_source_plane &&
(wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) {
pipes[pipe_cnt].dout.wb_enable = 1;
pipes[pipe_cnt].dout.num_active_wb++;
dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ?
wb_info->dwb_params.cnv_params.crop_height :
wb_info->dwb_params.cnv_params.src_height;
dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ?
wb_info->dwb_params.cnv_params.crop_width :
wb_info->dwb_params.cnv_params.src_width;
dout_wb.wb_dst_width = wb_info->dwb_params.dest_width;
dout_wb.wb_dst_height = wb_info->dwb_params.dest_height;
/* For IP that doesn't support WB scaling, set h/v taps to 1 to avoid DML validation failure */
if (dc->dml.ip.writeback_max_hscl_taps > 1) {
dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps;
dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;
} else {
dout_wb.wb_htaps_luma = 1;
dout_wb.wb_vtaps_luma = 1;
}
dout_wb.wb_htaps_chroma = 0;
dout_wb.wb_vtaps_chroma = 0;
dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ?
(double)wb_info->dwb_params.cnv_params.crop_width /
(double)wb_info->dwb_params.dest_width :
(double)wb_info->dwb_params.cnv_params.src_width /
(double)wb_info->dwb_params.dest_width;
dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ?
(double)wb_info->dwb_params.cnv_params.crop_height /
(double)wb_info->dwb_params.dest_height :
(double)wb_info->dwb_params.cnv_params.src_height /
(double)wb_info->dwb_params.dest_height;
if (wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB ||
wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA)
dout_wb.wb_pixel_format = dm_444_64;
else
dout_wb.wb_pixel_format = dm_444_32;
/* Workaround for cases where multiple writebacks are connected to same plane
* In which case, need to compute worst case and set the associated writeback parameters
* This workaround is necessary due to DML computation assuming only 1 set of writeback
* parameters per pipe
*/
writeback_dispclk = dml30_CalculateWriteBackDISPCLK(
dout_wb.wb_pixel_format,
pipes[pipe_cnt].pipe.dest.pixel_rate_mhz,
dout_wb.wb_hratio,
dout_wb.wb_vratio,
dout_wb.wb_htaps_luma,
dout_wb.wb_vtaps_luma,
dout_wb.wb_src_width,
dout_wb.wb_dst_width,
pipes[pipe_cnt].pipe.dest.htotal,
dc->current_state->bw_ctx.dml.ip.writeback_line_buffer_buffer_size);
if (writeback_dispclk > max_calc_writeback_dispclk) {
max_calc_writeback_dispclk = writeback_dispclk;
pipes[pipe_cnt].dout.wb = dout_wb;
}
}
}
pipe_cnt++;
}
}
void dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params *wb_arb_params,
struct display_mode_lib *dml,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int cur_pipe)
{
int i;
dc_assert_fp_enabled();
for (i = 0; i < ARRAY_SIZE(wb_arb_params->cli_watermark); i++) {
wb_arb_params->cli_watermark[i] = (unsigned int)(get_wm_writeback_urgent(dml, pipes, pipe_cnt) * 1000);
wb_arb_params->pstate_watermark[i] = (unsigned int)(get_wm_writeback_dram_clock_change(dml, pipes, pipe_cnt) * 1000);
}
wb_arb_params->dram_speed_change_duration = (unsigned int)(dml->vba.WritebackAllowDRAMClockChangeEndPosition[cur_pipe] * pipes[0].clks_cfg.refclk_mhz); /* num_clock_cycles = us * MHz */
}
void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
{
dc_assert_fp_enabled();
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) {
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching ||
context->bw_ctx.dml.soc.dram_clock_change_latency_us == 0)
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us;
}
}
void dcn30_fpu_calculate_wm_and_dlg(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel)
{
int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
int i, pipe_idx;
unsigned int pipe_i, state_i;
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb];
bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;
unsigned int dummy_latency_index = 0;
struct dc_stream_status *stream_status = NULL;
dc_assert_fp_enabled();
context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false;
for (i = 0; i < context->stream_count; i++) {
stream_status = NULL;
if (context->streams[i])
stream_status = dc_state_get_stream_status(context, context->streams[i]);
if (stream_status)
stream_status->fpo_in_use = false;
}
if (!pstate_en) {
/* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */
context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching =
dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context);
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
dummy_latency_index = dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(dc,
context, pipes, pipe_cnt, vlevel);
/* After calling dcn30_find_dummy_latency_index_for_fw_based_mclk_switch
* we reinstate the original dram_clock_change_latency_us on the context
* and all variables that may have changed up to this point, except the
* newly found dummy_latency_index
*/
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel,
DC_VALIDATE_MODE_AND_PROGRAMMING, true);
maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;
}
}
if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
pipes[0].clks_cfg.voltage = vlevel;
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
/* Set B:
* DCFCLK: 1GHz or min required above 1GHz
* FCLK/UCLK: Max
*/
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) {
if (vlevel == 0) {
pipes[0].clks_cfg.voltage = 1;
pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz;
}
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us;
}
context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = (uint32_t)(get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = (uint32_t)(get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = (uint32_t)(get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = (uint32_t)(get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = (uint32_t)(get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = (uint32_t)(get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = (uint32_t)(get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = (uint32_t)(get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
pipes[0].clks_cfg.voltage = vlevel;
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
/* Set D:
* DCFCLK: Min Required
* FCLK(proportional to UCLK): 1GHz or Max
* MALL stutter, sr_enter_exit = 4, sr_exit = 2us
*/
/*
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us;
}
context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
*/
/* Set C:
* DCFCLK: Min Required
* FCLK(proportional to UCLK): 1GHz or Max
* pstate latency overridden to 5us
*/
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
unsigned int min_dram_speed_mts = (unsigned int)context->bw_ctx.dml.vba.DRAMSpeed;
unsigned int min_dram_speed_mts_margin = 160;
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
dc->clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us;
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
dm_dram_clock_change_unsupported) {
int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1;
min_dram_speed_mts =
dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
}
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
/* find largest table entry that is lower than dram speed,
* but lower than DPM0 still uses DPM0
*/
for (dummy_latency_index = 3; dummy_latency_index > 0; dummy_latency_index--)
if (min_dram_speed_mts + min_dram_speed_mts_margin >
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dram_speed_mts)
break;
}
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
}
context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = (uint32_t)(get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = (uint32_t)(get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = (uint32_t)(get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = (uint32_t)(get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = (uint32_t)(get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = (uint32_t)(get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = (uint32_t)(get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = (uint32_t)(get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
if (!pstate_en) {
/* The only difference between A and C is p-state latency, if p-state is not supported we want to
* calculate DLG based on dummy p-state latency, and max out the set A p-state watermark
*/
context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c;
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0;
} else {
/* Set A:
* DCFCLK: Min Required
* FCLK(proportional to UCLK): 1GHz or Max
*
* Set A calculated last so that following calculations are based on Set A
*/
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = (uint32_t)(get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = (uint32_t)(get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = (uint32_t)(get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = (uint32_t)(get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = (uint32_t)(get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = (uint32_t)(get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = (uint32_t)(get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = (uint32_t)(get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
}
context->perf_params.stutter_period_us = (unsigned int)context->bw_ctx.dml.vba.StutterPeriod;
/* Make set D = set A until set D is enabled */
context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a;
for (pipe_i = 0, pipe_idx = 0; pipe_i < dc->res_pool->pipe_count; pipe_i++) {
if (!context->res_ctx.pipe_ctx[pipe_i].stream)
continue;
pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
if (dc->config.forced_clocks) {
pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
}
if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
pipe_idx++;
}
// WA: restrict FPO to use first non-strobe mode (NV24 BW issue)
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching &&
dc->dml.soc.num_chans <= 4 &&
context->bw_ctx.dml.vba.DRAMSpeed <= 1700 &&
context->bw_ctx.dml.vba.DRAMSpeed >= 1500) {
for (state_i = 0; state_i < dc->dml.soc.num_states; state_i++) {
if (dc->dml.soc.clock_limits[state_i].dram_speed_mts > 1700) {
context->bw_ctx.dml.vba.DRAMSpeed = dc->dml.soc.clock_limits[state_i].dram_speed_mts;
break;
}
}
}
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
if (!pstate_en)
/* Restore full p-state latency */
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
}
void dcn30_fpu_update_dram_channel_width_bytes(struct dc *dc)
{
dc_assert_fp_enabled();
if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
dcn3_0_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
}
void dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk *dcn30_bb_max_clk)
{
dc_assert_fp_enabled();
if (!dcn30_bb_max_clk->max_dcfclk_mhz)
dcn30_bb_max_clk->max_dcfclk_mhz = (int)dcn3_0_soc.clock_limits[0].dcfclk_mhz;
if (!dcn30_bb_max_clk->max_dispclk_mhz)
dcn30_bb_max_clk->max_dispclk_mhz = (int)dcn3_0_soc.clock_limits[0].dispclk_mhz;
if (!dcn30_bb_max_clk->max_dppclk_mhz)
dcn30_bb_max_clk->max_dppclk_mhz = (int)dcn3_0_soc.clock_limits[0].dppclk_mhz;
if (!dcn30_bb_max_clk->max_phyclk_mhz)
dcn30_bb_max_clk->max_phyclk_mhz = (int)dcn3_0_soc.clock_limits[0].phyclk_mhz;
}
void dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk)
{
double bw_from_dram, bw_from_dram1, bw_from_dram2;
dc_assert_fp_enabled();
bw_from_dram1 = uclk_mts * dcn3_0_soc.num_chans *
dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100);
bw_from_dram2 = uclk_mts * dcn3_0_soc.num_chans *
dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100);
bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
if (optimal_fclk)
*optimal_fclk = (unsigned int)(bw_from_dram /
(dcn3_0_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)));
if (optimal_dcfclk)
*optimal_dcfclk = (unsigned int)(bw_from_dram /
(dcn3_0_soc.return_bus_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)));
}
void dcn30_fpu_update_bw_bounding_box(struct dc *dc,
struct clk_bw_params *bw_params,
struct dc_bounding_box_max_clk *dcn30_bb_max_clk,
unsigned int *dcfclk_mhz,
unsigned int *dram_speed_mts)
{
(void)bw_params;
unsigned int i;
dc_assert_fp_enabled();
dcn3_0_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
for (i = 0; i < dcn3_0_soc.num_states; i++) {
dcn3_0_soc.clock_limits[i].state = i;
dcn3_0_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
dcn3_0_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
dcn3_0_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
/* Fill all states with max values of all other clocks */
dcn3_0_soc.clock_limits[i].dispclk_mhz = dcn30_bb_max_clk->max_dispclk_mhz;
dcn3_0_soc.clock_limits[i].dppclk_mhz = dcn30_bb_max_clk->max_dppclk_mhz;
dcn3_0_soc.clock_limits[i].phyclk_mhz = dcn30_bb_max_clk->max_phyclk_mhz;
dcn3_0_soc.clock_limits[i].dtbclk_mhz = dcn3_0_soc.clock_limits[0].dtbclk_mhz;
/* These clocks cannot come from bw_params, always fill from dcn3_0_soc[1] */
/* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */
dcn3_0_soc.clock_limits[i].phyclk_d18_mhz = dcn3_0_soc.clock_limits[0].phyclk_d18_mhz;
dcn3_0_soc.clock_limits[i].socclk_mhz = dcn3_0_soc.clock_limits[0].socclk_mhz;
dcn3_0_soc.clock_limits[i].dscclk_mhz = dcn3_0_soc.clock_limits[0].dscclk_mhz;
}
/* re-init DML with updated bb */
dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
if (dc->current_state)
dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
}
/**
* dcn30_find_dummy_latency_index_for_fw_based_mclk_switch() - Finds
* dummy_latency_index when MCLK switching using firmware based vblank stretch
* is enabled. This function will iterate through the table of dummy pstate
* latencies until the lowest value that allows
* dm_allow_self_refresh_and_mclk_switch to happen is found
*
* @dc: Current DC state
* @context: new dc state
* @pipes: DML pipe params
* @pipe_cnt: number of DML pipes
* @vlevel: Voltage level calculated by DML
*
* Return: lowest dummy_latency_index value
*/
int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel)
{
const int max_latency_table_entries = 4;
int dummy_latency_index = 0;
dc_assert_fp_enabled();
while (dummy_latency_index < max_latency_table_entries) {
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel,
DC_VALIDATE_MODE_AND_PROGRAMMING, true);
if (context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank ==
dm_allow_self_refresh_and_mclk_switch)
break;
dummy_latency_index++;
}
if (dummy_latency_index == max_latency_table_entries) {
ASSERT(dummy_latency_index != max_latency_table_entries);
/* If the execution gets here, it means dummy p_states are
* not possible. This should never happen and would mean
* something is severely wrong.
* Here we reset dummy_latency_index to 3, because it is
* better to have underflows than system crashes.
*/
dummy_latency_index = 3;
}
return dummy_latency_index;
}
void dcn3_fpu_build_wm_range_table(struct clk_mgr *base)
{
/* defaults */
double pstate_latency_us = base->ctx->dc->dml.soc.dram_clock_change_latency_us;
double sr_exit_time_us = base->ctx->dc->dml.soc.sr_exit_time_us;
double sr_enter_plus_exit_time_us = base->ctx->dc->dml.soc.sr_enter_plus_exit_time_us;
uint16_t min_uclk_mhz = (uint16_t)base->bw_params->clk_table.entries[0].memclk_mhz;
dc_assert_fp_enabled();
/* Set A - Normal - default values*/
base->bw_params->wm_table.nv_entries[WM_A].valid = true;
base->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us;
base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us;
base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;
base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0;
base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF;
base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz;
base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF;
/* Set B - Performance - higher minimum clocks */
// base->bw_params->wm_table.nv_entries[WM_B].valid = true;
// base->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us;
// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us;
// base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;
// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE;
// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF;
// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE;
// base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF;
/* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */
base->bw_params->wm_table.nv_entries[WM_C].valid = true;
base->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 0;
base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE;
base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0;
base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF;
base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
base->bw_params->dummy_pstate_table[0].dram_speed_mts = 1600;
base->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
base->bw_params->dummy_pstate_table[1].dram_speed_mts = 8000;
base->bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
base->bw_params->dummy_pstate_table[2].dram_speed_mts = 10000;
base->bw_params->dummy_pstate_table[2].dummy_pstate_latency_us = 8;
base->bw_params->dummy_pstate_table[3].dram_speed_mts = 16000;
base->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us = 5;
/* Set D - MALL - SR enter and exit times adjusted for MALL */
base->bw_params->wm_table.nv_entries[WM_D].valid = true;
base->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us;
base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2;
base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4;
base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL;
base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0;
base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF;
base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz;
base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF;
}
void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *soc_bb)
{
(void)soc_bb;
dc_assert_fp_enabled();
if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
struct bp_soc_bb_info bb_info = {0};
if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
if (bb_info.dram_clock_change_latency_100ns > 0)
dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
if (bb_info.dram_sr_exit_latency_100ns > 0)
dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
}
}
}
#undef DC_LOGGER
#define DC_LOGGER \
enc3->base.ctx->logger
#define hdmi_frl_print(str, ...) {DC_LOG_HDMI_FRL(str, ##__VA_ARGS__); }
#define DEBUG_FRL_CAP_CHK 1
void hpo_fpu_enc3_validate_hdmi_frl_output_link(struct hpo_frl_stream_encoder *enc,
struct dc_hdmi_frl_link_settings *frl_link_settings,
struct frl_cap_chk_params *frl_params,
const struct dc_crtc_timing *timing,
unsigned int dsc_max_rate)
{
(void)enc;
dc_assert_fp_enabled();
switch (frl_link_settings->frl_link_rate) {
case HDMI_FRL_LINK_RATE_3GBPS:
frl_params->r_bit_nominal = 3.0e9;
break;
case HDMI_FRL_LINK_RATE_6GBPS:
case HDMI_FRL_LINK_RATE_6GBPS_4LANE:
frl_params->r_bit_nominal = 6.0e9;
break;
case HDMI_FRL_LINK_RATE_8GBPS:
frl_params->r_bit_nominal = 8.0e9;
break;
case HDMI_FRL_LINK_RATE_10GBPS:
default:
frl_params->r_bit_nominal = 10.0e9;
break;
case HDMI_FRL_LINK_RATE_12GBPS:
frl_params->r_bit_nominal = 12.0e9;
break;
}
if (timing->flags.DSC &&
(unsigned int)frl_link_settings->frl_link_rate > dsc_max_rate) {
if (dsc_max_rate < HDMI_FRL_LINK_RATE_6GBPS_4LANE) {
frl_params->lanes = 3;
} else {
frl_params->lanes = 4;
}
switch (dsc_max_rate) {
case HDMI_FRL_LINK_RATE_3GBPS:
frl_params->r_bit_nominal = 3.0e9;
break;
case HDMI_FRL_LINK_RATE_6GBPS:
case HDMI_FRL_LINK_RATE_6GBPS_4LANE:
frl_params->r_bit_nominal = 6.0e9;
break;
case HDMI_FRL_LINK_RATE_8GBPS:
frl_params->r_bit_nominal = 8.0e9;
break;
case HDMI_FRL_LINK_RATE_10GBPS:
default:
frl_params->r_bit_nominal = 10.0e9;
break;
case HDMI_FRL_LINK_RATE_12GBPS:
frl_params->r_bit_nominal = 12.0e9;
break;
}
}
if (timing->flags.DSC && timing->rid > 0)
frl_params->is_ovt = true;
frl_params->f_pixel_clock_nominal = (double)timing->pix_clk_100hz * 100;
frl_params->h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
frl_params->h_blank = timing->h_total - frl_params->h_active;
frl_params->vic = timing->vic;
}
void hpo_fpu_enc3_validate_hdmi_frl_output_timing(
const struct dc_crtc_timing *timing,
const struct audio_check *audio,
struct frl_cap_chk_params *frl_params)
{
dc_assert_fp_enabled();
if (timing->flags.DSC) {
frl_params->compressed = true;
frl_params->slices = timing->dsc_cfg.num_slices_h;
frl_params->slice_width = (frl_params->h_active + frl_params->slices - 1) / frl_params->slices;
// If YCBCR420 slice width must be even
if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && frl_params->slice_width % 2 != 0)
frl_params->slice_width++;
frl_params->bpp_target = timing->dsc_cfg.bits_per_pixel / 16.0;
} else {
frl_params->compressed = false;
}
frl_params->audio_packet_type = audio->audio_packet_type;
frl_params->f_audio = audio->max_audiosample_rate;
frl_params->acat = audio->acat;
}
enum frl_cap_chk_result frl_fpu_cap_chk_common(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_intermediates *inter,
struct frl_cap_chk_params *params)
{
(void)enc;
return dml1_frl_cap_chk_common(inter, params);
}
enum frl_cap_chk_result frl_fpu_cap_chk_uncompressed(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter)
{
(void)enc;
return dml1_frl_cap_chk_uncompressed(params, inter);
}
enum frl_cap_chk_result frl_fpu_cap_chk_compressed(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter)
{
(void)enc;
return dml1_frl_cap_chk_compressed(params, inter);
}
@@ -0,0 +1,95 @@
/*
* Copyright 2020-2021 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 __DCN30_FPU_H__
#define __DCN30_FPU_H__
#include "core_types.h"
#include "dcn20/dcn20_optc.h"
void dcn30_fpu_populate_dml_writeback_from_context(
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
void dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params *wb_arb_params,
struct display_mode_lib *dml,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int cur_pipe);
void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
void dcn30_fpu_calculate_wm_and_dlg(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
void dcn30_fpu_update_dram_channel_width_bytes(struct dc *dc);
void dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk *dcn30_bb_max_clk);
void dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk);
void dcn30_fpu_update_bw_bounding_box(struct dc *dc,
struct clk_bw_params *bw_params,
struct dc_bounding_box_max_clk *dcn30_bb_max_clk,
unsigned int *dcfclk_mhz,
unsigned int *dram_speed_mts);
int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
void dcn3_fpu_build_wm_range_table(struct clk_mgr *base);
void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip);
void hpo_fpu_enc3_validate_hdmi_frl_output_link(struct hpo_frl_stream_encoder *enc,
struct dc_hdmi_frl_link_settings *frl_link_settings,
struct frl_cap_chk_params *frl_params,
const struct dc_crtc_timing *timing,
unsigned int dsc_max_rate);
void hpo_fpu_enc3_validate_hdmi_frl_output_timing(const struct dc_crtc_timing *timing,
const struct audio_check *audio,
struct frl_cap_chk_params *frl_params);
enum frl_cap_chk_result frl_fpu_cap_chk_common(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_intermediates *inter,
struct frl_cap_chk_params *params);
enum frl_cap_chk_result frl_fpu_cap_chk_uncompressed(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter);
enum frl_cap_chk_result frl_fpu_cap_chk_compressed(struct hpo_frl_stream_encoder *enc,
struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter);
#endif /* __DCN30_FPU_H__*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
/*
* Copyright 2020 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 __DML30_DISPLAY_MODE_VBA_H__
#define __DML30_DISPLAY_MODE_VBA_H__
void dml30_recalculate(struct display_mode_lib *mode_lib);
void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
double dml30_CalculateWriteBackDISPCLK(
enum source_format_class WritebackPixelFormat,
double PixelClock,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackHTaps,
unsigned int WritebackVTaps,
long WritebackSourceWidth,
long WritebackDestinationWidth,
unsigned int HTotal,
unsigned int WritebackLineBufferSize);
void dml30_CalculateBytePerPixelAnd256BBlockSizes(
enum source_format_class SourcePixelFormat,
enum dm_swizzle_mode SurfaceTiling,
unsigned int *BytePerPixelY,
unsigned int *BytePerPixelC,
double *BytePerPixelDETY,
double *BytePerPixelDETC,
unsigned int *BlockHeight256BytesY,
unsigned int *BlockHeight256BytesC,
unsigned int *BlockWidth256BytesY,
unsigned int *BlockWidth256BytesC);
#endif /* __DML30_DISPLAY_MODE_VBA_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
/*
* Copyright 2020 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 __DML30_DISPLAY_RQ_DLG_CALC_H__
#define __DML30_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_param - pipe source configuration (e.g. vp, pitch, scaling, dest, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
@@ -0,0 +1,487 @@
/*
* Copyright 2019-2021 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 "resource.h"
#include "clk_mgr.h"
#include "dcn20/dcn20_resource.h"
#include "dcn301/dcn301_resource.h"
#include "clk_mgr/dcn301/vg_clk_mgr.h"
#include "dml/dcn20/dcn20_fpu.h"
#include "dcn301_fpu.h"
#define TO_DCN301_RES_POOL(pool)\
container_of(pool, struct dcn301_resource_pool, base)
/* Based on: //vidip/dc/dcn3/doc/architecture/DCN3x_Display_Mode.xlsm#83 */
struct _vcs_dpi_ip_params_st dcn3_01_ip = {
.odm_capable = 1,
.gpuvm_enable = 1,
.hostvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_max_page_table_levels = 2,
.hostvm_cached_page_table_levels = 0,
.pte_group_size_bytes = 2048,
.num_dsc = 3,
.rob_buffer_size_kbytes = 184,
.det_buffer_size_kbytes = 184,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 32,
.pde_proc_buffer_size_64k_reqs = 48,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.meta_chunk_size_kbytes = 2,
.writeback_chunk_size_kbytes = 8,
.line_buffer_size_bits = 789504,
.is_line_buffer_bpp_fixed = 0, // ?
.line_buffer_fixed_bpp = 48, // ?
.dcc_supported = true,
.writeback_interface_buffer_size_kbytes = 90,
.writeback_line_buffer_buffer_size = 656640,
.max_line_buffer_lines = 12,
.writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
.writeback_chroma_buffer_size_kbytes = 8,
.writeback_chroma_line_buffer_width_pixels = 4,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.writeback_line_buffer_luma_buffer_size = 0,
.writeback_line_buffer_chroma_buffer_size = 14643,
.cursor_buffer_size = 8,
.cursor_chunk_size = 2,
.max_num_otg = 4,
.max_num_dpp = 4,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.hscl_mults = 4,
.vscl_mults = 4,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dispclk_ramp_margin_percent = 1,
.underscan_factor = 1.11,
.min_vblank_lines = 32,
.dppclk_delay_subtotal = 46,
.dynamic_metadata_vm_enabled = true,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_scl = 50,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dcfclk_cstate_latency = 5.2, // SRExitTime
.max_inter_dcn_tile_repeaters = 8,
.max_num_hdmi_frl_outputs = 0,
.odm_combine_4to1_supported = true,
.xfc_supported = false,
.xfc_fill_bw_overhead_percent = 10.0,
.xfc_fill_constant_bytes = 0,
.gfx7_compat_tiling_supported = 0,
.number_of_cursors = 1,
};
struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = {
.clock_limits = {
{
.state = 0,
.dram_speed_mts = 2400.0,
.fabricclk_mhz = 600,
.socclk_mhz = 278.0,
.dcfclk_mhz = 400.0,
.dscclk_mhz = 206.0,
.dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
.phyclk_mhz = 600.0,
},
{
.state = 1,
.dram_speed_mts = 2400.0,
.fabricclk_mhz = 688,
.socclk_mhz = 278.0,
.dcfclk_mhz = 400.0,
.dscclk_mhz = 206.0,
.dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
.phyclk_mhz = 600.0,
},
{
.state = 2,
.dram_speed_mts = 4267.0,
.fabricclk_mhz = 1067,
.socclk_mhz = 278.0,
.dcfclk_mhz = 608.0,
.dscclk_mhz = 296.0,
.dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
.phyclk_mhz = 810.0,
},
{
.state = 3,
.dram_speed_mts = 4267.0,
.fabricclk_mhz = 1067,
.socclk_mhz = 715.0,
.dcfclk_mhz = 676.0,
.dscclk_mhz = 338.0,
.dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
.phyclk_mhz = 810.0,
},
{
.state = 4,
.dram_speed_mts = 4267.0,
.fabricclk_mhz = 1067,
.socclk_mhz = 953.0,
.dcfclk_mhz = 810.0,
.dscclk_mhz = 338.0,
.dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
.phyclk_mhz = 810.0,
},
},
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.urgent_latency_us = 4.0,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.writeback_latency_us = 12.0,
.max_request_size_bytes = 256,
.dram_channel_width_bytes = 4,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.dcn_downspread_percent = 0.5,
.downspread_percent = 0.38,
.dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192,
.round_trip_ping_latency_dcfclk_cycles = 191,
.urgent_out_of_order_return_per_channel_bytes = 4096,
.channel_interleave_bytes = 256,
.num_banks = 8,
.num_chans = 4,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.dram_clock_change_latency_us = 23.84,
.writeback_dram_clock_change_latency_us = 23.0,
.return_bus_width_bytes = 64,
.dispclk_dppclk_vco_speed_mhz = 3550,
.xfc_bus_transport_time_us = 20, // ?
.xfc_xbuf_latency_tolerance_us = 4, // ?
.use_urgent_burst_bw = 1, // ?
.num_states = 5,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
};
struct wm_table ddr4_wm_table = {
.entries = {
{
.wm_inst = WM_A,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
.sr_exit_time_us = 6.09,
.sr_enter_plus_exit_time_us = 7.14,
.valid = true,
},
{
.wm_inst = WM_B,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
.sr_exit_time_us = 10.12,
.sr_enter_plus_exit_time_us = 11.48,
.valid = true,
},
{
.wm_inst = WM_C,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
.sr_exit_time_us = 10.12,
.sr_enter_plus_exit_time_us = 11.48,
.valid = true,
},
{
.wm_inst = WM_D,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
.sr_exit_time_us = 10.12,
.sr_enter_plus_exit_time_us = 11.48,
.valid = true,
},
}
};
struct wm_table lpddr5_wm_table = {
.entries = {
{
.wm_inst = WM_A,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
.sr_exit_time_us = 13.5,
.sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_B,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
.sr_exit_time_us = 13.5,
.sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_C,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
.sr_exit_time_us = 13.5,
.sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_D,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
.sr_exit_time_us = 13.5,
.sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
}
};
static void calculate_wm_set_for_vlevel(int vlevel,
struct wm_range_table_entry *table_entry,
struct dcn_watermarks *wm_set,
struct display_mode_lib *dml,
display_e2e_pipe_params_st *pipes,
int pipe_cnt)
{
double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
ASSERT(vlevel < (int)dml->soc.num_states);
/* only pipe 0 is read for voltage and dcf/soc clocks */
pipes[0].clks_cfg.voltage = vlevel;
pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
wm_set->urgent_ns = (uint32_t)(get_wm_urgent(dml, pipes, pipe_cnt) * 1000);
wm_set->cstate_pstate.cstate_enter_plus_exit_ns = (uint32_t)(get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000);
wm_set->cstate_pstate.cstate_exit_ns = (uint32_t)(get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000);
wm_set->cstate_pstate.pstate_change_ns = (uint32_t)(get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000);
wm_set->pte_meta_urgent_ns = (uint32_t)(get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000);
wm_set->frac_urg_bw_nom = (uint32_t)(get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000);
wm_set->frac_urg_bw_flip = (uint32_t)(get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000);
wm_set->urgent_latency_ns = (uint32_t)(get_urgent_latency(dml, pipes, pipe_cnt) * 1000);
dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
}
void dcn301_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool);
struct clk_limit_table *clk_table = &bw_params->clk_table;
unsigned int i, closest_clk_lvl;
int j = 0;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
dc_assert_fp_enabled();
memcpy(s, dcn3_01_soc.clock_limits, sizeof(dcn3_01_soc.clock_limits));
/* Default clock levels are used for diags, which may lead to overclocking. */
dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
dcn3_01_ip.max_num_dpp = pool->base.pipe_count;
dcn3_01_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) {
if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
s[i].state = i;
s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
s[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
/* Clocks independent of voltage level. */
s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
s[i].dram_bw_per_chan_gbps =
dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
s[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
s[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
s[i].phyclk_d18_mhz =
dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
s[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
if (clk_table->num_entries) {
dcn3_01_soc.num_states = clk_table->num_entries;
/* duplicate last level */
s[dcn3_01_soc.num_states] =
dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];
s[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;
}
memcpy(dcn3_01_soc.clock_limits, s, sizeof(dcn3_01_soc.clock_limits));
dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
if ((int)(dcn3_01_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_01_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000.0;
}
dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
}
void dcn301_fpu_set_wm_ranges(int i,
struct pp_smu_wm_range_sets *ranges,
struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
{
dc_assert_fp_enabled();
ranges->reader_wm_sets[i].min_fill_clk_mhz = (uint16_t)((i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0);
ranges->reader_wm_sets[i].max_fill_clk_mhz = (uint16_t)(loaded_bb->clock_limits[i].dram_speed_mts / 16);
}
void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
{
dc_assert_fp_enabled();
if (bb_info.dram_clock_change_latency_100ns > 0)
dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
if (bb_info.dram_sr_exit_latency_100ns > 0)
dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
}
void dcn301_fpu_calculate_wm_and_dlg(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel_req)
{
unsigned int i, pipe_idx;
int vlevel, vlevel_max;
struct wm_range_table_entry *table_entry;
struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
ASSERT(bw_params);
dc_assert_fp_enabled();
vlevel_max = bw_params->clk_table.num_entries - 1;
/* WM Set D */
table_entry = &bw_params->wm_table.entries[WM_D];
if (table_entry->wm_type == WM_TYPE_RETRAINING)
vlevel = 0;
else
vlevel = vlevel_max;
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set C */
table_entry = &bw_params->wm_table.entries[WM_C];
vlevel = clamp(vlevel_req, 2, vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set B */
table_entry = &bw_params->wm_table.entries[WM_B];
vlevel = clamp(vlevel_req, 1, vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set A */
table_entry = &bw_params->wm_table.entries[WM_A];
vlevel = min(vlevel_req, vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
&context->bw_ctx.dml, pipes, pipe_cnt);
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
if (dc->config.forced_clocks) {
pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
}
if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
pipe_idx++;
}
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
}
@@ -0,0 +1,41 @@
/*
* Copyright 2019-2021 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 __DCN301_FPU_H__
#define __DCN301_FPU_H__
void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
void dcn301_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
void dcn301_fpu_set_wm_ranges(int i,
struct pp_smu_wm_range_sets *ranges,
struct _vcs_dpi_soc_bounding_box_st *loaded_bb);
void dcn301_fpu_calculate_wm_and_dlg(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel_req);
#endif /* __DCN301_FPU_H__*/
@@ -0,0 +1,368 @@
/*
* Copyright 2021 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 "resource.h"
#include "clk_mgr.h"
#include "dcn20/dcn20_resource.h"
#include "dcn302/dcn302_resource.h"
#include "dml/dcn20/dcn20_fpu.h"
#include "dcn302_fpu.h"
struct _vcs_dpi_ip_params_st dcn3_02_ip = {
.use_min_dcfclk = 0,
.clamp_min_dcfclk = 0,
.odm_capable = 1,
.gpuvm_enable = 1,
.hostvm_enable = 0,
.gpuvm_max_page_table_levels = 4,
.hostvm_max_page_table_levels = 4,
.hostvm_cached_page_table_levels = 0,
.pte_group_size_bytes = 2048,
.num_dsc = 5,
.rob_buffer_size_kbytes = 184,
.det_buffer_size_kbytes = 184,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.pde_proc_buffer_size_64k_reqs = 48,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.pte_enable = 1,
.max_page_table_levels = 2,
.pte_chunk_size_kbytes = 2, // ?
.meta_chunk_size_kbytes = 2,
.writeback_chunk_size_kbytes = 8,
.line_buffer_size_bits = 789504,
.is_line_buffer_bpp_fixed = 0, // ?
.line_buffer_fixed_bpp = 0, // ?
.dcc_supported = true,
.writeback_interface_buffer_size_kbytes = 90,
.writeback_line_buffer_buffer_size = 0,
.max_line_buffer_lines = 12,
.writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
.writeback_chroma_buffer_size_kbytes = 8,
.writeback_chroma_line_buffer_width_pixels = 4,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.writeback_line_buffer_luma_buffer_size = 0,
.writeback_line_buffer_chroma_buffer_size = 14643,
.cursor_buffer_size = 8,
.cursor_chunk_size = 2,
.max_num_otg = 5,
.max_num_dpp = 5,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.hscl_mults = 4,
.vscl_mults = 4,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dispclk_ramp_margin_percent = 1,
.underscan_factor = 1.11,
.min_vblank_lines = 32,
.dppclk_delay_subtotal = 46,
.dynamic_metadata_vm_enabled = true,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_scl = 50,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dcfclk_cstate_latency = 5.2, // SRExitTime
.max_inter_dcn_tile_repeaters = 8,
.max_num_hdmi_frl_outputs = 1,
.odm_combine_4to1_supported = true,
.xfc_supported = false,
.xfc_fill_bw_overhead_percent = 10.0,
.xfc_fill_constant_bytes = 0,
.gfx7_compat_tiling_supported = 0,
.number_of_cursors = 1,
};
struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 562.0,
.dppclk_mhz = 300.0,
.phyclk_mhz = 300.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 405.6,
.dtbclk_mhz = 1217.0,
},
},
.min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
.num_states = 1,
.sr_exit_time_us = 26.5,
.sr_enter_plus_exit_time_us = 31,
.urgent_latency_us = 4.0,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 40.0,
.writeback_latency_us = 12.0,
.max_request_size_bytes = 256,
.fabric_datapath_to_dcn_data_return_bytes = 64,
.dcn_downspread_percent = 0.5,
.downspread_percent = 0.38,
.dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192,
.round_trip_ping_latency_dcfclk_cycles = 156,
.urgent_out_of_order_return_per_channel_bytes = 4096,
.channel_interleave_bytes = 256,
.num_banks = 8,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.dram_clock_change_latency_us = 404,
.dummy_pstate_latency_us = 5,
.writeback_dram_clock_change_latency_us = 23.0,
.return_bus_width_bytes = 64,
.dispclk_dppclk_vco_speed_mhz = 3650,
.xfc_bus_transport_time_us = 20, // ?
.xfc_xbuf_latency_tolerance_us = 4, // ?
.use_urgent_burst_bw = 1, // ?
.do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
};
static void dcn302_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk)
{
double bw_from_dram, bw_from_dram1, bw_from_dram2;
bw_from_dram1 = uclk_mts * dcn3_02_soc.num_chans *
dcn3_02_soc.dram_channel_width_bytes *
(dcn3_02_soc.max_avg_dram_bw_use_normal_percent / 100);
bw_from_dram2 = uclk_mts * dcn3_02_soc.num_chans *
dcn3_02_soc.dram_channel_width_bytes *
(dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100);
bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
if (optimal_fclk)
*optimal_fclk = (unsigned int)(bw_from_dram /
(dcn3_02_soc.fabric_datapath_to_dcn_data_return_bytes *
(dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100)));
if (optimal_dcfclk)
*optimal_dcfclk = (unsigned int)(bw_from_dram /
(dcn3_02_soc.return_bus_width_bytes *
(dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100)));
}
void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
unsigned int i, j;
unsigned int num_states = 0;
unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
unsigned int num_dcfclk_sta_targets = 4;
unsigned int num_uclk_states;
dc_assert_fp_enabled();
if (dc->ctx->dc_bios->vram_info.num_chans)
dcn3_02_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
dcn3_02_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
dcn3_02_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
if (bw_params->clk_table.entries[0].memclk_mhz) {
unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
}
if (!max_dcfclk_mhz)
max_dcfclk_mhz = (int)dcn3_02_soc.clock_limits[0].dcfclk_mhz;
if (!max_dispclk_mhz)
max_dispclk_mhz = (int)dcn3_02_soc.clock_limits[0].dispclk_mhz;
if (!max_dppclk_mhz)
max_dppclk_mhz = (int)dcn3_02_soc.clock_limits[0].dppclk_mhz;
if (!max_phyclk_mhz)
max_phyclk_mhz = (int)dcn3_02_soc.clock_limits[0].phyclk_mhz;
if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
/* If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array */
dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
num_dcfclk_sta_targets++;
} else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
/* If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates */
for (i = 0; i < num_dcfclk_sta_targets; i++) {
if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
dcfclk_sta_targets[i] = max_dcfclk_mhz;
break;
}
}
/* Update size of array since we "removed" duplicates */
num_dcfclk_sta_targets = i + 1;
}
num_uclk_states = bw_params->clk_table.num_entries;
/* Calculate optimal dcfclk for each uclk */
for (i = 0; i < num_uclk_states; i++) {
dcn302_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
&optimal_dcfclk_for_uclk[i], NULL);
if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
}
/* Calculate optimal uclk for each dcfclk sta target */
for (i = 0; i < num_dcfclk_sta_targets; i++) {
for (j = 0; j < num_uclk_states; j++) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
break;
}
}
}
i = 0;
j = 0;
/* create the final dcfclk and uclk table */
while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
} else {
if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} else {
j = num_uclk_states;
}
}
}
while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
}
while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_02_soc.num_states = num_states;
for (i = 0; i < dcn3_02_soc.num_states; i++) {
dcn3_02_soc.clock_limits[i].state = i;
dcn3_02_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
dcn3_02_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
dcn3_02_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
/* Fill all states with max values of all other clocks */
dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
/* Populate from bw_params for DTBCLK, SOCCLK */
if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[i-1].dtbclk_mhz;
else
dcn3_02_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[i-1].socclk_mhz;
else
dcn3_02_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
/* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */
/* FCLK, PHYCLK_D18, DSCCLK */
dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz;
dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz;
}
/* re-init DML with updated bb */
dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
if (dc->current_state)
dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
}
}
void dcn302_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
{
dc_assert_fp_enabled();
if (bb_info.dram_clock_change_latency_100ns > 0)
dcn3_02_soc.dram_clock_change_latency_us =
bb_info.dram_clock_change_latency_100ns * 10;
if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
dcn3_02_soc.sr_enter_plus_exit_time_us =
bb_info.dram_sr_enter_exit_latency_100ns * 10;
if (bb_info.dram_sr_exit_latency_100ns > 0)
dcn3_02_soc.sr_exit_time_us =
bb_info.dram_sr_exit_latency_100ns * 10;
}
@@ -0,0 +1,32 @@
/*
* Copyright 2019-2021 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 __DCN302_FPU_H__
#define __DCN302_FPU_H__
void dcn302_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
#endif /* __DCN302_FPU_H__*/
@@ -0,0 +1,381 @@
/*
* Copyright 2019-2021 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 "resource.h"
#include "clk_mgr.h"
#include "dcn20/dcn20_resource.h"
#include "dcn303/dcn303_resource.h"
#include "dml/dcn20/dcn20_fpu.h"
#include "dcn303_fpu.h"
struct _vcs_dpi_ip_params_st dcn3_03_ip = {
.use_min_dcfclk = 0,
.clamp_min_dcfclk = 0,
.odm_capable = 1,
.gpuvm_enable = 1,
.hostvm_enable = 0,
.gpuvm_max_page_table_levels = 4,
.hostvm_max_page_table_levels = 4,
.hostvm_cached_page_table_levels = 0,
.pte_group_size_bytes = 2048,
.num_dsc = 2,
.rob_buffer_size_kbytes = 184,
.det_buffer_size_kbytes = 184,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.pde_proc_buffer_size_64k_reqs = 48,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.pte_enable = 1,
.max_page_table_levels = 2,
.pte_chunk_size_kbytes = 2, // ?
.meta_chunk_size_kbytes = 2,
.writeback_chunk_size_kbytes = 8,
.line_buffer_size_bits = 789504,
.is_line_buffer_bpp_fixed = 0, // ?
.line_buffer_fixed_bpp = 0, // ?
.dcc_supported = true,
.writeback_interface_buffer_size_kbytes = 90,
.writeback_line_buffer_buffer_size = 0,
.max_line_buffer_lines = 12,
.writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
.writeback_chroma_buffer_size_kbytes = 8,
.writeback_chroma_line_buffer_width_pixels = 4,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.writeback_line_buffer_luma_buffer_size = 0,
.writeback_line_buffer_chroma_buffer_size = 14643,
.cursor_buffer_size = 8,
.cursor_chunk_size = 2,
.max_num_otg = 2,
.max_num_dpp = 2,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.hscl_mults = 4,
.vscl_mults = 4,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dispclk_ramp_margin_percent = 1,
.underscan_factor = 1.11,
.min_vblank_lines = 32,
.dppclk_delay_subtotal = 46,
.dynamic_metadata_vm_enabled = true,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_scl = 50,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dcfclk_cstate_latency = 5.2, // SRExitTime
.max_inter_dcn_tile_repeaters = 8,
.max_num_hdmi_frl_outputs = 1,
.odm_combine_4to1_supported = false,
.xfc_supported = false,
.xfc_fill_bw_overhead_percent = 10.0,
.xfc_fill_constant_bytes = 0,
.gfx7_compat_tiling_supported = 0,
.number_of_cursors = 1,
};
struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc = {
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 562.0,
.dppclk_mhz = 300.0,
.phyclk_mhz = 300.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 405.6,
.dtbclk_mhz = 1217.0,
},
},
.min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
.num_states = 1,
.sr_exit_time_us = 35.5,
.sr_enter_plus_exit_time_us = 40,
.urgent_latency_us = 4.0,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 40.0,
.writeback_latency_us = 12.0,
.max_request_size_bytes = 256,
.fabric_datapath_to_dcn_data_return_bytes = 64,
.dcn_downspread_percent = 0.5,
.downspread_percent = 0.38,
.dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192,
.round_trip_ping_latency_dcfclk_cycles = 156,
.urgent_out_of_order_return_per_channel_bytes = 4096,
.channel_interleave_bytes = 256,
.num_banks = 8,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.dram_clock_change_latency_us = 404,
.dummy_pstate_latency_us = 5,
.writeback_dram_clock_change_latency_us = 23.0,
.return_bus_width_bytes = 64,
.dispclk_dppclk_vco_speed_mhz = 3650,
.xfc_bus_transport_time_us = 20, // ?
.xfc_xbuf_latency_tolerance_us = 4, // ?
.use_urgent_burst_bw = 1, // ?
.do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
};
static void dcn303_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk)
{
double bw_from_dram, bw_from_dram1, bw_from_dram2;
bw_from_dram1 = uclk_mts * dcn3_03_soc.num_chans *
dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_dram_bw_use_normal_percent / 100);
bw_from_dram2 = uclk_mts * dcn3_03_soc.num_chans *
dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100);
bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
if (optimal_fclk)
*optimal_fclk = (unsigned int)(bw_from_dram /
(dcn3_03_soc.fabric_datapath_to_dcn_data_return_bytes *
(dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100)));
if (optimal_dcfclk)
*optimal_dcfclk = (unsigned int)(bw_from_dram /
(dcn3_03_soc.return_bus_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100)));
}
void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
unsigned int i, j;
unsigned int num_states = 0;
unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
unsigned int num_dcfclk_sta_targets = 4;
unsigned int num_uclk_states;
dc_assert_fp_enabled();
if (dc->ctx->dc_bios->vram_info.num_chans)
dcn3_03_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
dcn3_03_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
dcn3_03_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
if (bw_params->clk_table.entries[0].memclk_mhz) {
unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
}
if (!max_dcfclk_mhz)
max_dcfclk_mhz = (int)dcn3_03_soc.clock_limits[0].dcfclk_mhz;
if (!max_dispclk_mhz)
max_dispclk_mhz = (int)dcn3_03_soc.clock_limits[0].dispclk_mhz;
if (!max_dppclk_mhz)
max_dppclk_mhz = (int)dcn3_03_soc.clock_limits[0].dppclk_mhz;
if (!max_phyclk_mhz)
max_phyclk_mhz = (int)dcn3_03_soc.clock_limits[0].phyclk_mhz;
if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
num_dcfclk_sta_targets++;
} else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
for (i = 0; i < num_dcfclk_sta_targets; i++) {
if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
dcfclk_sta_targets[i] = max_dcfclk_mhz;
break;
}
}
/* Update size of array since we "removed" duplicates */
num_dcfclk_sta_targets = i + 1;
}
num_uclk_states = bw_params->clk_table.num_entries;
/* Calculate optimal dcfclk for each uclk */
for (i = 0; i < num_uclk_states; i++) {
dcn303_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
&optimal_dcfclk_for_uclk[i], NULL);
if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
}
/* Calculate optimal uclk for each dcfclk sta target */
for (i = 0; i < num_dcfclk_sta_targets; i++) {
for (j = 0; j < num_uclk_states; j++) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
break;
} else {
/* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
* This is required for dcn303 because it just so happens that the memory
* bandwidth is low enough such that all the optimal DCFCLK for each UCLK
* is lower than the smallest DCFCLK STA target. In this case we need to
* populate the optimal UCLK for each DCFCLK STA target to be the max UCLK.
*/
if (j == num_uclk_states - 1) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
}
}
}
}
i = 0;
j = 0;
/* create the final dcfclk and uclk table */
while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
} else {
if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] =
bw_params->clk_table.entries[j++].memclk_mhz * 16;
} else {
j = num_uclk_states;
}
}
}
while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
}
while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_03_soc.num_states = num_states;
for (i = 0; i < dcn3_03_soc.num_states; i++) {
dcn3_03_soc.clock_limits[i].state = i;
dcn3_03_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
dcn3_03_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
dcn3_03_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
/* Fill all states with max values of all other clocks */
dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
dcn3_03_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
/* Populate from bw_params for DTBCLK, SOCCLK */
if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
dcn3_03_soc.clock_limits[i].dtbclk_mhz = dcn3_03_soc.clock_limits[i-1].dtbclk_mhz;
else
dcn3_03_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
dcn3_03_soc.clock_limits[i].socclk_mhz = dcn3_03_soc.clock_limits[i-1].socclk_mhz;
else
dcn3_03_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
/* These clocks cannot come from bw_params, always fill from dcn3_03_soc[1] */
/* FCLK, PHYCLK_D18, DSCCLK */
dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz;
dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz;
}
if (dcn3_03_soc.num_chans <= 4) {
for (i = 0; i < dcn3_03_soc.num_states; i++) {
if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700)
break;
if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) {
dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100;
dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100;
}
}
}
/* re-init DML with updated bb */
dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
if (dc->current_state)
dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
}
}
void dcn303_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
{
dc_assert_fp_enabled();
if (bb_info.dram_clock_change_latency_100ns > 0)
dcn3_03_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
dcn3_03_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
if (bb_info.dram_sr_exit_latency_100ns > 0)
dcn3_03_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
}
@@ -0,0 +1,32 @@
/*
* Copyright 2019-2021 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 __DCN303_FPU_H__
#define __DCN303_FPU_H__
void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
void dcn303_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
#endif /* __DCN303_FPU_H__*/
@@ -0,0 +1,830 @@
/*
* Copyright 2019-2021 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 "resource.h"
#include "clk_mgr.h"
#include "dcn31/dcn31_resource.h"
#include "dcn315/dcn315_resource.h"
#include "dcn316/dcn316_resource.h"
#include "dml/dcn20/dcn20_fpu.h"
#include "dcn31_fpu.h"
/**
* DOC: DCN31x FPU manipulation Overview
*
* The DCN architecture relies on FPU operations, which require special
* compilation flags and the use of kernel_fpu_begin/end functions; ideally, we
* want to avoid spreading FPU access across multiple files. With this idea in
* mind, this file aims to centralize all DCN3.1.x functions that require FPU
* access in a single place. Code in this file follows the following code
* pattern:
*
* 1. Functions that use FPU operations should be isolated in static functions.
* 2. The FPU functions should have the noinline attribute to ensure anything
* that deals with FP register is contained within this call.
* 3. All function that needs to be accessed outside this file requires a
* public interface that not uses any FPU reference.
* 4. Developers **must not** use DC_FP_START/END in this file, but they need
* to ensure that the caller invokes it before access any function available
* in this file. For this reason, public functions in this file must invoke
* dc_assert_fp_enabled();
*/
struct _vcs_dpi_ip_params_st dcn3_1_ip = {
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = DCN3_1_DEFAULT_DET_SIZE,
.config_return_buffer_size_in_kbytes = 1792,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 3,
.maximum_dsc_bits_per_component = 10,
.dsc422_native_support = false,
.is_line_buffer_bpp_fixed = true,
.line_buffer_fixed_bpp = 48,
.line_buffer_size_bits = 789504,
.max_line_buffer_lines = 12,
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.dispclk_ramp_margin_percent = 1,
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 46,
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
};
static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 186.0,
.dtbclk_mhz = 625.0,
},
{
.state = 1,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 625.0,
},
{
.state = 2,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 625.0,
},
{
.state = 3,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 371.0,
.dtbclk_mhz = 625.0,
},
{
.state = 4,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 417.0,
.dtbclk_mhz = 625.0,
},
},
.num_states = 5,
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.sr_exit_z8_time_us = 442.0,
.sr_enter_plus_exit_z8_time_us = 560.0,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,
.round_trip_ping_latency_dcfclk_cycles = 106,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
};
struct _vcs_dpi_ip_params_st dcn3_15_ip = {
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = DCN3_15_DEFAULT_DET_SIZE,
.min_comp_buffer_size_kbytes = 64,
.config_return_buffer_size_in_kbytes = 1024,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 3,
.maximum_dsc_bits_per_component = 10,
.dsc422_native_support = false,
.is_line_buffer_bpp_fixed = true,
.line_buffer_fixed_bpp = 48,
.line_buffer_size_bits = 789504,
.max_line_buffer_lines = 12,
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.dispclk_ramp_margin_percent = 1,
.max_inter_dcn_tile_repeaters = 9,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 46,
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
};
static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.sr_exit_z8_time_us = 50.0,
.sr_enter_plus_exit_z8_time_us = 50.0,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,
.round_trip_ping_latency_dcfclk_cycles = 106,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.38,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
.dispclk_dppclk_vco_speed_mhz = 2400.0,
.num_chans = 4,
.dummy_pstate_latency_us = 10.0
};
struct _vcs_dpi_ip_params_st dcn3_16_ip = {
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = DCN3_16_DEFAULT_DET_SIZE,
.min_comp_buffer_size_kbytes = 64,
.config_return_buffer_size_in_kbytes = 1024,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 3,
.maximum_dsc_bits_per_component = 10,
.dsc422_native_support = false,
.is_line_buffer_bpp_fixed = true,
.line_buffer_fixed_bpp = 48,
.line_buffer_size_bits = 789504,
.max_line_buffer_lines = 12,
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.dispclk_ramp_margin_percent = 1,
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 46,
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
};
static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 556.0,
.dppclk_mhz = 556.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 445.0,
.dscclk_mhz = 186.0,
.dtbclk_mhz = 625.0,
},
{
.state = 1,
.dispclk_mhz = 625.0,
.dppclk_mhz = 625.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 625.0,
},
{
.state = 2,
.dispclk_mhz = 625.0,
.dppclk_mhz = 625.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 625.0,
},
{
.state = 3,
.dispclk_mhz = 1112.0,
.dppclk_mhz = 1112.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 371.0,
.dtbclk_mhz = 625.0,
},
{
.state = 4,
.dispclk_mhz = 1250.0,
.dppclk_mhz = 1250.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 417.0,
.dtbclk_mhz = 625.0,
},
},
.num_states = 5,
.sr_exit_time_us = 9.0,
.sr_enter_plus_exit_time_us = 11.0,
.sr_exit_z8_time_us = 442.0,
.sr_enter_plus_exit_z8_time_us = 560.0,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,
.round_trip_ping_latency_dcfclk_cycles = 106,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
.dispclk_dppclk_vco_speed_mhz = 2500.0,
};
void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
int pipe_cnt)
{
dc_assert_fp_enabled();
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
}
void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
{
dc_assert_fp_enabled();
if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) {
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_exit_time_us;
}
}
void dcn315_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
{
dc_assert_fp_enabled();
if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) {
/* For 315 pstate change is only supported if possible in vactive */
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[context->bw_ctx.dml.vba.VoltageLevel][context->bw_ctx.dml.vba.maxMpcComb] != dm_dram_clock_change_vactive)
context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
else
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us =
dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us =
dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_exit_time_us;
}
}
void dcn31_calculate_wm_and_dlg_fp(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel)
{
int total_det = 0, active_hubp_count = 0;
unsigned int i, pipe_idx;
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
uint32_t cstate_enter_plus_exit_z8_ns;
uint32_t minimum_z8_residency_time_ns =
(uint32_t)dc->debug.minimum_z8_residency_time * 1000U;
dc_assert_fp_enabled();
if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
/* We don't recalculate clocks for 0 pipe configs, which can block
* S0i3 as high clocks will block low power states
* Override any clocks that can block S0i3 to min here
*/
if (pipe_cnt == 0) {
context->bw_ctx.bw.dcn.clk.dcfclk_khz = (int)dcfclk; // always should be vlevel 0
return;
}
pipes[0].clks_cfg.voltage = vlevel;
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
cstate_enter_plus_exit_z8_ns =
(uint32_t)(get_wm_z8_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
if (get_stutter_period(&context->bw_ctx.dml, pipes, pipe_cnt) < dc->debug.minimum_z8_residency_time &&
cstate_enter_plus_exit_z8_ns < minimum_z8_residency_time_ns)
cstate_enter_plus_exit_z8_ns = minimum_z8_residency_time_ns;
/* Set A:
* All clocks min required
*
* Set A calculated last so that following calculations are based on Set A
*/
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = (uint32_t)(get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = (uint32_t)(get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = (uint32_t)(get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = (uint32_t)(get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns = cstate_enter_plus_exit_z8_ns;
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_z8_ns = (uint32_t)(get_wm_z8_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = (uint32_t)(get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = (uint32_t)(get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = (uint32_t)(get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = (uint32_t)(get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000);
context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a;
context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a;
context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a;
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
if (context->res_ctx.pipe_ctx[i].plane_state)
active_hubp_count++;
pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
if (dc->config.forced_clocks || dc->debug.max_disp_clk) {
pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
}
if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
pipe_idx++;
}
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
/* For 31x apu pstate change is only supported if possible in vactive*/
context->bw_ctx.bw.dcn.clk.p_state_change_support =
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_vactive;
/* If DCN isn't making memory requests we can allow pstate change and lower clocks */
if (!active_hubp_count) {
context->bw_ctx.bw.dcn.clk.socclk_khz = 0;
context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
context->bw_ctx.bw.dcn.clk.dcfclk_khz = 0;
context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = 0;
context->bw_ctx.bw.dcn.clk.dramclk_khz = 0;
context->bw_ctx.bw.dcn.clk.fclk_khz = 0;
context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
for (i = 0; i < dc->res_pool->pipe_count; i++)
if (context->res_ctx.pipe_ctx[i].stream)
context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = 0;
}
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
context->res_ctx.pipe_ctx[i].det_buffer_size_kb =
(int)get_det_buffer_size_kbytes(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
if (context->res_ctx.pipe_ctx[i].det_buffer_size_kb > 384)
context->res_ctx.pipe_ctx[i].det_buffer_size_kb /= 2;
total_det += context->res_ctx.pipe_ctx[i].det_buffer_size_kb;
pipe_idx++;
}
context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - total_det;
}
void dcn31_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct clk_limit_table *clk_table = &bw_params->clk_table;
unsigned int i, closest_clk_lvl;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
int j;
dc_assert_fp_enabled();
memcpy(s, dcn3_1_soc.clock_limits, sizeof(dcn3_1_soc.clock_limits));
// Default clock levels are used for diags, which may lead to overclocking.
dcn3_1_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
dcn3_1_ip.max_num_dpp = dc->res_pool->pipe_count;
dcn3_1_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_1_soc.num_states - 1; j >= 0; j--) {
if ((unsigned int) dcn3_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
s[i].state = i;
/* Clocks dependent on voltage level. */
s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
s[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz *
2 * clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
dcn3_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
dcn3_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
s[i].dram_bw_per_chan_gbps =
dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
s[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
s[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
s[i].phyclk_d18_mhz =
dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
s[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
if (clk_table->num_entries)
dcn3_1_soc.num_states = clk_table->num_entries;
memcpy(dcn3_1_soc.clock_limits, s, sizeof(dcn3_1_soc.clock_limits));
dcn3_1_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
if ((int)(dcn3_1_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_1_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000;
}
dml_init_instance(&dc->dml, &dcn3_1_soc, &dcn3_1_ip, DML_PROJECT_DCN31);
}
void dcn315_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct clk_limit_table *clk_table = &bw_params->clk_table;
unsigned int i, max_dispclk_mhz = 0, max_dppclk_mhz = 0;
dc_assert_fp_enabled();
dcn3_15_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
dcn3_15_ip.max_num_dpp = dc->res_pool->pipe_count;
if (bw_params->num_channels > 0)
dcn3_15_soc.num_chans = bw_params->num_channels;
if (bw_params->dram_channel_width_bytes > 0)
dcn3_15_soc.dram_channel_width_bytes = bw_params->dram_channel_width_bytes;
ASSERT(clk_table->num_entries);
/* Setup soc to always use max dispclk/dppclk to avoid odm-to-lower-voltage */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
dcn3_15_soc.clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
dcn3_15_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
dcn3_15_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
dcn3_15_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
dcn3_15_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
/* These aren't actually read from smu, but rather set in clk_mgr defaults */
dcn3_15_soc.clock_limits[i].dtbclk_mhz = clk_table->entries[i].dtbclk_mhz;
dcn3_15_soc.clock_limits[i].phyclk_d18_mhz = clk_table->entries[i].phyclk_d18_mhz;
dcn3_15_soc.clock_limits[i].phyclk_mhz = clk_table->entries[i].phyclk_mhz;
/* Clocks independent of voltage level. */
dcn3_15_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
dcn3_15_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
dcn3_15_soc.clock_limits[i].dscclk_mhz = max_dispclk_mhz / 3.0;
}
dcn3_15_soc.num_states = clk_table->num_entries;
/* Set vco to max_dispclk * 2 to make sure the highest dispclk is always available for dml calcs,
* no impact outside of dml validation
*/
dcn3_15_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
if ((int)(dcn3_15_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_15_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000;
}
dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN315);
}
void dcn316_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct clk_limit_table *clk_table = &bw_params->clk_table;
unsigned int i, closest_clk_lvl;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
int j;
dc_assert_fp_enabled();
memcpy(s, dcn3_16_soc.clock_limits, sizeof(dcn3_16_soc.clock_limits));
// Default clock levels are used for diags, which may lead to overclocking.
dcn3_16_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
dcn3_16_ip.max_num_dpp = dc->res_pool->pipe_count;
dcn3_16_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_16_soc.num_states - 1; j >= 0; j--) {
if ((unsigned int) dcn3_16_soc.clock_limits[j].dcfclk_mhz <=
clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
s[i].state = i;
/* Clocks dependent on voltage level. */
s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
s[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz *
2 * clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
dcn3_16_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
dcn3_16_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
s[i].dram_bw_per_chan_gbps =
dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
s[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
s[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
s[i].phyclk_d18_mhz =
dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
s[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
if (clk_table->num_entries)
dcn3_16_soc.num_states = clk_table->num_entries;
memcpy(dcn3_16_soc.clock_limits, s, sizeof(dcn3_16_soc.clock_limits));
if (max_dispclk_mhz) {
dcn3_16_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
}
if ((int)(dcn3_16_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_16_soc.dram_clock_change_latency_us = dc->debug.dram_clock_change_latency_ns / 1000;
}
dml_init_instance(&dc->dml, &dcn3_16_soc, &dcn3_16_ip, DML_PROJECT_DCN31);
}
int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc)
{
dc_assert_fp_enabled();
return (int)(soc->clock_limits[0].dispclk_mhz * 10000.0 / (1.0 + soc->dcn_downspread_percent / 100.0));
}
int dcn_get_approx_det_segs_required_for_pstate(
struct _vcs_dpi_soc_bounding_box_st *soc,
int pix_clk_100hz, int bpp, int seg_size_kb)
{
dc_assert_fp_enabled();
/* Roughly calculate required crb to hide latency. In practice there is slightly
* more buffer available for latency hiding
*/
return (int)(soc->dram_clock_change_latency_us * pix_clk_100hz * bpp
/ 10240000 + seg_size_kb - 1) / seg_size_kb;
}
@@ -0,0 +1,59 @@
/*
* Copyright 2019-2021 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 __DCN31_FPU_H__
#define __DCN31_FPU_H__
#define DCN3_1_DEFAULT_DET_SIZE 384
#define DCN3_15_DEFAULT_DET_SIZE 192
#define DCN3_15_MIN_COMPBUF_SIZE_KB 128
#define DCN3_16_DEFAULT_DET_SIZE 192
#define DCN3_16_MIN_COMPBUF_SIZE_KB 128
void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
int pipe_cnt);
void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
void dcn315_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
void dcn31_calculate_wm_and_dlg_fp(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
void dcn31_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
void dcn315_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
void dcn316_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc);
int dcn_get_approx_det_segs_required_for_pstate(
struct _vcs_dpi_soc_bounding_box_st *soc,
int pix_clk_100hz, int bpp, int seg_size_kb);
int dcn31x_populate_dml_pipes_from_context(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
#endif /* __DCN31_FPU_H__*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,43 @@
/*
* Copyright 2017 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 __DML31_DISPLAY_MODE_VBA_H__
#define __DML31_DISPLAY_MODE_VBA_H__
void dml31_recalculate(struct display_mode_lib *mode_lib);
void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
double dml31_CalculateWriteBackDISPCLK(
enum source_format_class WritebackPixelFormat,
double PixelClock,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackHTaps,
unsigned int WritebackVTaps,
long WritebackSourceWidth,
long WritebackDestinationWidth,
unsigned int HTotal,
unsigned int WritebackLineBufferSize);
#endif /* __DML31_DISPLAY_MODE_VBA_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
/*
* Copyright 2017 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 __DML31_DISPLAY_RQ_DLG_CALC_H__
#define __DML31_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_param - pipe source configuration (e.g. vp, pitch, scaling, dest, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml31_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
@@ -0,0 +1,429 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2022 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 "clk_mgr.h"
#include "resource.h"
#include "dcn31/dcn31_hubbub.h"
#include "dcn314_fpu.h"
#include "dml/dcn20/dcn20_fpu.h"
#include "dml/dcn31/dcn31_fpu.h"
#include "dml/display_mode_vba.h"
#include "dml/dml_inline_defs.h"
struct _vcs_dpi_ip_params_st dcn3_14_ip = {
.VBlankNomDefaultUS = 668,
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE,
.config_return_buffer_size_in_kbytes = 1792,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 4,
.maximum_dsc_bits_per_component = 10,
.dsc422_native_support = false,
.is_line_buffer_bpp_fixed = true,
.line_buffer_fixed_bpp = 48,
.line_buffer_size_bits = 789504,
.max_line_buffer_lines = 12,
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.dispclk_ramp_margin_percent = 1,
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 46,
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 27,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 119,
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
};
static struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 186.0,
.dtbclk_mhz = 600.0,
},
{
.state = 1,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 2,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 3,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 371.0,
.dtbclk_mhz = 600.0,
},
{
.state = 4,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 417.0,
.dtbclk_mhz = 600.0,
},
},
.num_states = 5,
.sr_exit_time_us = 16.5,
.sr_enter_plus_exit_time_us = 18.5,
.sr_exit_z8_time_us = 268.0,
.sr_enter_plus_exit_z8_time_us = 393.0,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,
.round_trip_ping_latency_dcfclk_cycles = 106,
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
};
void dcn314_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct clk_limit_table *clk_table = &bw_params->clk_table;
struct _vcs_dpi_voltage_scaling_st *clock_limits =
dcn3_14_soc.clock_limits;
unsigned int i, closest_clk_lvl;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
int j;
dc_assert_fp_enabled();
// Default clock levels are used for diags, which may lead to overclocking.
if (dc->config.use_default_clock_table == false) {
dcn3_14_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
dcn3_14_ip.max_num_dpp = dc->res_pool->pipe_count;
if (bw_params->dram_channel_width_bytes > 0)
dcn3_14_soc.dram_channel_width_bytes = bw_params->dram_channel_width_bytes;
if (bw_params->num_channels > 0)
dcn3_14_soc.num_chans = bw_params->num_channels;
ASSERT(dcn3_14_soc.num_chans);
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_14_soc.num_states - 1; j >= 0; j--) {
if ((unsigned int) dcn3_14_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
if (clk_table->num_entries == 1) {
/*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_14_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz < dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
/*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
if (clk_table->entries[i].memclk_mhz && clk_table->entries[i].wck_ratio)
clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
dcn3_14_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
dcn3_14_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
clock_limits[i].dram_bw_per_chan_gbps = dcn3_14_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
clock_limits[i].dscclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
clock_limits[i].dtbclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
clock_limits[i].phyclk_d18_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
clock_limits[i].phyclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++)
dcn3_14_soc.clock_limits[i] = clock_limits[i];
if (clk_table->num_entries) {
dcn3_14_soc.num_states = clk_table->num_entries;
}
}
if (max_dispclk_mhz) {
dcn3_14_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
}
dcn20_patch_bounding_box(dc, &dcn3_14_soc);
dml_init_instance(&dc->dml, &dcn3_14_soc, &dcn3_14_ip, DML_PROJECT_DCN314);
}
static bool is_dual_plane(enum surface_pixel_format format)
{
return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/*
* micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing
*
* @param: num_us: number of microseconds
* @return: number of vertical lines. If exact number of vertical lines is not found then
* it will round up to next number of lines to guarantee num_us
*/
static unsigned int micro_sec_to_vert_lines(unsigned int num_us, struct dc_crtc_timing *timing)
{
unsigned int num_lines = 0;
double lines_time_in_ns = 1000.0 *
(((double)timing->h_total * 1000.0) /
((double)timing->pix_clk_100hz / 10.0));
num_lines = (unsigned int)dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0);
return num_lines;
}
static unsigned int get_vertical_back_porch(struct dc_crtc_timing *timing)
{
unsigned int v_active = 0, v_blank = 0, v_back_porch = 0;
v_active = timing->v_border_top + timing->v_addressable + timing->v_border_bottom;
v_blank = timing->v_total - v_active;
v_back_porch = v_blank - timing->v_front_porch - timing->v_sync_width;
return v_back_porch;
}
int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
int pipe_cnt;
unsigned int i;
struct resource_context *res_ctx = &context->res_ctx;
struct pipe_ctx *pipe = 0;
bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023;
dc_assert_fp_enabled();
dcn31x_populate_dml_pipes_from_context(dc, context, pipes, validate_mode);
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_crtc_timing *timing;
unsigned int num_lines = 0;
unsigned int v_back_porch = 0;
if (!res_ctx->pipe_ctx[i].stream)
continue;
pipe = &res_ctx->pipe_ctx[i];
timing = &pipe->stream->timing;
num_lines = micro_sec_to_vert_lines(dcn3_14_ip.VBlankNomDefaultUS, timing);
if (pipe->stream->adjust.v_total_min != 0)
pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
else
pipes[pipe_cnt].pipe.dest.vtotal = timing->v_total;
v_back_porch = get_vertical_back_porch(timing);
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines);
// vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2)
// + 2 is because
// 1 -> VStartup_start should be 1 line before VSync
// 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
if (pipe->plane_state &&
(pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
upscaled = true;
/* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */
if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active;
/*
* Immediate flip can be set dynamically after enabling the plane.
* We need to require support for immediate flip or underflow can be
* intermittently experienced depending on peak b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
if (pipes[pipe_cnt].dout.dsc_enable) {
switch (timing->display_color_depth) {
case COLOR_DEPTH_888:
pipes[pipe_cnt].dout.dsc_input_bpc = 8;
break;
case COLOR_DEPTH_101010:
pipes[pipe_cnt].dout.dsc_input_bpc = 10;
break;
case COLOR_DEPTH_121212:
pipes[pipe_cnt].dout.dsc_input_bpc = 12;
break;
default:
ASSERT(0);
break;
}
}
pipe_cnt++;
}
context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE;
if (pipe_cnt == 1 && pipe->plane_state
&& pipe->plane_state->rotation == ROTATION_ANGLE_0 && !dc->debug.disable_z9_mpc) {
if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
/* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
pipes[0].pipe.src.unbounded_req_mode = true;
}
} else if (context->stream_count >= dc->debug.crb_alloc_policy_min_disp_count
&& dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes = dc->debug.crb_alloc_policy * 64;
} else if (context->stream_count >= 3 && upscaled) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
}
if (dc->debug.force_odm_combine_4to1)
context->bw_ctx.dml.ip.odm_combine_4to1_supported = true;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i];
if (!cur_pipe->stream)
continue;
if (cur_pipe->stream->signal == SIGNAL_TYPE_EDP && dc->debug.seamless_boot_odm_combine &&
cur_pipe->stream->apply_seamless_boot_optimization) {
if (cur_pipe->stream->apply_boot_odm_mode == dm_odm_combine_policy_2to1) {
context->bw_ctx.dml.vba.ODMCombinePolicy = dm_odm_combine_policy_2to1;
break;
}
}
}
return pipe_cnt;
}
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DCN314_FPU_H__
#define __DCN314_FPU_H__
#define DCN3_14_DEFAULT_DET_SIZE 384
#define DCN3_14_MAX_DET_SIZE 384
#define DCN3_14_MIN_COMPBUF_SIZE_KB 128
#define DCN3_14_CRB_SEGMENT_SIZE_KB 64
void dcn314_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DML314_DISPLAY_MODE_VBA_H__
#define __DML314_DISPLAY_MODE_VBA_H__
void dml314_recalculate(struct display_mode_lib *mode_lib);
void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
double dml314_CalculateWriteBackDISPCLK(
enum source_format_class WritebackPixelFormat,
double PixelClock,
double WritebackHRatio,
double WritebackVRatio,
unsigned int WritebackHTaps,
unsigned int WritebackVTaps,
long WritebackSourceWidth,
long WritebackDestinationWidth,
unsigned int HTotal,
unsigned int WritebackLineBufferSize);
#endif /* __DML314_DISPLAY_MODE_VBA_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DML314_DISPLAY_RQ_DLG_CALC_H__
#define __DML314_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_param - pipe source configuration (e.g. vp, pitch, scaling, dest, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml314_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml314_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DCN32_FPU_H__
#define __DCN32_FPU_H__
#include "clk_mgr_internal.h"
void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr);
void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt);
void dcn32_set_phantom_stream_timing(struct dc *dc,
struct dc_state *context,
struct pipe_ctx *ref_pipe,
struct dc_stream_state *phantom_stream,
display_e2e_pipe_params_st *pipes,
unsigned int pipe_cnt,
unsigned int dc_pipe_idx);
bool dcn32_internal_validate_bw(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *pipe_cnt_out,
int *vlevel_out,
enum dc_validate_mode validate_mode);
void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
void dcn32_patch_dpm_table(struct clk_bw_params *bw_params);
void dcn32_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
int pipe_cnt);
void dcn32_assign_fpo_vactive_candidate(struct dc *dc, const struct dc_state *context, struct dc_stream_state **fpo_candidate_stream);
bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, struct dc_stream_state *fpo_candidate_stream, uint32_t vactive_margin_req);
void dcn32_override_min_req_memclk(struct dc *dc, struct dc_state *context);
void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb);
unsigned int dcn32_get_max_dispclk_mhz(struct dc *dc, struct dc_state *context);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,64 @@
/*
* Copyright 2022 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 __DML32_DISPLAY_MODE_VBA_H__
#define __DML32_DISPLAY_MODE_VBA_H__
#include "../display_mode_enums.h"
// To enable a lot of debug msg
//#define __DML_VBA_DEBUG__
// For DML-C changes that hasn't been propagated to VBA yet
//#define __DML_VBA_ALLOW_DELTA__
// Move these to ip parameters/constant
// At which vstartup the DML start to try if the mode can be supported
#define __DML_VBA_MIN_VSTARTUP__ 9
// Delay in DCFCLK from ARB to DET (1st num is ARB to SDPIF, 2nd number is SDPIF to DET)
#define __DML_ARB_TO_RET_DELAY__ 7 + 95
// fudge factor for min dcfclk calclation
#define __DML_MIN_DCFCLK_FACTOR__ 1.15
// Prefetch schedule max vratio
#define __DML_MAX_VRATIO_PRE__ 7.9
#define __DML_MAX_BW_RATIO_PRE__ 4.0
#define __DML_VBA_MAX_DST_Y_PRE__ 63.75
#define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff
#define MEM_STROBE_FREQ_MHZ 1600
#define DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ 300
#define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0
struct display_mode_lib;
void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
void dml32_recalculate(struct display_mode_lib *mode_lib);
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,614 @@
/*
* Copyright 2022 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 "../display_mode_lib.h"
#include "../display_mode_vba.h"
#include "../dml_inline_defs.h"
#include "display_rq_dlg_calc_32.h"
static bool is_dual_plane(enum source_format_class source_format)
{
bool ret_val = 0;
if ((source_format == dm_420_12) || (source_format == dm_420_8) || (source_format == dm_420_10)
|| (source_format == dm_rgbe_alpha))
ret_val = 1;
return ret_val;
}
void dml32_rq_dlg_get_rq_reg(display_rq_regs_st *rq_regs,
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx)
{
const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
bool dual_plane = is_dual_plane((enum source_format_class) (src->source_format));
double stored_swath_l_bytes;
double stored_swath_c_bytes;
bool is_phantom_pipe;
uint32_t pixel_chunk_bytes = 0;
uint32_t min_pixel_chunk_bytes = 0;
uint32_t meta_chunk_bytes = 0;
uint32_t min_meta_chunk_bytes = 0;
uint32_t dpte_group_bytes = 0;
uint32_t mpte_group_bytes = 0;
uint32_t p1_pixel_chunk_bytes = 0;
uint32_t p1_min_pixel_chunk_bytes = 0;
uint32_t p1_meta_chunk_bytes = 0;
uint32_t p1_min_meta_chunk_bytes = 0;
uint32_t p1_dpte_group_bytes = 0;
uint32_t p1_mpte_group_bytes = 0;
unsigned int detile_buf_size_in_bytes;
unsigned int detile_buf_plane1_addr;
unsigned int pte_row_height_linear;
memset(rq_regs, 0, sizeof(*rq_regs));
dml_print("DML_DLG::%s: Calculation for pipe[%d] start, num_pipes=%d\n", __func__, pipe_idx, num_pipes);
pixel_chunk_bytes = (uint32_t)(get_pixel_chunk_size_in_kbyte(mode_lib, e2e_pipe_param, num_pipes) * 1024); // From VBA
min_pixel_chunk_bytes = (uint32_t)get_min_pixel_chunk_size_in_byte(mode_lib, e2e_pipe_param, num_pipes); // From VBA
if (pixel_chunk_bytes == 64 * 1024)
min_pixel_chunk_bytes = 0;
meta_chunk_bytes = (uint32_t)(get_meta_chunk_size_in_kbyte(mode_lib, e2e_pipe_param, num_pipes) * 1024); // From VBA
min_meta_chunk_bytes = (uint32_t)get_min_meta_chunk_size_in_byte(mode_lib, e2e_pipe_param, num_pipes); // From VBA
dpte_group_bytes = (uint32_t)get_dpte_group_size_in_bytes(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
mpte_group_bytes = (uint32_t)get_vm_group_size_in_bytes(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
p1_pixel_chunk_bytes = pixel_chunk_bytes;
p1_min_pixel_chunk_bytes = min_pixel_chunk_bytes;
p1_meta_chunk_bytes = meta_chunk_bytes;
p1_min_meta_chunk_bytes = min_meta_chunk_bytes;
p1_dpte_group_bytes = dpte_group_bytes;
p1_mpte_group_bytes = mpte_group_bytes;
if ((enum source_format_class) src->source_format == dm_rgbe_alpha)
p1_pixel_chunk_bytes = (uint32_t)(get_alpha_pixel_chunk_size_in_kbyte(mode_lib, e2e_pipe_param, num_pipes) * 1024);
rq_regs->rq_regs_l.chunk_size = (uint32_t)(dml_log2(pixel_chunk_bytes) - 10);
rq_regs->rq_regs_c.chunk_size = (uint32_t)(dml_log2(p1_pixel_chunk_bytes) - 10);
if (min_pixel_chunk_bytes == 0)
rq_regs->rq_regs_l.min_chunk_size = 0;
else
rq_regs->rq_regs_l.min_chunk_size = dml_log2(min_pixel_chunk_bytes) - 8 + 1;
if (p1_min_pixel_chunk_bytes == 0)
rq_regs->rq_regs_c.min_chunk_size = 0;
else
rq_regs->rq_regs_c.min_chunk_size = dml_log2(p1_min_pixel_chunk_bytes) - 8 + 1;
rq_regs->rq_regs_l.meta_chunk_size = (uint32_t)(dml_log2(meta_chunk_bytes) - 10);
rq_regs->rq_regs_c.meta_chunk_size = (uint32_t)(dml_log2(p1_meta_chunk_bytes) - 10);
if (min_meta_chunk_bytes == 0)
rq_regs->rq_regs_l.min_meta_chunk_size = 0;
else
rq_regs->rq_regs_l.min_meta_chunk_size = dml_log2(min_meta_chunk_bytes) - 6 + 1;
if (p1_min_meta_chunk_bytes == 0)
rq_regs->rq_regs_c.min_meta_chunk_size = 0;
else
rq_regs->rq_regs_c.min_meta_chunk_size = dml_log2(p1_min_meta_chunk_bytes) - 6 + 1;
rq_regs->rq_regs_l.dpte_group_size = (uint32_t)(dml_log2(dpte_group_bytes) - 6);
rq_regs->rq_regs_l.mpte_group_size = dml_log2(mpte_group_bytes) - 6;
rq_regs->rq_regs_c.dpte_group_size = dml_log2(p1_dpte_group_bytes) - 6;
rq_regs->rq_regs_c.mpte_group_size = dml_log2(p1_mpte_group_bytes) - 6;
detile_buf_size_in_bytes = (unsigned int)(get_det_buffer_size_kbytes(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * 1024);
detile_buf_plane1_addr = 0;
pte_row_height_linear = (unsigned int)get_dpte_row_height_linear_l(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx);
if (src->sw_mode == dm_sw_linear)
ASSERT(pte_row_height_linear >= 8);
rq_regs->rq_regs_l.pte_row_height_linear = (unsigned int)(dml_floor(dml_log2(pte_row_height_linear), 1) - 3);
if (dual_plane) {
unsigned int p1_pte_row_height_linear = (unsigned int)get_dpte_row_height_linear_c(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx);
if (src->sw_mode == dm_sw_linear)
ASSERT(p1_pte_row_height_linear >= 8);
rq_regs->rq_regs_c.pte_row_height_linear = (unsigned int)(dml_floor(dml_log2(p1_pte_row_height_linear), 1) - 3);
}
rq_regs->rq_regs_l.swath_height = (unsigned int)dml_log2(get_swath_height_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx));
rq_regs->rq_regs_c.swath_height = (unsigned int)dml_log2(get_swath_height_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx));
// FIXME: take the max between luma, chroma chunk size?
// okay for now, as we are setting pixel_chunk_bytes to 8kb anyways
if (pixel_chunk_bytes >= 32 * 1024 || (dual_plane && p1_pixel_chunk_bytes >= 32 * 1024)) { //32kb
rq_regs->drq_expansion_mode = 0;
} else {
rq_regs->drq_expansion_mode = 2;
}
rq_regs->prq_expansion_mode = 1;
rq_regs->mrq_expansion_mode = 1;
rq_regs->crq_expansion_mode = 1;
stored_swath_l_bytes = get_det_stored_buffer_size_l_bytes(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx);
stored_swath_c_bytes = get_det_stored_buffer_size_c_bytes(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx);
is_phantom_pipe = get_is_phantom_pipe(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
// Note: detile_buf_plane1_addr is in unit of 1KB
if (dual_plane) {
if (is_phantom_pipe) {
detile_buf_plane1_addr = (unsigned int)((1024.0 * 1024.0) / 2.0 / 1024.0); // half to chroma
} else {
if (stored_swath_l_bytes / stored_swath_c_bytes <= 1.5) {
detile_buf_plane1_addr = (unsigned int)(detile_buf_size_in_bytes / 2.0 / 1024.0); // half to chroma
#ifdef __DML_RQ_DLG_CALC_DEBUG__
dml_print("DML_DLG: %s: detile_buf_plane1_addr = %d (1/2 to chroma)\n",
__func__, detile_buf_plane1_addr);
#endif
} else {
detile_buf_plane1_addr = (unsigned int)(
dml_round_to_multiple(
(unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
1024, 0) / 1024.0); // 2/3 to luma
#ifdef __DML_RQ_DLG_CALC_DEBUG__
dml_print("DML_DLG: %s: detile_buf_plane1_addr = %d (1/3 chroma)\n",
__func__, detile_buf_plane1_addr);
#endif
}
}
}
rq_regs->plane1_base_address = detile_buf_plane1_addr;
#ifdef __DML_RQ_DLG_CALC_DEBUG__
dml_print("DML_DLG: %s: is_phantom_pipe = %d\n", __func__, is_phantom_pipe);
dml_print("DML_DLG: %s: stored_swath_l_bytes = %f\n", __func__, stored_swath_l_bytes);
dml_print("DML_DLG: %s: stored_swath_c_bytes = %f\n", __func__, stored_swath_c_bytes);
dml_print("DML_DLG: %s: detile_buf_size_in_bytes = %d\n", __func__, detile_buf_size_in_bytes);
dml_print("DML_DLG: %s: detile_buf_plane1_addr = %d\n", __func__, detile_buf_plane1_addr);
dml_print("DML_DLG: %s: plane1_base_address = %d\n", __func__, rq_regs->plane1_base_address);
#endif
print__rq_regs_st(mode_lib, rq_regs);
dml_print("DML_DLG::%s: Calculation for pipe[%d] done, num_pipes=%d\n", __func__, pipe_idx, num_pipes);
}
void dml32_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx)
{
const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
double refcyc_per_req_delivery_pre_cur0 = 0.;
double refcyc_per_req_delivery_cur0 = 0.;
double refcyc_per_req_delivery_pre_c = 0.;
double refcyc_per_req_delivery_c = 0.;
double refcyc_per_req_delivery_pre_l;
double refcyc_per_req_delivery_l;
double refcyc_per_line_delivery_pre_c = 0.;
double refcyc_per_line_delivery_c = 0.;
double refcyc_per_line_delivery_pre_l;
double refcyc_per_line_delivery_l;
double min_ttu_vblank;
double vratio_pre_l;
double vratio_pre_c;
unsigned int min_dst_y_next_start;
unsigned int htotal = dst->htotal;
unsigned int hblank_end = dst->hblank_end;
unsigned int vblank_end = dst->vblank_end;
bool interlaced = dst->interlaced;
double pclk_freq_in_mhz = dst->pixel_rate_mhz;
unsigned int vready_after_vcount0;
double refclk_freq_in_mhz = clks->refclk_mhz;
double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
bool dual_plane = 0;
unsigned int pipe_index_in_combine[DC__NUM_PIPES__MAX];
unsigned int dst_x_after_scaler;
unsigned int dst_y_after_scaler;
double dst_y_prefetch;
double dst_y_per_vm_vblank;
double dst_y_per_row_vblank;
double dst_y_per_vm_flip;
double dst_y_per_row_flip;
double max_dst_y_per_vm_vblank = 32.0;
double max_dst_y_per_row_vblank = 16.0;
double dst_y_per_pte_row_nom_l;
double dst_y_per_pte_row_nom_c;
double dst_y_per_meta_row_nom_l;
double dst_y_per_meta_row_nom_c;
double refcyc_per_pte_group_nom_l;
double refcyc_per_pte_group_nom_c;
double refcyc_per_pte_group_vblank_l;
double refcyc_per_pte_group_vblank_c;
double refcyc_per_pte_group_flip_l;
double refcyc_per_pte_group_flip_c;
double refcyc_per_meta_chunk_nom_l;
double refcyc_per_meta_chunk_nom_c;
double refcyc_per_meta_chunk_vblank_l;
double refcyc_per_meta_chunk_vblank_c;
double refcyc_per_meta_chunk_flip_l;
double refcyc_per_meta_chunk_flip_c;
memset(dlg_regs, 0, sizeof(*dlg_regs));
memset(ttu_regs, 0, sizeof(*ttu_regs));
dml_print("DML_DLG::%s: Calculation for pipe[%d] starts, num_pipes=%d\n", __func__, pipe_idx, num_pipes);
dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, ref_freq_to_pix_freq);
dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced);
ASSERT(ref_freq_to_pix_freq < 4.0);
dlg_regs->ref_freq_to_pix_freq = (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal * dml_pow(2, 8));
dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits
min_ttu_vblank = get_min_ttu_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
min_dst_y_next_start = (unsigned int)get_min_dst_y_next_start(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
dml_print("DML_DLG: %s: min_ttu_vblank (us) = %3.2f\n", __func__, min_ttu_vblank);
dml_print("DML_DLG: %s: min_dst_y_next_start = %d\n", __func__, min_dst_y_next_start);
dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, ref_freq_to_pix_freq);
dual_plane = is_dual_plane((enum source_format_class) (src->source_format));
vready_after_vcount0 = (unsigned int)get_vready_at_or_after_vsync(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx); // From VBA
dlg_regs->vready_after_vcount0 = vready_after_vcount0;
dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, dlg_regs->vready_after_vcount0);
dst_x_after_scaler = (unsigned int)dml_ceil(get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
dst_y_after_scaler = (unsigned int)dml_ceil(get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
// do some adjustment on the dst_after scaler to account for odm combine mode
dml_print("DML_DLG: %s: input dst_x_after_scaler = %d\n", __func__, dst_x_after_scaler);
dml_print("DML_DLG: %s: input dst_y_after_scaler = %d\n", __func__, dst_y_after_scaler);
// need to figure out which side of odm combine we're in
if (dst->odm_combine == dm_odm_combine_mode_2to1 || dst->odm_combine == dm_odm_combine_mode_4to1) {
// figure out which pipes go together
bool visited[DC__NUM_PIPES__MAX];
unsigned int i, j, k;
for (k = 0; k < num_pipes; ++k) {
visited[k] = false;
pipe_index_in_combine[k] = 0;
}
for (i = 0; i < num_pipes; i++) {
if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) {
unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp;
unsigned int grp_idx = 0;
for (j = i; j < num_pipes; j++) {
if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp
&& e2e_pipe_param[j].pipe.src.is_hsplit && !visited[j]) {
pipe_index_in_combine[j] = grp_idx;
dml_print("DML_DLG: %s: pipe[%d] is in grp %d idx %d\n",
__func__, j, grp, grp_idx);
grp_idx++;
visited[j] = true;
}
}
}
}
}
if (dst->odm_combine == dm_odm_combine_mode_disabled) {
// FIXME how about ODM split??
dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end * ref_freq_to_pix_freq);
} else {
if (dst->odm_combine == dm_odm_combine_mode_2to1 || dst->odm_combine == dm_odm_combine_mode_4to1) {
// TODO: We should really check that 4to1 is supported before setting it to 4
unsigned int odm_combine_factor = (dst->odm_combine == dm_odm_combine_mode_2to1 ? 2 : 4);
unsigned int odm_pipe_index = pipe_index_in_combine[pipe_idx];
dlg_regs->refcyc_h_blank_end = (unsigned int) (((double) hblank_end
+ odm_pipe_index * (double) dst->hactive / odm_combine_factor) * ref_freq_to_pix_freq);
}
}
ASSERT(dlg_regs->refcyc_h_blank_end < (unsigned int)dml_pow(2, 13));
dml_print("DML_DLG: %s: htotal= %d\n", __func__, htotal);
dml_print("DML_DLG: %s: dst_x_after_scaler[%d]= %d\n", __func__, pipe_idx, dst_x_after_scaler);
dml_print("DML_DLG: %s: dst_y_after_scaler[%d] = %d\n", __func__, pipe_idx, dst_y_after_scaler);
dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
// From VBA
dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
// From VBA
dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
// magic!
if (htotal <= 75) {
max_dst_y_per_vm_vblank = 100.0;
max_dst_y_per_row_vblank = 100.0;
}
dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
dml_print("DML_DLG: %s: dst_y_per_vm_flip = %3.2f\n", __func__, dst_y_per_vm_flip);
dml_print("DML_DLG: %s: dst_y_per_row_flip = %3.2f\n", __func__, dst_y_per_row_flip);
dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank);
dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank);
ASSERT(dst_y_per_vm_vblank < max_dst_y_per_vm_vblank);
ASSERT(dst_y_per_row_vblank < max_dst_y_per_row_vblank);
ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
dml_print("DML_DLG: %s: vratio_pre_l = %3.2f\n", __func__, vratio_pre_l);
dml_print("DML_DLG: %s: vratio_pre_c = %3.2f\n", __func__, vratio_pre_c);
// Active
refcyc_per_line_delivery_pre_l = get_refcyc_per_line_delivery_pre_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_line_delivery_l = get_refcyc_per_line_delivery_l_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, refcyc_per_line_delivery_pre_l);
dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", __func__, refcyc_per_line_delivery_l);
if (dual_plane) {
refcyc_per_line_delivery_pre_c = get_refcyc_per_line_delivery_pre_c_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_line_delivery_c = get_refcyc_per_line_delivery_c_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
__func__, refcyc_per_line_delivery_pre_c);
dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n",
__func__, refcyc_per_line_delivery_c);
}
if (src->dynamic_metadata_enable && src->gpuvm)
dlg_regs->refcyc_per_vm_dmdata = (unsigned int)(get_refcyc_per_vm_dmdata_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz); // From VBA
dlg_regs->dmdata_dl_delta = (unsigned int)(get_dmdata_dl_delta_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx)
* refclk_freq_in_mhz); // From VBA
refcyc_per_req_delivery_pre_l = (unsigned int)(get_refcyc_per_req_delivery_pre_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz); // From VBA
refcyc_per_req_delivery_l = (unsigned int)(get_refcyc_per_req_delivery_l_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz); // From VBA
dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, refcyc_per_req_delivery_pre_l);
dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", __func__, refcyc_per_req_delivery_l);
if (dual_plane) {
refcyc_per_req_delivery_pre_c = get_refcyc_per_req_delivery_pre_c_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_req_delivery_c = get_refcyc_per_req_delivery_c_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
__func__, refcyc_per_req_delivery_pre_c);
dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", __func__, refcyc_per_req_delivery_c);
}
// TTU - Cursor
ASSERT(src->num_cursors <= 1);
if (src->num_cursors > 0) {
refcyc_per_req_delivery_pre_cur0 = get_refcyc_per_cursor_req_delivery_pre_in_us(mode_lib,
e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_req_delivery_cur0 = get_refcyc_per_cursor_req_delivery_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f\n",
__func__, refcyc_per_req_delivery_pre_cur0);
dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f\n",
__func__, refcyc_per_req_delivery_cur0);
}
// Assign to register structures
dlg_regs->min_dst_y_next_start = (unsigned int)(min_dst_y_next_start * dml_pow(2, 2));
ASSERT(dlg_regs->min_dst_y_next_start < (unsigned int)dml_pow(2, 18));
dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
dlg_regs->refcyc_x_after_scaler = (unsigned int)(dst_x_after_scaler * ref_freq_to_pix_freq); // in terms of refclk
dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
dml_print("DML_DLG: %s: dlg_regs->dst_y_per_vm_vblank = 0x%x\n", __func__, dlg_regs->dst_y_per_vm_vblank);
dml_print("DML_DLG: %s: dlg_regs->dst_y_per_row_vblank = 0x%x\n", __func__, dlg_regs->dst_y_per_row_vblank);
dml_print("DML_DLG: %s: dlg_regs->dst_y_per_vm_flip = 0x%x\n", __func__, dlg_regs->dst_y_per_vm_flip);
dml_print("DML_DLG: %s: dlg_regs->dst_y_per_row_flip = 0x%x\n", __func__, dlg_regs->dst_y_per_row_flip);
dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(get_refcyc_per_vm_group_vblank_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz); // From VBA
dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(get_refcyc_per_vm_group_flip_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz); // From VBA
dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(get_refcyc_per_vm_req_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10)); // From VBA
dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(get_refcyc_per_vm_req_flip_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10)); // From VBA
// From VBA
dst_y_per_pte_row_nom_l = get_dst_y_per_pte_row_nom_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
// From VBA
dst_y_per_pte_row_nom_c = get_dst_y_per_pte_row_nom_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
// From VBA
dst_y_per_meta_row_nom_l = get_dst_y_per_meta_row_nom_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
// From VBA
dst_y_per_meta_row_nom_c = get_dst_y_per_meta_row_nom_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
refcyc_per_pte_group_nom_l = get_refcyc_per_pte_group_nom_l_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_pte_group_nom_c = get_refcyc_per_pte_group_nom_c_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_pte_group_vblank_l = get_refcyc_per_pte_group_vblank_l_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_pte_group_vblank_c = get_refcyc_per_pte_group_vblank_c_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_pte_group_flip_l = get_refcyc_per_pte_group_flip_l_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_pte_group_flip_c = get_refcyc_per_pte_group_flip_c_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_nom_l = get_refcyc_per_meta_chunk_nom_l_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_nom_c = get_refcyc_per_meta_chunk_nom_c_in_us(mode_lib, e2e_pipe_param, num_pipes,
pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_vblank_l = get_refcyc_per_meta_chunk_vblank_l_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_vblank_c = get_refcyc_per_meta_chunk_vblank_c_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_flip_l = get_refcyc_per_meta_chunk_flip_l_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
refcyc_per_meta_chunk_flip_c = get_refcyc_per_meta_chunk_flip_c_in_us(mode_lib, e2e_pipe_param,
num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int)(dst_y_per_pte_row_nom_l * dml_pow(2, 2));
dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int)(dst_y_per_pte_row_nom_c * dml_pow(2, 2));
dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int)(dst_y_per_meta_row_nom_l * dml_pow(2, 2));
dlg_regs->dst_y_per_meta_row_nom_c = (unsigned int)(dst_y_per_meta_row_nom_c * dml_pow(2, 2));
dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)refcyc_per_pte_group_nom_l;
dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)refcyc_per_pte_group_nom_c;
dlg_regs->refcyc_per_pte_group_vblank_l = (unsigned int)refcyc_per_pte_group_vblank_l;
dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int)refcyc_per_pte_group_vblank_c;
dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int)refcyc_per_pte_group_flip_l;
dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int)refcyc_per_pte_group_flip_c;
dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int)refcyc_per_meta_chunk_nom_l;
dlg_regs->refcyc_per_meta_chunk_nom_c = (unsigned int)refcyc_per_meta_chunk_nom_c;
dlg_regs->refcyc_per_meta_chunk_vblank_l = (unsigned int)refcyc_per_meta_chunk_vblank_l;
dlg_regs->refcyc_per_meta_chunk_vblank_c = (unsigned int)refcyc_per_meta_chunk_vblank_c;
dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int)refcyc_per_meta_chunk_flip_l;
dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int)refcyc_per_meta_chunk_flip_c;
dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l, 1);
dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l, 1);
dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c, 1);
dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c, 1);
dlg_regs->chunk_hdl_adjust_cur0 = 3;
dlg_regs->dst_y_offset_cur0 = 0;
dlg_regs->chunk_hdl_adjust_cur1 = 3;
dlg_regs->dst_y_offset_cur1 = 0;
dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_pre_cur0 =
(unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
ttu_regs->refcyc_per_req_delivery_pre_cur1 = 0;
ttu_regs->refcyc_per_req_delivery_cur1 = 0;
ttu_regs->qos_level_low_wm = 0;
ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal * ref_freq_to_pix_freq);
ttu_regs->qos_level_flip = 14;
ttu_regs->qos_level_fixed_l = 8;
ttu_regs->qos_level_fixed_c = 8;
ttu_regs->qos_level_fixed_cur0 = 8;
ttu_regs->qos_ramp_disable_l = 0;
ttu_regs->qos_ramp_disable_c = 0;
ttu_regs->qos_ramp_disable_cur0 = 0;
ttu_regs->min_ttu_vblank = (unsigned int)(min_ttu_vblank * refclk_freq_in_mhz);
// CHECK for HW registers' range, assert or clamp
ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
if (dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_vm_group_vblank = (unsigned int)(dml_pow(2, 23) - 1);
if (dlg_regs->refcyc_per_vm_group_flip >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_vm_group_flip = (unsigned int)(dml_pow(2, 23) - 1);
if (dlg_regs->refcyc_per_vm_req_vblank >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_vm_req_vblank = (unsigned int)(dml_pow(2, 23) - 1);
if (dlg_regs->refcyc_per_vm_req_flip >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(dml_pow(2, 23) - 1);
ASSERT(dlg_regs->dst_y_after_scaler < (unsigned int) 8);
ASSERT(dlg_regs->refcyc_x_after_scaler < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int)dml_pow(2, 17));
if (dual_plane) {
if (dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
// FIXME what so special about chroma, can we just assert?
dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u > register max U15.2 %u\n",
__func__, dlg_regs->dst_y_per_pte_row_nom_c, (unsigned int)dml_pow(2, 17) - 1);
}
}
ASSERT(dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int)dml_pow(2, 17));
ASSERT(dlg_regs->dst_y_per_meta_row_nom_c < (unsigned int)dml_pow(2, 17));
if (dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int)(dml_pow(2, 23) - 1);
if (dual_plane) {
if (dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int)(dml_pow(2, 23) - 1);
}
ASSERT(dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int)dml_pow(2, 13));
if (dual_plane) {
ASSERT(dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int)dml_pow(2, 13));
}
if (dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int)(dml_pow(2, 23) - 1);
if (dual_plane) {
if (dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
dlg_regs->refcyc_per_meta_chunk_nom_c = (unsigned int)(dml_pow(2, 23) - 1);
}
ASSERT(dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->refcyc_per_meta_chunk_vblank_c < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->refcyc_per_line_delivery_l < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int)dml_pow(2, 13));
ASSERT(dlg_regs->refcyc_per_line_delivery_c < (unsigned int)dml_pow(2, 13));
ASSERT(ttu_regs->qos_level_low_wm < dml_pow(2, 14));
ASSERT(ttu_regs->qos_level_high_wm < dml_pow(2, 14));
ASSERT(ttu_regs->min_ttu_vblank < dml_pow(2, 24));
print__ttu_regs_st(mode_lib, ttu_regs);
print__dlg_regs_st(mode_lib, dlg_regs);
dml_print("DML_DLG::%s: Calculation for pipe[%d] done, num_pipes=%d\n", __func__, pipe_idx, num_pipes);
}
@@ -0,0 +1,70 @@
/*
* Copyright 2022 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 __DML32_DISPLAY_RQ_DLG_CALC_H__
#define __DML32_DISPLAY_RQ_DLG_CALC_H__
#include "../display_rq_dlg_helpers.h"
struct display_mode_lib;
/*
* Function: dml_rq_dlg_get_rq_reg
* Main entry point for test to get the register values out of this DML class.
* This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
* and then populate the rq_regs struct
* Input:
* pipe_param - pipe source configuration (e.g. vp, pitch, scaling, dest, etc.)
* Output:
* rq_regs - struct that holds all the RQ registers field value.
* See also: <display_rq_regs_st>
*/
void dml32_rq_dlg_get_rq_reg(display_rq_regs_st *rq_regs,
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx);
/*
* Function: dml_rq_dlg_get_dlg_reg
* Calculate and return DLG and TTU register struct given the system setting
* Output:
* dlg_regs - output DLG register struct
* ttu_regs - output DLG TTU register struct
* Input:
* e2e_pipe_param - "compacted" array of e2e pipe param struct
* num_pipes - num of active "pipe" or "route"
* pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
* cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
* Added for legacy or unrealistic timing tests.
*/
void dml32_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx);
#endif
@@ -0,0 +1,934 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2022 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 "clk_mgr.h"
#include "resource.h"
#include "dcn321_fpu.h"
#include "dcn32/dcn32_resource.h"
#include "dcn321/dcn321_resource.h"
#include "dml/dcn32/display_mode_vba_util_32.h"
#define DCN3_2_DEFAULT_DET_SIZE 256
struct _vcs_dpi_ip_params_st dcn3_21_ip = {
.gpuvm_enable = 0,
.gpuvm_max_page_table_levels = 4,
.hostvm_enable = 0,
.rob_buffer_size_kbytes = 128,
.det_buffer_size_kbytes = DCN3_2_DEFAULT_DET_SIZE,
.config_return_buffer_size_in_kbytes = 1280,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 22,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,
.opp_output_buffer_lines = 1,
.pixel_chunk_size_kbytes = 8,
.alpha_pixel_chunk_size_kbytes = 4,
.min_pixel_chunk_size_bytes = 1024,
.dcc_meta_buffer_size_bytes = 6272,
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 4,
.maximum_dsc_bits_per_component = 12,
.maximum_pixels_per_line_per_dsc_unit = 6016,
.dsc422_native_support = true,
.is_line_buffer_bpp_fixed = true,
.line_buffer_fixed_bpp = 57,
.line_buffer_size_bits = 1171920,
.max_line_buffer_lines = 32,
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 64,
.dpte_buffer_size_in_pte_reqs_chroma = 34,
.dispclk_ramp_margin_percent = 1,
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 47,
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 28,
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 125,
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
.max_num_dp2p0_outputs = 2,
.max_num_dp2p0_streams = 4,
};
struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.clock_limits = {
{
.state = 0,
.dcfclk_mhz = 1434.0,
.fabricclk_mhz = 2250.0,
.dispclk_mhz = 1720.0,
.dppclk_mhz = 1720.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.phyclk_d32_mhz = 313.0,
.socclk_mhz = 1200.0,
.dscclk_mhz = 573.333,
.dram_speed_mts = 16000.0,
.dtbclk_mhz = 1564.0,
},
},
.num_states = 1,
.sr_exit_time_us = 19.95,
.sr_enter_plus_exit_time_us = 24.36,
.sr_exit_z8_time_us = 285.0,
.sr_enter_plus_exit_z8_time_us = 320,
.writeback_latency_us = 12.0,
.round_trip_ping_latency_dcfclk_cycles = 207,
.urgent_latency_pixel_data_only_us = 4,
.urgent_latency_pixel_mixed_with_vm_data_us = 4,
.urgent_latency_vm_data_only_us = 4,
.fclk_change_latency_us = 7,
.usr_retraining_latency_us = 0,
.smn_latency_us = 0,
.mall_allocated_for_dcn_mbytes = 32,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 90.0,
.pct_ideal_fabric_bw_after_urgent = 67.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.pct_ideal_dram_bw_after_urgent_strobe = 67.0,
.max_avg_sdp_bw_use_normal_percent = 80.0,
.max_avg_fabric_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_strobe_percent = 50.0,
.max_avg_dram_bw_use_normal_percent = 15.0,
.num_chans = 8,
.dram_channel_width_bytes = 2,
.fabric_datapath_to_dcn_data_return_bytes = 64,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.dram_clock_change_latency_us = 400,
.dispclk_dppclk_vco_speed_mhz = 4300.0,
.do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
};
static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
{
if (entry->dcfclk_mhz > 0) {
float bw_on_sdp = (float)(entry->dcfclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
entry->fabricclk_mhz = bw_on_sdp / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
entry->dram_speed_mts = bw_on_sdp / (dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
} else if (entry->fabricclk_mhz > 0) {
float bw_on_fabric = (float)(entry->fabricclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
entry->dcfclk_mhz = bw_on_fabric / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
entry->dram_speed_mts = bw_on_fabric / (dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
} else if (entry->dram_speed_mts > 0) {
float bw_on_dram = (float)(entry->dram_speed_mts * dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
entry->fabricclk_mhz = bw_on_dram / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
entry->dcfclk_mhz = bw_on_dram / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
}
}
static float calculate_net_bw_in_kbytes_sec(struct _vcs_dpi_voltage_scaling_st *entry)
{
float memory_bw_kbytes_sec;
float fabric_bw_kbytes_sec;
float sdp_bw_kbytes_sec;
float limiting_bw_kbytes_sec;
memory_bw_kbytes_sec = (float)(entry->dram_speed_mts * dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
fabric_bw_kbytes_sec = (float)(entry->fabricclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
sdp_bw_kbytes_sec = (float)(entry->dcfclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
limiting_bw_kbytes_sec = memory_bw_kbytes_sec;
if (fabric_bw_kbytes_sec < limiting_bw_kbytes_sec)
limiting_bw_kbytes_sec = fabric_bw_kbytes_sec;
if (sdp_bw_kbytes_sec < limiting_bw_kbytes_sec)
limiting_bw_kbytes_sec = sdp_bw_kbytes_sec;
return limiting_bw_kbytes_sec;
}
static void dcn321_insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table,
unsigned int *num_entries,
struct _vcs_dpi_voltage_scaling_st *entry)
{
unsigned int i = 0;
unsigned int index = 0;
dc_assert_fp_enabled();
if (*num_entries == 0) {
table[0] = *entry;
(*num_entries)++;
} else {
while (entry->net_bw_in_kbytes_sec > table[index].net_bw_in_kbytes_sec) {
index++;
if (index >= *num_entries)
break;
}
for (i = *num_entries; i > index; i--)
table[i] = table[i - 1];
table[index] = *entry;
(*num_entries)++;
}
}
static void remove_entry_from_table_at_index(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries,
unsigned int index)
{
unsigned int i;
if (*num_entries == 0)
return;
for (i = index; i < *num_entries - 1; i++) {
table[i] = table[i + 1];
}
memset(&table[--(*num_entries)], 0, sizeof(struct _vcs_dpi_voltage_scaling_st));
}
static void swap_table_entries(struct _vcs_dpi_voltage_scaling_st *first_entry,
struct _vcs_dpi_voltage_scaling_st *second_entry)
{
struct _vcs_dpi_voltage_scaling_st temp_entry = *first_entry;
*first_entry = *second_entry;
*second_entry = temp_entry;
}
/*
* sort_entries_with_same_bw - Sort entries sharing the same bandwidth by DCFCLK
*/
static void sort_entries_with_same_bw(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
{
unsigned int start_index = 0;
unsigned int end_index = 0;
unsigned int current_bw = 0;
for (unsigned int i = 0; i + 1 < *num_entries; i++) {
if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) {
current_bw = (unsigned int)table[i].net_bw_in_kbytes_sec;
start_index = i;
end_index = ++i;
while ((i + 1 < *num_entries) && (table[i+1].net_bw_in_kbytes_sec == current_bw))
end_index = ++i;
}
if (start_index != end_index) {
for (unsigned int j = start_index; j < end_index; j++) {
for (unsigned int k = start_index; k < end_index; k++) {
if (table[k].dcfclk_mhz > table[k+1].dcfclk_mhz)
swap_table_entries(&table[k], &table[k+1]);
}
}
}
start_index = 0;
end_index = 0;
}
}
/*
* remove_inconsistent_entries - Ensure entries with the same bandwidth have MEMCLK and FCLK monotonically increasing
* and remove entries that do not follow this order
*/
static void remove_inconsistent_entries(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
{
for (unsigned int i = 0; i + 1 < *num_entries; i++) {
if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) {
if ((table[i].dram_speed_mts > table[i+1].dram_speed_mts) ||
(table[i].fabricclk_mhz > table[i+1].fabricclk_mhz))
remove_entry_from_table_at_index(table, num_entries, i);
}
}
}
/*
* override_max_clk_values - Overwrite the max clock frequencies with the max DC mode timings
* Input:
* max_clk_limit - struct containing the desired clock timings
* Output:
* curr_clk_limit - struct containing the timings that need to be overwritten
* Return: 0 upon success, non-zero for failure
*/
static int override_max_clk_values(struct clk_limit_table_entry *max_clk_limit,
struct clk_limit_table_entry *curr_clk_limit)
{
if (NULL == max_clk_limit || NULL == curr_clk_limit)
return -1; //invalid parameters
//only overwrite if desired max clock frequency is initialized
if (max_clk_limit->dcfclk_mhz != 0)
curr_clk_limit->dcfclk_mhz = max_clk_limit->dcfclk_mhz;
if (max_clk_limit->fclk_mhz != 0)
curr_clk_limit->fclk_mhz = max_clk_limit->fclk_mhz;
if (max_clk_limit->memclk_mhz != 0)
curr_clk_limit->memclk_mhz = max_clk_limit->memclk_mhz;
if (max_clk_limit->socclk_mhz != 0)
curr_clk_limit->socclk_mhz = max_clk_limit->socclk_mhz;
if (max_clk_limit->dtbclk_mhz != 0)
curr_clk_limit->dtbclk_mhz = max_clk_limit->dtbclk_mhz;
if (max_clk_limit->dispclk_mhz != 0)
curr_clk_limit->dispclk_mhz = max_clk_limit->dispclk_mhz;
return 0;
}
static int build_synthetic_soc_states(bool disable_dc_mode_overwrite, struct clk_bw_params *bw_params,
struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
{
int i;
unsigned int j, k;
struct _vcs_dpi_voltage_scaling_st entry = {0};
struct clk_limit_table_entry max_clk_data = {0};
unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
static const unsigned int num_dcfclk_stas = 5;
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564};
unsigned int num_uclk_dpms = 0;
unsigned int num_fclk_dpms = 0;
unsigned int num_dcfclk_dpms = 0;
unsigned int num_dc_uclk_dpms = 0;
unsigned int num_dc_fclk_dpms = 0;
unsigned int num_dc_dcfclk_dpms = 0;
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_clk_data.dcfclk_mhz)
max_clk_data.dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
if (bw_params->clk_table.entries[i].fclk_mhz > max_clk_data.fclk_mhz)
max_clk_data.fclk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
if (bw_params->clk_table.entries[i].memclk_mhz > max_clk_data.memclk_mhz)
max_clk_data.memclk_mhz = bw_params->clk_table.entries[i].memclk_mhz;
if (bw_params->clk_table.entries[i].dispclk_mhz > max_clk_data.dispclk_mhz)
max_clk_data.dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
if (bw_params->clk_table.entries[i].dppclk_mhz > max_clk_data.dppclk_mhz)
max_clk_data.dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
if (bw_params->clk_table.entries[i].phyclk_mhz > max_clk_data.phyclk_mhz)
max_clk_data.phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
if (bw_params->clk_table.entries[i].dtbclk_mhz > max_clk_data.dtbclk_mhz)
max_clk_data.dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
if (bw_params->clk_table.entries[i].memclk_mhz > 0) {
num_uclk_dpms++;
if (bw_params->clk_table.entries[i].memclk_mhz <= bw_params->dc_mode_limit.memclk_mhz)
num_dc_uclk_dpms++;
}
if (bw_params->clk_table.entries[i].fclk_mhz > 0) {
num_fclk_dpms++;
if (bw_params->clk_table.entries[i].fclk_mhz <= bw_params->dc_mode_limit.fclk_mhz)
num_dc_fclk_dpms++;
}
if (bw_params->clk_table.entries[i].dcfclk_mhz > 0) {
num_dcfclk_dpms++;
if (bw_params->clk_table.entries[i].dcfclk_mhz <= bw_params->dc_mode_limit.dcfclk_mhz)
num_dc_dcfclk_dpms++;
}
}
if (!disable_dc_mode_overwrite) {
//Overwrite max frequencies with max DC mode frequencies for DC mode systems
override_max_clk_values(&bw_params->dc_mode_limit, &max_clk_data);
num_uclk_dpms = num_dc_uclk_dpms;
num_fclk_dpms = num_dc_fclk_dpms;
num_dcfclk_dpms = num_dc_dcfclk_dpms;
bw_params->clk_table.num_entries_per_clk.num_memclk_levels = num_uclk_dpms;
bw_params->clk_table.num_entries_per_clk.num_fclk_levels = num_fclk_dpms;
}
if (num_dcfclk_dpms > 0 && bw_params->clk_table.entries[0].fclk_mhz > min_fclk_mhz)
min_fclk_mhz = bw_params->clk_table.entries[0].fclk_mhz;
if (!max_clk_data.dcfclk_mhz || !max_clk_data.dispclk_mhz || !max_clk_data.dtbclk_mhz)
return -1;
if (max_clk_data.dppclk_mhz == 0)
max_clk_data.dppclk_mhz = max_clk_data.dispclk_mhz;
if (max_clk_data.fclk_mhz == 0)
max_clk_data.fclk_mhz = (unsigned int)(max_clk_data.dcfclk_mhz *
dcn3_21_soc.pct_ideal_sdp_bw_after_urgent /
dcn3_21_soc.pct_ideal_fabric_bw_after_urgent);
if (max_clk_data.phyclk_mhz == 0)
max_clk_data.phyclk_mhz = (unsigned int)dcn3_21_soc.clock_limits[0].phyclk_mhz;
*num_entries = 0;
entry.dispclk_mhz = max_clk_data.dispclk_mhz;
entry.dscclk_mhz = max_clk_data.dispclk_mhz / 3;
entry.dppclk_mhz = max_clk_data.dppclk_mhz;
entry.dtbclk_mhz = max_clk_data.dtbclk_mhz;
entry.phyclk_mhz = max_clk_data.phyclk_mhz;
entry.phyclk_d18_mhz = dcn3_21_soc.clock_limits[0].phyclk_d18_mhz;
entry.phyclk_d32_mhz = dcn3_21_soc.clock_limits[0].phyclk_d32_mhz;
// Insert all the DCFCLK STAs
for (k = 0; k < num_dcfclk_stas; k++) {
entry.dcfclk_mhz = dcfclk_sta_targets[k];
entry.fabricclk_mhz = 0;
entry.dram_speed_mts = 0;
get_optimal_ntuple(&entry);
entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
}
// Insert the max DCFCLK
entry.dcfclk_mhz = max_clk_data.dcfclk_mhz;
entry.fabricclk_mhz = 0;
entry.dram_speed_mts = 0;
get_optimal_ntuple(&entry);
entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
// Insert the UCLK DPMS
for (k = 0; k < num_uclk_dpms; k++) {
entry.dcfclk_mhz = 0;
entry.fabricclk_mhz = 0;
entry.dram_speed_mts = bw_params->clk_table.entries[k].memclk_mhz * 16;
get_optimal_ntuple(&entry);
entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
}
// If FCLK is coarse grained, insert individual DPMs.
if (num_fclk_dpms > 2) {
for (k = 0; k < num_fclk_dpms; k++) {
entry.dcfclk_mhz = 0;
entry.fabricclk_mhz = bw_params->clk_table.entries[k].fclk_mhz;
entry.dram_speed_mts = 0;
get_optimal_ntuple(&entry);
entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
}
}
// If FCLK fine grained, only insert max
else {
entry.dcfclk_mhz = 0;
entry.fabricclk_mhz = max_clk_data.fclk_mhz;
entry.dram_speed_mts = 0;
get_optimal_ntuple(&entry);
entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
}
// At this point, the table contains all "points of interest" based on
// DPMs from PMFW, and STAs. Table is sorted by BW, and all clock
// ratios (by derate, are exact).
// Remove states that require higher clocks than are supported
for (i = (int)*num_entries - 1; i >= 0 ; i--) {
if (table[i].dcfclk_mhz > max_clk_data.dcfclk_mhz ||
table[i].fabricclk_mhz > max_clk_data.fclk_mhz ||
table[i].dram_speed_mts > max_clk_data.memclk_mhz * 16)
remove_entry_from_table_at_index(table, num_entries, i);
}
// Insert entry with all max dc limits without bandwitch matching
if (!disable_dc_mode_overwrite) {
struct _vcs_dpi_voltage_scaling_st max_dc_limits_entry = entry;
max_dc_limits_entry.dcfclk_mhz = max_clk_data.dcfclk_mhz;
max_dc_limits_entry.fabricclk_mhz = max_clk_data.fclk_mhz;
max_dc_limits_entry.dram_speed_mts = max_clk_data.memclk_mhz * 16;
max_dc_limits_entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&max_dc_limits_entry);
dcn321_insert_entry_into_table_sorted(table, num_entries, &max_dc_limits_entry);
sort_entries_with_same_bw(table, num_entries);
remove_inconsistent_entries(table, num_entries);
}
// At this point, the table only contains supported points of interest
// it could be used as is, but some states may be redundant due to
// coarse grained nature of some clocks, so we want to round up to
// coarse grained DPMs and remove duplicates.
// Round up UCLKs
for (i = (int)*num_entries - 1; i >= 0 ; i--) {
for (j = 0; j < num_uclk_dpms; j++) {
if (bw_params->clk_table.entries[j].memclk_mhz * 16 >= table[i].dram_speed_mts) {
table[i].dram_speed_mts = bw_params->clk_table.entries[j].memclk_mhz * 16;
break;
}
}
}
// If FCLK is coarse grained, round up to next DPMs
if (num_fclk_dpms > 2) {
for (i = (int)*num_entries - 1; i >= 0 ; i--) {
for (j = 0; j < num_fclk_dpms; j++) {
if (bw_params->clk_table.entries[j].fclk_mhz >= table[i].fabricclk_mhz) {
table[i].fabricclk_mhz = bw_params->clk_table.entries[j].fclk_mhz;
break;
}
}
}
}
// Otherwise, round up to minimum.
else {
for (i = (int)*num_entries - 1; i >= 0 ; i--) {
if (table[i].fabricclk_mhz < min_fclk_mhz) {
table[i].fabricclk_mhz = min_fclk_mhz;
}
}
}
// Round DCFCLKs up to minimum
for (i = (int)*num_entries - 1; i >= 0 ; i--) {
if (table[i].dcfclk_mhz < min_dcfclk_mhz) {
table[i].dcfclk_mhz = min_dcfclk_mhz;
}
}
// Remove duplicate states, note duplicate states are always neighbouring since table is sorted.
i = 0;
while (i < (int)*num_entries - 1) {
if (table[i].dcfclk_mhz == table[i + 1].dcfclk_mhz &&
table[i].fabricclk_mhz == table[i + 1].fabricclk_mhz &&
table[i].dram_speed_mts == table[i + 1].dram_speed_mts)
remove_entry_from_table_at_index(table, num_entries, i + 1);
else
i++;
}
// Fix up the state indicies
for (i = (int)*num_entries - 1; i >= 0 ; i--)
table[i].state = i;
return 0;
}
static void dcn321_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk)
{
double bw_from_dram, bw_from_dram1, bw_from_dram2;
bw_from_dram1 = uclk_mts * dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * (dcn3_21_soc.max_avg_dram_bw_use_normal_percent / 100);
bw_from_dram2 = uclk_mts * dcn3_21_soc.num_chans *
dcn3_21_soc.dram_channel_width_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100);
bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
if (optimal_fclk)
*optimal_fclk = (unsigned int)(bw_from_dram /
(dcn3_21_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100)));
if (optimal_dcfclk)
*optimal_dcfclk = (unsigned int)(bw_from_dram /
(dcn3_21_soc.return_bus_width_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100)));
}
/** dcn321_update_bw_bounding_box
* This would override some dcn3_2 ip_or_soc initial parameters hardcoded from spreadsheet
* with actual values as per dGPU SKU:
* -with passed few options from dc->config
* -with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might need to get it from PM FW)
* -with passed latency values (passed in ns units) in dc-> bb override for debugging purposes
* -with passed latencies from VBIOS (in 100_ns units) if available for certain dGPU SKU
* -with number of DRAM channels from VBIOS (which differ for certain dGPU SKU of the same ASIC)
* -clocks levels with passed clk_table entries from Clk Mgr as reported by PM FW for different
* clocks (which might differ for certain dGPU SKU of the same ASIC)
*/
void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
dc_assert_fp_enabled();
/* Overrides from dc->config options */
dcn3_21_ip.clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
/* Override from passed dc->bb_overrides if available*/
if ((int)(dcn3_21_soc.sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
&& dc->bb_overrides.sr_exit_time_ns) {
dc->dml2_options.bbox_overrides.sr_exit_latency_us =
dcn3_21_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
}
if ((int)(dcn3_21_soc.sr_enter_plus_exit_time_us * 1000)
!= dc->bb_overrides.sr_enter_plus_exit_time_ns
&& dc->bb_overrides.sr_enter_plus_exit_time_ns) {
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us =
dcn3_21_soc.sr_enter_plus_exit_time_us =
dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
}
if ((int)(dcn3_21_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
&& dc->bb_overrides.urgent_latency_ns) {
dcn3_21_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
dc->dml2_options.bbox_overrides.urgent_latency_us =
dcn3_21_soc.urgent_latency_pixel_data_only_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
}
if ((int)(dcn3_21_soc.dram_clock_change_latency_us * 1000)
!= dc->bb_overrides.dram_clock_change_latency_ns
&& dc->bb_overrides.dram_clock_change_latency_ns) {
dc->dml2_options.bbox_overrides.dram_clock_change_latency_us =
dcn3_21_soc.dram_clock_change_latency_us =
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
}
if ((int)(dcn3_21_soc.fclk_change_latency_us * 1000)
!= dc->bb_overrides.fclk_clock_change_latency_ns
&& dc->bb_overrides.fclk_clock_change_latency_ns) {
dc->dml2_options.bbox_overrides.fclk_change_latency_us =
dcn3_21_soc.fclk_change_latency_us =
dc->bb_overrides.fclk_clock_change_latency_ns / 1000;
}
if ((int)(dcn3_21_soc.dummy_pstate_latency_us * 1000)
!= dc->bb_overrides.dummy_clock_change_latency_ns
&& dc->bb_overrides.dummy_clock_change_latency_ns) {
dcn3_21_soc.dummy_pstate_latency_us =
dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
}
/* Override from VBIOS if VBIOS bb_info available */
if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
struct bp_soc_bb_info bb_info = {0};
if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
if (bb_info.dram_clock_change_latency_100ns > 0)
dc->dml2_options.bbox_overrides.dram_clock_change_latency_us =
dcn3_21_soc.dram_clock_change_latency_us =
bb_info.dram_clock_change_latency_100ns * 10;
if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us =
dcn3_21_soc.sr_enter_plus_exit_time_us =
bb_info.dram_sr_enter_exit_latency_100ns * 10;
if (bb_info.dram_sr_exit_latency_100ns > 0)
dc->dml2_options.bbox_overrides.sr_exit_latency_us =
dcn3_21_soc.sr_exit_time_us =
bb_info.dram_sr_exit_latency_100ns * 10;
}
}
/* Override from VBIOS for num_chan */
if (dc->ctx->dc_bios->vram_info.num_chans) {
dc->dml2_options.bbox_overrides.dram_num_chan =
dcn3_21_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
dcn3_21_soc.mall_allocated_for_dcn_mbytes = (double)(dcn32_calc_num_avail_chans_for_mall(dc,
dc->ctx->dc_bios->vram_info.num_chans) * dc->caps.mall_size_per_mem_channel);
}
if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) {
unsigned int dram_channel_width_bytes = (unsigned int)dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
dc->dml2_options.bbox_overrides.dram_chanel_width_bytes = dram_channel_width_bytes;
dcn3_21_soc.dram_channel_width_bytes = dram_channel_width_bytes;
}
/* DML DSC delay factor workaround */
dcn3_21_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0;
dcn3_21_ip.min_prefetch_in_strobe_us = dc->debug.min_prefetch_in_strobe_ns / 1000.0;
/* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */
dcn3_21_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml2_options.bbox_overrides.disp_pll_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml2_options.bbox_overrides.xtalclk_mhz = dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency / 1000.0;
dc->dml2_options.bbox_overrides.dchub_refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
dc->dml2_options.bbox_overrides.dprefclk_mhz = dc->clk_mgr->dprefclk_khz / 1000.0;
/* Overrides Clock levelsfrom CLK Mgr table entries as reported by PM FW */
if (dc->debug.use_legacy_soc_bb_mechanism) {
unsigned int i = 0, j = 0, num_states = 0;
unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {615, 906, 1324, 1564};
unsigned int num_dcfclk_sta_targets = 4, num_uclk_states = 0;
unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
}
if (!max_dcfclk_mhz)
max_dcfclk_mhz = (unsigned int)dcn3_21_soc.clock_limits[0].dcfclk_mhz;
if (!max_dispclk_mhz)
max_dispclk_mhz = (unsigned int)dcn3_21_soc.clock_limits[0].dispclk_mhz;
if (!max_dppclk_mhz)
max_dppclk_mhz = (unsigned int)dcn3_21_soc.clock_limits[0].dppclk_mhz;
if (!max_phyclk_mhz)
max_phyclk_mhz = (unsigned int)dcn3_21_soc.clock_limits[0].phyclk_mhz;
if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
// If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array
dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
num_dcfclk_sta_targets++;
} else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
// If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates
for (i = 0; i < num_dcfclk_sta_targets; i++) {
if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
dcfclk_sta_targets[i] = max_dcfclk_mhz;
break;
}
}
// Update size of array since we "removed" duplicates
num_dcfclk_sta_targets = i + 1;
}
num_uclk_states = bw_params->clk_table.num_entries;
// Calculate optimal dcfclk for each uclk
for (i = 0; i < num_uclk_states; i++) {
dcn321_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
&optimal_dcfclk_for_uclk[i], NULL);
if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) {
optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
}
}
// Calculate optimal uclk for each dcfclk sta target
for (i = 0; i < num_dcfclk_sta_targets; i++) {
for (j = 0; j < num_uclk_states; j++) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
break;
}
}
}
i = 0;
j = 0;
// create the final dcfclk and uclk table
while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
} else {
if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} else {
j = num_uclk_states;
}
}
}
while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
}
while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_21_soc.num_states = num_states;
for (i = 0; i < dcn3_21_soc.num_states; i++) {
dcn3_21_soc.clock_limits[i].state = i;
dcn3_21_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
dcn3_21_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
/* Fill all states with max values of all these clocks */
dcn3_21_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
dcn3_21_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
dcn3_21_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
dcn3_21_soc.clock_limits[i].dscclk_mhz = max_dispclk_mhz / 3;
/* Populate from bw_params for DTBCLK, SOCCLK */
if (i > 0) {
if (!bw_params->clk_table.entries[i].dtbclk_mhz) {
dcn3_21_soc.clock_limits[i].dtbclk_mhz = dcn3_21_soc.clock_limits[i-1].dtbclk_mhz;
} else {
dcn3_21_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
}
} else if (bw_params->clk_table.entries[i].dtbclk_mhz) {
dcn3_21_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
}
if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
dcn3_21_soc.clock_limits[i].socclk_mhz = dcn3_21_soc.clock_limits[i-1].socclk_mhz;
else
dcn3_21_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
if (!dram_speed_mts[i] && i > 0)
dcn3_21_soc.clock_limits[i].dram_speed_mts = dcn3_21_soc.clock_limits[i-1].dram_speed_mts;
else
dcn3_21_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
/* These clocks cannot come from bw_params, always fill from dcn3_21_soc[0] */
/* PHYCLK_D18, PHYCLK_D32 */
dcn3_21_soc.clock_limits[i].phyclk_d18_mhz = dcn3_21_soc.clock_limits[0].phyclk_d18_mhz;
dcn3_21_soc.clock_limits[i].phyclk_d32_mhz = dcn3_21_soc.clock_limits[0].phyclk_d32_mhz;
}
} else {
build_synthetic_soc_states(dc->debug.disable_dc_mode_overwrite, bw_params,
dcn3_21_soc.clock_limits, &dcn3_21_soc.num_states);
}
/* Re-init DML with updated bb */
dml_init_instance(&dc->dml, &dcn3_21_soc, &dcn3_21_ip, DML_PROJECT_DCN32);
if (dc->current_state)
dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_21_soc, &dcn3_21_ip, DML_PROJECT_DCN32);
if (dc->clk_mgr->bw_params->clk_table.num_entries > 1) {
unsigned int i = 0;
dc->dml2_options.bbox_overrides.clks_table.num_states = dc->clk_mgr->bw_params->clk_table.num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_fclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_socclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dtbclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels =
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dppclk_levels;
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].dcfclk_mhz)
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].dcfclk_mhz;
}
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_fclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].fclk_mhz)
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].fclk_mhz;
}
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz)
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz;
}
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_socclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].socclk_mhz)
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].socclk_mhz;
}
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].dtbclk_mhz)
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].dtbclk_mhz;
}
for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels; i++) {
if (dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz) {
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz =
dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz;
}
}
}
}
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DCN32_FPU_H__
#define __DCN32_FPU_H__
#include "dml/display_mode_vba.h"
void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
#endif
@@ -0,0 +1,617 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2023 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 "resource.h"
#include "dcn35_fpu.h"
#include "dcn31/dcn31_resource.h"
#include "dcn32/dcn32_resource.h"
#include "dcn35/dcn35_resource.h"
#include "dml/dcn31/dcn31_fpu.h"
#include "dml/dml_inline_defs.h"
#include "link_service.h"
#define DC_LOGGER_INIT(logger)
struct _vcs_dpi_ip_params_st dcn3_5_ip = {
.VBlankNomDefaultUS = 668,
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = 1536,
.config_return_buffer_size_in_kbytes = 1792,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,/*not used*/
.opp_output_buffer_lines = 1,/*not used*/
.pixel_chunk_size_kbytes = 8,
//.alpha_pixel_chunk_size_kbytes = 4;/*new*/
//.min_pixel_chunk_size_bytes = 1024;/*new*/
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 4,
.maximum_dsc_bits_per_component = 12,/*delta from 10*/
.dsc422_native_support = true,/*delta from false*/
.is_line_buffer_bpp_fixed = true,/*new*/
.line_buffer_fixed_bpp = 32,/*delta from 48*/
.line_buffer_size_bits = 986880,/*delta from 789504*/
.max_line_buffer_lines = 32,/*delta from 12*/
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
/*.max_num_hdmi_frl_outputs = 1; new in dml2*/
/*.max_num_dp2p0_outputs = 2; new in dml2*/
/*.max_num_dp2p0_streams = 4; new in dml2*/
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 68,/*changed from 64,*/
.dpte_buffer_size_in_pte_reqs_chroma = 36,/*changed from 34*/
/*.dcc_meta_buffer_size_bytes = 6272; new to dml2*/
.dispclk_ramp_margin_percent = 1.11,/*delta from 1*/
/*.dppclk_delay_subtotal = 47;
.dppclk_delay_scl = 50;
.dppclk_delay_scl_lb_only = 16;
.dppclk_delay_cnvc_formatter = 28;
.dppclk_delay_cnvc_cursor = 6;
.dispclk_delay_subtotal = 125;*/ /*new to dml2*/
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 47, /* changed from 46,*/
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 28,/*changed from 27,*/
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 125, /*changed from 119,*/
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
// .config_return_buffer_segment_size_in_kbytes = 64;/*required, hard coded in dml2_translate_ip_params*/
};
struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 186.0,
.dtbclk_mhz = 600.0,
},
{
.state = 1,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 2,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 3,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 371.0,
.dtbclk_mhz = 600.0,
},
{
.state = 4,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 400.0,
.dtbclk_mhz = 600.0,
},
},
.num_states = 5,
.sr_exit_time_us = 31.0,
.sr_enter_plus_exit_time_us = 33.0,
.sr_exit_z8_time_us = 250.0,
.sr_enter_plus_exit_z8_time_us = 350.0,
.fclk_change_latency_us = 24.0,
.usr_retraining_latency_us = 2,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,/*not exist in dml2*/
.round_trip_ping_latency_dcfclk_cycles = 106,/*not exist in dml2*/
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.dram_clock_change_latency_us = 34.0,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_fabric_bw_after_urgent = 80.0, /*new to dml2*/
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = 0,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
};
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
{
(void)clk_mgr;
//TODO
}
/*
* dcn35_update_bw_bounding_box
*
* This would override some dcn3_5 ip_or_soc initial parameters hardcoded from
* spreadsheet with actual values as per dGPU SKU:
* - with passed few options from dc->config
* - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might
* need to get it from PM FW)
* - with passed latency values (passed in ns units) in dc-> bb override for
* debugging purposes
* - with passed latencies from VBIOS (in 100_ns units) if available for
* certain dGPU SKU
* - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU
* of the same ASIC)
* - clocks levels with passed clk_table entries from Clk Mgr as reported by PM
* FW for different clocks (which might differ for certain dGPU SKU of the
* same ASIC)
*/
void dcn35_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params)
{
unsigned int i, closest_clk_lvl;
int j;
struct clk_limit_table *clk_table = &bw_params->clk_table;
struct _vcs_dpi_voltage_scaling_st *clock_limits =
dc->scratch.update_bw_bounding_box.clock_limits;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
dc_assert_fp_enabled();
dcn3_5_ip.max_num_otg =
dc->res_pool->res_cap->num_timing_generator;
dcn3_5_ip.max_num_dpp = dc->res_pool->pipe_count;
dcn3_5_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_5_soc.num_states - 1;
j >= 0; j--) {
if (dcn3_5_soc.clock_limits[j].dcfclk_mhz <=
clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
if (clk_table->num_entries == 1) {
/*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_5_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz <
dcn3_5_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
/*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
clock_limits[i].fabricclk_mhz =
clk_table->entries[i].fclk_mhz;
clock_limits[i].socclk_mhz =
clk_table->entries[i].socclk_mhz;
if (clk_table->entries[i].memclk_mhz &&
clk_table->entries[i].wck_ratio)
clock_limits[i].dram_speed_mts =
clk_table->entries[i].memclk_mhz * 2 *
clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
clock_limits[i].dispclk_mhz = max_dispclk_mhz ?
max_dispclk_mhz :
dcn3_5_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
clock_limits[i].dppclk_mhz = max_dppclk_mhz ?
max_dppclk_mhz :
dcn3_5_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
clock_limits[i].dram_bw_per_chan_gbps =
dcn3_5_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
clock_limits[i].dscclk_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
clock_limits[i].dtbclk_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
clock_limits[i].phyclk_d18_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
clock_limits[i].phyclk_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
memcpy(dcn3_5_soc.clock_limits, clock_limits,
sizeof(dcn3_5_soc.clock_limits));
if (clk_table->num_entries)
dcn3_5_soc.num_states = clk_table->num_entries;
if (max_dispclk_mhz) {
dcn3_5_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
}
if ((int)(dcn3_5_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_5_soc.dram_clock_change_latency_us =
dc->debug.dram_clock_change_latency_ns / 1000.0;
}
if (dc->bb_overrides.dram_clock_change_latency_ns > 0)
dcn3_5_soc.dram_clock_change_latency_us =
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
if (dc->bb_overrides.sr_exit_time_ns > 0)
dcn3_5_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_time_ns > 0)
dcn3_5_soc.sr_enter_plus_exit_time_us =
dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_exit_z8_time_ns > 0)
dcn3_5_soc.sr_exit_z8_time_us = dc->bb_overrides.sr_exit_z8_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_z8_time_ns > 0)
dcn3_5_soc.sr_enter_plus_exit_z8_time_us =
dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0;
/*temp till dml2 fully work without dml1*/
dml_init_instance(&dc->dml, &dcn3_5_soc, &dcn3_5_ip,
DML_PROJECT_DCN31);
/*copy to dml2, before dml2_create*/
if (clk_table->num_entries > 2) {
for (i = 0; i < clk_table->num_entries; i++) {
dc->dml2_options.bbox_overrides.clks_table.num_states =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz =
(unsigned int)clock_limits[i].dcfclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz =
(unsigned int)clock_limits[i].fabricclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz =
(unsigned int)clock_limits[i].dispclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz =
(unsigned int)clock_limits[i].dppclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz =
(unsigned int)clock_limits[i].socclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz =
clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dram_speed_mts = (unsigned int)clock_limits[i].dram_speed_mts;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz =
(unsigned int)clock_limits[i].dtbclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dtbclk_levels =
clk_table->num_entries;
}
}
/* Update latency values */
dc->dml2_options.bbox_overrides.dram_clock_change_latency_us = dcn3_5_soc.dram_clock_change_latency_us;
dc->dml2_options.bbox_overrides.sr_exit_latency_us = dcn3_5_soc.sr_exit_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us = dcn3_5_soc.sr_enter_plus_exit_time_us;
dc->dml2_options.bbox_overrides.sr_exit_z8_time_us = dcn3_5_soc.sr_exit_z8_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_z8_time_us = dcn3_5_soc.sr_enter_plus_exit_z8_time_us;
}
static bool is_dual_plane(enum surface_pixel_format format)
{
return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/*
* micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing
*
* @param: num_us: number of microseconds
* @return: number of vertical lines. If exact number of vertical lines is not found then
* it will round up to next number of lines to guarantee num_us
*/
static unsigned int micro_sec_to_vert_lines(unsigned int num_us, struct dc_crtc_timing *timing)
{
unsigned int num_lines = 0;
double lines_time_in_ns = 1000.0 *
(((double)timing->h_total * 1000.0) /
((double)timing->pix_clk_100hz / 10.0));
num_lines = (unsigned int)dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0);
return num_lines;
}
static unsigned int get_vertical_back_porch(struct dc_crtc_timing *timing)
{
unsigned int v_active = 0, v_blank = 0, v_back_porch = 0;
v_active = timing->v_border_top + timing->v_addressable + timing->v_border_bottom;
v_blank = timing->v_total - v_active;
v_back_porch = v_blank - timing->v_front_porch - timing->v_sync_width;
return v_back_porch;
}
int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
unsigned int i;
int pipe_cnt;
struct resource_context *res_ctx = &context->res_ctx;
struct pipe_ctx *pipe = 0;
bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023;
dc_assert_fp_enabled();
dcn31_populate_dml_pipes_from_context(dc, context, pipes,
validate_mode);
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_crtc_timing *timing;
unsigned int num_lines = 0;
unsigned int v_back_porch = 0;
if (!res_ctx->pipe_ctx[i].stream)
continue;
pipe = &res_ctx->pipe_ctx[i];
timing = &pipe->stream->timing;
num_lines = micro_sec_to_vert_lines(dcn3_5_ip.VBlankNomDefaultUS, timing);
v_back_porch = get_vertical_back_porch(timing);
if (pipe->stream->adjust.v_total_max ==
pipe->stream->adjust.v_total_min &&
pipe->stream->adjust.v_total_min > timing->v_total) {
pipes[pipe_cnt].pipe.dest.vtotal =
pipe->stream->adjust.v_total_min;
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total -
pipes[pipe_cnt].pipe.dest.vactive;
}
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines);
// vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2)
// + 2 is because
// 1 -> VStartup_start should be 1 line before VSync
// 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
if (pipe->plane_state &&
(pipe->plane_state->src_rect.height <
pipe->plane_state->dst_rect.height ||
pipe->plane_state->src_rect.width <
pipe->plane_state->dst_rect.width))
upscaled = true;
/*
* Immediate flip can be set dynamically after enabling the
* plane. We need to require support for immediate flip or
* underflow can be intermittently experienced depending on peak
* b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256;
if (pipes[pipe_cnt].dout.dsc_enable) {
switch (timing->display_color_depth) {
case COLOR_DEPTH_888:
pipes[pipe_cnt].dout.dsc_input_bpc = 8;
break;
case COLOR_DEPTH_101010:
pipes[pipe_cnt].dout.dsc_input_bpc = 10;
break;
case COLOR_DEPTH_121212:
pipes[pipe_cnt].dout.dsc_input_bpc = 12;
break;
default:
ASSERT(0);
break;
}
}
pipe_cnt++;
}
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/
if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
if (!is_dual_plane(pipe->plane_state->format) &&
pipe->plane_state->src_rect.width <= 5120) {
/*
* Limit to 5k max to avoid forced pipe split when there
* is not enough detile for swath
*/
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
pipes[0].pipe.src.unbounded_req_mode = true;
}
} else if (context->stream_count >=
dc->debug.crb_alloc_policy_min_disp_count &&
dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes =
dc->debug.crb_alloc_policy * 64;
} else if (context->stream_count >= 3 && upscaled) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i];
if (!cur_pipe->stream)
continue;
if (cur_pipe->stream->signal == SIGNAL_TYPE_EDP &&
dc->debug.seamless_boot_odm_combine &&
cur_pipe->stream->apply_seamless_boot_optimization) {
if (cur_pipe->stream->apply_boot_odm_mode ==
dm_odm_combine_policy_2to1) {
context->bw_ctx.dml.vba.ODMCombinePolicy =
dm_odm_combine_policy_2to1;
break;
}
}
}
return pipe_cnt;
}
void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context)
{
enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW;
unsigned int i, plane_count = 0;
DC_LOGGER_INIT(dc->ctx->logger);
dc_assert_fp_enabled();
for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (context->res_ctx.pipe_ctx[i].plane_state)
plane_count++;
}
if (context->stream_count == 0 || plane_count == 0) {
support = DCN_ZSTATE_SUPPORT_ALLOW;
} else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
struct dc_link *link = context->streams[0]->sink->link;
bool is_pwrseq0 = link && link->link_index == 0;
bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr);
bool is_replay = link && link->replay_settings.replay_feature_enabled;
int minmum_z8_residency =
dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;
bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
int minmum_z10_residency =
dc->debug.minimum_z10_residency_time > 0 ? dc->debug.minimum_z10_residency_time : 5000;
bool allow_z10 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z10_residency;
/*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/
if (is_pwrseq0 && allow_z10)
support = DCN_ZSTATE_SUPPORT_ALLOW;
else if (is_pwrseq0 && (is_psr || is_replay))
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY;
else if (allow_z8)
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
}
DC_LOG_SMU("zstate_support: %d, StutterPeriod: %d\n", support,
(int)context->bw_ctx.dml.vba.StutterPeriod);
context->bw_ctx.bw.dcn.clk.zstate_support = support;
}
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2023 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 __DCN35_FPU_H__
#define __DCN35_FPU_H__
#include "clk_mgr.h"
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr);
void dcn35_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params);
int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context);
#endif
@@ -0,0 +1,635 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#include "resource.h"
#include "dcn351_fpu.h"
#include "dcn31/dcn31_resource.h"
#include "dcn32/dcn32_resource.h"
#include "dcn35/dcn35_resource.h"
#include "dcn351/dcn351_resource.h"
#include "dml/dcn31/dcn31_fpu.h"
#include "dml/dcn35/dcn35_fpu.h"
#include "dml/dml_inline_defs.h"
#include "link_service.h"
#define DC_LOGGER_INIT(logger)
struct _vcs_dpi_ip_params_st dcn3_51_ip = {
.VBlankNomDefaultUS = 668,
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = 1536,
.config_return_buffer_size_in_kbytes = 1792,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,/*not used*/
.opp_output_buffer_lines = 1,/*not used*/
.pixel_chunk_size_kbytes = 8,
//.alpha_pixel_chunk_size_kbytes = 4;/*new*/
//.min_pixel_chunk_size_bytes = 1024;/*new*/
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 4,
.maximum_dsc_bits_per_component = 12,/*delta from 10*/
.dsc422_native_support = true,/*delta from false*/
.is_line_buffer_bpp_fixed = true,/*new*/
.line_buffer_fixed_bpp = 32,/*delta from 48*/
.line_buffer_size_bits = 986880,/*delta from 789504*/
.max_line_buffer_lines = 32,/*delta from 12*/
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
/*.max_num_hdmi_frl_outputs = 1; new in dml2*/
/*.max_num_dp2p0_outputs = 2; new in dml2*/
/*.max_num_dp2p0_streams = 4; new in dml2*/
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 68,/*changed from 64,*/
.dpte_buffer_size_in_pte_reqs_chroma = 36,/*changed from 34*/
/*.dcc_meta_buffer_size_bytes = 6272; new to dml2*/
.dispclk_ramp_margin_percent = 1.11,/*delta from 1*/
/*.dppclk_delay_subtotal = 47;
.dppclk_delay_scl = 50;
.dppclk_delay_scl_lb_only = 16;
.dppclk_delay_cnvc_formatter = 28;
.dppclk_delay_cnvc_cursor = 6;
.dispclk_delay_subtotal = 125;*/ /*new to dml2*/
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 47, /* changed from 46,*/
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 28,/*changed from 27,*/
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 125, /*changed from 119,*/
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
// .config_return_buffer_segment_size_in_kbytes = 64;/*required, hard coded in dml2_translate_ip_params*/
};
struct _vcs_dpi_soc_bounding_box_st dcn3_51_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dcfclk_mhz = 400.0,
.fabricclk_mhz = 400.0,
.socclk_mhz = 600.0,
.dram_speed_mts = 3200.0,
.dispclk_mhz = 600.0,
.dppclk_mhz = 600.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 200.0,
.dtbclk_mhz = 600.0,
},
{
.state = 1,
.dcfclk_mhz = 600.0,
.fabricclk_mhz = 1000.0,
.socclk_mhz = 733.0,
.dram_speed_mts = 6400.0,
.dispclk_mhz = 800.0,
.dppclk_mhz = 800.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 266.7,
.dtbclk_mhz = 600.0,
},
{
.state = 2,
.dcfclk_mhz = 738.0,
.fabricclk_mhz = 1200.0,
.socclk_mhz = 880.0,
.dram_speed_mts = 7500.0,
.dispclk_mhz = 800.0,
.dppclk_mhz = 800.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 266.7,
.dtbclk_mhz = 600.0,
},
{
.state = 3,
.dcfclk_mhz = 800.0,
.fabricclk_mhz = 1400.0,
.socclk_mhz = 978.0,
.dram_speed_mts = 7500.0,
.dispclk_mhz = 960.0,
.dppclk_mhz = 960.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 320.0,
.dtbclk_mhz = 600.0,
},
{
.state = 4,
.dcfclk_mhz = 873.0,
.fabricclk_mhz = 1600.0,
.socclk_mhz = 1100.0,
.dram_speed_mts = 8533.0,
.dispclk_mhz = 1066.7,
.dppclk_mhz = 1066.7,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 355.6,
.dtbclk_mhz = 600.0,
},
{
.state = 5,
.dcfclk_mhz = 960.0,
.fabricclk_mhz = 1700.0,
.socclk_mhz = 1257.0,
.dram_speed_mts = 8533.0,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 400.0,
.dtbclk_mhz = 600.0,
},
{
.state = 6,
.dcfclk_mhz = 1067.0,
.fabricclk_mhz = 1850.0,
.socclk_mhz = 1257.0,
.dram_speed_mts = 8533.0,
.dispclk_mhz = 1371.4,
.dppclk_mhz = 1371.4,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 457.1,
.dtbclk_mhz = 600.0,
},
{
.state = 7,
.dcfclk_mhz = 1200.0,
.fabricclk_mhz = 2000.0,
.socclk_mhz = 1467.0,
.dram_speed_mts = 8533.0,
.dispclk_mhz = 1600.0,
.dppclk_mhz = 1600.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 533.3,
.dtbclk_mhz = 600.0,
},
},
.num_states = 8,
.sr_exit_time_us = 28.0,
.sr_enter_plus_exit_time_us = 30.0,
.sr_exit_z8_time_us = 263.0,
.sr_enter_plus_exit_z8_time_us = 363.0,
.fclk_change_latency_us = 24.0,
.usr_retraining_latency_us = 2,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,/*not exist in dml2*/
.round_trip_ping_latency_dcfclk_cycles = 106,/*not exist in dml2*/
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.dram_clock_change_latency_us = 34,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_fabric_bw_after_urgent = 80.0, /*new to dml2*/
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = 0,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
.num_chans = 4,
.dispclk_dppclk_vco_speed_mhz = 2400.0,
};
/*
* dcn351_update_bw_bounding_box
*
* This would override some dcn3_51 ip_or_soc initial parameters hardcoded from
* spreadsheet with actual values as per dGPU SKU:
* - with passed few options from dc->config
* - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might
* need to get it from PM FW)
* - with passed latency values (passed in ns units) in dc-> bb override for
* debugging purposes
* - with passed latencies from VBIOS (in 100_ns units) if available for
* certain dGPU SKU
* - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU
* of the same ASIC)
* - clocks levels with passed clk_table entries from Clk Mgr as reported by PM
* FW for different clocks (which might differ for certain dGPU SKU of the
* same ASIC)
*/
void dcn351_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params)
{
unsigned int i, closest_clk_lvl;
int j;
struct clk_limit_table *clk_table = &bw_params->clk_table;
struct _vcs_dpi_voltage_scaling_st *clock_limits =
dc->scratch.update_bw_bounding_box.clock_limits;
unsigned int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
dc_assert_fp_enabled();
dcn3_51_ip.max_num_otg =
dc->res_pool->res_cap->num_timing_generator;
dcn3_51_ip.max_num_dpp = dc->res_pool->pipe_count;
dcn3_51_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_51_soc.num_states - 1;
j >= 0; j--) {
if (dcn3_51_soc.clock_limits[j].dcfclk_mhz <=
clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
if (clk_table->num_entries == 1) {
/*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_51_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz <
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
/*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
clock_limits[i].fabricclk_mhz =
clk_table->entries[i].fclk_mhz;
clock_limits[i].socclk_mhz =
clk_table->entries[i].socclk_mhz;
if (clk_table->entries[i].memclk_mhz &&
clk_table->entries[i].wck_ratio)
clock_limits[i].dram_speed_mts =
clk_table->entries[i].memclk_mhz * 2 *
clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
clock_limits[i].dispclk_mhz = max_dispclk_mhz ?
max_dispclk_mhz :
dcn3_51_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
clock_limits[i].dppclk_mhz = max_dppclk_mhz ?
max_dppclk_mhz :
dcn3_51_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
clock_limits[i].dram_bw_per_chan_gbps =
dcn3_51_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
clock_limits[i].dscclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
clock_limits[i].dtbclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
clock_limits[i].phyclk_d18_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
clock_limits[i].phyclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
memcpy(dcn3_51_soc.clock_limits, clock_limits,
sizeof(dcn3_51_soc.clock_limits));
if (clk_table->num_entries)
dcn3_51_soc.num_states = clk_table->num_entries;
if (max_dispclk_mhz) {
dcn3_51_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
}
if ((int)(dcn3_51_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_51_soc.dram_clock_change_latency_us =
dc->debug.dram_clock_change_latency_ns / 1000.0;
}
if (dc->bb_overrides.dram_clock_change_latency_ns > 0)
dcn3_51_soc.dram_clock_change_latency_us =
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
if (dc->bb_overrides.sr_exit_time_ns > 0)
dcn3_51_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_time_ns > 0)
dcn3_51_soc.sr_enter_plus_exit_time_us =
dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_exit_z8_time_ns > 0)
dcn3_51_soc.sr_exit_z8_time_us = dc->bb_overrides.sr_exit_z8_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_z8_time_ns > 0)
dcn3_51_soc.sr_enter_plus_exit_z8_time_us =
dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0;
/*temp till dml2 fully work without dml1*/
dml_init_instance(&dc->dml, &dcn3_51_soc, &dcn3_51_ip,
DML_PROJECT_DCN31);
/*copy to dml2, before dml2_create*/
if (clk_table->num_entries > 2) {
for (i = 0; i < clk_table->num_entries; i++) {
dc->dml2_options.bbox_overrides.clks_table.num_states =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz =
(unsigned int)clock_limits[i].dcfclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz =
(unsigned int)clock_limits[i].fabricclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz =
(unsigned int)clock_limits[i].dispclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz =
(unsigned int)clock_limits[i].dppclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz =
(unsigned int)clock_limits[i].socclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz =
clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dram_speed_mts = (unsigned int)clock_limits[i].dram_speed_mts;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz =
(unsigned int)clock_limits[i].dtbclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dtbclk_levels =
clk_table->num_entries;
}
}
/* Update latency values */
dc->dml2_options.bbox_overrides.dram_clock_change_latency_us = dcn3_51_soc.dram_clock_change_latency_us;
dc->dml2_options.bbox_overrides.sr_exit_latency_us = dcn3_51_soc.sr_exit_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us = dcn3_51_soc.sr_enter_plus_exit_time_us;
dc->dml2_options.bbox_overrides.sr_exit_z8_time_us = dcn3_51_soc.sr_exit_z8_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_z8_time_us = dcn3_51_soc.sr_enter_plus_exit_z8_time_us;
}
static bool is_dual_plane(enum surface_pixel_format format)
{
return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/*
* micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing
*
* @param: num_us: number of microseconds
* @return: number of vertical lines. If exact number of vertical lines is not found then
* it will round up to next number of lines to guarantee num_us
*/
static unsigned int micro_sec_to_vert_lines(unsigned int num_us, struct dc_crtc_timing *timing)
{
unsigned int num_lines = 0;
double lines_time_in_ns = 1000.0 *
(((double)timing->h_total * 1000.0) /
((double)timing->pix_clk_100hz / 10.0));
num_lines = (unsigned int)dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0);
return num_lines;
}
static unsigned int get_vertical_back_porch(struct dc_crtc_timing *timing)
{
unsigned int v_active = 0, v_blank = 0, v_back_porch = 0;
v_active = timing->v_border_top + timing->v_addressable + timing->v_border_bottom;
v_blank = timing->v_total - v_active;
v_back_porch = v_blank - timing->v_front_porch - timing->v_sync_width;
return v_back_porch;
}
int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
int pipe_cnt;
unsigned int i;
struct resource_context *res_ctx = &context->res_ctx;
struct pipe_ctx *pipe = 0;
bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023;
dc_assert_fp_enabled();
dcn31_populate_dml_pipes_from_context(dc, context, pipes,
validate_mode);
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_crtc_timing *timing;
unsigned int num_lines = 0;
unsigned int v_back_porch = 0;
if (!res_ctx->pipe_ctx[i].stream)
continue;
pipe = &res_ctx->pipe_ctx[i];
timing = &pipe->stream->timing;
num_lines = micro_sec_to_vert_lines(dcn3_51_ip.VBlankNomDefaultUS, timing);
v_back_porch = get_vertical_back_porch(timing);
if (pipe->stream->adjust.v_total_max ==
pipe->stream->adjust.v_total_min &&
pipe->stream->adjust.v_total_min > timing->v_total) {
pipes[pipe_cnt].pipe.dest.vtotal =
pipe->stream->adjust.v_total_min;
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total -
pipes[pipe_cnt].pipe.dest.vactive;
}
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines);
// vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2)
// + 2 is because
// 1 -> VStartup_start should be 1 line before VSync
// 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
if (pipe->plane_state &&
(pipe->plane_state->src_rect.height <
pipe->plane_state->dst_rect.height ||
pipe->plane_state->src_rect.width <
pipe->plane_state->dst_rect.width))
upscaled = true;
/*
* Immediate flip can be set dynamically after enabling the
* plane. We need to require support for immediate flip or
* underflow can be intermittently experienced depending on peak
* b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256;
if (pipes[pipe_cnt].dout.dsc_enable) {
switch (timing->display_color_depth) {
case COLOR_DEPTH_888:
pipes[pipe_cnt].dout.dsc_input_bpc = 8;
break;
case COLOR_DEPTH_101010:
pipes[pipe_cnt].dout.dsc_input_bpc = 10;
break;
case COLOR_DEPTH_121212:
pipes[pipe_cnt].dout.dsc_input_bpc = 12;
break;
default:
ASSERT(0);
break;
}
}
pipe_cnt++;
}
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/
if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
if (!is_dual_plane(pipe->plane_state->format) &&
pipe->plane_state->src_rect.width <= 5120) {
/*
* Limit to 5k max to avoid forced pipe split when there
* is not enough detile for swath
*/
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
pipes[0].pipe.src.unbounded_req_mode = true;
}
} else if (context->stream_count >=
dc->debug.crb_alloc_policy_min_disp_count &&
dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes =
dc->debug.crb_alloc_policy * 64;
} else if (context->stream_count >= 3 && upscaled) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i];
if (!cur_pipe->stream)
continue;
if (cur_pipe->stream->signal == SIGNAL_TYPE_EDP &&
dc->debug.seamless_boot_odm_combine &&
cur_pipe->stream->apply_seamless_boot_optimization) {
if (cur_pipe->stream->apply_boot_odm_mode ==
dm_odm_combine_policy_2to1) {
context->bw_ctx.dml.vba.ODMCombinePolicy =
dm_odm_combine_policy_2to1;
break;
}
}
}
return pipe_cnt;
}
void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context)
{
enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW;
unsigned int i, plane_count = 0;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (context->res_ctx.pipe_ctx[i].plane_state)
plane_count++;
}
/*dcn351 does not support z9/z10*/
if (context->stream_count == 0 || plane_count == 0) {
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
} else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
struct dc_link *link = context->streams[0]->sink->link;
bool is_pwrseq0 = link && link->link_index == 0;
bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr);
bool is_replay = link && link->replay_settings.replay_feature_enabled;
int minmum_z8_residency =
dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;
bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
/*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/
if (is_pwrseq0 && (is_psr || is_replay))
support = allow_z8 ? allow_z8 : DCN_ZSTATE_SUPPORT_DISALLOW;
}
context->bw_ctx.bw.dcn.clk.zstate_support = support;
}
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef __DCN351_FPU_H__
#define __DCN351_FPU_H__
#include "clk_mgr.h"
void dcn351_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params);
int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode);
void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context);
#endif
@@ -0,0 +1,312 @@
/*
* Copyright 2017 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 __DISPLAY_MODE_ENUMS_H__
#define __DISPLAY_MODE_ENUMS_H__
enum output_encoder_class {
dm_dp = 0,
dm_hdmi = 1,
dm_wb = 2,
dm_edp = 3,
dm_hdmifrl = 4,
dm_dp2p0 = 5,
};
enum output_format_class {
dm_444 = 0, dm_420 = 1, dm_n422, dm_s422
};
enum source_format_class {
dm_444_16 = 0,
dm_444_32 = 1,
dm_444_64 = 2,
dm_420_8 = 3,
dm_420_10 = 4,
dm_420_12 = 5,
dm_422_8 = 6,
dm_422_10 = 7,
dm_444_8 = 8,
dm_mono_8 = dm_444_8,
dm_mono_16 = dm_444_16,
dm_rgbe = 9,
dm_rgbe_alpha = 10,
};
enum output_bpc_class {
dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4
};
enum scan_direction_class {
dm_horz = 0, dm_vert = 1
};
enum dm_swizzle_mode {
dm_sw_linear = 0,
dm_sw_256b_s = 1,
dm_sw_256b_d = 2,
dm_sw_SPARE_0 = 3,
dm_sw_SPARE_1 = 4,
dm_sw_4kb_s = 5,
dm_sw_4kb_d = 6,
dm_sw_SPARE_2 = 7,
dm_sw_SPARE_3 = 8,
dm_sw_64kb_s = 9,
dm_sw_64kb_d = 10,
dm_sw_SPARE_4 = 11,
dm_sw_SPARE_5 = 12,
dm_sw_var_s = 13,
dm_sw_var_d = 14,
dm_sw_SPARE_6 = 15,
dm_sw_SPARE_7 = 16,
dm_sw_64kb_s_t = 17,
dm_sw_64kb_d_t = 18,
dm_sw_SPARE_10 = 19,
dm_sw_SPARE_11 = 20,
dm_sw_4kb_s_x = 21,
dm_sw_4kb_d_x = 22,
dm_sw_SPARE_12 = 23,
dm_sw_SPARE_13 = 24,
dm_sw_64kb_s_x = 25,
dm_sw_64kb_d_x = 26,
dm_sw_64kb_r_x = 27,
dm_sw_SPARE_15 = 28,
dm_sw_var_s_x = 29,
dm_sw_var_d_x = 30,
dm_sw_var_r_x = 31,
dm_sw_gfx7_2d_thin_l_vp,
dm_sw_gfx7_2d_thin_gl,
};
enum lb_depth {
dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16 = 4,
dm_lb_19 = 5
};
enum voltage_state {
dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3
};
enum source_macro_tile_size {
dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2
};
enum cursor_bpp {
dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
};
/**
* @enum clock_change_support - It represents possible reasons to change the DRAM clock.
*
* DC may change the DRAM clock during its execution, and this enum tracks all
* the available methods. Note that every ASIC has their specific way to deal
* with these clock switch.
*/
enum clock_change_support {
/**
* @dm_dram_clock_change_uninitialized: If you see this, we might have
* a code initialization issue
*/
dm_dram_clock_change_uninitialized = 0,
/**
* @dm_dram_clock_change_vactive: Support DRAM switch in VActive
*/
dm_dram_clock_change_vactive,
/**
* @dm_dram_clock_change_vblank: Support DRAM switch in VBlank
*/
dm_dram_clock_change_vblank,
dm_dram_clock_change_vactive_w_mall_full_frame,
dm_dram_clock_change_vactive_w_mall_sub_vp,
dm_dram_clock_change_vblank_w_mall_full_frame,
dm_dram_clock_change_vblank_w_mall_sub_vp,
/**
* @dm_dram_clock_change_unsupported: Do not support DRAM switch
*/
dm_dram_clock_change_unsupported
};
enum output_standard {
dm_std_uninitialized = 0,
dm_std_cvtr2,
dm_std_cvt
};
enum mpc_combine_affinity {
dm_mpc_always_when_possible,
dm_mpc_reduce_voltage,
dm_mpc_reduce_voltage_and_clocks,
dm_mpc_never
};
enum RequestType {
REQ_256Bytes, REQ_128BytesNonContiguous, REQ_128BytesContiguous, REQ_NA
};
enum self_refresh_affinity {
dm_try_to_allow_self_refresh_and_mclk_switch,
dm_allow_self_refresh_and_mclk_switch,
dm_allow_self_refresh,
dm_neither_self_refresh_nor_mclk_switch
};
enum dm_validation_status {
DML_VALIDATION_OK,
DML_FAIL_SCALE_RATIO_TAP,
DML_FAIL_SOURCE_PIXEL_FORMAT,
DML_FAIL_VIEWPORT_SIZE,
DML_FAIL_TOTAL_V_ACTIVE_BW,
DML_FAIL_DIO_SUPPORT,
DML_FAIL_NOT_ENOUGH_DSC,
DML_FAIL_DSC_CLK_REQUIRED,
DML_FAIL_DSC_VALIDATION_FAILURE,
DML_FAIL_URGENT_LATENCY,
DML_FAIL_REORDERING_BUFFER,
DML_FAIL_DISPCLK_DPPCLK,
DML_FAIL_TOTAL_AVAILABLE_PIPES,
DML_FAIL_NUM_OTG,
DML_FAIL_WRITEBACK_MODE,
DML_FAIL_WRITEBACK_LATENCY,
DML_FAIL_WRITEBACK_SCALE_RATIO_TAP,
DML_FAIL_CURSOR_SUPPORT,
DML_FAIL_PITCH_SUPPORT,
DML_FAIL_PTE_BUFFER_SIZE,
DML_FAIL_HOST_VM_IMMEDIATE_FLIP,
DML_FAIL_DSC_INPUT_BPC,
DML_FAIL_PREFETCH_SUPPORT,
DML_FAIL_V_RATIO_PREFETCH,
DML_FAIL_P2I_WITH_420,
DML_FAIL_DSC_ONLY_IF_NECESSARY_WITH_BPP,
DML_FAIL_NOT_DSC422_NATIVE,
DML_FAIL_ODM_COMBINE4TO1,
DML_FAIL_ENOUGH_WRITEBACK_UNITS,
DML_FAIL_VIEWPORT_EXCEEDS_SURFACE,
DML_FAIL_DYNAMIC_METADATA,
DML_FAIL_FMT_BUFFER_EXCEEDED,
};
enum writeback_config {
dm_normal,
dm_whole_buffer_for_single_stream_no_interleave,
dm_whole_buffer_for_single_stream_interleave,
};
enum odm_combine_mode {
dm_odm_combine_mode_disabled,
dm_odm_combine_mode_2to1,
dm_odm_combine_mode_4to1,
dm_odm_split_mode_1to2,
dm_odm_mode_mso_1to2,
dm_odm_mode_mso_1to4
};
enum odm_combine_policy {
dm_odm_combine_policy_dal,
dm_odm_combine_policy_none,
dm_odm_combine_policy_2to1,
dm_odm_combine_policy_4to1,
dm_odm_split_policy_1to2,
dm_odm_mso_policy_1to2,
dm_odm_mso_policy_1to4,
};
enum immediate_flip_requirement {
dm_immediate_flip_not_required,
dm_immediate_flip_required,
dm_immediate_flip_opportunistic,
};
enum unbounded_requesting_policy {
dm_unbounded_requesting,
dm_unbounded_requesting_edp_only,
dm_unbounded_requesting_disable
};
enum dm_rotation_angle {
dm_rotation_0,
dm_rotation_90,
dm_rotation_180,
dm_rotation_270,
dm_rotation_0m,
dm_rotation_90m,
dm_rotation_180m,
dm_rotation_270m,
};
enum dm_use_mall_for_pstate_change_mode {
dm_use_mall_pstate_change_disable,
dm_use_mall_pstate_change_full_frame,
dm_use_mall_pstate_change_sub_viewport,
dm_use_mall_pstate_change_phantom_pipe
};
enum dm_use_mall_for_static_screen_mode {
dm_use_mall_static_screen_disable,
dm_use_mall_static_screen_optimize,
dm_use_mall_static_screen_enable,
};
enum dm_output_link_dp_rate {
dm_dp_rate_na,
dm_dp_rate_hbr,
dm_dp_rate_hbr2,
dm_dp_rate_hbr3,
dm_dp_rate_uhbr10,
dm_dp_rate_uhbr13p5,
dm_dp_rate_uhbr20,
};
enum dm_fclock_change_support {
dm_fclock_change_vactive,
dm_fclock_change_vblank,
dm_fclock_change_unsupported,
};
enum dm_prefetch_modes {
dm_prefetch_support_uclk_fclk_and_stutter_if_possible,
dm_prefetch_support_uclk_fclk_and_stutter,
dm_prefetch_support_fclk_and_stutter,
dm_prefetch_support_stutter,
dm_prefetch_support_none,
};
enum dm_output_type {
dm_output_type_unknown,
dm_output_type_dp,
dm_output_type_edp,
dm_output_type_dp2p0,
dm_output_type_hdmi,
dm_output_type_hdmifrl,
};
enum dm_output_rate {
dm_output_rate_unknown,
dm_output_rate_dp_rate_hbr,
dm_output_rate_dp_rate_hbr2,
dm_output_rate_dp_rate_hbr3,
dm_output_rate_dp_rate_uhbr10,
dm_output_rate_dp_rate_uhbr13p5,
dm_output_rate_dp_rate_uhbr20,
dm_output_rate_hdmi_rate_3x3,
dm_output_rate_hdmi_rate_6x3,
dm_output_rate_hdmi_rate_6x4,
dm_output_rate_hdmi_rate_8x4,
dm_output_rate_hdmi_rate_10x4,
dm_output_rate_hdmi_rate_12x4,
};
#endif
@@ -0,0 +1,321 @@
/*
* Copyright 2017 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 "display_mode_lib.h"
#include "dc_features.h"
#include "dcn20/display_mode_vba_20.h"
#include "dcn20/display_rq_dlg_calc_20.h"
#include "dcn20/display_mode_vba_20v2.h"
#include "dcn20/display_rq_dlg_calc_20v2.h"
#include "dcn21/display_mode_vba_21.h"
#include "dcn21/display_rq_dlg_calc_21.h"
#include "dcn30/display_mode_vba_30.h"
#include "dcn30/display_rq_dlg_calc_30.h"
#include "dcn31/display_mode_vba_31.h"
#include "dcn31/display_rq_dlg_calc_31.h"
#include "dcn314/display_mode_vba_314.h"
#include "dcn314/display_rq_dlg_calc_314.h"
#include "dcn32/display_mode_vba_32.h"
#include "dcn32/display_rq_dlg_calc_32.h"
#include "dml_logger.h"
static const struct dml_funcs dml20_funcs = {
.validate = dml20_ModeSupportAndSystemConfigurationFull,
.recalculate = dml20_recalculate,
.rq_dlg_get_dlg_reg = dml20_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml20_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml20v2_funcs = {
.validate = dml20v2_ModeSupportAndSystemConfigurationFull,
.recalculate = dml20v2_recalculate,
.rq_dlg_get_dlg_reg = dml20v2_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml20v2_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml21_funcs = {
.validate = dml21_ModeSupportAndSystemConfigurationFull,
.recalculate = dml21_recalculate,
.rq_dlg_get_dlg_reg = dml21_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml21_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml30_funcs = {
.validate = dml30_ModeSupportAndSystemConfigurationFull,
.recalculate = dml30_recalculate,
.rq_dlg_get_dlg_reg = dml30_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml30_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml31_funcs = {
.validate = dml31_ModeSupportAndSystemConfigurationFull,
.recalculate = dml31_recalculate,
.rq_dlg_get_dlg_reg = dml31_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml31_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml314_funcs = {
.validate = dml314_ModeSupportAndSystemConfigurationFull,
.recalculate = dml314_recalculate,
.rq_dlg_get_dlg_reg = dml314_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg = dml314_rq_dlg_get_rq_reg
};
static const struct dml_funcs dml32_funcs = {
.validate = dml32_ModeSupportAndSystemConfigurationFull,
.recalculate = dml32_recalculate,
.rq_dlg_get_dlg_reg_v2 = dml32_rq_dlg_get_dlg_reg,
.rq_dlg_get_rq_reg_v2 = dml32_rq_dlg_get_rq_reg
};
void dml_init_instance(struct display_mode_lib *lib,
const struct _vcs_dpi_soc_bounding_box_st *soc_bb,
const struct _vcs_dpi_ip_params_st *ip_params,
enum dml_project project)
{
lib->soc = *soc_bb;
lib->ip = *ip_params;
lib->project = project;
switch (project) {
case DML_PROJECT_NAVI10:
case DML_PROJECT_DCN201:
lib->funcs = dml20_funcs;
break;
case DML_PROJECT_NAVI10v2:
lib->funcs = dml20v2_funcs;
break;
case DML_PROJECT_DCN21:
lib->funcs = dml21_funcs;
break;
case DML_PROJECT_DCN30:
lib->funcs = dml30_funcs;
break;
case DML_PROJECT_DCN31:
case DML_PROJECT_DCN315:
lib->funcs = dml31_funcs;
break;
case DML_PROJECT_DCN314:
lib->funcs = dml314_funcs;
break;
case DML_PROJECT_DCN32:
lib->funcs = dml32_funcs;
break;
default:
break;
}
}
const char *dml_get_status_message(enum dm_validation_status status)
{
switch (status) {
case DML_VALIDATION_OK: return "Validation OK";
case DML_FAIL_SCALE_RATIO_TAP: return "Scale ratio/tap";
case DML_FAIL_SOURCE_PIXEL_FORMAT: return "Source pixel format";
case DML_FAIL_VIEWPORT_SIZE: return "Viewport size";
case DML_FAIL_TOTAL_V_ACTIVE_BW: return "Total vertical active bandwidth";
case DML_FAIL_DIO_SUPPORT: return "DIO support";
case DML_FAIL_NOT_ENOUGH_DSC: return "Not enough DSC Units";
case DML_FAIL_DSC_CLK_REQUIRED: return "DSC clock required";
case DML_FAIL_URGENT_LATENCY: return "Urgent latency";
case DML_FAIL_REORDERING_BUFFER: return "Re-ordering buffer";
case DML_FAIL_DISPCLK_DPPCLK: return "Dispclk and Dppclk";
case DML_FAIL_TOTAL_AVAILABLE_PIPES: return "Total available pipes";
case DML_FAIL_NUM_OTG: return "Number of OTG";
case DML_FAIL_WRITEBACK_MODE: return "Writeback mode";
case DML_FAIL_WRITEBACK_LATENCY: return "Writeback latency";
case DML_FAIL_WRITEBACK_SCALE_RATIO_TAP: return "Writeback scale ratio/tap";
case DML_FAIL_CURSOR_SUPPORT: return "Cursor support";
case DML_FAIL_PITCH_SUPPORT: return "Pitch support";
case DML_FAIL_PTE_BUFFER_SIZE: return "PTE buffer size";
case DML_FAIL_DSC_INPUT_BPC: return "DSC input bpc";
case DML_FAIL_PREFETCH_SUPPORT: return "Prefetch support";
case DML_FAIL_V_RATIO_PREFETCH: return "Vertical ratio prefetch";
default: return "Unknown Status";
}
}
void dml_log_pipe_params(
struct display_mode_lib *mode_lib,
display_e2e_pipe_params_st *pipes,
int pipe_cnt)
{
(void)mode_lib;
display_pipe_source_params_st *pipe_src;
display_pipe_dest_params_st *pipe_dest;
scaler_ratio_depth_st *scale_ratio_depth;
scaler_taps_st *scale_taps;
display_output_params_st *dout;
display_clocks_and_cfg_st *clks_cfg;
int i;
for (i = 0; i < pipe_cnt; i++) {
pipe_src = &(pipes[i].pipe.src);
pipe_dest = &(pipes[i].pipe.dest);
scale_ratio_depth = &(pipes[i].pipe.scale_ratio_depth);
scale_taps = &(pipes[i].pipe.scale_taps);
dout = &(pipes[i].dout);
clks_cfg = &(pipes[i].clks_cfg);
dml_print("DML PARAMS: =====================================\n");
dml_print("DML PARAMS: PIPE [%d] SOURCE PARAMS:\n", i);
dml_print("DML PARAMS: source_format = %d\n", pipe_src->source_format);
dml_print("DML PARAMS: dcc = %d\n", pipe_src->dcc);
dml_print("DML PARAMS: dcc_rate = %d\n", pipe_src->dcc_rate);
dml_print("DML PARAMS: dcc_use_global = %d\n", pipe_src->dcc_use_global);
dml_print("DML PARAMS: vm = %d\n", pipe_src->vm);
dml_print("DML PARAMS: gpuvm = %d\n", pipe_src->gpuvm);
dml_print("DML PARAMS: hostvm = %d\n", pipe_src->hostvm);
dml_print("DML PARAMS: gpuvm_levels_force_en = %d\n", pipe_src->gpuvm_levels_force_en);
dml_print("DML PARAMS: gpuvm_levels_force = %d\n", pipe_src->gpuvm_levels_force);
dml_print("DML PARAMS: source_scan = %d\n", pipe_src->source_scan);
dml_print("DML PARAMS: sw_mode = %d\n", pipe_src->sw_mode);
dml_print("DML PARAMS: macro_tile_size = %d\n", pipe_src->macro_tile_size);
dml_print("DML PARAMS: viewport_width = %d\n", pipe_src->viewport_width);
dml_print("DML PARAMS: viewport_height = %d\n", pipe_src->viewport_height);
dml_print("DML PARAMS: viewport_y_y = %d\n", pipe_src->viewport_y_y);
dml_print("DML PARAMS: viewport_y_c = %d\n", pipe_src->viewport_y_c);
dml_print("DML PARAMS: viewport_width_c = %d\n", pipe_src->viewport_width_c);
dml_print("DML PARAMS: viewport_height_c = %d\n", pipe_src->viewport_height_c);
dml_print("DML PARAMS: data_pitch = %d\n", pipe_src->data_pitch);
dml_print("DML PARAMS: data_pitch_c = %d\n", pipe_src->data_pitch_c);
dml_print("DML PARAMS: meta_pitch = %d\n", pipe_src->meta_pitch);
dml_print("DML PARAMS: meta_pitch_c = %d\n", pipe_src->meta_pitch_c);
dml_print("DML PARAMS: cur0_src_width = %d\n", pipe_src->cur0_src_width);
dml_print("DML PARAMS: cur0_bpp = %d\n", pipe_src->cur0_bpp);
dml_print("DML PARAMS: cur1_src_width = %d\n", pipe_src->cur1_src_width);
dml_print("DML PARAMS: cur1_bpp = %d\n", pipe_src->cur1_bpp);
dml_print("DML PARAMS: num_cursors = %d\n", pipe_src->num_cursors);
dml_print("DML PARAMS: is_hsplit = %d\n", pipe_src->is_hsplit);
dml_print("DML PARAMS: hsplit_grp = %d\n", pipe_src->hsplit_grp);
dml_print("DML PARAMS: dynamic_metadata_enable = %d\n", pipe_src->dynamic_metadata_enable);
dml_print("DML PARAMS: dmdata_lines_before_active = %d\n", pipe_src->dynamic_metadata_lines_before_active);
dml_print("DML PARAMS: dmdata_xmit_bytes = %d\n", pipe_src->dynamic_metadata_xmit_bytes);
dml_print("DML PARAMS: immediate_flip = %d\n", pipe_src->immediate_flip);
dml_print("DML PARAMS: v_total_min = %d\n", pipe_src->v_total_min);
dml_print("DML PARAMS: v_total_max = %d\n", pipe_src->v_total_max);
dml_print("DML PARAMS: =====================================\n");
dml_print("DML PARAMS: PIPE [%d] DESTINATION PARAMS:\n", i);
dml_print("DML PARAMS: recout_width = %d\n", pipe_dest->recout_width);
dml_print("DML PARAMS: recout_height = %d\n", pipe_dest->recout_height);
dml_print("DML PARAMS: full_recout_width = %d\n", pipe_dest->full_recout_width);
dml_print("DML PARAMS: full_recout_height = %d\n", pipe_dest->full_recout_height);
dml_print("DML PARAMS: hblank_start = %d\n", pipe_dest->hblank_start);
dml_print("DML PARAMS: hblank_end = %d\n", pipe_dest->hblank_end);
dml_print("DML PARAMS: vblank_start = %d\n", pipe_dest->vblank_start);
dml_print("DML PARAMS: vblank_end = %d\n", pipe_dest->vblank_end);
dml_print("DML PARAMS: htotal = %d\n", pipe_dest->htotal);
dml_print("DML PARAMS: vtotal = %d\n", pipe_dest->vtotal);
dml_print("DML PARAMS: vactive = %d\n", pipe_dest->vactive);
dml_print("DML PARAMS: hactive = %d\n", pipe_dest->hactive);
dml_print("DML PARAMS: vstartup_start = %d\n", pipe_dest->vstartup_start);
dml_print("DML PARAMS: vupdate_offset = %d\n", pipe_dest->vupdate_offset);
dml_print("DML PARAMS: vupdate_width = %d\n", pipe_dest->vupdate_width);
dml_print("DML PARAMS: vready_offset = %d\n", pipe_dest->vready_offset);
dml_print("DML PARAMS: interlaced = %d\n", pipe_dest->interlaced);
dml_print("DML PARAMS: pixel_rate_mhz = %3.2f\n", pipe_dest->pixel_rate_mhz);
dml_print("DML PARAMS: sync_vblank_all_planes = %d\n", pipe_dest->synchronized_vblank_all_planes);
dml_print("DML PARAMS: otg_inst = %d\n", pipe_dest->otg_inst);
dml_print("DML PARAMS: odm_combine = %d\n", pipe_dest->odm_combine);
dml_print("DML PARAMS: use_maximum_vstartup = %d\n", pipe_dest->use_maximum_vstartup);
dml_print("DML PARAMS: vtotal_max = %d\n", pipe_dest->vtotal_max);
dml_print("DML PARAMS: vtotal_min = %d\n", pipe_dest->vtotal_min);
dml_print("DML PARAMS: =====================================\n");
dml_print("DML PARAMS: PIPE [%d] SCALER PARAMS:\n", i);
dml_print("DML PARAMS: hscl_ratio = %3.4f\n", scale_ratio_depth->hscl_ratio);
dml_print("DML PARAMS: vscl_ratio = %3.4f\n", scale_ratio_depth->vscl_ratio);
dml_print("DML PARAMS: hscl_ratio_c = %3.4f\n", scale_ratio_depth->hscl_ratio_c);
dml_print("DML PARAMS: vscl_ratio_c = %3.4f\n", scale_ratio_depth->vscl_ratio_c);
dml_print("DML PARAMS: vinit = %3.4f\n", scale_ratio_depth->vinit);
dml_print("DML PARAMS: vinit_c = %3.4f\n", scale_ratio_depth->vinit_c);
dml_print("DML PARAMS: vinit_bot = %3.4f\n", scale_ratio_depth->vinit_bot);
dml_print("DML PARAMS: vinit_bot_c = %3.4f\n", scale_ratio_depth->vinit_bot_c);
dml_print("DML PARAMS: lb_depth = %d\n", scale_ratio_depth->lb_depth);
dml_print("DML PARAMS: scl_enable = %d\n", scale_ratio_depth->scl_enable);
dml_print("DML PARAMS: htaps = %d\n", scale_taps->htaps);
dml_print("DML PARAMS: vtaps = %d\n", scale_taps->vtaps);
dml_print("DML PARAMS: htaps_c = %d\n", scale_taps->htaps_c);
dml_print("DML PARAMS: vtaps_c = %d\n", scale_taps->vtaps_c);
dml_print("DML PARAMS: =====================================\n");
dml_print("DML PARAMS: PIPE [%d] DISPLAY OUTPUT PARAMS:\n", i);
dml_print("DML PARAMS: output_type = %d\n", dout->output_type);
dml_print("DML PARAMS: output_format = %d\n", dout->output_format);
dml_print("DML PARAMS: dsc_input_bpc = %d\n", dout->dsc_input_bpc);
dml_print("DML PARAMS: output_bpp = %3.4f\n", dout->output_bpp);
dml_print("DML PARAMS: dp_lanes = %d\n", dout->dp_lanes);
dml_print("DML PARAMS: dsc_enable = %d\n", dout->dsc_enable);
dml_print("DML PARAMS: dsc_slices = %d\n", dout->dsc_slices);
dml_print("DML PARAMS: wb_enable = %d\n", dout->wb_enable);
dml_print("DML PARAMS: num_active_wb = %d\n", dout->num_active_wb);
dml_print("DML PARAMS: =====================================\n");
dml_print("DML PARAMS: PIPE [%d] CLOCK CONFIG PARAMS:\n", i);
dml_print("DML PARAMS: voltage = %d\n", clks_cfg->voltage);
dml_print("DML PARAMS: dppclk_mhz = %3.2f\n", clks_cfg->dppclk_mhz);
dml_print("DML PARAMS: refclk_mhz = %3.2f\n", clks_cfg->refclk_mhz);
dml_print("DML PARAMS: dispclk_mhz = %3.2f\n", clks_cfg->dispclk_mhz);
dml_print("DML PARAMS: dcfclk_mhz = %3.2f\n", clks_cfg->dcfclk_mhz);
dml_print("DML PARAMS: socclk_mhz = %3.2f\n", clks_cfg->socclk_mhz);
dml_print("DML PARAMS: =====================================\n");
}
}
void dml_log_mode_support_params(struct display_mode_lib *mode_lib)
{
int i;
for (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
dml_print("DML SUPPORT: ===============================================\n");
dml_print("DML SUPPORT: Voltage State %d\n", i);
dml_print("DML SUPPORT: Mode Supported : %s\n", mode_lib->vba.ModeSupport[i][0] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Mode Supported (pipe split) : %s\n", mode_lib->vba.ModeSupport[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Scale Ratio And Taps : %s\n", mode_lib->vba.ScaleRatioAndTapsSupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Source Format Pixel And Scan : %s\n", mode_lib->vba.SourceFormatPixelAndScanSupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Viewport Size : [%s, %s]\n", mode_lib->vba.ViewportSizeSupport[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.ViewportSizeSupport[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: DIO Support : %s\n", mode_lib->vba.DIOSupport[i] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: ODM Combine 4To1 Support Check : %s\n", mode_lib->vba.ODMCombine4To1SupportCheckOK[i] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: DSC Units : %s\n", mode_lib->vba.NotEnoughDSCUnits[i] ? "Not Supported" : "Supported");
dml_print("DML SUPPORT: DSCCLK Required : %s\n", mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] ? "Not Supported" : "Supported");
dml_print("DML SUPPORT: DTBCLK Required : %s\n", mode_lib->vba.DTBCLKRequiredMoreThanSupported[i] ? "Not Supported" : "Supported");
dml_print("DML SUPPORT: Re-ordering Buffer : [%s, %s]\n", mode_lib->vba.ROBSupport[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.ROBSupport[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: DISPCLK and DPPCLK : [%s, %s]\n", mode_lib->vba.DISPCLK_DPPCLK_Support[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.DISPCLK_DPPCLK_Support[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Total Available Pipes : [%s, %s]\n", mode_lib->vba.TotalAvailablePipesSupport[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.TotalAvailablePipesSupport[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Writeback Latency : %s\n", mode_lib->vba.WritebackLatencySupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Writeback Scale Ratio And Taps : %s\n", mode_lib->vba.WritebackScaleRatioAndTapsSupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Cursor : %s\n", mode_lib->vba.CursorSupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Pitch : %s\n", mode_lib->vba.PitchSupport ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Prefetch : [%s, %s]\n", mode_lib->vba.PrefetchSupported[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.PrefetchSupported[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Dynamic Metadata : [%s, %s]\n", mode_lib->vba.DynamicMetadataSupported[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.DynamicMetadataSupported[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: Total Vertical Active Bandwidth : [%s, %s]\n", mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: VRatio In Prefetch : [%s, %s]\n", mode_lib->vba.VRatioInPrefetchSupported[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.VRatioInPrefetchSupported[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: PTE Buffer Size Not Exceeded : [%s, %s]\n", mode_lib->vba.PTEBufferSizeNotExceeded[i][0] ? "Supported" : "NOT Supported", mode_lib->vba.PTEBufferSizeNotExceeded[i][1] ? "Supported" : "NOT Supported");
dml_print("DML SUPPORT: DSC Input BPC : %s\n", mode_lib->vba.NonsupportedDSCInputBPC ? "Not Supported" : "Supported");
dml_print("DML SUPPORT: HostVMEnable : %d\n", mode_lib->vba.HostVMEnable);
dml_print("DML SUPPORT: ImmediateFlipSupportedForState : [%d, %d]\n", mode_lib->vba.ImmediateFlipSupportedForState[i][0], mode_lib->vba.ImmediateFlipSupportedForState[i][1]);
}
}
@@ -0,0 +1,109 @@
/*
* Copyright 2017 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 __DISPLAY_MODE_LIB_H__
#define __DISPLAY_MODE_LIB_H__
#include "dm_services.h"
#include "dc_features.h"
#include "display_mode_structs.h"
#include "display_mode_enums.h"
#include "display_mode_vba.h"
enum dml_project {
DML_PROJECT_UNDEFINED,
DML_PROJECT_RAVEN1,
DML_PROJECT_NAVI10,
DML_PROJECT_NAVI10v2,
DML_PROJECT_DCN201,
DML_PROJECT_DCN21,
DML_PROJECT_DCN30,
DML_PROJECT_DCN31,
DML_PROJECT_DCN315,
DML_PROJECT_DCN314,
DML_PROJECT_DCN32,
};
struct display_mode_lib;
struct dml_funcs {
void (*rq_dlg_get_dlg_reg)(
struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool ignore_viewport_pos,
const bool immediate_flip_support);
void (*rq_dlg_get_rq_reg)(
struct display_mode_lib *mode_lib,
display_rq_regs_st *rq_regs,
const display_pipe_params_st *pipe_param);
// DLG interfaces have different function parameters in DCN32.
// Create new function pointers to address the changes
void (*rq_dlg_get_dlg_reg_v2)(
struct display_mode_lib *mode_lib,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx);
void (*rq_dlg_get_rq_reg_v2)(display_rq_regs_st *rq_regs,
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx);
void (*recalculate)(struct display_mode_lib *mode_lib);
void (*validate)(struct display_mode_lib *mode_lib);
};
struct display_mode_lib {
struct _vcs_dpi_ip_params_st ip;
struct _vcs_dpi_soc_bounding_box_st soc;
enum dml_project project;
struct vba_vars_st vba;
struct dal_logger *logger;
struct dml_funcs funcs;
struct _vcs_dpi_display_e2e_pipe_params_st dml_pipe_state[6];
bool validate_max_state;
};
void dml_init_instance(struct display_mode_lib *lib,
const struct _vcs_dpi_soc_bounding_box_st *soc_bb,
const struct _vcs_dpi_ip_params_st *ip_params,
enum dml_project project);
const char *dml_get_status_message(enum dm_validation_status status);
void dml_log_pipe_params(
struct display_mode_lib *mode_lib,
display_e2e_pipe_params_st *pipes,
int pipe_cnt);
void dml_log_mode_support_params(struct display_mode_lib *mode_lib);
#endif
@@ -0,0 +1,741 @@
/*
* Copyright 2017 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 "dc_features.h"
#include "display_mode_enums.h"
/**
* DOC: overview
*
* Most of the DML code is automatically generated and tested via hardware
* description language. Usually, we use the reference _vcs_dpi in the code
* where VCS means "Verilog Compiled Simulator" and DPI stands for "Direct
* Programmer Interface". In other words, those structs can be used to
* interface with Verilog with other languages such as C.
*/
#ifndef __DISPLAY_MODE_STRUCTS_H__
#define __DISPLAY_MODE_STRUCTS_H__
typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
typedef struct _vcs_dpi_ip_params_st ip_params_st;
typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st;
typedef struct _vcs_dpi_display_output_params_st display_output_params_st;
typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st;
typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st;
typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st;
typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st;
typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st;
typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st;
typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st;
typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st;
typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st;
typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st;
typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st;
typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st;
typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st;
typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st;
typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st;
typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st;
typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st;
typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st;
typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st;
typedef struct {
double UrgentWatermark;
double WritebackUrgentWatermark;
double DRAMClockChangeWatermark;
double FCLKChangeWatermark;
double WritebackDRAMClockChangeWatermark;
double WritebackFCLKChangeWatermark;
double StutterExitWatermark;
double StutterEnterPlusExitWatermark;
double Z8StutterExitWatermark;
double Z8StutterEnterPlusExitWatermark;
double USRRetrainingWatermark;
} Watermarks;
typedef struct {
double UrgentLatency;
double ExtraLatency;
double WritebackLatency;
double DRAMClockChangeLatency;
double FCLKChangeLatency;
double SRExitTime;
double SREnterPlusExitTime;
double SRExitZ8Time;
double SREnterPlusExitZ8Time;
double USRRetrainingLatencyPlusSMNLatency;
} Latencies;
typedef struct {
double Dppclk;
double Dispclk;
double PixelClock;
double DCFClkDeepSleep;
unsigned int DPPPerSurface;
bool ScalerEnabled;
enum dm_rotation_angle SourceRotation;
unsigned int ViewportHeight;
unsigned int ViewportHeightChroma;
unsigned int BlockWidth256BytesY;
unsigned int BlockHeight256BytesY;
unsigned int BlockWidth256BytesC;
unsigned int BlockHeight256BytesC;
unsigned int BlockWidthY;
unsigned int BlockHeightY;
unsigned int BlockWidthC;
unsigned int BlockHeightC;
unsigned int InterlaceEnable;
unsigned int NumberOfCursors;
unsigned int VBlank;
unsigned int HTotal;
unsigned int HActive;
bool DCCEnable;
enum odm_combine_mode ODMMode;
enum source_format_class SourcePixelFormat;
enum dm_swizzle_mode SurfaceTiling;
unsigned int BytePerPixelY;
unsigned int BytePerPixelC;
bool ProgressiveToInterlaceUnitInOPP;
double VRatio;
double VRatioChroma;
unsigned int VTaps;
unsigned int VTapsChroma;
unsigned int PitchY;
unsigned int DCCMetaPitchY;
unsigned int PitchC;
unsigned int DCCMetaPitchC;
bool ViewportStationary;
unsigned int ViewportXStart;
unsigned int ViewportYStart;
unsigned int ViewportXStartC;
unsigned int ViewportYStartC;
bool FORCE_ONE_ROW_FOR_FRAME;
unsigned int SwathHeightY;
unsigned int SwathHeightC;
} DmlPipe;
typedef struct {
double UrgentLatency;
double ExtraLatency;
double WritebackLatency;
double DRAMClockChangeLatency;
double FCLKChangeLatency;
double SRExitTime;
double SREnterPlusExitTime;
double SRExitZ8Time;
double SREnterPlusExitZ8Time;
double USRRetrainingLatency;
double SMNLatency;
} SOCParametersList;
struct _vcs_dpi_voltage_scaling_st {
int state;
double dscclk_mhz;
double dcfclk_mhz;
double socclk_mhz;
double phyclk_d18_mhz;
double phyclk_d32_mhz;
double dram_speed_mts;
double fabricclk_mhz;
double dispclk_mhz;
double dram_bw_per_chan_gbps;
double phyclk_mhz;
double dppclk_mhz;
double dtbclk_mhz;
float net_bw_in_kbytes_sec;
};
/**
* _vcs_dpi_soc_bounding_box_st: SOC definitions
*
* This struct maintains the SOC Bounding Box information for the ASIC; it
* defines things such as clock, voltage, performance, etc. Usually, we load
* these values from VBIOS; if something goes wrong, we use some hard-coded
* values, which will enable the ASIC to light up with limitations.
*/
struct _vcs_dpi_soc_bounding_box_st {
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
/**
* @num_states: It represents the total of Display Power Management
* (DPM) supported by the specific ASIC.
*/
unsigned int num_states;
double sr_exit_time_us;
double sr_enter_plus_exit_time_us;
double sr_exit_z8_time_us;
double sr_enter_plus_exit_z8_time_us;
double urgent_latency_us;
double urgent_latency_pixel_data_only_us;
double urgent_latency_pixel_mixed_with_vm_data_us;
double urgent_latency_vm_data_only_us;
double usr_retraining_latency_us;
double smn_latency_us;
double fclk_change_latency_us;
double mall_allocated_for_dcn_mbytes;
double pct_ideal_fabric_bw_after_urgent;
double pct_ideal_dram_bw_after_urgent_strobe;
double max_avg_fabric_bw_use_normal_percent;
double max_avg_dram_bw_use_normal_strobe_percent;
enum dm_prefetch_modes allow_for_pstate_or_stutter_in_vblank_final;
bool dram_clock_change_requirement_final;
double writeback_latency_us;
double ideal_dram_bw_after_urgent_percent;
double pct_ideal_dram_sdp_bw_after_urgent_pixel_only; // PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly
double pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm;
double pct_ideal_dram_sdp_bw_after_urgent_vm_only;
double pct_ideal_sdp_bw_after_urgent;
double max_avg_sdp_bw_use_normal_percent;
double max_avg_dram_bw_use_normal_percent;
unsigned int max_request_size_bytes;
double downspread_percent;
double dram_page_open_time_ns;
double dram_rw_turnaround_time_ns;
double dram_return_buffer_per_channel_bytes;
double dram_channel_width_bytes;
double fabric_datapath_to_dcn_data_return_bytes;
double dcn_downspread_percent;
double dispclk_dppclk_vco_speed_mhz;
double dfs_vco_period_ps;
unsigned int urgent_out_of_order_return_per_channel_pixel_only_bytes;
unsigned int urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
unsigned int urgent_out_of_order_return_per_channel_vm_only_bytes;
unsigned int round_trip_ping_latency_dcfclk_cycles;
unsigned int urgent_out_of_order_return_per_channel_bytes;
unsigned int channel_interleave_bytes;
unsigned int num_banks;
unsigned int num_chans;
unsigned int vmm_page_size_bytes;
unsigned int hostvm_min_page_size_bytes;
unsigned int gpuvm_min_page_size_bytes;
double dram_clock_change_latency_us;
double dummy_pstate_latency_us;
double writeback_dram_clock_change_latency_us;
unsigned int return_bus_width_bytes;
unsigned int voltage_override;
double xfc_bus_transport_time_us;
double xfc_xbuf_latency_tolerance_us;
int use_urgent_burst_bw;
double min_dcfclk;
bool do_urgent_latency_adjustment;
double urgent_latency_adjustment_fabric_clock_component_us;
double urgent_latency_adjustment_fabric_clock_reference_mhz;
bool disable_dram_clock_change_vactive_support;
bool allow_dram_clock_one_display_vactive;
enum self_refresh_affinity allow_dram_self_refresh_or_dram_clock_change_in_vblank;
double max_vratio_pre;
};
/**
* @_vcs_dpi_ip_params_st: IP configuraion for DCN blocks
*
* In this struct you can find the DCN configuration associated to the specific
* ASIC. For example, here we can save how many DPPs the ASIC is using and it
* is available.
*
*/
struct _vcs_dpi_ip_params_st {
bool use_min_dcfclk;
bool clamp_min_dcfclk;
bool gpuvm_enable;
bool hostvm_enable;
bool dsc422_native_support;
unsigned int gpuvm_max_page_table_levels;
unsigned int hostvm_max_page_table_levels;
unsigned int hostvm_cached_page_table_levels;
unsigned int pte_group_size_bytes;
unsigned int max_inter_dcn_tile_repeaters;
unsigned int num_dsc;
unsigned int odm_capable;
unsigned int rob_buffer_size_kbytes;
unsigned int det_buffer_size_kbytes;
unsigned int min_comp_buffer_size_kbytes;
unsigned int dpte_buffer_size_in_pte_reqs_luma;
unsigned int dpte_buffer_size_in_pte_reqs_chroma;
unsigned int pde_proc_buffer_size_64k_reqs;
unsigned int dpp_output_buffer_pixels;
unsigned int opp_output_buffer_lines;
unsigned int pixel_chunk_size_kbytes;
unsigned int alpha_pixel_chunk_size_kbytes;
unsigned int min_pixel_chunk_size_bytes;
unsigned int dcc_meta_buffer_size_bytes;
unsigned char pte_enable;
unsigned int pte_chunk_size_kbytes;
unsigned int meta_chunk_size_kbytes;
unsigned int min_meta_chunk_size_bytes;
unsigned int writeback_chunk_size_kbytes;
unsigned int line_buffer_size_bits;
unsigned int max_line_buffer_lines;
unsigned int writeback_luma_buffer_size_kbytes;
unsigned int writeback_chroma_buffer_size_kbytes;
unsigned int writeback_chroma_line_buffer_width_pixels;
unsigned int writeback_interface_buffer_size_kbytes;
unsigned int writeback_line_buffer_buffer_size;
unsigned int writeback_10bpc420_supported;
double writeback_max_hscl_ratio;
double writeback_max_vscl_ratio;
double writeback_min_hscl_ratio;
double writeback_min_vscl_ratio;
unsigned int maximum_dsc_bits_per_component;
unsigned int maximum_pixels_per_line_per_dsc_unit;
unsigned int writeback_max_hscl_taps;
unsigned int writeback_max_vscl_taps;
unsigned int writeback_line_buffer_luma_buffer_size;
unsigned int writeback_line_buffer_chroma_buffer_size;
unsigned int max_page_table_levels;
/**
* @max_num_dpp: Maximum number of DPP supported in the target ASIC.
*/
unsigned int max_num_dpp;
unsigned int max_num_otg;
unsigned int cursor_chunk_size;
unsigned int cursor_buffer_size;
unsigned int max_num_wb;
unsigned int max_dchub_pscl_bw_pix_per_clk;
unsigned int max_pscl_lb_bw_pix_per_clk;
unsigned int max_lb_vscl_bw_pix_per_clk;
unsigned int max_vscl_hscl_bw_pix_per_clk;
double max_hscl_ratio;
double max_vscl_ratio;
unsigned int hscl_mults;
unsigned int vscl_mults;
unsigned int max_hscl_taps;
unsigned int max_vscl_taps;
unsigned int xfc_supported;
unsigned int ptoi_supported;
unsigned int gfx7_compat_tiling_supported;
bool odm_combine_4to1_supported;
bool dynamic_metadata_vm_enabled;
unsigned int max_num_hdmi_frl_outputs;
unsigned int xfc_fill_constant_bytes;
double dispclk_ramp_margin_percent;
double xfc_fill_bw_overhead_percent;
double underscan_factor;
unsigned int min_vblank_lines;
unsigned int dppclk_delay_subtotal;
unsigned int dispclk_delay_subtotal;
double dcfclk_cstate_latency;
unsigned int dppclk_delay_scl;
unsigned int dppclk_delay_scl_lb_only;
unsigned int dppclk_delay_cnvc_formatter;
unsigned int dppclk_delay_cnvc_cursor;
unsigned int is_line_buffer_bpp_fixed;
unsigned int line_buffer_fixed_bpp;
unsigned int dcc_supported;
unsigned int config_return_buffer_size_in_kbytes;
unsigned int compressed_buffer_segment_size_in_kbytes;
unsigned int meta_fifo_size_in_kentries;
unsigned int zero_size_buffer_entries;
unsigned int compbuf_reserved_space_64b;
unsigned int compbuf_reserved_space_zs;
unsigned int IsLineBufferBppFixed;
unsigned int LineBufferFixedBpp;
unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
unsigned int bug_forcing_LC_req_same_size_fixed;
unsigned int number_of_cursors;
unsigned int max_num_dp2p0_outputs;
unsigned int max_num_dp2p0_streams;
unsigned int VBlankNomDefaultUS;
/* DM workarounds */
double dsc_delay_factor_wa; // TODO: Remove after implementing root cause fix
double min_prefetch_in_strobe_us;
};
struct _vcs_dpi_display_xfc_params_st {
double xfc_tslv_vready_offset_us;
double xfc_tslv_vupdate_width_us;
double xfc_tslv_vupdate_offset_us;
int xfc_slv_chunk_size_bytes;
};
struct _vcs_dpi_display_pipe_source_params_st {
int source_format;
double dcc_fraction_of_zs_req_luma;
double dcc_fraction_of_zs_req_chroma;
unsigned char dcc;
unsigned int dcc_rate;
unsigned int dcc_rate_chroma;
unsigned char dcc_use_global;
unsigned char vm;
bool unbounded_req_mode;
bool gpuvm; // gpuvm enabled
bool hostvm; // hostvm enabled
bool gpuvm_levels_force_en;
unsigned int gpuvm_levels_force;
bool hostvm_levels_force_en;
unsigned int hostvm_levels_force;
int source_scan;
int source_rotation; // new in dml32
unsigned int det_size_override; // use to populate DETSizeOverride in vba struct
int sw_mode;
int macro_tile_size;
unsigned int surface_width_y;
unsigned int surface_height_y;
unsigned int surface_width_c;
unsigned int surface_height_c;
unsigned int viewport_width;
unsigned int viewport_height;
unsigned int viewport_y_y;
unsigned int viewport_y_c;
unsigned int viewport_width_c;
unsigned int viewport_height_c;
unsigned int viewport_width_max;
unsigned int viewport_height_max;
unsigned int viewport_x_y;
unsigned int viewport_x_c;
bool viewport_stationary;
unsigned int dcc_rate_luma;
unsigned int gpuvm_min_page_size_kbytes;
unsigned int use_mall_for_pstate_change;
unsigned int use_mall_for_static_screen;
bool force_one_row_for_frame;
bool pte_buffer_mode;
unsigned int data_pitch;
unsigned int data_pitch_c;
unsigned int meta_pitch;
unsigned int meta_pitch_c;
unsigned int cur0_src_width;
int cur0_bpp;
unsigned int cur1_src_width;
int cur1_bpp;
int num_cursors;
unsigned char is_hsplit;
unsigned char dynamic_metadata_enable;
unsigned int dynamic_metadata_lines_before_active;
unsigned int dynamic_metadata_xmit_bytes;
unsigned int hsplit_grp;
unsigned char xfc_enable;
unsigned char xfc_slave;
unsigned char immediate_flip;
struct _vcs_dpi_display_xfc_params_st xfc_params;
//for vstartuplines calculation freesync
unsigned char v_total_min;
unsigned char v_total_max;
};
struct writeback_st {
int wb_src_height;
int wb_src_width;
int wb_dst_width;
int wb_dst_height;
int wb_pixel_format;
int wb_htaps_luma;
int wb_vtaps_luma;
int wb_htaps_chroma;
int wb_vtaps_chroma;
unsigned int wb_htaps;
unsigned int wb_vtaps;
double wb_hratio;
double wb_vratio;
};
struct display_audio_params_st {
unsigned int audio_sample_rate_khz;
int audio_sample_layout;
};
struct _vcs_dpi_display_output_params_st {
int dp_lanes;
double output_bpp;
unsigned int dsc_input_bpc;
int dsc_enable;
int wb_enable;
int num_active_wb;
int output_type;
int is_virtual;
int output_format;
int dsc_slices;
int max_audio_sample_rate;
struct writeback_st wb;
struct display_audio_params_st audio;
unsigned int output_bpc;
int dp_rate;
unsigned int dp_multistream_id;
bool dp_multistream_en;
};
struct _vcs_dpi_scaler_ratio_depth_st {
double hscl_ratio;
double vscl_ratio;
double hscl_ratio_c;
double vscl_ratio_c;
double vinit;
double vinit_c;
double vinit_bot;
double vinit_bot_c;
int lb_depth;
int scl_enable;
};
struct _vcs_dpi_scaler_taps_st {
unsigned int htaps;
unsigned int vtaps;
unsigned int htaps_c;
unsigned int vtaps_c;
};
struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int recout_width;
unsigned int recout_height;
unsigned int full_recout_width;
unsigned int full_recout_height;
unsigned int hblank_start;
unsigned int hblank_end;
unsigned int vblank_start;
unsigned int vblank_end;
unsigned int htotal;
unsigned int vtotal;
unsigned int vfront_porch;
unsigned int vblank_nom;
unsigned int vactive;
unsigned int hactive;
unsigned int vstartup_start;
unsigned int vupdate_offset;
unsigned int vupdate_width;
unsigned int vready_offset;
unsigned int pstate_keepout;
unsigned char interlaced;
double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes;
unsigned char otg_inst;
unsigned int odm_combine;
unsigned char use_maximum_vstartup;
unsigned int vtotal_max;
unsigned int vtotal_min;
unsigned int refresh_rate;
bool synchronize_timings;
unsigned int odm_combine_policy;
bool drr_display;
};
struct _vcs_dpi_display_pipe_params_st {
display_pipe_source_params_st src;
display_pipe_dest_params_st dest;
scaler_ratio_depth_st scale_ratio_depth;
scaler_taps_st scale_taps;
};
struct _vcs_dpi_display_clocks_and_cfg_st {
int voltage;
double dppclk_mhz;
double refclk_mhz;
double dispclk_mhz;
double dcfclk_mhz;
double socclk_mhz;
};
struct _vcs_dpi_display_e2e_pipe_params_st {
display_pipe_params_st pipe;
display_output_params_st dout;
display_clocks_and_cfg_st clks_cfg;
};
struct _vcs_dpi_display_data_rq_misc_params_st {
unsigned int full_swath_bytes;
unsigned int stored_swath_bytes;
unsigned int blk256_height;
unsigned int blk256_width;
unsigned int req_height;
unsigned int req_width;
};
struct _vcs_dpi_display_data_rq_sizing_params_st {
unsigned int chunk_bytes;
unsigned int min_chunk_bytes;
unsigned int meta_chunk_bytes;
unsigned int min_meta_chunk_bytes;
unsigned int mpte_group_bytes;
unsigned int dpte_group_bytes;
};
struct _vcs_dpi_display_data_rq_dlg_params_st {
unsigned int swath_width_ub;
unsigned int swath_height;
unsigned int req_per_swath_ub;
unsigned int meta_pte_bytes_per_frame_ub;
unsigned int dpte_req_per_row_ub;
unsigned int dpte_groups_per_row_ub;
unsigned int dpte_row_height;
unsigned int dpte_bytes_per_row_ub;
unsigned int meta_chunks_per_row_ub;
unsigned int meta_req_per_row_ub;
unsigned int meta_row_height;
unsigned int meta_bytes_per_row_ub;
};
struct _vcs_dpi_display_rq_dlg_params_st {
display_data_rq_dlg_params_st rq_l;
display_data_rq_dlg_params_st rq_c;
};
struct _vcs_dpi_display_rq_sizing_params_st {
display_data_rq_sizing_params_st rq_l;
display_data_rq_sizing_params_st rq_c;
};
struct _vcs_dpi_display_rq_misc_params_st {
display_data_rq_misc_params_st rq_l;
display_data_rq_misc_params_st rq_c;
};
struct _vcs_dpi_display_rq_params_st {
unsigned char yuv420;
unsigned char yuv420_10bpc;
unsigned char rgbe_alpha;
display_rq_misc_params_st misc;
display_rq_sizing_params_st sizing;
display_rq_dlg_params_st dlg;
};
struct _vcs_dpi_display_dlg_regs_st {
unsigned int refcyc_h_blank_end;
unsigned int dlg_vblank_end;
unsigned int min_dst_y_next_start;
unsigned int min_dst_y_next_start_us;
unsigned int refcyc_per_htotal;
unsigned int refcyc_x_after_scaler;
unsigned int dst_y_after_scaler;
unsigned int dst_y_prefetch;
unsigned int dst_y_per_vm_vblank;
unsigned int dst_y_per_row_vblank;
unsigned int dst_y_per_vm_flip;
unsigned int dst_y_per_row_flip;
unsigned int ref_freq_to_pix_freq;
unsigned int vratio_prefetch;
unsigned int vratio_prefetch_c;
unsigned int refcyc_per_tdlut_group;
unsigned int refcyc_per_pte_group_vblank_l;
unsigned int refcyc_per_pte_group_vblank_c;
unsigned int refcyc_per_meta_chunk_vblank_l;
unsigned int refcyc_per_meta_chunk_vblank_c;
unsigned int refcyc_per_pte_group_flip_l;
unsigned int refcyc_per_pte_group_flip_c;
unsigned int refcyc_per_meta_chunk_flip_l;
unsigned int refcyc_per_meta_chunk_flip_c;
unsigned int dst_y_per_pte_row_nom_l;
unsigned int dst_y_per_pte_row_nom_c;
unsigned int refcyc_per_pte_group_nom_l;
unsigned int refcyc_per_pte_group_nom_c;
unsigned int dst_y_per_meta_row_nom_l;
unsigned int dst_y_per_meta_row_nom_c;
unsigned int refcyc_per_meta_chunk_nom_l;
unsigned int refcyc_per_meta_chunk_nom_c;
unsigned int refcyc_per_line_delivery_pre_l;
unsigned int refcyc_per_line_delivery_pre_c;
unsigned int refcyc_per_line_delivery_l;
unsigned int refcyc_per_line_delivery_c;
unsigned int chunk_hdl_adjust_cur0;
unsigned int chunk_hdl_adjust_cur1;
unsigned int vready_after_vcount0;
unsigned int dst_y_offset_cur0;
unsigned int dst_y_offset_cur1;
unsigned int xfc_reg_transfer_delay;
unsigned int xfc_reg_precharge_delay;
unsigned int xfc_reg_remote_surface_flip_latency;
unsigned int xfc_reg_prefetch_margin;
unsigned int dst_y_delta_drq_limit;
unsigned int refcyc_per_vm_group_vblank;
unsigned int refcyc_per_vm_group_flip;
unsigned int refcyc_per_vm_req_vblank;
unsigned int refcyc_per_vm_req_flip;
unsigned int refcyc_per_vm_dmdata;
unsigned int dmdata_dl_delta;
};
struct _vcs_dpi_display_ttu_regs_st {
unsigned int qos_level_low_wm;
unsigned int qos_level_high_wm;
unsigned int min_ttu_vblank;
unsigned int qos_level_flip;
unsigned int refcyc_per_req_delivery_l;
unsigned int refcyc_per_req_delivery_c;
unsigned int refcyc_per_req_delivery_cur0;
unsigned int refcyc_per_req_delivery_cur1;
unsigned int refcyc_per_req_delivery_pre_l;
unsigned int refcyc_per_req_delivery_pre_c;
unsigned int refcyc_per_req_delivery_pre_cur0;
unsigned int refcyc_per_req_delivery_pre_cur1;
unsigned int qos_level_fixed_l;
unsigned int qos_level_fixed_c;
unsigned int qos_level_fixed_cur0;
unsigned int qos_level_fixed_cur1;
unsigned int qos_ramp_disable_l;
unsigned int qos_ramp_disable_c;
unsigned int qos_ramp_disable_cur0;
unsigned int qos_ramp_disable_cur1;
};
struct _vcs_dpi_display_data_rq_regs_st {
unsigned int chunk_size;
unsigned int min_chunk_size;
unsigned int meta_chunk_size;
unsigned int min_meta_chunk_size;
unsigned int dpte_group_size;
unsigned int mpte_group_size;
unsigned int swath_height;
unsigned int pte_row_height_linear;
};
struct _vcs_dpi_display_rq_regs_st {
display_data_rq_regs_st rq_regs_l;
display_data_rq_regs_st rq_regs_c;
unsigned int drq_expansion_mode;
unsigned int prq_expansion_mode;
unsigned int mrq_expansion_mode;
unsigned int crq_expansion_mode;
unsigned int plane1_base_address;
unsigned int aperture_low_addr; // bits [47:18]
unsigned int aperture_high_addr; // bits [47:18]
};
struct _vcs_dpi_display_dlg_sys_params_st {
double t_mclk_wm_us;
double t_urg_wm_us;
double t_sr_wm_us;
double t_extra_us;
double mem_trip_us;
double deepsleep_dcfclk_mhz;
double total_flip_bw;
unsigned int total_flip_bytes;
};
struct _vcs_dpi_display_arb_params_st {
int max_req_outstanding;
int min_req_outstanding;
int sat_level_us;
int hvm_min_req_outstand_commit_threshold;
int hvm_max_qos_commit_threshold;
int compbuf_reserved_space_kbytes;
};
#endif /*__DISPLAY_MODE_STRUCTS_H__*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,396 @@
/*
* Copyright 2017 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 "display_rq_dlg_helpers.h"
#include "dml_logger.h"
void print__rq_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_params_st *rq_param)
{
dml_print("DML_RQ_DLG_CALC: ***************************\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_sizing_params_st(mode_lib, &rq_param->sizing.rq_l);
dml_print("DML_RQ_DLG_CALC: <CHROMA> ===\n");
print__data_rq_sizing_params_st(mode_lib, &rq_param->sizing.rq_c);
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_dlg_params_st(mode_lib, &rq_param->dlg.rq_l);
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_dlg_params_st(mode_lib, &rq_param->dlg.rq_c);
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_misc_params_st(mode_lib, &rq_param->misc.rq_l);
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_misc_params_st(mode_lib, &rq_param->misc.rq_c);
dml_print("DML_RQ_DLG_CALC: ***************************\n");
}
void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing)
{
(void)mode_lib;
(void)rq_sizing;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing->chunk_bytes);
dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing->min_chunk_bytes);
dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing->meta_chunk_bytes);
dml_print(
"DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n",
rq_sizing->min_meta_chunk_bytes);
dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing->mpte_group_bytes);
dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing->dpte_group_bytes);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param)
{
(void)mode_lib;
(void)rq_dlg_param;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n");
dml_print(
"DML_RQ_DLG_CALC: swath_width_ub = %0d\n",
rq_dlg_param->swath_width_ub);
dml_print(
"DML_RQ_DLG_CALC: swath_height = %0d\n",
rq_dlg_param->swath_height);
dml_print(
"DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n",
rq_dlg_param->req_per_swath_ub);
dml_print(
"DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n",
rq_dlg_param->meta_pte_bytes_per_frame_ub);
dml_print(
"DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n",
rq_dlg_param->dpte_req_per_row_ub);
dml_print(
"DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n",
rq_dlg_param->dpte_groups_per_row_ub);
dml_print(
"DML_RQ_DLG_CALC: dpte_row_height = %0d\n",
rq_dlg_param->dpte_row_height);
dml_print(
"DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n",
rq_dlg_param->dpte_bytes_per_row_ub);
dml_print(
"DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n",
rq_dlg_param->meta_chunks_per_row_ub);
dml_print(
"DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n",
rq_dlg_param->meta_req_per_row_ub);
dml_print(
"DML_RQ_DLG_CALC: meta_row_height = %0d\n",
rq_dlg_param->meta_row_height);
dml_print(
"DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n",
rq_dlg_param->meta_bytes_per_row_ub);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param)
{
(void)mode_lib;
(void)rq_misc_param;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n");
dml_print(
"DML_RQ_DLG_CALC: full_swath_bytes = %0d\n",
rq_misc_param->full_swath_bytes);
dml_print(
"DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n",
rq_misc_param->stored_swath_bytes);
dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param->blk256_width);
dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param->blk256_height);
dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param->req_width);
dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param->req_height);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param)
{
(void)dlg_sys_param;
(void)mode_lib;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param->t_mclk_wm_us);
dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param->t_urg_wm_us);
dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param->t_sr_wm_us);
dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param->t_extra_us);
dml_print(
"DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n",
dlg_sys_param->deepsleep_dcfclk_mhz);
dml_print(
"DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n",
dlg_sys_param->total_flip_bw);
dml_print(
"DML_RQ_DLG_CALC: total_flip_bytes = %i\n",
dlg_sys_param->total_flip_bytes);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_regs_st *rq_regs)
{
(void)mode_lib;
(void)rq_regs;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n");
dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs->chunk_size);
dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs->min_chunk_size);
dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs->meta_chunk_size);
dml_print(
"DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n",
rq_regs->min_meta_chunk_size);
dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs->dpte_group_size);
dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs->mpte_group_size);
dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs->swath_height);
dml_print(
"DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n",
rq_regs->pte_row_height_linear);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_regs_st *rq_regs)
{
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_regs_st(mode_lib, &rq_regs->rq_regs_l);
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_regs_st(mode_lib, &rq_regs->rq_regs_c);
dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs->drq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs->prq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs->mrq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs->crq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs->plane1_base_address);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__dlg_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_regs_st *dlg_regs)
{
(void)dlg_regs;
(void)mode_lib;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n");
dml_print(
"DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n",
dlg_regs->refcyc_h_blank_end);
dml_print(
"DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n",
dlg_regs->dlg_vblank_end);
dml_print(
"DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n",
dlg_regs->min_dst_y_next_start);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n",
dlg_regs->refcyc_per_htotal);
dml_print(
"DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n",
dlg_regs->refcyc_x_after_scaler);
dml_print(
"DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n",
dlg_regs->dst_y_after_scaler);
dml_print(
"DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n",
dlg_regs->dst_y_prefetch);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n",
dlg_regs->dst_y_per_vm_vblank);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n",
dlg_regs->dst_y_per_row_vblank);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n",
dlg_regs->dst_y_per_vm_flip);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n",
dlg_regs->dst_y_per_row_flip);
dml_print(
"DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n",
dlg_regs->ref_freq_to_pix_freq);
dml_print(
"DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n",
dlg_regs->vratio_prefetch);
dml_print(
"DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n",
dlg_regs->vratio_prefetch_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_vblank_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_vblank_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_vblank_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_vblank_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_flip_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_flip_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_flip_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_flip_c);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n",
dlg_regs->dst_y_per_pte_row_nom_l);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n",
dlg_regs->dst_y_per_pte_row_nom_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_nom_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n",
dlg_regs->refcyc_per_pte_group_nom_c);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n",
dlg_regs->dst_y_per_meta_row_nom_l);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n",
dlg_regs->dst_y_per_meta_row_nom_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_nom_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n",
dlg_regs->refcyc_per_meta_chunk_nom_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n",
dlg_regs->refcyc_per_line_delivery_pre_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n",
dlg_regs->refcyc_per_line_delivery_pre_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n",
dlg_regs->refcyc_per_line_delivery_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n",
dlg_regs->refcyc_per_line_delivery_c);
dml_print(
"DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n",
dlg_regs->chunk_hdl_adjust_cur0);
dml_print(
"DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n",
dlg_regs->dst_y_offset_cur1);
dml_print(
"DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n",
dlg_regs->chunk_hdl_adjust_cur1);
dml_print(
"DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n",
dlg_regs->vready_after_vcount0);
dml_print(
"DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n",
dlg_regs->dst_y_delta_drq_limit);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n",
dlg_regs->xfc_reg_transfer_delay);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n",
dlg_regs->xfc_reg_precharge_delay);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n",
dlg_regs->xfc_reg_remote_surface_flip_latency);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_vm_dmdata = 0x%0x\n",
dlg_regs->refcyc_per_vm_dmdata);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__ttu_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_ttu_regs_st *ttu_regs)
{
(void)mode_lib;
(void)ttu_regs;
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n");
dml_print(
"DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n",
ttu_regs->qos_level_low_wm);
dml_print(
"DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n",
ttu_regs->qos_level_high_wm);
dml_print(
"DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n",
ttu_regs->min_ttu_vblank);
dml_print(
"DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n",
ttu_regs->qos_level_flip);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_pre_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_pre_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_cur0);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_pre_cur0);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_cur1);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n",
ttu_regs->refcyc_per_req_delivery_pre_cur1);
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n",
ttu_regs->qos_level_fixed_l);
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n",
ttu_regs->qos_ramp_disable_l);
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n",
ttu_regs->qos_level_fixed_c);
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n",
ttu_regs->qos_ramp_disable_c);
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n",
ttu_regs->qos_level_fixed_cur0);
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n",
ttu_regs->qos_ramp_disable_cur0);
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n",
ttu_regs->qos_level_fixed_cur1);
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n",
ttu_regs->qos_ramp_disable_cur1);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
@@ -0,0 +1,45 @@
/*
* Copyright 2017 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 __DISPLAY_RQ_DLG_HELPERS_H__
#define __DISPLAY_RQ_DLG_HELPERS_H__
#include "display_mode_lib.h"
/* Function: Printer functions
* Print various struct
*/
void print__rq_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_params_st *rq_param);
void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing);
void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param);
void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param);
void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param);
void print__data_rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_regs_st *rq_regs);
void print__rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_regs_st *rq_regs);
void print__dlg_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_regs_st *dlg_regs);
void print__ttu_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_ttu_regs_st *ttu_regs);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
/*
* Copyright 2017 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 __DISPLAY_RQ_DLG_CALC_H__
#define __DISPLAY_RQ_DLG_CALC_H__
struct display_mode_lib;
#include "display_rq_dlg_helpers.h"
void dml1_extract_rq_regs(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
const struct _vcs_dpi_display_rq_params_st *rq_param);
/* Function: dml_rq_dlg_get_rq_params
* Calculate requestor related parameters that register definition agnostic
* (i.e. this layer does try to separate real values from register definition)
* Input:
* pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
* Output:
* rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
*/
void dml1_rq_dlg_get_rq_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_params_st *rq_param,
const struct _vcs_dpi_display_pipe_source_params_st *pipe_src_param);
/* Function: dml_rq_dlg_get_dlg_params
* Calculate deadline related parameters
*/
void dml1_rq_dlg_get_dlg_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param,
const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param,
const struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool iflip_en);
#endif
@@ -0,0 +1,790 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2023 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 "dml_logger.h"
#include "dml1_frl_cap_chk.h"
#include "dml_inline_defs.h"
static const double __maybe_unused EPSILON = 0.01;
static const double __maybe_unused DBL_EPSILON = 2.2204460492503131e-16;
static const double __maybe_unused OVERHEAD_M = 0.003; /* % */
static const double __maybe_unused TOLERANCE_PIXEL_CLOCK = 0.005; /* % */
static const double __maybe_unused DML_TOLERANCE_AUDIO_CLOCK = 1000; /* ppm */
#define frl_dump_var(fmt, var) {}
#define frl_print(fmt, ...) {}
const struct frl_primary_format prim_format_444[] = {
/* VIC/Rate/Lanes/HCactive/HCBlank */
{64, 3, 3, 960, 360}, /* 1920x1080 @ 100 */
{77, 3, 3, 960, 360}, /* 1920x1080 @ 100 */
{63, 3, 3, 960, 140}, /* 1920x1080 @ 120 */
{78, 3, 3, 960, 140}, /* 1920x1080 @ 120 */
{93, 3, 3, 1920, 828}, /* 3840x2160 @ 24 */
{103, 3, 3, 1920, 828}, /* 3840x2160 @ 24 */
{94, 3, 3, 1920, 720}, /* 3840x2160 @ 25 */
{104, 3, 3, 1920, 720}, /* 3840x2160 @ 25 */
{95, 3, 3, 1920, 280}, /* 3840x2160 @ 30 */
{105, 3, 3, 1920, 280}, /* 3840x2160 @ 30 */
{114, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{116, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{96, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{106, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{97, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{107, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{117, 6, 3, 1920, 720}, /* 3840x2160 @ 100 */
{119, 6, 3, 1920, 720}, /* 3840x2160 @ 100 */
{118, 6, 3, 1920, 280}, /* 3840x2160 @ 120 */
{120, 6, 3, 1920, 280}, /* 3840x2160 @ 120 */
{98, 3, 3, 2048, 700}, /* 4096x2160 @ 24 */
{99, 3, 3, 2048, 592}, /* 4096x2160 @ 25 */
{100, 3, 3, 2048, 152}, /* 4096x2160 @ 30 */
{115, 3, 3, 2048, 700}, /* 4096x2160 @ 48 */
{101, 3, 3, 2048, 592}, /* 4096x2160 @ 50 */
{102, 3, 3, 2048, 152}, /* 4096x2160 @ 60 */
{218, 6, 3, 2048, 592}, /* 4096x2160 @ 100 */
{219, 6, 3, 2048, 152}, /* 4096x2160 @ 120 */
{121, 3, 3, 2560, 1188}, /* 5120x2160 @ 24 */
{122, 3, 3, 2560, 1040}, /* 5120x2160 @ 25 */
{123, 3, 3, 2560, 440}, /* 5120x2160 @ 30 */
{124, 3, 3, 2560, 256}, /* 5120x2160 @ 48 */
{125, 3, 3, 2560, 484}, /* 5120x2160 @ 50 */
{126, 3, 3, 2307, 144}, /* 5120x2160 @ 60 */
{127, 6, 3, 2560, 484}, /* 5120x2160 @ 100 */
{193, 6, 3, 2334, 104}, /* 5120x2160 @ 120 */
{194, 6, 3, 3840, 1660}, /* 7680x2160 @ 24 */
{202, 6, 3, 3840, 1660}, /* 7680x2160 @ 24 */
{195, 6, 3, 3840, 1560}, /* 7680x2160 @ 25 */
{203, 6, 3, 3840, 1560}, /* 7680x2160 @ 25 */
{196, 6, 3, 3840, 660}, /* 7680x2160 @ 30 */
{204, 6, 3, 3840, 660}, /* 7680x2160 @ 30 */
{197, 6, 4, 3142, 1292}, /* 7680x2160 @ 48 */
{205, 6, 4, 3142, 1292}, /* 7680x2160 @ 48 */
{198, 6, 4, 3142, 1180}, /* 7680x2160 @ 50 */
{206, 6, 4, 3142, 1180}, /* 7680x2160 @ 50 */
{199, 6, 4, 3182, 140}, /* 7680x2160 @ 60 */
{207, 6, 4, 3182, 140}, /* 7680x2160 @ 60 */
{200, 10, 4, 2680, 784}, /* 7680x2160 @ 100 */
{208, 10, 4, 2680, 784}, /* 7680x2160 @ 100 */
{201, 10, 4, 2600, 100}, /* 7680x2160 @ 120 */
{209, 10, 4, 2600, 100}, /* 7680x2160 @ 120 */
{210, 6, 3, 4854, 912}, /* 10240x4320 @ 24 */
{211, 6, 3, 4827, 1536}, /* 10240x4320 @ 25 */
{212, 6, 3, 4720, 128}, /* 10240x4320 @ 30 */
{213, 8, 4, 4347, 756}, /* 10240x4320 @ 48 */
{214, 8, 4, 4320, 1376}, /* 10240x4320 @ 50 */
{215, 8, 4, 4187, 124}, /* 10240x4320 @ 60 */
};
const struct frl_primary_format prim_format_422[] = {
/* VIC/Rate/Lanes/HCactive/HCBlank */
{64, 3, 3, 960, 360}, /* 1920x1080 @ 100 */
{77, 3, 3, 960, 360}, /* 1920x1080 @ 100 */
{63, 3, 3, 960, 140}, /* 1920x1080 @ 120 */
{78, 3, 3, 960, 140}, /* 1920x1080 @ 120 */
{93, 3, 3, 1920, 828}, /* 3840x2160 @ 24 */
{103, 3, 3, 1920, 828}, /* 3840x2160 @ 24 */
{94, 3, 3, 1920, 720}, /* 3840x2160 @ 25 */
{104, 3, 3, 1920, 720}, /* 3840x2160 @ 25 */
{95, 3, 3, 1920, 280}, /* 3840x2160 @ 30 */
{105, 3, 3, 1920, 280}, /* 3840x2160 @ 30 */
{114, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{116, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{96, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{106, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{97, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{107, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{117, 3, 3, 1370, 104}, /* 3840x2160 @ 100 */
{119, 3, 3, 1370, 104}, /* 3840x2160 @ 100 */
{118, 3, 3, 1130, 104}, /* 3840x2160 @ 120 */
{120, 3, 3, 1130, 104}, /* 3840x2160 @ 120 */
{98, 3, 3, 2048, 700}, /* 4096x2160 @ 24 */
{99, 3, 3, 2048, 592}, /* 4096x2160 @ 25 */
{100, 3, 3, 2048, 152}, /* 4096x2160 @ 30 */
{115, 3, 3, 2048, 700}, /* 4096x2160 @ 48 */
{101, 3, 3, 2048, 592}, /* 4096x2160 @ 50 */
{102, 3, 3, 2048, 152}, /* 4096x2160 @ 60 */
{218, 6, 3, 2048, 592}, /* 4096x2160 @ 100 */
{219, 6, 3, 2048, 152}, /* 4096x2160 @ 120 */
{121, 3, 3, 2560, 1188}, /* 5120x2160 @ 24 */
{122, 3, 3, 2560, 1040}, /* 5120x2160 @ 25 */
{123, 3, 3, 2560, 440}, /* 5120x2160 @ 30 */
{124, 3, 3, 2560, 256}, /* 5120x2160 @ 48 */
{125, 3, 3, 2560, 484}, /* 5120x2160 @ 50 */
{126, 3, 3, 2307, 144}, /* 5120x2160 @ 60 */
{127, 6, 3, 2560, 484}, /* 5120x2160 @ 100 */
{193, 6, 3, 2334, 104}, /* 5120x2160 @ 120 */
{194, 3, 3, 2460, 816}, /* 7680x2160 @ 24 */
{202, 3, 3, 2460, 816}, /* 7680x2160 @ 24 */
{195, 3, 3, 2460, 732}, /* 7680x2160 @ 25 */
{203, 3, 3, 2460, 732}, /* 7680x2160 @ 25 */
{196, 3, 3, 2360, 144}, /* 7680x2160 @ 30 */
{204, 3, 3, 2360, 144}, /* 7680x2160 @ 30 */
{197, 6, 3, 2460, 816}, /* 7680x2160 @ 48 */
{205, 6, 3, 2460, 816}, /* 7680x2160 @ 48 */
{198, 6, 3, 2460, 732}, /* 7680x2160 @ 50 */
{206, 6, 3, 2460, 732}, /* 7680x2160 @ 50 */
{199, 6, 3, 2380, 116}, /* 7680x2160 @ 60 */
{207, 6, 3, 2380, 116}, /* 7680x2160 @ 60 */
{200, 10, 4, 2680, 784}, /* 7680x2160 @ 100 */
{208, 10, 4, 2680, 784}, /* 7680x2160 @ 100 */
{201, 10, 4, 2600, 100}, /* 7680x2160 @ 120 */
{209, 10, 4, 2600, 100}, /* 7680x2160 @ 120 */
{210, 6, 3, 4854, 912}, /* 10240x4320 @ 24 */
{211, 6, 3, 4827, 1536}, /* 10240x4320 @ 25 */
{212, 6, 3, 4720, 128}, /* 10240x4320 @ 30 */
{213, 6, 4, 3360, 420}, /* 10240x4320 @ 48 */
{214, 6, 4, 3334, 892}, /* 10240x4320 @ 50 */
{215, 6, 4, 3120, 124}, /* 10240x4320 @ 60 */
{216, 12, 4, 3334, 764}, /* 10240x4320 @ 100 */
{217, 12, 4, 3120, 124}, /* 10240x4320 @ 120 */
};
const struct frl_primary_format prim_format_420[] = {
/* VIC/Rate/Lanes/HCactive/HCBlank */
{114, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{116, 3, 3, 1920, 828}, /* 3840x2160 @ 48 */
{96, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{106, 3, 3, 1920, 720}, /* 3840x2160 @ 50 */
{97, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{107, 3, 3, 1920, 280}, /* 3840x2160 @ 60 */
{117, 3, 3, 1370, 104}, /* 3840x2160 @ 100 */
{119, 3, 3, 1370, 104}, /* 3840x2160 @ 100 */
{118, 3, 3, 1130, 104}, /* 3840x2160 @ 120 */
{120, 3, 3, 1130, 104}, /* 3840x2160 @ 120 */
{115, 3, 3, 2048, 700}, /* 4096x2160 @ 48 */
{101, 3, 3, 2048, 592}, /* 4096x2160 @ 50 */
{102, 3, 3, 2048, 152}, /* 4096x2160 @ 60 */
{218, 3, 3, 1376, 96}, /* 4096x2160 @ 100 */
{219, 3, 3, 1131, 84}, /* 4096x2160 @ 120 */
{124, 3, 3, 2560, 256}, /* 5120x2160 @ 48 */
{125, 3, 3, 2560, 484}, /* 5120x2160 @ 50 */
{126, 3, 3, 2307, 144}, /* 5120x2160 @ 60 */
{127, 6, 3, 2560, 484}, /* 5120x2160 @ 100 */
{193, 6, 3, 2334, 104}, /* 5120x2160 @ 120 */
{194, 3, 3, 2460, 816}, /* 7680x2160 @ 24 */
{202, 3, 3, 2460, 816}, /* 7680x2160 @ 24 */
{195, 3, 3, 2460, 732}, /* 7680x2160 @ 25 */
{203, 3, 3, 2460, 732}, /* 7680x2160 @ 25 */
{196, 3, 3, 2360, 144}, /* 7680x2160 @ 30 */
{204, 3, 3, 2360, 144}, /* 7680x2160 @ 30 */
{197, 6, 3, 2460, 816}, /* 7680x2160 @ 48 */
{205, 6, 3, 2460, 816}, /* 7680x2160 @ 48 */
{198, 6, 3, 2460, 732}, /* 7680x2160 @ 50 */
{206, 6, 3, 2460, 732}, /* 7680x2160 @ 50 */
{199, 6, 3, 2380, 116}, /* 7680x2160 @ 60 */
{207, 6, 3, 2380, 116}, /* 7680x2160 @ 60 */
{200, 8, 4, 2240, 480}, /* 7680x2160 @ 100 */
{208, 8, 4, 2240, 480}, /* 7680x2160 @ 100 */
{201, 8, 4, 2062, 108}, /* 7680x2160 @ 120 */
{209, 8, 4, 2062, 108}, /* 7680x2160 @ 120 */
{210, 3, 3, 2614, 172}, /* 10240x4320 @ 24 */
{211, 3, 3, 2614, 500}, /* 10240x4320 @ 25 */
{212, 6, 3, 4720, 128}, /* 10240x4320 @ 30 */
{213, 6, 3, 2614, 172}, /* 10240x4320 @ 48 */
{214, 6, 4, 3334, 892}, /* 10240x4320 @ 50 */
{215, 6, 4, 3120, 124}, /* 10240x4320 @ 60 */
{216, 10, 4, 2854, 520}, /* 10240x4320 @ 100 */
{217, 10, 4, 2587, 120}, /* 10240x4320 @ 120 */
};
enum frl_cap_chk_result dml1_frl_cap_chk_common(struct frl_cap_chk_intermediates *inter,
struct frl_cap_chk_params *params)
{
double audio_bw_reserve = (params->compressed ? 192000.0 : 0.0);
dc_assert_fp_enabled();
#ifdef DEBUG_FRL_CAP_CHK
{
printf("frl_cap_chk inputs:\n");
printf("-------------------\n");
frl_dump_var("%i", params->lanes);
frl_dump_var("%le", params->f_pixel_clock_nominal);
frl_dump_var("%le", params->r_bit_nominal);
frl_dump_var("%i", params->audio_packet_type);
frl_dump_var("%le", params->f_audio);
frl_dump_var("%i", params->h_active);
frl_dump_var("%i", params->h_blank);
frl_dump_var("%i", params->bpc);
frl_dump_var("%i", params->pixel_encoding);
frl_dump_var("%i", params->compressed);
frl_dump_var("%i", params->slices);
frl_dump_var("%i", params->slice_width);
frl_dump_var("%le", params->bpp_target);
frl_dump_var("%i", params->layout);
frl_dump_var("%i", params->acat);
printf("frl_cap_chk outputs:\n");
printf("---------------------\n");
}
#endif
inter->c_frl_sb = 4 * C_FRL_CB + params->lanes;
inter->overhead_sb = (double)params->lanes / inter->c_frl_sb;
inter->overhead_rs = 8.0 * 4.0 / inter->c_frl_sb;
inter->overhead_map = 2.5 / inter->c_frl_sb;
inter->overhead_min = inter->overhead_sb + inter->overhead_rs + inter->overhead_map;
inter->overhead_max = inter->overhead_min + OVERHEAD_M;
inter->f_pixel_clock_max = params->f_pixel_clock_nominal * (1.0 + TOLERANCE_PIXEL_CLOCK);
inter->t_line = (params->h_active + params->h_blank) / inter->f_pixel_clock_max;
inter->r_bit_min = params->r_bit_nominal * (1.0 - TOLERANCE_FRL_BIT / 1000000.0);
inter->r_frl_char_min = inter->r_bit_min / 18.0;
inter->c_frl_line = dml_floor(inter->t_line * inter->r_frl_char_min * params->lanes, 1);
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%i", inter->c_frl_sb);
frl_dump_var("%le", inter->overhead_sb);
frl_dump_var("%le", inter->overhead_rs);
frl_dump_var("%le", inter->overhead_map);
frl_dump_var("%le", inter->overhead_min);
frl_dump_var("%le", inter->overhead_max);
frl_dump_var("%le", inter->f_pixel_clock_max);
frl_dump_var("%le", inter->t_line);
frl_dump_var("%le", inter->r_bit_min);
frl_dump_var("%le", inter->r_frl_char_min);
frl_dump_var("%le", inter->c_frl_line);
}
#endif
switch (params->audio_packet_type) {
case 0x02:
if (params->layout == 0)
inter->ap = 0.25;
else if (params->layout == 1)
inter->ap = 1.0;
break;
case 0x08:
inter->ap = 0.25;
break;
case 0x09:
inter->ap = 1.0;
break;
case 0x07:
case 0x0e:
case 0x0f:
case 0x0b:
case 0x0c:
/* Unsupported audio format */
return FRL_CAP_CHK_ERROR_UNSUPPORTED_AUDIO;
default:
inter->ap = 0.0;
}
inter->r_ap = (dml_max(audio_bw_reserve, params->f_audio * inter->ap) + 2 * ACR_RATE_MAX) * (1 + DML_TOLERANCE_AUDIO_CLOCK / 1000000.0);
inter->avg_audio_packets_line = inter->r_ap * inter->t_line;
inter->audio_packets_line = (int)dml_ceil(inter->avg_audio_packets_line, 1);
inter->blank_audio_min = 32 + 32 * inter->audio_packets_line; // h_blank_audio_min or hc_blank_audio_min
params->borrow_params.audio_packets_line = inter->audio_packets_line;
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%le", inter->ap);
frl_dump_var("%le", inter->r_ap);
frl_dump_var("%le", inter->avg_audio_packets_line);
frl_dump_var("%i", inter->audio_packets_line);
frl_dump_var("%i", inter->blank_audio_min);
}
#endif
return FRL_CAP_CHK_OK;
}
enum frl_cap_chk_result dml1_frl_cap_chk_uncompressed(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter)
{
enum frl_cap_chk_result res;
int k_420;
double k_cd;
int c_frl_free;
int c_frl_rc_margin;
int c_frl_rc_savings;
int bpp;
double bytes_line;
int tb_active;
int tb_blank;
double f_tb_average;
double t_active_ref;
double t_blank_ref;
double t_active_min;
double t_blank_min;
double t_borrowed;
double tb_borrowed;
int c_frl_actual_payload;
double utilization;
double margin;
dc_assert_fp_enabled();
res = dml1_frl_cap_chk_common(inter, params);
if (res != FRL_CAP_CHK_OK)
return res;
k_420 = params->pixel_encoding == HDMI_FRL_PIXEL_ENCODING_420 ? 2 : 1;
k_cd = params->pixel_encoding == HDMI_FRL_PIXEL_ENCODING_422 ? 1.0 : params->bpc / 8.0;
c_frl_free = (int)dml_max(params->h_blank * k_cd / k_420 - 32 * (1 + inter->audio_packets_line) - 7, 0);
c_frl_rc_margin = 4;
c_frl_rc_savings = (int)dml_floor(dml_max(((7.0 / 8.0) * c_frl_free) - c_frl_rc_margin, 0.0), 1);
bpp = (int)(24 * k_cd / k_420);
bytes_line = bpp * params->h_active / 8.0;
tb_active = (int)dml_ceil(bytes_line / 3, 1);
tb_blank = (int)dml_ceil(params->h_blank * k_cd / k_420, 1);
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%i", k_420);
frl_dump_var("%le", k_cd);
frl_dump_var("%i", c_frl_free);
frl_dump_var("%i", c_frl_rc_margin);
frl_dump_var("%i", c_frl_rc_savings);
frl_dump_var("%i", bpp);
frl_dump_var("%le", bytes_line);
frl_dump_var("%i", tb_active);
frl_dump_var("%i", tb_blank);
}
#endif
if (!(inter->blank_audio_min <= tb_blank)) {
frl_dump_var("%i", inter->blank_audio_min);
frl_dump_var("%i", tb_blank);
return FRL_CAP_CHK_ERROR_AUDIO_BW;
}
f_tb_average = (inter->f_pixel_clock_max / (params->h_active + params->h_blank)) * (tb_active + tb_blank);
t_active_ref = inter->t_line * ((double)params->h_active / (params->h_active + params->h_blank));
t_blank_ref = inter->t_line * ((double)params->h_blank / (params->h_active + params->h_blank));
t_active_min = (3.0 / 2.0) * tb_active / (params->lanes * inter->r_frl_char_min * (1.0 - inter->overhead_max));
t_blank_min = tb_blank / (params->lanes * inter->r_frl_char_min * (1.0 - inter->overhead_max));
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%le", f_tb_average);
frl_dump_var("%le", t_active_ref);
frl_dump_var("%le", t_blank_ref);
frl_dump_var("%le", t_active_min);
frl_dump_var("%le", t_blank_min);
}
#endif
if (t_active_ref >= t_active_min && t_blank_ref >= t_blank_min) {
t_borrowed = 0;
params->borrow_params.borrow_mode = FRL_BORROW_MODE_NONE;
} else if ((t_active_ref < t_active_min) && (t_blank_ref >= t_blank_min)) {
t_borrowed = t_active_min - t_active_ref;
params->borrow_params.borrow_mode = FRL_BORROW_MODE_FROM_BLANK;
} else {
return FRL_CAP_CHK_ERROR_BORROW;
}
tb_borrowed = dml_ceil(t_borrowed * f_tb_average, 1);
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%le", tb_borrowed);
frl_dump_var("%i", params->borrow_params.borrow_mode);
}
#endif
if (!(tb_borrowed <= TB_BORROWED_MAX))
return FRL_CAP_CHK_ERROR_MAX_BORROW;
c_frl_actual_payload = (int)(dml_ceil((3.0 / 2.0) * tb_active, 1) + tb_blank - c_frl_rc_savings);
utilization = c_frl_actual_payload / inter->c_frl_line;
margin = 1.0 - (utilization + inter->overhead_max);
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%i", c_frl_actual_payload);
frl_dump_var("%le", utilization);
frl_dump_var("%le", margin);
}
#endif
if (margin < 0 && dcn_bw_fabs(margin) > EPSILON)
return FRL_CAP_CHK_ERROR_MARGIN;
return FRL_CAP_CHK_OK;
}
#if defined (CONFIG_DRM_AMD_DC_FP)
enum frl_cap_chk_result dml1_frl_cap_chk_compressed(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter)
{
enum frl_cap_chk_result res;
int c_frl_available;
#if defined(DEBUG_FRL_CAP_CHK)
int c_frl_active_available;
int c_frl_blank_available;
#endif
int bytes_target = 0;
int hc_active_target;
int hc_blank_target_est1;
int hc_blank_target_est2;
int hc_blank_target = 0;
int c_frl_actual_target_payload;
double utilization_targeted;
double margin_target;
double f_tb_average;
double t_active_ref;
double t_blank_ref;
double t_active_target;
double t_blank_target;
double tb_borrowed;
#ifdef DEBUG_FRL_CAP_CHK
double tb_delta;
double tb_delta_limit;
int tb_worst;
#endif
int table_size_444 = ARRAY_SIZE(prim_format_444);
int table_size_422 = ARRAY_SIZE(prim_format_422);
int table_size_420 = ARRAY_SIZE(prim_format_420);
int i;
bool hc_active_blank_predefined = false;
dc_assert_fp_enabled();
res = dml1_frl_cap_chk_common(inter, params);
if (res != FRL_CAP_CHK_OK)
return res;
c_frl_available = (int)dml_floor((1 - inter->overhead_max) * inter->c_frl_line, 1);
#if defined(DEBUG_FRL_CAP_CHK)
c_frl_active_available = dml_floor(c_frl_available * ((double)params->h_active / (params->h_active + params->h_blank)), 1);
c_frl_blank_available = dml_floor(c_frl_available * ((double)params->h_blank / (params->h_active + params->h_blank)), 1);
#endif
bytes_target = (int)(params->slices * dml_ceil(params->bpp_target * params->slice_width / 8.0, 1));
if (!params->bypass_hc_target_calc)
hc_active_target = (int)dml_ceil(bytes_target / 3.0, 1);
else
hc_active_target = params->borrow_params.hc_active_target;
if (!params->allow_all_bpp && params->vic != 0) {
if (params->pixel_encoding == HDMI_FRL_PIXEL_ENCODING_444) {
for (i = 0; i < table_size_444 ; i++) {
if (prim_format_444[i].vic == params->vic) {
params->borrow_params.hc_active_target = prim_format_444[i].hc_active;
params->borrow_params.hc_blank_target = prim_format_444[i].hc_blank;
hc_active_blank_predefined = true;
break;
}
}
} else if (params->pixel_encoding == HDMI_FRL_PIXEL_ENCODING_422) {
for (i = 0; i < table_size_422 ; i++) {
if (prim_format_422[i].vic == params->vic) {
params->borrow_params.hc_active_target = prim_format_422[i].hc_active;
params->borrow_params.hc_blank_target = prim_format_422[i].hc_blank;
hc_active_blank_predefined = true;
break;
}
}
} else if (params->pixel_encoding == HDMI_FRL_PIXEL_ENCODING_420) {
for (i = 0; i < table_size_420 ; i++) {
if (prim_format_420[i].vic == params->vic) {
params->borrow_params.hc_active_target = prim_format_420[i].hc_active;
params->borrow_params.hc_blank_target = prim_format_420[i].hc_blank;
hc_active_blank_predefined = true;
break;
}
}
}
if (hc_active_blank_predefined) {
hc_active_target = params->borrow_params.hc_active_target;
hc_blank_target = params->borrow_params.hc_blank_target;
}
}
hc_blank_target_est1 = (int)dml_ceil(hc_active_target * ((double)params->h_blank / params->h_active), 1);
hc_blank_target_est2 = (int)dml_max(hc_blank_target_est1, inter->blank_audio_min);
if (!hc_active_blank_predefined) {
if (!params->bypass_hc_target_calc) {
hc_blank_target = (int)(4 * dml_floor(dml_min(hc_blank_target_est2, c_frl_available - 3.0 / 2.0 * hc_active_target) / 4.0, 1));
params->borrow_params.hc_active_target = hc_active_target;
params->borrow_params.hc_blank_target = hc_blank_target;
} else {
hc_blank_target = params->borrow_params.hc_blank_target;
}
}
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%i", c_frl_available);
frl_dump_var("%i", c_frl_active_available);
frl_dump_var("%i", c_frl_blank_available);
frl_dump_var("%i", bytes_target);
frl_dump_var("%i", hc_active_target);
frl_dump_var("%i", hc_blank_target_est1);
frl_dump_var("%i", hc_blank_target_est2);
frl_dump_var("%i", hc_blank_target);
}
#endif
if (!(inter->blank_audio_min <= hc_blank_target)) {
frl_dump_var("%i", inter->blank_audio_min);
frl_dump_var("%i", hc_blank_target);
return FRL_CAP_CHK_ERROR_AUDIO_BW;
}
f_tb_average = inter->f_pixel_clock_max / (params->h_active + params->h_blank) * (hc_active_target + hc_blank_target);
t_active_ref = inter->t_line * ((double)params->h_active / (params->h_active + params->h_blank));
t_blank_ref = inter->t_line - t_active_ref; // * ((double) params->h_blank / (params->h_active + params->h_blank));
t_active_target = dml_max((hc_active_target / f_tb_average),
(3.0 / 2.0 * hc_active_target) /
(params->lanes * inter->r_frl_char_min * (1.0 - inter->overhead_max)));
t_blank_target = inter->t_line - t_active_target;
tb_borrowed = t_active_target * f_tb_average - hc_active_target;
#ifdef DEBUG_FRL_CAP_CHK
tb_delta = dcn_bw_fabs(t_active_target - t_active_ref) * (hc_active_target + hc_blank_target_est1) / inter->t_line;
{
frl_dump_var("%le", f_tb_average);
frl_dump_var("%le", t_active_ref);
frl_dump_var("%le", t_blank_ref);
frl_dump_var("%le", t_active_target);
frl_dump_var("%le", t_blank_target);
frl_dump_var("%le", tb_delta);
}
#endif
if (t_blank_target - t_blank_ref > DBL_EPSILON) {
#ifdef DEBUG_FRL_CAP_CHK
tb_delta_limit = (t_active_ref - hc_active_target / f_tb_average) * (hc_active_target + hc_blank_target_est1) / inter->t_line;
#endif
params->borrow_params.borrow_mode = FRL_BORROW_MODE_FROM_ACTIVE;
} else if (t_active_target - t_active_ref > DBL_EPSILON) {
#ifdef DEBUG_FRL_CAP_CHK
tb_delta_limit = tb_delta;
#endif
params->borrow_params.borrow_mode = FRL_BORROW_MODE_FROM_BLANK;
} else {
#ifdef DEBUG_FRL_CAP_CHK
tb_delta_limit = 0;
#endif
params->borrow_params.borrow_mode = FRL_BORROW_MODE_NONE;
}
#ifdef DEBUG_FRL_CAP_CHK
tb_worst = dml_ceil(dml_max(tb_borrowed, tb_delta_limit), 1);
{
frl_dump_var("%le", tb_delta_limit);
frl_dump_var("%le", tb_borrowed);
frl_dump_var("%i", params->borrow_params.borrow_mode);
frl_dump_var("%i", tb_worst);
}
#endif
if (!(tb_borrowed <= TB_BORROWED_MAX))
return FRL_CAP_CHK_ERROR_MAX_BORROW;
c_frl_actual_target_payload = (int)(dml_ceil(3.0 / 2.0 * hc_active_target, 1) + hc_blank_target);
utilization_targeted = c_frl_actual_target_payload / inter->c_frl_line;
margin_target = 1.0 - (utilization_targeted + inter->overhead_max);
#ifdef DEBUG_FRL_CAP_CHK
{
frl_dump_var("%i", c_frl_actual_target_payload);
frl_dump_var("%le", utilization_targeted);
frl_dump_var("%le", margin_target);
}
#endif
// oversubscribed bandwidth relative to margin
if (margin_target < 0 && dcn_bw_fabs(margin_target) > EPSILON)
return FRL_CAP_CHK_ERROR_MARGIN;
return FRL_CAP_CHK_OK;
}
#endif
enum frl_cap_chk_result dml1_frl_cap_chk(struct frl_cap_chk_params *params)
{
struct frl_cap_chk_intermediates inter;
#if defined (CONFIG_DRM_AMD_DC_FP)
if (params->compressed)
return dml1_frl_cap_chk_compressed(params, &inter);
#endif
return dml1_frl_cap_chk_inter(params, &inter);
}
enum frl_cap_chk_result dml1_frl_cap_chk_inter(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter)
{
return dml1_frl_cap_chk_uncompressed(params, inter);
}
static double calculate_compressed_active_time(uint32_t h_active,
const uint32_t h_blank,
const int hc_active,
const int hc_blank,
const uint32_t frl_num_lanes,
const double pix_clk,
const int frl_link_rate)
{
double f_tb_average;
double r_bit_nominal;
double r_bit_min;
double r_frl_char_min;
double t_active_est_1;
double t_active_est_2;
double t_active_target;
int c_frl_sb = 510;
int frl_bit_tolerance = 300;
double overhead_m = 0.003;
double overhead_sb;
double overhead_rs;
double overhead_map;
double overhead_min;
double overhead_max;
switch (frl_link_rate) {
case FRL_LINK_RATE_3GBPS:
r_bit_nominal = 3.0e9;
break;
case FRL_LINK_RATE_6GBPS:
case FRL_LINK_RATE_6GBPS_4LANE:
r_bit_nominal = 6.0e9;
break;
case FRL_LINK_RATE_8GBPS:
r_bit_nominal = 8.0e9;
break;
case FRL_LINK_RATE_10GBPS:
default:
r_bit_nominal = 10.0e9;
break;
case FRL_LINK_RATE_12GBPS:
r_bit_nominal = 12.0e9;
break;
}
f_tb_average = pix_clk / (h_active + h_blank)
* (hc_active + hc_blank);
c_frl_sb = 4 * c_frl_sb + frl_num_lanes;
overhead_sb = (double)frl_num_lanes / c_frl_sb;
overhead_rs = 8.0 * 4.0 / c_frl_sb;
overhead_map = 2.5 / c_frl_sb;
overhead_min = overhead_sb + overhead_rs + overhead_map;
overhead_max = overhead_min + overhead_m;
r_bit_min = r_bit_nominal * (1.0 - frl_bit_tolerance / 1000000.0);
r_frl_char_min = r_bit_min / 18.0;
t_active_est_1 = hc_active / f_tb_average;
t_active_est_2 = (3.0 / 2.0 * hc_active) /
(frl_num_lanes * r_frl_char_min * (1.0 - overhead_max));
if (t_active_est_1 > t_active_est_2) {
t_active_target = t_active_est_1;
} else {
t_active_target = t_active_est_2;
}
return t_active_target;
}
void frl_modified_pix_clock_for_dsc_padding(const int hc_active_target,
const int hc_blank_target,
const uint8_t frl_num_lanes,
const uint32_t pix_clk_100hz,
const int frl_link_rate,
const uint32_t h_addressable,
const uint32_t h_border_left,
const uint32_t h_border_right,
const uint32_t h_total,
const uint32_t h_addressable_otg,
uint32_t *pix_clk_100hz_otg,
uint32_t *h_total_otg)
{
double pix_clk;
int h_active;
int h_blank;
double t_active_target;
double hw_pix_clk;
double h_total_otg_temp;
pix_clk = (double)pix_clk_100hz * 100;
h_active = h_addressable + h_border_left + h_border_right;
h_blank = h_total - h_active;
t_active_target = calculate_compressed_active_time(h_active, h_blank, hc_active_target, hc_blank_target, frl_num_lanes, pix_clk, frl_link_rate);
h_total_otg_temp = ((double)h_addressable_otg * (double)h_total) / ((double)pix_clk_100hz * 100.0 * t_active_target);
/* Htotal must be a multiple of 4, also take the ceiling */
*h_total_otg = (uint32_t)dml_ceil(h_total_otg_temp, 4.0);
hw_pix_clk = (double)(pix_clk_100hz * 100.0 * (double)*h_total_otg) / (double)h_total;
*pix_clk_100hz_otg = (uint32_t)(hw_pix_clk / 100.0);
}
int frl_modify_borrow_mode_for_dsc_padding(const uint32_t pix_clk_100hz,
const uint32_t h_active,
const uint32_t h_active_padded,
const uint32_t h_blank,
const uint32_t h_blank_padded,
const int hc_active,
const int hc_blank,
const uint8_t frl_num_lanes,
const int frl_link_rate)
{
double f_pixel_clock_max;
double t_line;
double t_active;
double t_blank;
double t_active_target;
double t_blank_target;
double pix_clk_tolerance = 0.005;
enum frl_borrow_mode borrow_mode;
f_pixel_clock_max = (double)pix_clk_100hz * (1.0 + pix_clk_tolerance);
t_line = (double)(h_active + h_blank) / f_pixel_clock_max;
t_active_target = calculate_compressed_active_time(h_active, h_blank, hc_active, hc_blank, frl_num_lanes, f_pixel_clock_max, frl_link_rate);
t_active = t_line * ((double)h_active_padded / (h_active_padded + h_blank_padded));
t_blank = t_line - t_active;
t_blank_target = t_line - t_active_target;
if (t_blank_target - t_blank > DBL_EPSILON) {
borrow_mode = FRL_BORROW_MODE_FROM_ACTIVE;
} else if (t_active_target - t_active > DBL_EPSILON) {
borrow_mode = FRL_BORROW_MODE_FROM_BLANK;
} else {
borrow_mode = FRL_BORROW_MODE_NONE;
}
return borrow_mode;
}
@@ -0,0 +1,173 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2022 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 __DML1_FRL_CAP_CHK_H__
#define __DML1_FRL_CAP_CHK_H__
#include "os_types.h"
#define TB_BORROWED_MAX 400
#define C_FRL_CB 510
#define TOLERANCE_FRL_BIT 300 /* ppm */
#define ACR_RATE_MAX 1500
enum hdmi_frl_pixel_encoding {
HDMI_FRL_PIXEL_ENCODING_444,
HDMI_FRL_PIXEL_ENCODING_422,
HDMI_FRL_PIXEL_ENCODING_420
};
enum frl_cap_chk_result {
FRL_CAP_CHK_OK = 0,
FRL_CAP_CHK_ERROR_AUDIO_BW = -1,
FRL_CAP_CHK_ERROR_BORROW = -2,
FRL_CAP_CHK_ERROR_MAX_BORROW = -3,
FRL_CAP_CHK_ERROR_MARGIN = -4,
FRL_CAP_CHK_ERROR_UNSUPPORTED_AUDIO = -1000
};
enum frl_borrow_mode {
FRL_BORROW_MODE_NONE,
FRL_BORROW_MODE_FROM_ACTIVE,
FRL_BORROW_MODE_FROM_BLANK
};
enum frl_link_rate {
FRL_LINK_RATE_DISABLE = 0,
FRL_LINK_RATE_3GBPS,
FRL_LINK_RATE_6GBPS,
FRL_LINK_RATE_6GBPS_4LANE,
FRL_LINK_RATE_8GBPS,
FRL_LINK_RATE_10GBPS,
FRL_LINK_RATE_12GBPS,
FRL_LINK_RATE_16GBPS,
FRL_LINK_RATE_20GBPS,
FRL_LINK_RATE_24GBPS
};
struct frl_dml_borrow_params {
int audio_packets_line;
int hc_active_target;
int hc_blank_target;
enum frl_borrow_mode borrow_mode;
};
struct frl_primary_format {
uint32_t vic;
uint32_t frl_rate;
uint32_t frl_lanes;
uint32_t hc_active;
uint32_t hc_blank;
};
struct frl_cap_chk_intermediates {
int c_frl_sb;
double overhead_sb;
double overhead_rs;
double overhead_map;
double overhead_min;
double overhead_max;
double f_pixel_clock_max;
double t_line;
double r_bit_min;
double r_frl_char_min;
double c_frl_line;
double ap;
double r_ap;
double avg_audio_packets_line;
int audio_packets_line;
int blank_audio_min;
};
struct frl_cap_chk_params {
int lanes;
double f_pixel_clock_nominal; /* Pixel Clock rate (Hz) */
double r_bit_nominal; /* FRL bitrate (bps) */
int audio_packet_type;
double f_audio; /* Audio rate (Hz) */
int h_active; /* Active pixels per line */
int h_blank; /* Blanking pixels per line */
int bpc; /* Bits per component */
int vic; /* Video Identification Code */
enum hdmi_frl_pixel_encoding pixel_encoding;
bool compressed; /* set to true if DSC is enabled */
bool bypass_hc_target_calc; /* debug only */
bool allow_all_bpp; /* dsc_all_bpp */
/* DSC parameters */
int slices;
int slice_width;
double bpp_target;
bool is_ovt;
int layout;
int acat; /* not supported */
/* outputs */
struct frl_dml_borrow_params borrow_params;
int average_tribyte_rate;
};
enum frl_cap_chk_result dml1_frl_cap_chk(struct frl_cap_chk_params *params);
enum frl_cap_chk_result dml1_frl_cap_chk_inter(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter);
enum frl_cap_chk_result dml1_frl_cap_chk_common(struct frl_cap_chk_intermediates *inter,
struct frl_cap_chk_params *params);
enum frl_cap_chk_result dml1_frl_cap_chk_uncompressed(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter);
enum frl_cap_chk_result dml1_frl_cap_chk_compressed(struct frl_cap_chk_params *params,
struct frl_cap_chk_intermediates *inter);
#endif
void frl_modified_pix_clock_for_dsc_padding(const int hc_active_target,
const int hc_blank_target,
const uint8_t frl_num_lanes,
const uint32_t pix_clk_100hz,
const int frl_link_rate,
const uint32_t h_addressable,
const uint32_t h_border_left,
const uint32_t h_border_right,
const uint32_t h_total,
const uint32_t h_addressable_otg,
uint32_t *pix_clk_100hz_otg,
uint32_t *h_total_otg);
int frl_modify_borrow_mode_for_dsc_padding(const uint32_t pix_clk_100hz,
const uint32_t h_active,
const uint32_t h_active_padded,
const uint32_t h_blank,
const uint32_t h_blank_padded,
const int hc_active,
const int hc_blank,
const uint8_t frl_num_lanes,
const int frl_link_rate);
@@ -0,0 +1,160 @@
/*
* Copyright 2017 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 __DML_INLINE_DEFS_H__
#define __DML_INLINE_DEFS_H__
#include "dcn_calc_math.h"
#include "dml_logger.h"
static inline double dml_min(double a, double b)
{
return (double)dcn_bw_min2((float)a, (float)b);
}
static inline double dml_min3(double a, double b, double c)
{
return dml_min(dml_min(a, b), c);
}
static inline double dml_min4(double a, double b, double c, double d)
{
return dml_min(dml_min(a, b), dml_min(c, d));
}
static inline double dml_max(double a, double b)
{
return (double)dcn_bw_max2((float)a, (float)b);
}
static inline double dml_max3(double a, double b, double c)
{
return dml_max(dml_max(a, b), c);
}
static inline double dml_max4(double a, double b, double c, double d)
{
return dml_max(dml_max(a, b), dml_max(c, d));
}
static inline double dml_max5(double a, double b, double c, double d, double e)
{
return dml_max(dml_max4(a, b, c, d), e);
}
static inline double dml_ceil(double a, double granularity)
{
if (granularity == 0)
return 0;
return (double)dcn_bw_ceil2((float)a, (float)granularity);
}
static inline double dml_floor(double a, double granularity)
{
if (granularity == 0)
return 0;
return (double)dcn_bw_floor2((float)a, (float)granularity);
}
static inline double dml_round(double a)
{
const double round_pt = 0.5;
return dml_floor(a + round_pt, 1);
}
/* float
static inline int dml_log2(float x)
{
unsigned int ix = *((unsigned int *)&x);
return (int)((ix >> 23) & 0xff) - 127;
}*/
/* double */
static inline int dml_log2(double x)
{
unsigned long long ix = *((unsigned long long *)&x);
return (int)((ix >> 52) & 0x7ff) - 1023;
}
static inline double dml_pow(double a, int exp)
{
return (double)dcn_bw_pow((float)a, (float)exp);
}
static inline double dml_fmod(double f, int val)
{
return (double)dcn_bw_mod((float)f, (float)val);
}
static inline double dml_ceil_2(double f)
{
return (double)dcn_bw_ceil2((float)f, 2.0f);
}
static inline double dml_ceil_ex(double x, double granularity)
{
if (granularity == 0)
return 0;
return (double)dcn_bw_ceil2((float)x, (float)granularity);
}
static inline double dml_floor_ex(double x, double granularity)
{
if (granularity == 0)
return 0;
return (double)dcn_bw_floor2((float)x, (float)granularity);
}
static inline unsigned int dml_round_to_multiple(unsigned int num,
unsigned int multiple,
unsigned char up)
{
unsigned int remainder;
if (multiple == 0)
return num;
remainder = num % multiple;
if (remainder == 0)
return num;
if (up)
return (num + multiple - remainder);
else
return (num - remainder);
}
static inline double dml_abs(double a)
{
if (a > 0)
return a;
else
return (a*(-1));
}
#endif
@@ -0,0 +1,38 @@
/*
* Copyright 2018 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 __DML_LOGGER_H_
#define __DML_LOGGER_H_
#define DC_LOGGER \
mode_lib->logger
#define dml_print(str, ...) {DC_LOG_DML(str, ##__VA_ARGS__); }
#define DTRACE(str, ...) {DC_LOG_DML(str, ##__VA_ARGS__); }
#endif
@@ -0,0 +1,704 @@
/*
* Copyright 2017 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
*
*/
static const qp_table qp_table_422_10bpc_min = {
{ 6, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} },
{ 6.5, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} },
{ 7, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 7, 9, 9, 9, 11, 15} },
{ 7.5, { 0, 2, 4, 6, 6, 6, 6, 7, 7, 7, 8, 9, 9, 11, 15} },
{ 8, { 0, 2, 3, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 11, 14} },
{ 8.5, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 14} },
{ 9, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} },
{ 9.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} },
{ 10, { 0, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} },
{10.5, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 11, 12} },
{ 11, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11} },
{11.5, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 10, 11} },
{ 12, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10} },
{12.5, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} },
{ 13, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 9} },
{13.5, { 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 9} },
{ 14, { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8} },
{14.5, { 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8} },
{ 15, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 6, 8} },
{15.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7} },
{ 16, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} },
{16.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} },
{ 17, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 6} },
{17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} },
{ 18, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 5} },
{18.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} },
{ 19, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 4} },
{19.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} },
{ 20, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 3} }
};
static const qp_table qp_table_444_8bpc_max = {
{ 6, { 4, 6, 8, 8, 9, 9, 9, 10, 11, 12, 12, 12, 12, 13, 15} },
{ 6.5, { 4, 6, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 12, 13, 15} },
{ 7, { 4, 5, 7, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14} },
{ 7.5, { 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} },
{ 8, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} },
{ 8.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} },
{ 9, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} },
{ 9.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} },
{ 10, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} },
{10.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 11, 12} },
{ 11, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11} },
{11.5, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} },
{ 12, { 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 9, 9, 10, 11} },
{12.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} },
{ 13, { 1, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 10} },
{13.5, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} },
{ 14, { 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} },
{14.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9} },
{ 15, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} },
{15.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} },
{ 16, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} },
{16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} },
{ 17, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} },
{17.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} },
{ 18, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} },
{18.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} },
{ 19, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} },
{19.5, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} },
{ 20, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} },
{20.5, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} },
{ 21, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} },
{21.5, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} },
{ 22, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} },
{22.5, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} },
{ 23, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} },
{23.5, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} },
{ 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4} }
};
static const qp_table qp_table_420_12bpc_max = {
{ 4, {11, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 21, 22} },
{ 4.5, {10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} },
{ 5, { 9, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 21} },
{ 5.5, { 8, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 19, 20} },
{ 6, { 6, 9, 11, 12, 13, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} },
{ 6.5, { 6, 8, 10, 11, 11, 13, 14, 15, 15, 16, 16, 17, 17, 18, 19} },
{ 7, { 5, 7, 9, 10, 10, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18} },
{ 7.5, { 5, 7, 8, 9, 9, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17} },
{ 8, { 4, 6, 7, 8, 8, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} },
{ 8.5, { 3, 6, 6, 7, 7, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} },
{ 9, { 3, 5, 6, 7, 7, 10, 11, 12, 12, 13, 13, 14, 14, 14, 15} },
{ 9.5, { 2, 5, 6, 6, 7, 9, 10, 11, 12, 12, 13, 13, 13, 14, 15} },
{ 10, { 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 15} },
{10.5, { 2, 3, 5, 5, 6, 7, 8, 9, 11, 11, 12, 12, 12, 12, 14} },
{ 11, { 1, 3, 4, 5, 6, 6, 7, 9, 10, 11, 11, 11, 12, 12, 13} },
{11.5, { 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 10, 11, 11, 11, 13} },
{ 12, { 1, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 12} },
{12.5, { 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} },
{ 13, { 1, 1, 1, 2, 4, 4, 6, 6, 7, 8, 8, 9, 9, 9, 11} },
{13.5, { 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8, 9, 11} },
{ 14, { 1, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} },
{14.5, { 0, 1, 1, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} },
{ 15, { 0, 1, 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 9} },
{15.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} },
{ 16, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 7} },
{16.5, { 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 7} },
{ 17, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} },
{17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} },
{ 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} }
};
static const qp_table qp_table_444_10bpc_min = {
{ 6, { 0, 4, 7, 7, 9, 9, 9, 9, 9, 10, 10, 10, 10, 12, 18} },
{ 6.5, { 0, 4, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 12, 18} },
{ 7, { 0, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 10, 10, 12, 17} },
{ 7.5, { 0, 4, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9, 10, 12, 17} },
{ 8, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} },
{ 8.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} },
{ 9, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} },
{ 9.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} },
{ 10, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} },
{10.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} },
{ 11, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} },
{11.5, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} },
{ 12, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9, 9, 11, 14} },
{12.5, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 9, 9, 11, 14} },
{ 13, { 0, 2, 4, 4, 5, 6, 7, 7, 7, 7, 8, 9, 9, 11, 13} },
{13.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 13} },
{ 14, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 11, 13} },
{14.5, { 0, 2, 3, 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 11, 12} },
{ 15, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} },
{15.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} },
{ 16, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} },
{16.5, { 0, 1, 2, 3, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} },
{ 17, { 0, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 9, 11} },
{17.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 11} },
{ 18, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} },
{18.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} },
{ 19, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} },
{19.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} },
{ 20, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 9} },
{20.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 9} },
{ 21, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 9} },
{21.5, { 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8} },
{ 22, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} },
{22.5, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} },
{ 23, { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} },
{23.5, { 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} },
{ 24, { 0, 0, 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 7} },
{24.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 7} },
{ 25, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} },
{25.5, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} },
{ 26, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 5} },
{26.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} },
{ 27, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} },
{27.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} },
{ 28, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} },
{28.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 4} },
{ 29, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3} },
{29.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3} },
{ 30, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }
};
static const qp_table qp_table_420_8bpc_max = {
{ 4, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 13, 14} },
{ 4.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} },
{ 5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 12, 13} },
{ 5.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} },
{ 6, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} },
{ 6.5, { 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} },
{ 7, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10} },
{ 7.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9} },
{ 8, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} },
{ 8.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} },
{ 9, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7} },
{ 9.5, { 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} },
{ 10, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6} },
{10.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} },
{ 11, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5} },
{11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} },
{ 12, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} }
};
static const qp_table qp_table_444_8bpc_min = {
{ 6, { 0, 1, 3, 3, 5, 5, 5, 5, 5, 6, 6, 6, 6, 9, 14} },
{ 6.5, { 0, 1, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 9, 14} },
{ 7, { 0, 0, 2, 2, 4, 4, 4, 4, 4, 5, 5, 6, 6, 9, 13} },
{ 7.5, { 0, 0, 2, 2, 3, 4, 4, 4, 4, 4, 5, 5, 6, 9, 13} },
{ 8, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} },
{ 8.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} },
{ 9, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} },
{ 9.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} },
{ 10, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} },
{10.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} },
{ 11, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} },
{11.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} },
{ 12, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} },
{12.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 4, 5, 5, 7, 10} },
{ 13, { 0, 0, 1, 1, 2, 3, 3, 3, 3, 3, 4, 5, 5, 7, 9} },
{13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} },
{ 14, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 5, 5, 7, 9} },
{14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} },
{ 15, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} },
{15.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} },
{ 16, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} },
{16.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} },
{ 17, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} },
{17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} },
{ 18, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} },
{18.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} },
{ 19, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} },
{19.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} },
{ 20, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} },
{20.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} },
{ 21, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} },
{21.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} },
{ 22, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} },
{22.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} },
{ 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} },
{23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} },
{ 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3} }
};
static const qp_table qp_table_444_12bpc_min = {
{ 6, { 0, 5, 11, 11, 13, 13, 13, 13, 13, 14, 14, 14, 14, 17, 22} },
{ 6.5, { 0, 5, 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 17, 22} },
{ 7, { 0, 5, 10, 10, 12, 12, 12, 12, 12, 13, 13, 14, 14, 17, 21} },
{ 7.5, { 0, 5, 9, 10, 11, 12, 12, 12, 12, 12, 13, 13, 14, 17, 21} },
{ 8, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} },
{ 8.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} },
{ 9, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} },
{ 9.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} },
{ 10, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} },
{10.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} },
{ 11, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{11.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{ 12, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{12.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{ 13, { 0, 4, 7, 8, 9, 11, 11, 11, 11, 11, 13, 13, 13, 15, 17} },
{13.5, { 0, 3, 6, 7, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 17} },
{ 14, { 0, 3, 5, 6, 9, 9, 9, 10, 11, 11, 12, 13, 13, 15, 17} },
{14.5, { 0, 2, 5, 6, 8, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{ 15, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{15.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{ 16, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} },
{16.5, { 0, 2, 3, 5, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} },
{ 17, { 0, 2, 3, 5, 5, 6, 9, 9, 10, 10, 11, 11, 12, 13, 15} },
{17.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 15} },
{ 18, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} },
{18.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} },
{ 19, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{19.5, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{ 20, { 0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 9, 10, 10, 11, 13} },
{20.5, { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 13} },
{ 21, { 0, 1, 2, 3, 4, 5, 5, 7, 7, 8, 9, 10, 10, 11, 13} },
{21.5, { 0, 1, 2, 3, 3, 4, 5, 7, 7, 8, 9, 10, 10, 11, 12} },
{ 22, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 12} },
{22.5, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 11} },
{ 23, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} },
{23.5, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} },
{ 24, { 0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 8, 8, 9, 11} },
{24.5, { 0, 0, 1, 2, 3, 4, 4, 6, 6, 7, 8, 8, 8, 9, 11} },
{ 25, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 8, 8, 10} },
{25.5, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} },
{ 26, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 9} },
{26.5, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 7, 9} },
{ 27, { 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} },
{27.5, { 0, 0, 1, 1, 2, 2, 4, 4, 4, 5, 6, 7, 7, 7, 9} },
{ 28, { 0, 0, 0, 1, 1, 2, 3, 4, 4, 4, 6, 6, 6, 7, 9} },
{28.5, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} },
{ 29, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8} },
{29.5, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7} },
{ 30, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 5, 5, 5, 5, 7} },
{30.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} },
{ 31, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} },
{31.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} },
{ 32, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} },
{32.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 6} },
{ 33, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} },
{33.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} },
{ 34, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 5} },
{34.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 5} },
{ 35, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} },
{35.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 4} },
{ 36, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }
};
static const qp_table qp_table_420_12bpc_min = {
{ 4, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 21} },
{ 4.5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} },
{ 5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} },
{ 5.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} },
{ 6, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{ 6.5, { 0, 4, 6, 8, 9, 10, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{ 7, { 0, 3, 5, 7, 9, 10, 10, 11, 11, 11, 13, 13, 13, 15, 17} },
{ 7.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 16} },
{ 8, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{ 8.5, { 0, 2, 4, 6, 6, 9, 9, 10, 11, 11, 12, 12, 13, 14, 15} },
{ 9, { 0, 2, 4, 6, 6, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14} },
{ 9.5, { 0, 2, 4, 5, 6, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14} },
{ 10, { 0, 2, 3, 5, 6, 7, 8, 8, 9, 10, 10, 12, 12, 12, 14} },
{10.5, { 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 11, 11, 13} },
{ 11, { 0, 2, 3, 4, 5, 5, 6, 8, 8, 9, 9, 10, 11, 11, 12} },
{11.5, { 0, 1, 2, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 10, 12} },
{ 12, { 0, 0, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} },
{12.5, { 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 10} },
{ 13, { 0, 0, 0, 1, 3, 3, 5, 5, 6, 7, 7, 8, 8, 8, 10} },
{13.5, { 0, 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 7, 8, 10} },
{ 14, { 0, 0, 0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 9} },
{14.5, { 0, 0, 0, 0, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} },
{ 15, { 0, 0, 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 8} },
{15.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} },
{ 16, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 6} },
{16.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} },
{ 17, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} },
{17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 5} },
{ 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} }
};
static const qp_table qp_table_422_12bpc_min = {
{ 6, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} },
{ 6.5, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} },
{ 7, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} },
{ 7.5, { 0, 4, 8, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} },
{ 8, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} },
{ 8.5, { 0, 3, 6, 8, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 18} },
{ 9, { 0, 3, 5, 8, 9, 10, 10, 10, 11, 11, 12, 13, 13, 15, 17} },
{ 9.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 17} },
{ 10, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{10.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} },
{ 11, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 14, 15} },
{11.5, { 0, 2, 4, 6, 7, 7, 9, 9, 10, 11, 11, 12, 12, 14, 15} },
{ 12, { 0, 2, 4, 6, 6, 6, 8, 8, 9, 9, 11, 11, 12, 13, 14} },
{12.5, { 0, 1, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 13, 14} },
{ 13, { 0, 1, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 11, 12, 13} },
{13.5, { 0, 1, 3, 3, 4, 5, 7, 7, 8, 8, 10, 10, 10, 12, 13} },
{ 14, { 0, 0, 2, 3, 4, 5, 6, 6, 7, 7, 9, 10, 10, 11, 12} },
{14.5, { 0, 0, 1, 3, 4, 4, 6, 6, 6, 7, 9, 9, 9, 11, 12} },
{ 15, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 6, 8, 9, 9, 10, 12} },
{15.5, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 10, 11} },
{ 16, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 9, 11} },
{16.5, { 0, 0, 0, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7, 9, 10} },
{ 17, { 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 6, 6, 6, 8, 10} },
{17.5, { 0, 0, 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 8, 9} },
{ 18, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 9} },
{18.5, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 3, 5, 5, 5, 7, 9} },
{ 19, { 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 8} },
{19.5, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 6, 8} },
{ 20, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} },
{20.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 7} },
{ 21, { 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6} },
{21.5, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} },
{ 22, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 6} },
{22.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} },
{ 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 5} },
{23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} },
{ 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} }
};
static const qp_table qp_table_422_12bpc_max = {
{ 6, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} },
{ 6.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} },
{ 7, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} },
{ 7.5, { 9, 10, 12, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20} },
{ 8, { 6, 9, 10, 12, 14, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} },
{ 8.5, { 6, 8, 9, 11, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} },
{ 9, { 5, 7, 8, 10, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} },
{ 9.5, { 5, 7, 7, 9, 10, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} },
{ 10, { 4, 6, 6, 8, 9, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} },
{10.5, { 4, 6, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} },
{ 11, { 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} },
{11.5, { 3, 5, 6, 8, 9, 9, 11, 11, 12, 13, 13, 14, 14, 15, 16} },
{ 12, { 3, 5, 6, 8, 8, 8, 10, 10, 11, 11, 13, 13, 14, 14, 15} },
{12.5, { 3, 4, 6, 7, 8, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15} },
{ 13, { 2, 4, 5, 6, 7, 7, 9, 10, 10, 11, 12, 12, 13, 13, 14} },
{13.5, { 2, 4, 5, 5, 6, 7, 9, 9, 10, 10, 12, 12, 12, 13, 14} },
{ 14, { 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 11, 12, 12, 12, 13} },
{14.5, { 2, 3, 3, 5, 6, 6, 8, 8, 8, 9, 11, 11, 11, 12, 13} },
{ 15, { 2, 3, 3, 5, 5, 6, 7, 8, 8, 8, 10, 11, 11, 11, 13} },
{15.5, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 11, 12} },
{ 16, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 10, 12} },
{16.5, { 1, 2, 2, 4, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 11} },
{ 17, { 1, 1, 2, 3, 4, 4, 6, 6, 6, 7, 8, 8, 8, 9, 11} },
{17.5, { 1, 1, 2, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 10} },
{ 18, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 7, 7, 8, 8, 10} },
{18.5, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 5, 7, 7, 7, 8, 10} },
{ 19, { 1, 1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 9} },
{19.5, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 7, 9} },
{ 20, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 6, 8} },
{20.5, { 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} },
{ 21, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 7} },
{21.5, { 0, 0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} },
{ 22, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 7} },
{22.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 6} },
{ 23, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6} },
{23.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} },
{ 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} }
};
static const qp_table qp_table_444_12bpc_max = {
{ 6, {12, 14, 16, 16, 17, 17, 17, 18, 19, 20, 20, 20, 20, 21, 23} },
{ 6.5, {12, 14, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 20, 21, 23} },
{ 7, {12, 13, 15, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 21, 22} },
{ 7.5, {12, 13, 14, 15, 15, 16, 16, 17, 18, 18, 19, 19, 20, 21, 22} },
{ 8, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} },
{ 8.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} },
{ 9, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} },
{ 9.5, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} },
{ 10, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} },
{10.5, {10, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 18, 19, 20} },
{ 11, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19} },
{11.5, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} },
{ 12, { 6, 9, 12, 13, 14, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} },
{12.5, { 6, 9, 12, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} },
{ 13, { 5, 9, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 17, 18} },
{13.5, { 5, 8, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} },
{ 14, { 5, 8, 10, 11, 12, 12, 12, 13, 14, 14, 15, 16, 16, 16, 18} },
{14.5, { 4, 7, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17} },
{ 15, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} },
{15.5, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} },
{ 16, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} },
{16.5, { 4, 5, 7, 8, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} },
{ 17, { 4, 5, 7, 8, 8, 9, 11, 11, 12, 12, 12, 13, 13, 14, 16} },
{17.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 16} },
{ 18, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} },
{18.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} },
{ 19, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} },
{19.5, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} },
{ 20, { 2, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11, 11, 12, 14} },
{20.5, { 2, 3, 5, 5, 7, 8, 8, 8, 9, 10, 10, 11, 11, 12, 14} },
{ 21, { 2, 3, 5, 5, 7, 7, 7, 8, 8, 9, 10, 11, 11, 12, 14} },
{21.5, { 2, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13} },
{ 22, { 2, 2, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 10, 11, 13} },
{22.5, { 2, 2, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 10, 11, 12} },
{ 23, { 2, 2, 4, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} },
{23.5, { 2, 2, 3, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} },
{ 24, { 2, 2, 3, 4, 4, 5, 7, 7, 7, 8, 9, 9, 9, 10, 12} },
{24.5, { 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 12} },
{ 25, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9, 11} },
{25.5, { 1, 1, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 11} },
{ 26, { 1, 1, 3, 3, 3, 4, 5, 6, 6, 7, 8, 8, 8, 8, 10} },
{26.5, { 1, 1, 2, 3, 3, 4, 5, 6, 6, 6, 8, 8, 8, 8, 10} },
{ 27, { 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 10} },
{27.5, { 1, 1, 2, 2, 3, 3, 5, 5, 5, 6, 7, 8, 8, 8, 10} },
{ 28, { 0, 1, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 8, 10} },
{28.5, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} },
{ 29, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 9} },
{29.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8} },
{ 30, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6, 6, 6, 8} },
{30.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} },
{ 31, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} },
{31.5, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} },
{ 32, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 7} },
{32.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 7} },
{ 33, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} },
{33.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} },
{ 34, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} },
{34.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 3, 3, 3, 3, 4, 6} },
{ 35, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} },
{35.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5} },
{ 36, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} }
};
static const qp_table qp_table_420_8bpc_min = {
{ 4, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 13} },
{ 4.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} },
{ 5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} },
{ 5.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} },
{ 6, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} },
{ 6.5, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 5, 7, 10} },
{ 7, { 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} },
{ 7.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} },
{ 8, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} },
{ 8.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} },
{ 9, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6} },
{ 9.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} },
{ 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5} },
{10.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} },
{ 11, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} },
{11.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} },
{ 12, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3} }
};
static const qp_table qp_table_422_8bpc_min = {
{ 6, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} },
{ 6.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} },
{ 7, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} },
{ 7.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} },
{ 8, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} },
{ 8.5, { 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 7, 10} },
{ 9, { 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} },
{ 9.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 9} },
{ 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} },
{10.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} },
{ 11, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} },
{11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} },
{ 12, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6} },
{12.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} },
{ 13, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5} },
{13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 5} },
{ 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4} },
{14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} },
{ 15, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 4} },
{15.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} },
{ 16, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} }
};
static const qp_table qp_table_422_10bpc_max = {
{ 6, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} },
{ 6.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} },
{ 7, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} },
{ 7.5, { 5, 6, 8, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16} },
{ 8, { 4, 6, 7, 9, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} },
{ 8.5, { 4, 5, 6, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} },
{ 9, { 3, 4, 5, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} },
{ 9.5, { 3, 4, 4, 6, 6, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} },
{ 10, { 2, 3, 3, 5, 5, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{10.5, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{ 11, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} },
{11.5, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 9, 9, 10, 10, 11, 12} },
{ 12, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 8, 9, 9, 10, 10, 11} },
{12.5, { 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11} },
{ 13, { 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10} },
{13.5, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10} },
{ 14, { 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 9} },
{14.5, { 1, 2, 2, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9} },
{ 15, { 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 9} },
{15.5, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 8} },
{ 16, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 8} },
{16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7} },
{ 17, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 7} },
{17.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} },
{ 18, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 6} },
{18.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 6} },
{ 19, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 5} },
{19.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 5} },
{ 20, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 4} }
};
static const qp_table qp_table_420_10bpc_max = {
{ 4, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 17, 18} },
{ 4.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} },
{ 5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 16, 17} },
{ 5.5, { 6, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 16} },
{ 6, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} },
{ 6.5, { 4, 5, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 15} },
{ 7, { 3, 4, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14} },
{ 7.5, { 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13} },
{ 8, { 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{ 8.5, { 1, 3, 3, 4, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} },
{ 9, { 1, 3, 3, 4, 4, 6, 7, 8, 8, 9, 9, 10, 10, 10, 11} },
{ 9.5, { 1, 3, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} },
{ 10, { 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} },
{10.5, { 1, 1, 3, 3, 3, 4, 5, 5, 7, 7, 8, 8, 8, 8, 10} },
{ 11, { 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 8, 9} },
{11.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 7, 9} },
{ 12, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 8} },
{12.5, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} },
{ 13, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7} },
{13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} },
{ 14, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} },
{14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5} },
{ 15, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} }
};
static const qp_table qp_table_420_10bpc_min = {
{ 4, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 17} },
{ 4.5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} },
{ 5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} },
{ 5.5, { 0, 3, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15} },
{ 6, { 0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} },
{ 6.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 14} },
{ 7, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 11, 13} },
{ 7.5, { 0, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 11, 12} },
{ 8, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} },
{ 8.5, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11} },
{ 9, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10} },
{ 9.5, { 0, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10} },
{ 10, { 0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 8, 8, 8, 10} },
{10.5, { 0, 0, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} },
{ 11, { 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8} },
{11.5, { 0, 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 8} },
{ 12, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 7} },
{12.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6} },
{ 13, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} },
{13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} },
{ 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} },
{14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} },
{ 15, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} }
};
static const qp_table qp_table_444_10bpc_max = {
{ 6, { 8, 10, 12, 12, 13, 13, 13, 14, 15, 16, 16, 16, 16, 17, 19} },
{ 6.5, { 8, 10, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 16, 17, 19} },
{ 7, { 8, 9, 11, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 17, 18} },
{ 7.5, { 8, 9, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} },
{ 8, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} },
{ 8.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} },
{ 9, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} },
{ 9.5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} },
{ 10, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} },
{10.5, { 6, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14, 15, 16} },
{ 11, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15} },
{11.5, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} },
{ 12, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} },
{12.5, { 4, 6, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} },
{ 13, { 3, 6, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 14} },
{13.5, { 3, 5, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} },
{ 14, { 3, 5, 6, 7, 8, 8, 8, 9, 10, 10, 11, 12, 12, 12, 14} },
{14.5, { 2, 4, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13} },
{ 15, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{15.5, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} },
{ 16, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} },
{16.5, { 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} },
{ 17, { 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 12} },
{17.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 12} },
{ 18, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} },
{18.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} },
{ 19, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} },
{19.5, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} },
{ 20, { 1, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 10} },
{20.5, { 1, 2, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 10} },
{ 21, { 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 10} },
{21.5, { 1, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 7, 7, 8, 9} },
{ 22, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 9} },
{22.5, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8} },
{ 23, { 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} },
{23.5, { 1, 1, 1, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} },
{ 24, { 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 8} },
{24.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 8} },
{ 25, { 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} },
{25.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 7} },
{ 26, { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 6} },
{26.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6} },
{ 27, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} },
{27.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} },
{ 28, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} },
{28.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} },
{ 29, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4} },
{29.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} },
{ 30, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} }
};
static const qp_table qp_table_422_8bpc_max = {
{ 6, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} },
{ 6.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} },
{ 7, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} },
{ 7.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} },
{ 8, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} },
{ 8.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} },
{ 9, { 1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} },
{ 9.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10} },
{ 10, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} },
{10.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} },
{ 11, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} },
{11.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8} },
{ 12, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7} },
{12.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7} },
{ 13, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6} },
{13.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 6} },
{ 14, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5} },
{14.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5} },
{ 15, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5} },
{15.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} },
{ 16, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} }
};
@@ -0,0 +1,260 @@
/*
* Copyright 2021 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 "rc_calc_fpu.h"
#include "qp_tables.h"
#include "amdgpu_dm/dc_fpu.h"
#define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min)
#define MODE_SELECT(val444, val422, val420) \
(cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420))
#define TABLE_CASE(mode, bpc, max) case (table_hash(mode, BPC_##bpc, max)): \
table = qp_table_##mode##_##bpc##bpc_##max; \
table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \
break
static int median3(int a, int b, int c)
{
if (a > b)
swap(a, b);
if (b > c)
swap(b, c);
if (a > b)
swap(b, c);
return b;
}
static double dsc_roundf(double num)
{
if (num < 0.0)
num = num - 0.5;
else
num = num + 0.5;
return (int)(num);
}
static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
enum max_min max_min, float bpp)
{
int mode = MODE_SELECT(444, 422, 420);
int sel = table_hash(mode, bpc, max_min);
int table_size = 0;
int index;
const struct qp_entry *table = NULL;
// alias enum
enum { min = DAL_MM_MIN, max = DAL_MM_MAX };
switch (sel) {
TABLE_CASE(444, 8, max);
TABLE_CASE(444, 8, min);
TABLE_CASE(444, 10, max);
TABLE_CASE(444, 10, min);
TABLE_CASE(444, 12, max);
TABLE_CASE(444, 12, min);
TABLE_CASE(422, 8, max);
TABLE_CASE(422, 8, min);
TABLE_CASE(422, 10, max);
TABLE_CASE(422, 10, min);
TABLE_CASE(422, 12, max);
TABLE_CASE(422, 12, min);
TABLE_CASE(420, 8, max);
TABLE_CASE(420, 8, min);
TABLE_CASE(420, 10, max);
TABLE_CASE(420, 10, min);
TABLE_CASE(420, 12, max);
TABLE_CASE(420, 12, min);
}
if (!table)
return;
index = (int)((bpp - table[0].bpp) * 2);
/* requested size is bigger than the table */
if (index >= table_size) {
dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n");
return;
}
memcpy(qps, table[index].qps, sizeof(qp_set));
}
static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
{
int *p = ofs;
if (mode == CM_444 || mode == CM_RGB) {
*p++ = (int)((bpp <= 6) ? (0) : ((((bpp >= 8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0)))))));
*p++ = (int)((bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0)))))));
*p++ = (int)((bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0)))))));
*p++ = (int)((bpp <= 6) ? (-4) : ((((bpp >= 8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0)))))));
*p++ = (int)((bpp <= 6) ? (-6) : ((((bpp >= 8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0)))))));
*p++ = (int)((bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0)))));
*p++ = (int)((bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0)))));
*p++ = (int)((bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0)))));
*p++ = (int)((bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0)))));
*p++ = (int)((bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0)))));
*p++ = -10;
*p++ = (int)((bpp <= 6) ? (-12) : ((bpp >= 8) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2 / 2.0)))));
*p++ = -12;
*p++ = -12;
*p++ = -12;
} else if (mode == CM_422) {
*p++ = (int)((bpp <= 8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp - 8) * (8 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp - 8) * (8 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp - 8) * (6 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp - 8) * (6 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp - 8) * (6 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp - 8) * (6 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp - 8) * (6 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp - 8) * (4 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp - 8) * (2 / 2.0)))));
*p++ = (int)((bpp <= 8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp - 8) * (2 / 2.0)))));
*p++ = -10;
*p++ = (int)((bpp <= 6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2.0 / 1)))));
*p++ = -12;
*p++ = -12;
*p++ = -12;
} else {
*p++ = (int)((bpp <= 6) ? (2) : ((bpp >= 8) ? (10) : (2 + dsc_roundf((bpp - 6) * (8 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (0) : ((bpp >= 8) ? (8) : (0 + dsc_roundf((bpp - 6) * (8 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (0) : ((bpp >= 8) ? (6) : (0 + dsc_roundf((bpp - 6) * (6 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-2) : ((bpp >= 8) ? (4) : (-2 + dsc_roundf((bpp - 6) * (6 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-4) : ((bpp >= 8) ? (2) : (-4 + dsc_roundf((bpp - 6) * (6 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-6) : ((bpp >= 8) ? (0) : (-6 + dsc_roundf((bpp - 6) * (6 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-8) : ((bpp >= 8) ? (-2) : (-8 + dsc_roundf((bpp - 6) * (6 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-8) : ((bpp >= 8) ? (-4) : (-8 + dsc_roundf((bpp - 6) * (4 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-8) : ((bpp >= 8) ? (-6) : (-8 + dsc_roundf((bpp - 6) * (2 / 2.0)))));
*p++ = (int)((bpp <= 6) ? (-10) : ((bpp >= 8) ? (-8) : (-10 + dsc_roundf((bpp - 6) * (2 / 2.0)))));
*p++ = -10;
*p++ = (int)((bpp <= 4) ? (-12) : ((bpp >= 5) ? (-10) : (-12 + dsc_roundf((bpp - 4) * (2 / 1.0)))));
*p++ = -12;
*p++ = -12;
*p++ = -12;
}
}
void _do_calc_rc_params(struct rc_params *rc,
enum colour_mode cm,
enum bits_per_comp bpc,
u16 drm_bpp,
bool is_navite_422_or_420,
int slice_width,
int slice_height,
int minor_version)
{
float bpp;
float bpp_group;
float initial_xmit_delay_factor;
int padding_pixels;
int i;
dc_assert_fp_enabled();
bpp = (float)((float)drm_bpp / 16.0);
/* in native_422 or native_420 modes, the bits_per_pixel is double the
* target bpp (the latter is what calc_rc_params expects)
*/
if (is_navite_422_or_420)
bpp /= 2.0;
rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
bpp_group = MODE_SELECT(bpp, bpp * 2.0f, bpp * 2.0f);
switch (cm) {
case CM_420:
rc->initial_fullness_offset = (int)((bpp >= 6) ? (2048) : ((bpp <= 4) ? (6144) : ((((bpp > 4) && (bpp <= 5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp - 5) * (3584))))));
rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group)));
rc->second_line_bpg_offset = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group)));
break;
case CM_422:
rc->initial_fullness_offset = (int)((bpp >= 8) ? (2048) : ((bpp <= 7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584)))));
rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group)));
rc->second_line_bpg_offset = 0;
break;
case CM_444:
case CM_RGB:
rc->initial_fullness_offset = (int)((bpp >= 12) ? (2048) : ((bpp <= 8) ? (6144) : ((((bpp > 8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2))))));
rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group)));
rc->second_line_bpg_offset = 0;
break;
}
initial_xmit_delay_factor = (float)((cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0);
rc->initial_xmit_delay = (int)dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor);
if (cm == CM_422 || cm == CM_420)
slice_width /= 2;
padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0;
if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) {
if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1)
rc->initial_xmit_delay++;
}
rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
rc->flatness_det_thresh = 2 << (bpc - 8);
get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp);
get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp);
if (cm == CM_444 && minor_version == 1) {
for (i = 0; i < QP_SET_SIZE; ++i) {
rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0;
rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0;
}
}
get_ofs_set(rc->ofs, cm, bpp);
/* fixed parameters */
rc->rc_model_size = 8192;
rc->rc_edge_factor = 6;
rc->rc_tgt_offset_hi = 3;
rc->rc_tgt_offset_lo = 3;
rc->rc_buf_thresh[0] = 896;
rc->rc_buf_thresh[1] = 1792;
rc->rc_buf_thresh[2] = 2688;
rc->rc_buf_thresh[3] = 3584;
rc->rc_buf_thresh[4] = 4480;
rc->rc_buf_thresh[5] = 5376;
rc->rc_buf_thresh[6] = 6272;
rc->rc_buf_thresh[7] = 6720;
rc->rc_buf_thresh[8] = 7168;
rc->rc_buf_thresh[9] = 7616;
rc->rc_buf_thresh[10] = 7744;
rc->rc_buf_thresh[11] = 7872;
rc->rc_buf_thresh[12] = 8000;
rc->rc_buf_thresh[13] = 8064;
}
@@ -0,0 +1,90 @@
/*
* Copyright 2021 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 __RC_CALC_FPU_H__
#define __RC_CALC_FPU_H__
#include "os_types.h"
#include <drm/display/drm_dsc.h>
#define QP_SET_SIZE 15
typedef int qp_set[QP_SET_SIZE];
struct rc_params {
int rc_quant_incr_limit0;
int rc_quant_incr_limit1;
int initial_fullness_offset;
int initial_xmit_delay;
int first_line_bpg_offset;
int second_line_bpg_offset;
int flatness_min_qp;
int flatness_max_qp;
int flatness_det_thresh;
qp_set qp_min;
qp_set qp_max;
qp_set ofs;
int rc_model_size;
int rc_edge_factor;
int rc_tgt_offset_hi;
int rc_tgt_offset_lo;
int rc_buf_thresh[QP_SET_SIZE - 1];
};
enum colour_mode {
CM_RGB, /* 444 RGB */
CM_444, /* 444 YUV or simple 422 */
CM_422, /* native 422 */
CM_420 /* native 420 */
};
enum bits_per_comp {
BPC_8 = 8,
BPC_10 = 10,
BPC_12 = 12
};
enum max_min {
DAL_MM_MIN = 0,
DAL_MM_MAX = 1
};
struct qp_entry {
float bpp;
const qp_set qps;
};
typedef struct qp_entry qp_table[];
void _do_calc_rc_params(struct rc_params *rc,
enum colour_mode cm,
enum bits_per_comp bpc,
u16 drm_bpp,
bool is_navite_422_or_420,
int slice_width,
int slice_height,
int minor_version);
#endif