Blob Blame History Raw
From: Vitaly Prosyak <vitaly.prosyak@amd.com>
Date: Thu, 8 Jun 2017 15:55:02 -0500
Subject: drm/amd/display: RV stereo support
Git-commit: 7f5c22d1652327b64375e88b184b0df502c7bdc7
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

HDMI frame pack and DP frame alternate in band

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c              |    4 
 drivers/gpu/drm/amd/display/dc/core/dc.c                      |   25 +++
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c             |   14 +-
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c   |    6 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c     |   69 +++++++++-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c         |    4 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c |    2 
 7 files changed, 105 insertions(+), 19 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -972,9 +972,7 @@ bool dcn_validate_bandwidth(
 			if (pipe->surface) {
 				struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
 
-				if (v->dpp_per_plane[input_idx] == 2 ||
-						(pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
-						 pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE)) {
+				if (v->dpp_per_plane[input_idx] == 2) {
 					if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) {
 						/* update previously split pipe */
 						hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -832,6 +832,30 @@ static bool streams_changed(
 	return false;
 }
 
+bool dc_enable_stereo(
+	struct dc *dc,
+	struct validate_context *context,
+	const struct dc_stream *streams[],
+	uint8_t stream_count)
+{
+	bool ret = true;
+	int i, j;
+	struct pipe_ctx *pipe;
+	struct core_dc *core_dc = DC_TO_CORE(dc);
+	for (i = 0; i < MAX_PIPES; i++) {
+		if (context != NULL)
+			pipe = &context->res_ctx.pipe_ctx[i];
+		else
+			pipe = &core_dc->current_context->res_ctx.pipe_ctx[i];
+		for (j = 0 ; pipe && j < stream_count; j++)  {
+			if (streams[j] && streams[j] == &pipe->stream->public &&
+				core_dc->hwss.setup_stereo)
+				core_dc->hwss.setup_stereo(pipe, core_dc);
+		}
+	}
+	return ret;
+}
+
 bool dc_commit_streams(
 	struct dc *dc,
 	const struct dc_stream *streams[],
@@ -903,6 +927,7 @@ bool dc_commit_streams(
 					DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
 
 			core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
+			dc_enable_stereo(dc, context, streams, stream_count);
 		}
 
 		CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -440,8 +440,8 @@ static void calculate_viewport(struct pi
 	bool sec_split = pipe_ctx->top_pipe &&
 			pipe_ctx->top_pipe->surface == pipe_ctx->surface;
 
-	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE ||
-		stream->timing.timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM) {
+	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
+		stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
 		pri_split = false;
 		sec_split = false;
 	}
@@ -568,8 +568,7 @@ static void calculate_recout(struct pipe
 	/* Handle h & vsplit */
 	if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->surface ==
 		pipe_ctx->surface) {
-		if (stream->public.timing.timing_3d_format ==
-			TIMING_3D_FORMAT_TOP_AND_BOTTOM) {
+		if (stream->public.view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
 			pipe_ctx->scl_data.recout.height /= 2;
 			pipe_ctx->scl_data.recout.y += pipe_ctx->scl_data.recout.height;
 			/* Floor primary pipe, ceil 2ndary pipe */
@@ -581,8 +580,7 @@ static void calculate_recout(struct pipe
 		}
 	} else if (pipe_ctx->bottom_pipe &&
 			pipe_ctx->bottom_pipe->surface == pipe_ctx->surface) {
-		if (stream->public.timing.timing_3d_format ==
-			TIMING_3D_FORMAT_TOP_AND_BOTTOM)
+		if (stream->public.view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
 			pipe_ctx->scl_data.recout.height /= 2;
 		else
 			pipe_ctx->scl_data.recout.width /= 2;
@@ -626,7 +624,7 @@ static void calculate_scaling_ratios(str
 					surf_src.height,
 					surface->dst_rect.height);
 
-	if (surface->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE)
+	if (stream->public.view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
 		pipe_ctx->scl_data.ratios.horz.value *= 2;
 	else if (surface->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM)
 		pipe_ctx->scl_data.ratios.vert.value *= 2;
@@ -1772,6 +1770,8 @@ static void set_vendor_info_packet(
 	enum dc_timing_3d_format format;
 
 	format = stream->public.timing.timing_3d_format;
+	if (stream->public.view_format == VIEW_3D_FORMAT_NONE)
+		format = TIMING_3D_FORMAT_NONE;
 
 	/* Can be different depending on packet content */
 	length = 5;
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -2057,6 +2057,11 @@ void dce110_update_pending_status(struct
 		pipe_ctx->mi->current_address = pipe_ctx->mi->request_address;
 
 	surface->status.current_address = pipe_ctx->mi->current_address;
+	if (pipe_ctx->mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+			pipe_ctx->tg->funcs->is_stereo_left_eye) {
+		surface->status.is_right_eye =\
+				!pipe_ctx->tg->funcs->is_stereo_left_eye(pipe_ctx->tg);
+	}
 }
 
 void dce110_power_down(struct core_dc *dc)
@@ -2576,6 +2581,7 @@ static const struct hw_sequencer_funcs d
 	.set_static_screen_control = set_static_screen_control,
 	.reset_hw_ctx_wrap = reset_hw_ctx_wrap,
 	.prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg,
+	.setup_stereo = NULL
 };
 
 bool dce110_hw_sequencer_construct(struct core_dc *dc)
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -896,8 +896,9 @@ static void reset_hw_ctx_wrap(
 	reset_hw_ctx(dc, context, reset_back_end_for_pipe);
 }
 
-static bool patch_address_for_sbs_tb_stereo(
-		struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
+
+static bool patch_address_for_sbs_tb_stereo(struct pipe_ctx *pipe_ctx,
+											PHYSICAL_ADDRESS_LOC *addr)
 {
 	struct core_surface *surface = pipe_ctx->surface;
 	bool sec_split = pipe_ctx->top_pipe &&
@@ -912,6 +913,7 @@ static bool patch_address_for_sbs_tb_ste
 		surface->public.address.grph_stereo.right_addr;
 		return true;
 	}
+
 	return false;
 }
 
@@ -2061,6 +2063,66 @@ static void set_plane_config(
 	program_gamut_remap(pipe_ctx);
 }
 
+static void dcn10_config_stereo_parameters(struct core_stream *stream,\
+										   struct crtc_stereo_flags *flags)
+{
+	enum view_3d_format view_format = stream->public.view_format;
+	enum dc_timing_3d_format timing_3d_format =\
+			stream->public.timing.timing_3d_format;
+	bool non_stereo_timing = false;
+
+	if (timing_3d_format == TIMING_3D_FORMAT_NONE ||
+		timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE ||
+		timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM)
+		non_stereo_timing = true;
+
+	if (non_stereo_timing == false &&
+		view_format == VIEW_3D_FORMAT_FRAME_SEQUENTIAL) {
+
+		flags->PROGRAM_STEREO         = 1;
+		flags->PROGRAM_POLARITY       = 1;
+		if (timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
+			timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
+			timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+			enum display_dongle_type dongle = \
+					stream->sink->link->public.ddc->dongle_type;
+			if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
+				dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
+				dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
+				flags->DISABLE_STEREO_DP_SYNC = 1;
+		}
+		flags->RIGHT_EYE_POLARITY =\
+				stream->public.timing.flags.RIGHT_EYE_3D_POLARITY;
+		if (timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+			flags->FRAME_PACKED = 1;
+	}
+
+	return;
+}
+
+static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx,
+								struct core_dc *dc)
+{
+	struct crtc_stereo_flags flags = { 0 };
+	struct core_stream *stream = pipe_ctx->stream;
+
+	dcn10_config_stereo_parameters(stream, &flags);
+
+	pipe_ctx->opp->funcs->opp_set_stereo_polarity(
+		pipe_ctx->opp,
+		flags.PROGRAM_STEREO == 1 ? true:false,
+		stream->public.timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
+
+	pipe_ctx->tg->funcs->program_stereo(
+		pipe_ctx->tg,
+		&stream->public.timing,
+		&flags);
+
+
+
+	return;
+}
+
 static const struct hw_sequencer_funcs dcn10_funcs = {
 	.program_gamut_remap = program_gamut_remap,
 	.init_hw = init_hw,
@@ -2088,7 +2150,8 @@ static const struct hw_sequencer_funcs d
 	.prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg,
 	.set_drr = set_drr,
 	.get_position = get_position,
-	.set_static_screen_control = set_static_screen_control
+	.set_static_screen_control = set_static_screen_control,
+	.setup_stereo = dcn10_setup_stereo
 };
 
 
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -821,10 +821,6 @@ static void get_pixel_clock_parameters(
 	if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
 		pixel_clk_params->requested_pix_clk  /= 2;
 
-	if (stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING ||
-		stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_SW_FRAME_PACKING ||
-		stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA)
-		pixel_clk_params->requested_pix_clk *= 2;
 }
 
 static void build_clamping_params(struct core_stream *stream)
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
@@ -271,8 +271,6 @@ static void tg_program_timing_generator(
 	REG_UPDATE(OTG_H_TIMING_CNTL,
 			OTG_H_TIMING_DIV_BY2, h_div_2);
 
-	dcn10_disable_stereo( tg);
-
 }
 
 /** tg_program_blanking