diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0518-drm-amd-display-RV-stereo-support.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/0518-drm-amd-display-RV-stereo-support.patch | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0518-drm-amd-display-RV-stereo-support.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0518-drm-amd-display-RV-stereo-support.patch new file mode 100644 index 00000000..dd9b4109 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0518-drm-amd-display-RV-stereo-support.patch @@ -0,0 +1,288 @@ +From dbda423f8d1f7e95b419236a28045cd9207ad2e7 Mon Sep 17 00:00:00 2001 +From: Vitaly Prosyak <vitaly.prosyak@amd.com> +Date: Thu, 8 Jun 2017 15:55:02 -0500 +Subject: [PATCH 0518/4131] drm/amd/display: RV stereo support + +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> +--- + 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 ++--- + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 6 ++ + .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 69 +++++++++++++++++++++- + .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 4 -- + .../amd/display/dc/dcn10/dcn10_timing_generator.c | 2 - + 7 files changed, 105 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +index 66f0595..2b62efc 100644 +--- 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]; +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 47870a6..e518aed 100644 +--- 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}", +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index 73d04ef..a4c8c43 100644 +--- 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 pipe_ctx *pipe_ctx) + 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_ctx *pipe_ctx, struct view *recout_skip + /* 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_ctx *pipe_ctx, struct view *recout_skip + } + } 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(struct pipe_ctx *pipe_ctx) + 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; +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 616533e..ac99d28 100644 +--- 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 *pipe_ctx) + 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 dce110_funcs = { + .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) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index f412300..edcd736 100644 +--- 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_stereo( + 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 dcn10_funcs = { + .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 + }; + + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +index a227680..77fc251 100644 +--- 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) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c +index bc3934d..83efbec 100644 +--- 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 +-- +2.7.4 + |