mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm/amd/display: Add DML changes to support HDMI FRL
This adds DML support for HDMI FRL. Signed-off-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Fangzhi Zuo <Jerry.Zuo@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
08d4acb07f
commit
a7c7b927c8
|
|
@ -78,6 +78,7 @@ 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)
|
||||
|
|
@ -117,9 +118,11 @@ 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
|
||||
|
|
|
|||
|
|
@ -1049,6 +1049,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
|
|||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
if (dc_is_hdmi_frl_signal(context->res_ctx.pipe_ctx[i].stream->signal))
|
||||
return true;
|
||||
if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1467,6 +1469,9 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc,
|
|||
case SIGNAL_TYPE_DVI_DUAL_LINK:
|
||||
pipes[pipe_cnt].dout.output_type = dm_hdmi;
|
||||
break;
|
||||
case SIGNAL_TYPE_HDMI_FRL:
|
||||
pipes[pipe_cnt].dout.output_type = dm_hdmifrl;
|
||||
break;
|
||||
default:
|
||||
/* In case there is no signal, set dp with 4 lanes to allow max config */
|
||||
pipes[pipe_cnt].dout.is_virtual = 1;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include "display_mode_vba_30.h"
|
||||
#include "dcn30_fpu.h"
|
||||
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
|
||||
#define REG(reg)\
|
||||
optc1->tg_regs->reg
|
||||
|
||||
|
|
@ -131,6 +133,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = {
|
|||
.phyclk_mhz = 300.0,
|
||||
.phyclk_d18_mhz = 667.0,
|
||||
.dscclk_mhz = 405.6,
|
||||
.dtbclk_mhz = 1217.0,
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -741,3 +744,89 @@ void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_bo
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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;
|
||||
} 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 -5;
|
||||
}
|
||||
|
|
@ -70,4 +70,26 @@ 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__*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "display_mode_vba_30.h"
|
||||
#include "../dml_inline_defs.h"
|
||||
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
|
|
@ -324,6 +326,17 @@ static void CalculateUrgentBurstFactor(
|
|||
double *UrgentBurstFactorChroma,
|
||||
bool *NotEnoughUrgentLatencyHiding);
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
long HTotal,
|
||||
long HActive,
|
||||
int AudioRate,
|
||||
int AudioLayoutSingle);
|
||||
|
||||
static void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
struct vba_vars_st *v,
|
||||
|
|
@ -626,6 +639,8 @@ static unsigned int dscceComputeDelay(
|
|||
pixelsPerClock = 1;
|
||||
else if (pixelFormat == dm_n422)
|
||||
pixelsPerClock = 2;
|
||||
else if (Output == dm_hdmifrl)
|
||||
pixelsPerClock = 2;
|
||||
else
|
||||
pixelsPerClock = 1;
|
||||
|
||||
|
|
@ -646,6 +661,8 @@ static unsigned int dscceComputeDelay(
|
|||
//422 mode has an additional cycle of delay
|
||||
if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
|
||||
s = 0;
|
||||
else if (Output == dm_hdmifrl)
|
||||
s = 0;
|
||||
else
|
||||
s = 1;
|
||||
|
||||
|
|
@ -716,6 +733,25 @@ static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum o
|
|||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else if (Output == dm_hdmifrl && pixelFormat != dm_444) {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
// dsccif
|
||||
Delay = Delay + 1;
|
||||
// dscc - input deserializer
|
||||
Delay = Delay + 5;
|
||||
// dscc - input cdc fifo
|
||||
Delay = Delay + 25;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output cdc fifo
|
||||
Delay = Delay + 10;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output serializer
|
||||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
|
|
@ -2017,6 +2053,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
|||
v->DSCFormatFactor = 1;
|
||||
else if (v->OutputFormat[k] == dm_n422)
|
||||
v->DSCFormatFactor = 2;
|
||||
else if (v->Output[k] == dm_hdmifrl)
|
||||
v->DSCFormatFactor = 2;
|
||||
else
|
||||
v->DSCFormatFactor = 1;
|
||||
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
|
||||
|
|
@ -3309,19 +3347,38 @@ static double TruncToValidBPP(
|
|||
int NonDSCBPP1 = 0;
|
||||
int NonDSCBPP2 = 0;
|
||||
|
||||
enum frl_cap_chk_result hdmifrlresult = { 0 };
|
||||
struct frl_cap_chk_params hdmifrlparams = { 0 };
|
||||
struct frl_cap_chk_intermediates hdmifrlinter = { 0 };
|
||||
|
||||
hdmifrlparams.lanes = Lanes;
|
||||
hdmifrlparams.f_pixel_clock_nominal = PixelClock * 1000000;
|
||||
hdmifrlparams.r_bit_nominal = LinkBitRate * 1000000;
|
||||
hdmifrlparams.layout = AudioLayout;
|
||||
hdmifrlparams.f_audio = AudioRate * 1000;
|
||||
hdmifrlparams.h_active = HActive;
|
||||
hdmifrlparams.h_blank = HTotal - HActive;
|
||||
hdmifrlparams.compressed = DSCEnable;
|
||||
|
||||
if (Format == dm_420) {
|
||||
NonDSCBPP0 = 12;
|
||||
NonDSCBPP1 = 15;
|
||||
NonDSCBPP2 = 18;
|
||||
MinDSCBPP = 6;
|
||||
MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_420;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP * 2 / 3);
|
||||
} else if (Format == dm_444) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 30;
|
||||
NonDSCBPP2 = 36;
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_444;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 3);
|
||||
} else {
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_422;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 2);
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
|
|
@ -3329,12 +3386,20 @@ static double TruncToValidBPP(
|
|||
if (Format == dm_n422) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else if (Output == dm_hdmifrl) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else {
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Output == dm_hdmifrl) {
|
||||
hdmifrlresult = dml1_frl_cap_chk_inter(&hdmifrlparams, &hdmifrlinter);
|
||||
MaxLinkBPP = (1 - hdmifrlinter.overhead_max) * dml_min(hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max + 24 * TB_BORROWED_MAX / HActive,
|
||||
(hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max * HTotal - 16 * hdmifrlinter.blank_audio_min) / HActive);
|
||||
} else
|
||||
if (DSCEnable && Output == dm_dp) {
|
||||
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
|
||||
} else {
|
||||
|
|
@ -3372,6 +3437,8 @@ static double TruncToValidBPP(
|
|||
if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP == NonDSCBPP0 || DesiredBPP == 18)) ||
|
||||
(DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
|
||||
return BPP_INVALID;
|
||||
} else if ((Output == dm_hdmifrl && hdmifrlresult != FRL_CAP_CHK_OK) || (Output != dm_hdmifrl && MaxLinkBPP < DesiredBPP)) {
|
||||
return BPP_INVALID;
|
||||
} else {
|
||||
return DesiredBPP;
|
||||
}
|
||||
|
|
@ -4013,6 +4080,172 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
} else if (v->Output[k] == dm_hdmifrl) {
|
||||
if (v->DSCEnable[k] == true || v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresDSC[i][k] = false;
|
||||
v->LinkDSCEnable = false;
|
||||
v->RequiresFEC[i][k] = false;
|
||||
}
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKD18PerState[i] >= 3000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
3000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "3x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 8000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
8000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState(i, k) = v->Output[k] & "8x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->ForcedOutputLinkBPP[k] == 0
|
||||
&& v->PHYCLKD18PerState[i] < 12000.0 / 18) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->RequiresFEC[i][k] = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->RequiresFEC[i][k] = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v->OutputBppPerState[i][k] = 0;
|
||||
|
|
@ -4022,7 +4255,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
for (i = start_state; i < v->soc.num_states; i++) {
|
||||
v->DIOSupport[i] = true;
|
||||
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
|
||||
if (!v->skip_dio_check[k] && v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi)
|
||||
if (!v->skip_dio_check[k] && v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi || v->Output[k] == dm_hdmifrl)
|
||||
&& (v->OutputBppPerState[i][k] == 0
|
||||
|| (v->OutputFormat[k] == dm_420 && v->Interlace[k] == true && v->ProgressiveToInterlaceUnitInOPP == true))) {
|
||||
v->DIOSupport[i] = false;
|
||||
|
|
@ -4030,6 +4263,25 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
}
|
||||
}
|
||||
|
||||
for (i = start_state; i < v->soc.num_states; ++i) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = false;
|
||||
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
||||
if (v->BlendingAndTiming[k] == k && v->Output[k] == dm_hdmifrl
|
||||
&& RequiredDTBCLK(
|
||||
v->RequiresDSC[i][k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->OutputFormat[k],
|
||||
v->OutputBppPerState[i][k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k]) > v->DTBCLKPerState[i]) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = start_state; i < v->soc.num_states; ++i) {
|
||||
v->ODMCombine4To1SupportCheckOK[i] = true;
|
||||
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
||||
|
|
@ -6248,6 +6500,29 @@ static double CalculateUrgentLatency(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
long HTotal,
|
||||
long HActive,
|
||||
int AudioRate,
|
||||
int AudioLayout)
|
||||
{
|
||||
if (DSCEnable != true) {
|
||||
return dml_max(PixelClock / 4.0 * OutputBPP / 24.0, 25.0);
|
||||
} else {
|
||||
double PixelWordRate = PixelClock / (OutputFormat == dm_444 ? 1 : 2);
|
||||
double HCActive = dml_ceil(DSCSlices * dml_ceil(OutputBPP * dml_ceil(HActive / DSCSlices, 1) / 8.0, 1) / 3.0, 1);
|
||||
double HCBlank = 64 + 32 * dml_ceil((double)AudioRate * (AudioLayout == 1 ? 1.0 : 0.25) * HTotal / (PixelClock * 1000), 1);
|
||||
double AverageTribyteRate = PixelWordRate * (HCActive + HCBlank) / HTotal;
|
||||
double HActiveTribyteRate = PixelWordRate * HCActive / HActive;
|
||||
return dml_max4(PixelWordRate / 4.0, AverageTribyteRate / 4.0, HActiveTribyteRate / 4.0, 25.0) * 1.002;
|
||||
}
|
||||
}
|
||||
|
||||
static noinline_for_stack void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
struct vba_vars_st *v,
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
|
|||
.phyclk_mhz = 300.0,
|
||||
.phyclk_d18_mhz = 667.0,
|
||||
.dscclk_mhz = 405.6,
|
||||
.dtbclk_mhz = 1217.0,
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc = {
|
|||
.phyclk_mhz = 300.0,
|
||||
.phyclk_d18_mhz = 667.0,
|
||||
.dscclk_mhz = 405.6,
|
||||
.dtbclk_mhz = 1217.0,
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "display_mode_vba_31.h"
|
||||
#include "../dml_inline_defs.h"
|
||||
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* This file is gcc-parsable HW gospel, coming straight from HW engineers.
|
||||
|
|
@ -357,6 +359,17 @@ static void CalculateUrgentBurstFactor(
|
|||
double *UrgentBurstFactorChroma,
|
||||
bool *NotEnoughUrgentLatencyHiding);
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
int HTotal,
|
||||
int HActive,
|
||||
int AudioRate,
|
||||
int AudioLayoutSingle);
|
||||
|
||||
static void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
int MaxPrefetchMode,
|
||||
|
|
@ -695,6 +708,8 @@ static unsigned int dscceComputeDelay(
|
|||
pixelsPerClock = 1;
|
||||
else if (pixelFormat == dm_n422)
|
||||
pixelsPerClock = 2;
|
||||
else if (Output == dm_hdmifrl)
|
||||
pixelsPerClock = 2;
|
||||
// #all other modes operate at 1 pixel per clock
|
||||
else
|
||||
pixelsPerClock = 1;
|
||||
|
|
@ -716,6 +731,8 @@ static unsigned int dscceComputeDelay(
|
|||
//422 mode has an additional cycle of delay
|
||||
if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
|
||||
s = 0;
|
||||
else if (Output == dm_hdmifrl)
|
||||
s = 0;
|
||||
else
|
||||
s = 1;
|
||||
|
||||
|
|
@ -786,6 +803,25 @@ static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum o
|
|||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else if (Output == dm_hdmifrl && pixelFormat != dm_444) {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
// dsccif
|
||||
Delay = Delay + 1;
|
||||
// dscc - input deserializer
|
||||
Delay = Delay + 5;
|
||||
// dscc - input cdc fifo
|
||||
Delay = Delay + 25;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output cdc fifo
|
||||
Delay = Delay + 10;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output serializer
|
||||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
|
|
@ -2243,6 +2279,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
|||
v->DSCFormatFactor = 1;
|
||||
else if (v->OutputFormat[k] == dm_n422)
|
||||
v->DSCFormatFactor = 2;
|
||||
else if (v->Output[k] == dm_hdmifrl)
|
||||
v->DSCFormatFactor = 2;
|
||||
else
|
||||
v->DSCFormatFactor = 1;
|
||||
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
|
||||
|
|
@ -3615,19 +3653,38 @@ static double TruncToValidBPP(
|
|||
int NonDSCBPP1;
|
||||
int NonDSCBPP2;
|
||||
|
||||
enum frl_cap_chk_result hdmifrlresult = FRL_CAP_CHK_OK;
|
||||
struct frl_cap_chk_params hdmifrlparams = { 0 };
|
||||
struct frl_cap_chk_intermediates hdmifrlinter = { 0 };
|
||||
|
||||
hdmifrlparams.lanes = Lanes;
|
||||
hdmifrlparams.f_pixel_clock_nominal = PixelClock * 1000000;
|
||||
hdmifrlparams.r_bit_nominal = LinkBitRate * 1000000;
|
||||
hdmifrlparams.layout = AudioLayout;
|
||||
hdmifrlparams.f_audio = AudioRate * 1000;
|
||||
hdmifrlparams.h_active = HActive;
|
||||
hdmifrlparams.h_blank = HTotal - HActive;
|
||||
hdmifrlparams.compressed = DSCEnable;
|
||||
|
||||
if (Format == dm_420) {
|
||||
NonDSCBPP0 = 12;
|
||||
NonDSCBPP1 = 15;
|
||||
NonDSCBPP2 = 18;
|
||||
MinDSCBPP = 6;
|
||||
MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_420;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP * 2 / 3);
|
||||
} else if (Format == dm_444) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 30;
|
||||
NonDSCBPP2 = 36;
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_444;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 3);
|
||||
} else {
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_422;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 2);
|
||||
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
|
|
@ -3636,12 +3693,22 @@ static double TruncToValidBPP(
|
|||
if (Format == dm_n422) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else if (Output == dm_hdmifrl) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else {
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Output == dm_hdmifrl) {
|
||||
hdmifrlresult = dml1_frl_cap_chk_inter(&hdmifrlparams, &hdmifrlinter);
|
||||
MaxLinkBPP = (1 - hdmifrlinter.overhead_max)
|
||||
* dml_min(
|
||||
hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max + 24 * TB_BORROWED_MAX / HActive,
|
||||
(hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max * HTotal - 16 * hdmifrlinter.blank_audio_min) / HActive);
|
||||
} else
|
||||
if (DSCEnable && Output == dm_dp) {
|
||||
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
|
||||
} else {
|
||||
|
|
@ -3678,6 +3745,8 @@ static double TruncToValidBPP(
|
|||
if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP <= NonDSCBPP0))
|
||||
|| (DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
|
||||
return BPP_INVALID;
|
||||
} else if ((Output == dm_hdmifrl && hdmifrlresult != FRL_CAP_CHK_OK) || (Output != dm_hdmifrl && MaxLinkBPP < DesiredBPP)) {
|
||||
return BPP_INVALID;
|
||||
} else {
|
||||
return DesiredBPP;
|
||||
}
|
||||
|
|
@ -4105,6 +4174,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
|
||||
if (v->ODMCombinePolicy == dm_odm_combine_policy_none
|
||||
|| !(v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_dp2p0 ||
|
||||
v->Output[k] == dm_edp)) {
|
||||
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
|
|
@ -4529,6 +4599,131 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
}
|
||||
} else if (v->Output[k] == dm_hdmifrl) {
|
||||
if (v->DSCEnable[k] == true) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresDSC[i][k] = false;
|
||||
v->LinkDSCEnable = false;
|
||||
v->RequiresFEC[i][k] = false;
|
||||
}
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKD18PerState[i] >= 3000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
3000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "3x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 8000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
8000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState(i, k) = v->Output[k] & "8x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v->OutputBppPerState[i][k] = 0;
|
||||
|
|
@ -4542,6 +4737,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
if (v->BlendingAndTiming[k] == k
|
||||
&& (v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_edp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_hdmi) && v->OutputBppPerState[i][k] == 0) {
|
||||
v->LinkCapacitySupport[i] = false;
|
||||
}
|
||||
|
|
@ -4553,6 +4749,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
if (v->BlendingAndTiming[k] == k
|
||||
&& (v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_edp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_hdmi)) {
|
||||
if (v->OutputFormat[k] == dm_420 && v->Interlace[k] == 1 && v->ProgressiveToInterlaceUnitInOPP == true) {
|
||||
P2IWith420 = true;
|
||||
|
|
@ -4564,11 +4761,31 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < v->soc.num_states; ++i) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = false;
|
||||
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
||||
if (v->BlendingAndTiming[k] == k && v->Output[k] == dm_hdmifrl
|
||||
&& RequiredDTBCLK(
|
||||
v->RequiresDSC[i][k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->OutputFormat[k],
|
||||
v->OutputBppPerState[i][k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k]) > v->DTBCLKPerState[i]) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < v->soc.num_states; ++i) {
|
||||
v->ODMCombine4To1SupportCheckOK[i] = true;
|
||||
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
||||
if (v->BlendingAndTiming[k] == k && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
|
||||
&& (v->ODMCombine4To1Supported == false || v->Output[k] == dm_dp || v->Output[k] == dm_edp
|
||||
|| (v->Output[k] == dm_hdmifrl && v->DSCEnable[k] == false)
|
||||
|| v->Output[k] == dm_hdmi)) {
|
||||
v->ODMCombine4To1SupportCheckOK[i] = false;
|
||||
}
|
||||
|
|
@ -7055,6 +7272,29 @@ static double CalculateUrgentLatency(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
int HTotal,
|
||||
int HActive,
|
||||
int AudioRate,
|
||||
int AudioLayout)
|
||||
{
|
||||
if (DSCEnable != true) {
|
||||
return dml_max(PixelClock / 4.0 * OutputBPP / 24.0, 25.0);
|
||||
} else {
|
||||
double PixelWordRate = PixelClock / (OutputFormat == dm_444 ? 1 : 2);
|
||||
double HCActive = dml_ceil(DSCSlices * dml_ceil(OutputBPP * dml_ceil(HActive / DSCSlices, 1) / 8.0, 1) / 3.0, 1);
|
||||
double HCBlank = 64 + 32 * dml_ceil(AudioRate * (AudioLayout == 1 ? 1.0 : 0.25) * HTotal / (PixelClock * 1000), 1);
|
||||
double AverageTribyteRate = PixelWordRate * (HCActive + HCBlank) / HTotal;
|
||||
double HActiveTribyteRate = PixelWordRate * HCActive / HActive;
|
||||
return dml_max4(PixelWordRate / 4.0, AverageTribyteRate / 4.0, HActiveTribyteRate / 4.0, 25.0) * 1.002;
|
||||
}
|
||||
}
|
||||
|
||||
static noinline_for_stack void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
int MaxPrefetchMode,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "display_mode_vba_314.h"
|
||||
#include "../dml_inline_defs.h"
|
||||
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* This file is gcc-parsable HW gospel, coming straight from HW engineers.
|
||||
|
|
@ -366,6 +368,17 @@ static void CalculateUrgentBurstFactor(
|
|||
double *UrgentBurstFactorChroma,
|
||||
bool *NotEnoughUrgentLatencyHiding);
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
int HTotal,
|
||||
int HActive,
|
||||
int AudioRate,
|
||||
int AudioLayoutSingle);
|
||||
|
||||
static void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
int MaxPrefetchMode,
|
||||
|
|
@ -713,6 +726,8 @@ static unsigned int dscceComputeDelay(
|
|||
pixelsPerClock = 1;
|
||||
else if (pixelFormat == dm_n422)
|
||||
pixelsPerClock = 2;
|
||||
else if (Output == dm_hdmifrl)
|
||||
pixelsPerClock = 2;
|
||||
// #all other modes operate at 1 pixel per clock
|
||||
else
|
||||
pixelsPerClock = 1;
|
||||
|
|
@ -734,6 +749,8 @@ static unsigned int dscceComputeDelay(
|
|||
//422 mode has an additional cycle of delay
|
||||
if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
|
||||
s = 0;
|
||||
else if (Output == dm_hdmifrl)
|
||||
s = 0;
|
||||
else
|
||||
s = 1;
|
||||
|
||||
|
|
@ -804,6 +821,25 @@ static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum o
|
|||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else if (Output == dm_hdmifrl && pixelFormat != dm_444) {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
// dsccif
|
||||
Delay = Delay + 1;
|
||||
// dscc - input deserializer
|
||||
Delay = Delay + 5;
|
||||
// dscc - input cdc fifo
|
||||
Delay = Delay + 25;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output cdc fifo
|
||||
Delay = Delay + 10;
|
||||
// dscc - cdc uncertainty
|
||||
Delay = Delay + 2;
|
||||
// dscc - output serializer
|
||||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
|
|
@ -2261,6 +2297,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
|||
v->DSCFormatFactor = 1;
|
||||
else if (v->OutputFormat[k] == dm_n422)
|
||||
v->DSCFormatFactor = 2;
|
||||
else if (v->Output[k] == dm_hdmifrl)
|
||||
v->DSCFormatFactor = 2;
|
||||
else
|
||||
v->DSCFormatFactor = 1;
|
||||
if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
|
||||
|
|
@ -3721,19 +3759,38 @@ static double TruncToValidBPP(
|
|||
int NonDSCBPP1;
|
||||
int NonDSCBPP2;
|
||||
|
||||
enum frl_cap_chk_result hdmifrlresult = FRL_CAP_CHK_OK;
|
||||
struct frl_cap_chk_params hdmifrlparams = { 0 };
|
||||
struct frl_cap_chk_intermediates hdmifrlinter = { 0 };
|
||||
|
||||
hdmifrlparams.lanes = Lanes;
|
||||
hdmifrlparams.f_pixel_clock_nominal = PixelClock * 1000000;
|
||||
hdmifrlparams.r_bit_nominal = LinkBitRate * 1000000;
|
||||
hdmifrlparams.layout = AudioLayout;
|
||||
hdmifrlparams.f_audio = AudioRate * 1000;
|
||||
hdmifrlparams.h_active = HActive;
|
||||
hdmifrlparams.h_blank = HTotal - HActive;
|
||||
hdmifrlparams.compressed = DSCEnable;
|
||||
|
||||
if (Format == dm_420) {
|
||||
NonDSCBPP0 = 12;
|
||||
NonDSCBPP1 = 15;
|
||||
NonDSCBPP2 = 18;
|
||||
MinDSCBPP = 6;
|
||||
MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_420;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP * 2 / 3);
|
||||
} else if (Format == dm_444) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 30;
|
||||
NonDSCBPP2 = 36;
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_444;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 3);
|
||||
} else {
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_422;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 2);
|
||||
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
|
|
@ -3742,12 +3799,22 @@ static double TruncToValidBPP(
|
|||
if (Format == dm_n422) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else if (Output == dm_hdmifrl) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else {
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Output == dm_hdmifrl) {
|
||||
hdmifrlresult = dml1_frl_cap_chk_inter(&hdmifrlparams, &hdmifrlinter);
|
||||
MaxLinkBPP = (1 - hdmifrlinter.overhead_max)
|
||||
* dml_min(
|
||||
hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max + 24 * TB_BORROWED_MAX / HActive,
|
||||
(hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max * HTotal - 16 * hdmifrlinter.blank_audio_min) / HActive);
|
||||
} else
|
||||
if (DSCEnable && Output == dm_dp) {
|
||||
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
|
||||
} else {
|
||||
|
|
@ -3784,6 +3851,8 @@ static double TruncToValidBPP(
|
|||
if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP <= NonDSCBPP0))
|
||||
|| (DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
|
||||
return BPP_INVALID;
|
||||
} else if ((Output == dm_hdmifrl && hdmifrlresult != FRL_CAP_CHK_OK) || (Output != dm_hdmifrl && MaxLinkBPP < DesiredBPP)) {
|
||||
return BPP_INVALID;
|
||||
} else {
|
||||
return DesiredBPP;
|
||||
}
|
||||
|
|
@ -4195,6 +4264,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
|||
|
||||
if (v->ODMCombinePolicy == dm_odm_combine_policy_none
|
||||
|| !(v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_dp2p0 ||
|
||||
v->Output[k] == dm_edp)) {
|
||||
v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
|
|
@ -4616,6 +4686,131 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
|||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
}
|
||||
} else if (v->Output[k] == dm_hdmifrl) {
|
||||
if (v->DSCEnable[k] == true) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresDSC[i][k] = false;
|
||||
v->LinkDSCEnable = false;
|
||||
v->RequiresFEC[i][k] = false;
|
||||
}
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKD18PerState[i] >= 3000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
3000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "3x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
3,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x3";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 6000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
6000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "6x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 8000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
8000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState(i, k) = v->Output[k] & "8x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v->OutputBppPerState[i][k] = 0;
|
||||
|
|
@ -4629,6 +4824,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
|||
if (v->BlendingAndTiming[k] == k
|
||||
&& (v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_edp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_hdmi) && v->OutputBppPerState[i][k] == 0) {
|
||||
v->LinkCapacitySupport[i] = false;
|
||||
}
|
||||
|
|
@ -4640,6 +4836,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
|||
if (v->BlendingAndTiming[k] == k
|
||||
&& (v->Output[k] == dm_dp ||
|
||||
v->Output[k] == dm_edp ||
|
||||
v->Output[k] == dm_hdmifrl ||
|
||||
v->Output[k] == dm_hdmi)) {
|
||||
if (v->OutputFormat[k] == dm_420 && v->Interlace[k] == 1 && v->ProgressiveToInterlaceUnitInOPP == true) {
|
||||
P2IWith420 = true;
|
||||
|
|
@ -4651,6 +4848,24 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < v->soc.num_states; ++i) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = false;
|
||||
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
|
||||
if (v->BlendingAndTiming[k] == k && v->Output[k] == dm_hdmifrl
|
||||
&& RequiredDTBCLK(
|
||||
v->RequiresDSC[i][k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->OutputFormat[k],
|
||||
v->OutputBppPerState[i][k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k]) > v->DTBCLKPerState[i]) {
|
||||
v->DTBCLKRequiredMoreThanSupported[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < v->soc.num_states; ++i) {
|
||||
v->ODMCombine4To1SupportCheckOK[i] = true;
|
||||
|
|
@ -7141,6 +7356,29 @@ static double CalculateUrgentLatency(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static double RequiredDTBCLK(
|
||||
bool DSCEnable,
|
||||
double PixelClock,
|
||||
enum output_format_class OutputFormat,
|
||||
double OutputBPP,
|
||||
int DSCSlices,
|
||||
int HTotal,
|
||||
int HActive,
|
||||
int AudioRate,
|
||||
int AudioLayout)
|
||||
{
|
||||
if (DSCEnable != true) {
|
||||
return dml_max(PixelClock / 4.0 * OutputBPP / 24.0, 25.0);
|
||||
} else {
|
||||
double PixelWordRate = PixelClock / (OutputFormat == dm_444 ? 1 : 2);
|
||||
double HCActive = dml_ceil(DSCSlices * dml_ceil(OutputBPP * dml_ceil(HActive / DSCSlices, 1) / 8.0, 1) / 3.0, 1);
|
||||
double HCBlank = 64 + 32 * dml_ceil(AudioRate * (AudioLayout == 1 ? 1.0 : 0.25) * HTotal / (PixelClock * 1000), 1);
|
||||
double AverageTribyteRate = PixelWordRate * (HCActive + HCBlank) / HTotal;
|
||||
double HActiveTribyteRate = PixelWordRate * HCActive / HActive;
|
||||
return dml_max4(PixelWordRate / 4.0, AverageTribyteRate / 4.0, HActiveTribyteRate / 4.0, 25.0) * 1.002;
|
||||
}
|
||||
}
|
||||
|
||||
static noinline_for_stack void UseMinimumDCFCLK(
|
||||
struct display_mode_lib *mode_lib,
|
||||
int MaxPrefetchMode,
|
||||
|
|
|
|||
|
|
@ -1608,6 +1608,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
|
|||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
if (dc_is_hdmi_frl_signal(context->res_ctx.pipe_ctx[i].stream->signal))
|
||||
return true;
|
||||
if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3588,3 +3590,11 @@ void dcn32_override_min_req_memclk(struct dc *dc, struct dc_state *context)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int dcn32_get_max_dispclk_mhz(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
(void)dc;
|
||||
int max_level = context->bw_ctx.dml.soc.num_states;
|
||||
|
||||
return (unsigned int) context->bw_ctx.dml.soc.clock_limits[max_level - 1].dispclk_mhz;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "../dml_inline_defs.h"
|
||||
#include "display_mode_vba_util_32.h"
|
||||
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
|
||||
void dml32_recalculate(struct display_mode_lib *mode_lib);
|
||||
static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
|
||||
struct display_mode_lib *mode_lib);
|
||||
|
|
@ -342,6 +344,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
|||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
else if (mode_lib->vba.OutputFormat[k] == dm_n422)
|
||||
mode_lib->vba.DSCFormatFactor = 2;
|
||||
else if (mode_lib->vba.Output[k] == dm_hdmifrl)
|
||||
mode_lib->vba.DSCFormatFactor = 2;
|
||||
else
|
||||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
|
||||
|
|
@ -2282,6 +2286,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveOTG = v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveOTG + 1;
|
||||
if (mode_lib->vba.Output[k] == dm_hdmifrl)
|
||||
v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveDP2p0 = v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveDP2p0 + 1;
|
||||
if (mode_lib->vba.Output[k] == dm_dp2p0) {
|
||||
v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveDP2p0 = v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalNumberOfActiveDP2p0 + 1;
|
||||
if (mode_lib->vba.OutputMultistreamId[k]
|
||||
|
|
@ -2328,6 +2334,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
if (mode_lib->vba.BlendingAndTiming[k] == k
|
||||
&& (mode_lib->vba.Output[k] == dm_dp || mode_lib->vba.Output[k] == dm_dp2p0
|
||||
|| mode_lib->vba.Output[k] == dm_edp
|
||||
|| mode_lib->vba.Output[k] == dm_hdmifrl
|
||||
|| mode_lib->vba.Output[k] == dm_hdmi)
|
||||
&& mode_lib->vba.OutputBppPerState[i][k] == 0 &&
|
||||
(mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe)) {
|
||||
|
|
@ -2353,6 +2360,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
if (mode_lib->vba.BlendingAndTiming[k] == k
|
||||
&& (mode_lib->vba.Output[k] == dm_dp || mode_lib->vba.Output[k] == dm_dp2p0
|
||||
|| mode_lib->vba.Output[k] == dm_edp
|
||||
|| mode_lib->vba.Output[k] == dm_hdmifrl
|
||||
|| mode_lib->vba.Output[k] == dm_hdmi)) {
|
||||
if (mode_lib->vba.OutputFormat[k]
|
||||
== dm_420 && mode_lib->vba.Interlace[k] == 1 &&
|
||||
|
|
@ -2388,7 +2396,9 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
}
|
||||
}
|
||||
|
||||
if ((mode_lib->vba.Output[k] == dm_edp || mode_lib->vba.Output[k] == dm_hdmi)) {
|
||||
if ((mode_lib->vba.Output[k] == dm_edp
|
||||
|| mode_lib->vba.Output[k] == dm_hdmifrl
|
||||
|| mode_lib->vba.Output[k] == dm_hdmi)) {
|
||||
if (mode_lib->vba.OutputMultistreamEn[k] == true && mode_lib->vba.OutputMultistreamId[k] == k)
|
||||
mode_lib->vba.MultistreamWithHDMIOreDP = true;
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActiveSurfaces; ++j) {
|
||||
|
|
@ -2415,6 +2425,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
mode_lib->vba.DTBCLKRequiredMoreThanSupported[i] = false;
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k
|
||||
&& mode_lib->vba.Output[k] == dm_hdmifrl
|
||||
&& dml32_RequiredDTBCLK(mode_lib->vba.RequiresDSC[i][k],
|
||||
mode_lib->vba.PixelClockBackEnd[k],
|
||||
mode_lib->vba.OutputFormat[k],
|
||||
|
|
@ -2451,6 +2462,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
if (mode_lib->vba.Output[k] == dm_dp || mode_lib->vba.Output[k] == dm_dp2p0
|
||||
|| mode_lib->vba.Output[k] == dm_hdmifrl
|
||||
|| mode_lib->vba.Output[k] == dm_edp) {
|
||||
if (mode_lib->vba.OutputFormat[k] == dm_420) {
|
||||
mode_lib->vba.DSCFormatFactor = 2;
|
||||
|
|
@ -2458,6 +2470,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
} else if (mode_lib->vba.OutputFormat[k] == dm_n422) {
|
||||
mode_lib->vba.DSCFormatFactor = 2;
|
||||
} else if (mode_lib->vba.Output[k] == dm_hdmifrl) {
|
||||
mode_lib->vba.DSCFormatFactor = 2;
|
||||
} else {
|
||||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
#include "display_mode_vba_util_32.h"
|
||||
#include "../dml_inline_defs.h"
|
||||
#include "../dml1_frl_cap_chk.h"
|
||||
#include "display_mode_vba_32.h"
|
||||
#include "../display_mode_lib.h"
|
||||
|
||||
|
|
@ -55,6 +56,8 @@ unsigned int dml32_dscceComputeDelay(
|
|||
|
||||
if (pixelFormat == dm_420)
|
||||
pixelsPerClock = 2;
|
||||
else if (Output == dm_hdmifrl)
|
||||
pixelsPerClock = 2;
|
||||
else if (pixelFormat == dm_n422)
|
||||
pixelsPerClock = 2;
|
||||
// #all other modes operate at 1 pixel per clock
|
||||
|
|
@ -78,6 +81,8 @@ unsigned int dml32_dscceComputeDelay(
|
|||
//422 mode has an additional cycle of delay
|
||||
if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
|
||||
s = 0;
|
||||
else if (Output == dm_hdmifrl)
|
||||
s = 0;
|
||||
else
|
||||
s = 1;
|
||||
|
||||
|
|
@ -140,7 +145,7 @@ unsigned int dml32_dscComputeDelay(enum output_format_class pixelFormat, enum ou
|
|||
Delay = Delay + 1;
|
||||
// sft
|
||||
Delay = Delay + 1;
|
||||
} else if (pixelFormat == dm_n422 || (pixelFormat != dm_444)) {
|
||||
} else if (pixelFormat == dm_n422 || (Output == dm_hdmifrl && pixelFormat != dm_444)) {
|
||||
// sfr
|
||||
Delay = Delay + 2;
|
||||
// dsccif
|
||||
|
|
@ -1546,6 +1551,91 @@ void dml32_CalculateOutputLink(
|
|||
*OutputRate = dm_output_rate_dp_rate_hbr3;
|
||||
}
|
||||
}
|
||||
} else if (Output == dm_hdmifrl) {
|
||||
if (DSCEnable == true) {
|
||||
*RequiresDSC = true;
|
||||
LinkDSCEnable = true;
|
||||
*RequiresFEC = true;
|
||||
} else {
|
||||
*RequiresDSC = false;
|
||||
LinkDSCEnable = false;
|
||||
*RequiresFEC = false;
|
||||
}
|
||||
*OutBpp = 0;
|
||||
if (PHYCLKD18PerState >= 3000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(3000, 3, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
//OutputTypeAndRate = Output & "3x3";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_3x3;
|
||||
}
|
||||
if (*OutBpp == 0 && PHYCLKD18PerState >= 6000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(6000, 3, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
//OutputTypeAndRate = Output & "6x3";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_6x3;
|
||||
}
|
||||
if (*OutBpp == 0 && PHYCLKD18PerState >= 6000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(6000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
//OutputTypeAndRate = Output & "6x4";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_6x4;
|
||||
}
|
||||
if (*OutBpp == 0 && PHYCLKD18PerState >= 8000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(8000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
//OutputTypeAndRate = Output & "8x4";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_8x4;
|
||||
}
|
||||
if (*OutBpp == 0 && PHYCLKD18PerState >= 10000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(10000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
if (*OutBpp == 0 && DSCEnable == true && ForcedOutputLinkBPP == 0 &&
|
||||
PHYCLKD18PerState < 12000 / 18) {
|
||||
*RequiresDSC = true;
|
||||
LinkDSCEnable = true;
|
||||
*RequiresFEC = true;
|
||||
*OutBpp = dml32_TruncToValidBPP(10000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
}
|
||||
//OutputTypeAndRate = Output & "10x4";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_10x4;
|
||||
}
|
||||
|
||||
if (*OutBpp == 0 && PHYCLKD18PerState >= 12000 / 18) {
|
||||
*OutBpp = dml32_TruncToValidBPP(12000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
if (*OutBpp == 0 && DSCEnable == true && ForcedOutputLinkBPP == 0) {
|
||||
*RequiresDSC = true;
|
||||
LinkDSCEnable = true;
|
||||
*RequiresFEC = true;
|
||||
*OutBpp = dml32_TruncToValidBPP(12000, 4, HTotal, HActive, PixelClockBackEnd,
|
||||
ForcedOutputLinkBPP, LinkDSCEnable, Output, OutputFormat,
|
||||
DSCInputBitPerComponent, NumberOfDSCSlices, (unsigned int)AudioSampleRate,
|
||||
AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
|
||||
}
|
||||
//OutputTypeAndRate = Output & "12x4";
|
||||
*OutputType = dm_output_type_hdmifrl;
|
||||
*OutputRate = dm_output_rate_hdmi_rate_12x4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1599,12 +1689,27 @@ double dml32_TruncToValidBPP(
|
|||
unsigned int NonDSCBPP2;
|
||||
unsigned int NonDSCBPP3 = BPP_INVALID;
|
||||
|
||||
enum frl_cap_chk_result hdmifrlresult = FRL_CAP_CHK_OK;
|
||||
struct frl_cap_chk_params hdmifrlparams = { 0 };
|
||||
struct frl_cap_chk_intermediates hdmifrlinter = { 0 };
|
||||
|
||||
hdmifrlparams.lanes = Lanes;
|
||||
hdmifrlparams.f_pixel_clock_nominal = PixelClock * 1000000;
|
||||
hdmifrlparams.r_bit_nominal = LinkBitRate * 1000000;
|
||||
hdmifrlparams.layout = AudioLayout;
|
||||
hdmifrlparams.f_audio = AudioRate * 1000;
|
||||
hdmifrlparams.h_active = HActive;
|
||||
hdmifrlparams.h_blank = HTotal - HActive;
|
||||
hdmifrlparams.bpc = (int)(DesiredBPP / 3);
|
||||
hdmifrlparams.compressed = DSCEnable;
|
||||
|
||||
if (Format == dm_420) {
|
||||
NonDSCBPP0 = 12;
|
||||
NonDSCBPP1 = 15;
|
||||
NonDSCBPP2 = 18;
|
||||
MinDSCBPP = 6;
|
||||
MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_420;
|
||||
} else if (Format == dm_444) {
|
||||
NonDSCBPP3 = 18;
|
||||
NonDSCBPP0 = 24;
|
||||
|
|
@ -1612,8 +1717,10 @@ double dml32_TruncToValidBPP(
|
|||
NonDSCBPP2 = 36;
|
||||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_444;
|
||||
} else {
|
||||
if (Output == dm_hdmi) {
|
||||
hdmifrlparams.pixel_encoding = HDMI_FRL_PIXEL_ENCODING_422;
|
||||
if (Output == dm_hdmi || Output == dm_hdmifrl) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 24;
|
||||
NonDSCBPP2 = 24;
|
||||
|
|
@ -1622,7 +1729,7 @@ double dml32_TruncToValidBPP(
|
|||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
}
|
||||
if (Format == dm_n422) {
|
||||
if (Format == dm_n422 || Output == dm_hdmifrl) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
} else {
|
||||
|
|
@ -1630,7 +1737,13 @@ double dml32_TruncToValidBPP(
|
|||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
}
|
||||
}
|
||||
if (Output == dm_dp2p0) {
|
||||
if (Output == dm_hdmifrl) {
|
||||
hdmifrlresult = dml1_frl_cap_chk_inter(&hdmifrlparams, &hdmifrlinter);
|
||||
MaxLinkBPP = (1 - hdmifrlinter.overhead_max) * dml_min(hdmifrlinter.r_frl_char_min * 16 *
|
||||
Lanes / hdmifrlinter.f_pixel_clock_max + 24 * TB_BORROWED_MAX / HActive,
|
||||
(hdmifrlinter.r_frl_char_min * 16 * Lanes / hdmifrlinter.f_pixel_clock_max *
|
||||
HTotal - 16 * hdmifrlinter.blank_audio_min) / HActive);
|
||||
} else if (Output == dm_dp2p0) {
|
||||
MaxLinkBPP = LinkBitRate * Lanes / PixelClock * 128 / 132 * 383 / 384 * 65536 / 65540;
|
||||
} else if (DSCEnable && Output == dm_dp) {
|
||||
MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
|
||||
|
|
@ -1681,6 +1794,9 @@ double dml32_TruncToValidBPP(
|
|||
DesiredBPP <= NonDSCBPP0)) ||
|
||||
(DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP)))
|
||||
return BPP_INVALID;
|
||||
else if ((Output == dm_hdmifrl && hdmifrlresult != FRL_CAP_CHK_OK) ||
|
||||
(Output != dm_hdmifrl && MaxLinkBPP < DesiredBPP))
|
||||
return BPP_INVALID;
|
||||
else
|
||||
return DesiredBPP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ enum output_encoder_class {
|
|||
dm_hdmi = 1,
|
||||
dm_wb = 2,
|
||||
dm_edp = 3,
|
||||
dm_hdmifrl = 4,
|
||||
dm_dp2p0 = 5,
|
||||
};
|
||||
enum output_format_class {
|
||||
|
|
|
|||
589
drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.c
Normal file
589
drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.c
Normal file
|
|
@ -0,0 +1,589 @@
|
|||
// 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;
|
||||
}
|
||||
|
||||
enum frl_cap_chk_result dml1_frl_cap_chk(struct frl_cap_chk_params *params)
|
||||
{
|
||||
struct frl_cap_chk_intermediates inter;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -119,13 +119,6 @@ struct frl_cap_chk_params {
|
|||
|
||||
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 */
|
||||
|
||||
|
|
@ -145,8 +138,6 @@ enum frl_cap_chk_result dml1_frl_cap_chk_common(struct frl_cap_chk_intermediates
|
|||
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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user