From 7f5c22d1652327b64375e88b184b0df502c7bdc7 Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Thu, 8 Jun 2017 15:55:02 -0500 Subject: [PATCH] drm/amd/display: RV stereo support HDMI frame pack and DP frame alternate in band Signed-off-by: Vitaly Prosyak Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 25 +++++++ .../gpu/drm/amd/display/dc/core/dc_resource.c | 14 ++-- .../display/dc/dce110/dce110_hw_sequencer.c | 6 ++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 69 ++++++++++++++++++- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 4 -- .../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 66f0595a4c20..2b62efce73c5 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 47870a640f37..e518aeddfa58 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 c51ec617eff7..90eb839f5414 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 616533e25534..ac99d283bf0a 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 f41230013309..edcd7369cf9d 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 a2276803c0d0..77fc251d45ba 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 bc3934d75b46..83efbec77357 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.30.2