mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
drm/amd/display: refactor DSC cap calculation for dcn35
why: dcn35 currently uses a hardcoded DSC display clock value which is incorrect for some asic types. Newer DCN versions retrieve dsc display clock from clk_mgr. The same can be done for dcn35. how: Refactor the DSC cap calculation using pre-existing logic. Handle ODM combine requirements in dc_dsc.c. Replace hardcoded display clock with actual value retrieved from clk_mgr. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: Charlene Liu <charlene.liu@amd.com> Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Signed-off-by: Mohit Bawa <Mohit.Bawa@amd.com> Signed-off-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:
@@ -1295,6 +1295,35 @@ static void dcn35_update_clocks_fpga(struct clk_mgr *clk_mgr,
|
||||
dcn35_update_clocks_update_dtb_dto(clk_mgr_int, context, clk_mgr->clks.ref_dtbclk_khz);
|
||||
}
|
||||
|
||||
static unsigned int dcn35_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
unsigned int num_clk_levels;
|
||||
|
||||
switch (clk_type) {
|
||||
case CLK_TYPE_DISPCLK:
|
||||
num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
|
||||
return num_clk_levels ?
|
||||
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 :
|
||||
clk_mgr->base.boot_snapshot.dispclk;
|
||||
case CLK_TYPE_DPPCLK:
|
||||
num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dppclk_levels;
|
||||
return num_clk_levels ?
|
||||
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dppclk_mhz * 1000 :
|
||||
clk_mgr->base.boot_snapshot.dppclk;
|
||||
case CLK_TYPE_DSCCLK:
|
||||
num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
|
||||
return num_clk_levels ?
|
||||
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 / 3 :
|
||||
clk_mgr->base.boot_snapshot.dispclk / 3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_mgr_funcs dcn35_funcs = {
|
||||
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
|
||||
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
|
||||
@@ -1306,6 +1335,7 @@ static struct clk_mgr_funcs dcn35_funcs = {
|
||||
.set_low_power_state = dcn35_set_low_power_state,
|
||||
.exit_low_power_state = dcn35_exit_low_power_state,
|
||||
.is_ips_supported = dcn35_is_ips_supported,
|
||||
.get_max_clock_khz = dcn35_get_max_clock_khz,
|
||||
};
|
||||
|
||||
struct clk_mgr_funcs dcn35_fpga_funcs = {
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
#include "reg_helper.h"
|
||||
|
||||
static void dsc35_enable(struct display_stream_compressor *dsc, int opp_pipe);
|
||||
static void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz);
|
||||
|
||||
static const struct dsc_funcs dcn35_dsc_funcs = {
|
||||
.dsc_get_enc_caps = dsc2_get_enc_caps,
|
||||
.dsc_read_state = dsc2_read_state,
|
||||
.dsc_read_reg_state = dsc2_read_reg_state,
|
||||
.dsc_validate_stream = dsc2_validate_stream,
|
||||
@@ -40,6 +40,7 @@ static const struct dsc_funcs dcn35_dsc_funcs = {
|
||||
.dsc_disable = dsc2_disable,
|
||||
.dsc_disconnect = dsc2_disconnect,
|
||||
.dsc_wait_disconnect_pending_clear = dsc2_wait_disconnect_pending_clear,
|
||||
.dsc_get_single_enc_caps = dsc35_get_single_enc_caps,
|
||||
};
|
||||
|
||||
/* Macro definitios for REG_SET macros*/
|
||||
@@ -111,3 +112,31 @@ void dsc35_set_fgcg(struct dcn20_dsc *dsc20, bool enable)
|
||||
{
|
||||
REG_UPDATE(DSC_TOP_CONTROL, DSC_FGCG_REP_DIS, !enable);
|
||||
}
|
||||
|
||||
void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz)
|
||||
{
|
||||
dsc_enc_caps->dsc_version = 0x21; /* v1.2 - DP spec defined it in reverse order and we kept it */
|
||||
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_1 = 1;
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_2 = 1;
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_3 = 1;
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_4 = 1;
|
||||
|
||||
dsc_enc_caps->lb_bit_depth = 13;
|
||||
dsc_enc_caps->is_block_pred_supported = true;
|
||||
|
||||
dsc_enc_caps->color_formats.bits.RGB = 1;
|
||||
dsc_enc_caps->color_formats.bits.YCBCR_444 = 1;
|
||||
dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1;
|
||||
dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0;
|
||||
dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1;
|
||||
|
||||
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
|
||||
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_10_BPC = 1;
|
||||
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_12_BPC = 1;
|
||||
|
||||
dsc_enc_caps->max_total_throughput_mps = max_dscclk_khz * 3 / 1000;
|
||||
|
||||
dsc_enc_caps->max_slice_width = 5184; /* (including 64 overlap pixels for eDP MSO mode) */
|
||||
dsc_enc_caps->bpp_increment_div = 16; /* 1/16th of a bit */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user