Commit d7ef56db authored by Mohit Bawa's avatar Mohit Bawa Committed by Alex Deucher
Browse files

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: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: default avatarCharlene Liu <charlene.liu@amd.com>
Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarMohit Bawa <Mohit.Bawa@amd.com>
Signed-off-by: default avatarFangzhi Zuo <jerry.zuo@amd.com>
Tested-by: default avatarDan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3953a7ba
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -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 = {
+30 −1
Original line number Diff line number Diff line
@@ -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 */
}