diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 01530e686f43..abcb06044e6e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -611,7 +611,6 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) pipe_ctx->pipe_idx); } -#if defined(CONFIG_DRM_AMD_DC_DCN3_0) static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, int opp_cnt) { @@ -634,7 +633,6 @@ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, return flow_ctrl_cnt; } -#endif enum dc_status dcn20_enable_stream_timing( struct pipe_ctx *pipe_ctx, @@ -648,16 +646,12 @@ enum dc_status dcn20_enable_stream_timing( struct pipe_ctx *odm_pipe; int opp_cnt = 1; int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst }; - -#if defined(CONFIG_DRM_AMD_DC_DCN3_0) bool interlace = stream->timing.flags.INTERLACE; int i; - struct mpc_dwb_flow_control flow_control; struct mpc *mpc = dc->res_pool->mpc; bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing)); -#endif /* by upper caller loop, pipe0 is parent pipe and be called first. * back end is set up by for pipe0. Other children pipe share back end * with pipe 0. No program is needed. @@ -704,7 +698,6 @@ enum dc_status dcn20_enable_stream_timing( pipe_ctx->stream->signal, true); -#if defined(CONFIG_DRM_AMD_DC_DCN3_0) rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; flow_control.flow_ctrl_mode = 0; flow_control.flow_ctrl_cnt0 = 0x80; @@ -718,7 +711,7 @@ enum dc_status dcn20_enable_stream_timing( &flow_control); } } -#endif + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( odm_pipe->stream_res.opp, @@ -1030,8 +1023,8 @@ void dcn20_blank_pixel_data( test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; } - stream_res->opp->funcs->opp_set_disp_pattern_generator( - stream_res->opp, + dc->hwss.set_disp_pattern_generator(dc, + pipe_ctx, test_pattern, test_pattern_color_space, stream->timing.display_color_depth, @@ -1041,8 +1034,8 @@ void dcn20_blank_pixel_data( 0); for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { - odm_pipe->stream_res.opp->funcs->opp_set_disp_pattern_generator( - odm_pipe->stream_res.opp, + dc->hwss.set_disp_pattern_generator(dc, + odm_pipe, dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, test_pattern_color_space, @@ -1158,6 +1151,7 @@ void dcn20_pipe_control_lock( struct pipe_ctx *pipe, bool lock) { + struct pipe_ctx *temp_pipe; bool flip_immediate = false; /* use TG master update lock to lock everything on the TG @@ -1169,33 +1163,57 @@ void dcn20_pipe_control_lock( if (pipe->plane_state != NULL) flip_immediate = pipe->plane_state->flip_immediate; + if (pipe->stream_res.gsl_group > 0) { + temp_pipe = pipe->bottom_pipe; + while (!flip_immediate && temp_pipe) { + if (temp_pipe->plane_state != NULL) + flip_immediate = temp_pipe->plane_state->flip_immediate; + temp_pipe = temp_pipe->bottom_pipe; + } + } + if (flip_immediate && lock) { const int TIMEOUT_FOR_FLIP_PENDING = 100000; int i; - for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { - if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp)) - break; - udelay(1); - } - - if (pipe->bottom_pipe != NULL) { - for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { - if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp)) - break; - udelay(1); + temp_pipe = pipe; + while (temp_pipe) { + if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate) { + for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { + if (!temp_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(temp_pipe->plane_res.hubp)) + break; + udelay(1); + } + + /* no reason it should take this long for immediate flips */ + ASSERT(i != TIMEOUT_FOR_FLIP_PENDING); } + temp_pipe = temp_pipe->bottom_pipe; } } /* In flip immediate and pipe splitting case, we need to use GSL * for synchronization. Only do setup on locking and on flip type change. */ - if (lock && pipe->bottom_pipe != NULL) + if (lock && (pipe->bottom_pipe != NULL || !flip_immediate)) if ((flip_immediate && pipe->stream_res.gsl_group == 0) || (!flip_immediate && pipe->stream_res.gsl_group > 0)) dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate); + if (pipe->plane_state != NULL) + flip_immediate = pipe->plane_state->flip_immediate; + + temp_pipe = pipe->bottom_pipe; + while (flip_immediate && temp_pipe) { + if (temp_pipe->plane_state != NULL) + flip_immediate = temp_pipe->plane_state->flip_immediate; + temp_pipe = temp_pipe->bottom_pipe; + } + + if (!lock && pipe->stream_res.gsl_group > 0 && pipe->plane_state && + !flip_immediate) + dcn20_setup_gsl_group_as_lock(dc, pipe, false); + if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) { union dmub_hw_lock_flags hw_locks = { 0 }; struct dmub_hw_lock_inst_flags inst_flags = { 0 }; @@ -1478,7 +1496,6 @@ static void dcn20_update_dchubp_dpp( if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed || pipe_ctx->stream->update_flags.bits.gamut_remap || pipe_ctx->stream->update_flags.bits.out_csc) { -#if defined(CONFIG_DRM_AMD_DC_DCN3_0) struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; if (mpc->funcs->set_gamut_remap) { @@ -1509,7 +1526,6 @@ static void dcn20_update_dchubp_dpp( } mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); } else -#endif /* dpp/cm gamut remap*/ dc->hwss.program_gamut_remap(pipe_ctx); @@ -1679,6 +1695,15 @@ void dcn20_program_front_end_for_ctx( && context->res_ctx.pipe_ctx[i].stream) hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true); + /* wait for outstanding pending changes before adding or removing planes */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable || + context->res_ctx.pipe_ctx[i].update_flags.bits.enable) { + dc->hwss.wait_for_pending_cleared(dc, context); + break; + } + } + /* Disconnect mpcc */ for (i = 0; i < dc->res_pool->pipe_count; i++) if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable @@ -2034,6 +2059,8 @@ static bool patch_address_for_sbs_tb_stereo( plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; plane_state->address.grph_stereo.right_addr = plane_state->address.grph_stereo.left_addr; + plane_state->address.grph_stereo.right_meta_addr = + plane_state->address.grph_stereo.left_meta_addr; } return false; } @@ -2282,11 +2309,9 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) blnd_cfg.bottom_inside_gain = 0x1f000; blnd_cfg.bottom_outside_gain = 0x1f000; blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; -#if defined(CONFIG_DRM_AMD_DC_DCN3_0) if (pipe_ctx->plane_state->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA) blnd_cfg.pre_multiplied_alpha = false; -#endif /* * TODO: remove hack @@ -2545,3 +2570,15 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, return true; } #endif + +void dcn20_set_disp_pattern_generator(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + enum controller_dp_test_pattern test_pattern, + enum controller_dp_color_space color_space, + enum dc_color_depth color_depth, + const struct tg_color *solid_color, + int width, int height, int offset) +{ + pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern, + color_space, color_depth, solid_color, width, height, offset); +}
\ No newline at end of file |