Commit 97bda032 authored by Harry Wentland's avatar Harry Wentland Committed by Alex Deucher
Browse files

drm/amd/display: Add DSC support for Navi (v2)



Add support for DCN2 DSC (Display Stream Compression)

HW Blocks:

 +--------++------+       +----------+
 | HUBBUB || HUBP |  <--  | MMHUBBUB |
 +--------++------+       +----------+
        |                     ^
        v                     |
    +--------+            +--------+
    |  DPP   |            |  DWB   |
    +--------+            +--------+
        |
        v                      ^
    +--------+                 |
    |  MPC   |                 |
    +--------+                 |
        |                      |
        v                      |
    +-------+      +-------+   |
    |  OPP  | <--> |  DSC  |   |
    +-------+      +-------+   |
        |                      |
        v                      |
    +--------+                /
    |  OPTC  |  --------------
    +--------+
        |
        v
    +--------+       +--------+
    |  DIO   |       |  DCCG  |
    +--------+       +--------+

v2: rebase (Alex)

Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b4f199c7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -25,6 +25,16 @@ config DRM_AMD_DC_DCN2_0
	    Choose this option if you want to have
	    Navi support for display engine

config DRM_AMD_DC_DSC_SUPPORT
	bool "DSC support"
	default n
	depends on DRM_AMD_DC && X86
	depends on DRM_AMD_DC_DCN1_0
	depends on DRM_AMD_DC_DCN2_0
	help
	    Choose this option if you want to have
	    Dynamic Stream Compression support

config DEBUG_KERNEL_DC
	bool "Enable kgdb break in DC"
	depends on DRM_AMD_DC
+10 −0
Original line number Diff line number Diff line
@@ -542,6 +542,16 @@ bool dm_helpers_submit_i2c(

	return result;
}
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
bool dm_helpers_dp_write_dsc_enable(
		struct dc_context *ctx,
		const struct dc_stream_state *stream,
		bool enable
)
{
	return false;
}
#endif

bool dm_helpers_is_dp_sink_present(struct dc_link *link)
{
+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ DC_LIBS += dcn20
endif


ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
DC_LIBS += dsc
endif

ifdef CONFIG_DRM_AMD_DC_DCN1_0
DC_LIBS += dcn10 dml
+21 −0
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@

#include "dc_link_dp.h"

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
#include "dsc.h"
#endif

#ifdef CONFIG_DRM_AMD_DC_DCN2_0
#include "vm_helper.h"
#endif
@@ -1730,6 +1734,23 @@ static void commit_planes_do_stream_update(struct dc *dc,
#endif
			}

#if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
			if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) {
				if (stream_update->dsc_config->num_slices_h &&
						stream_update->dsc_config->num_slices_v) {
					/* dsc enable */
					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
					dp_set_dsc_enable(pipe_ctx, true);
					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
				} else {
					/* dsc disable */
					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
					dp_set_dsc_enable(pipe_ctx, false);
					dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
				}

			}
#endif
			/* Full fe update*/
			if (update_type == UPDATE_TYPE_FAST)
				continue;
+51 −0
Original line number Diff line number Diff line
@@ -1508,6 +1508,9 @@ static enum dc_status enable_link_dp(
	if (link_settings.link_rate == LINK_RATE_LOW)
			skip_video_pattern = false;

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	dp_set_fec_ready(link, true);
#endif

	if (perform_link_training_with_retries(
			link,
@@ -1520,6 +1523,9 @@ static enum dc_status enable_link_dp(
	else
		status = DC_FAIL_DP_LINK_TRAINING;

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	dp_set_fec_enable(link, true);
#endif
	return status;
}

@@ -2142,6 +2148,14 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
			dp_disable_link_phy(link, signal);
		else
			dp_disable_link_phy_mst(link, signal);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT

		if (dc_is_dp_sst_signal(signal) ||
				link->mst_stream_alloc_table.stream_count == 0) {
			dp_set_fec_enable(link, false);
			dp_set_fec_ready(link, false);
		}
#endif
	} else
		link->link_enc->funcs->disable_output(link->link_enc, signal);

@@ -2376,6 +2390,11 @@ static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
			&stream->link->cur_link_settings);
	link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	if (stream->link->fec_state != dc_link_fec_not_ready)
		link_rate_in_mbytes_per_sec = (link_rate_in_mbytes_per_sec * 970)/1000;
#endif

	mbytes_per_sec = dc_fixpt_from_int(link_rate_in_mbytes_per_sec);

	return dc_fixpt_div_int(mbytes_per_sec, 54);
@@ -2738,12 +2757,30 @@ void core_link_enable_stream(
		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
			allocate_mst_payload(pipe_ctx);

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
		if (pipe_ctx->stream->timing.flags.DSC &&
				(dc_is_dp_signal(pipe_ctx->stream->signal) ||
				dc_is_virtual_signal(pipe_ctx->stream->signal))) {
			dp_set_dsc_enable(pipe_ctx, true);
			pipe_ctx->stream_res.tg->funcs->wait_for_state(
					pipe_ctx->stream_res.tg,
					CRTC_STATE_VBLANK);
		}
#endif
		core_dc->hwss.unblank_stream(pipe_ctx,
			&pipe_ctx->stream->link->cur_link_settings);

		if (dc_is_dp_signal(pipe_ctx->stream->signal))
			enable_stream_features(pipe_ctx);
	}
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	else { // if (IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
		if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
				dc_is_virtual_signal(pipe_ctx->stream->signal))
			dp_set_dsc_enable(pipe_ctx, true);

	}
#endif
}

void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
@@ -2784,6 +2821,12 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
	core_dc->hwss.disable_stream(pipe_ctx, option);

	disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	if (pipe_ctx->stream->timing.flags.DSC &&
			dc_is_dp_signal(pipe_ctx->stream->signal)) {
		dp_set_dsc_enable(pipe_ctx, false);
	}
#endif
}

void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
@@ -2851,6 +2894,14 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
	uint32_t bits_per_channel = 0;
	uint32_t kbps;

#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
	if (timing->flags.DSC) {
		kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel);
		kbps = kbps / 160 + ((kbps % 160) ? 1 : 0);
		return kbps;
	}
#endif

	switch (timing->display_color_depth) {
	case COLOR_DEPTH_666:
		bits_per_channel = 6;
Loading