From 5ec43eda85506ddc2f91c3a4e28b38da3f14cf1e Mon Sep 17 00:00:00 2001 From: Martin Leung Date: Wed, 17 Jul 2019 16:08:19 -0400 Subject: drm/amd/display: enabling seamless boot sequence for dcn2 [Why] Seamless boot (building SW state inheriting BIOS-initialized timing) was enabled on DCN2, including fixes [How] Includes fixes for MPC, DPPCLK, and DIG FE mapping/OTG source select/ Pixel clock. This is part 2 of 2 for seamless boot NV10 Signed-off-by: Martin Leung Reviewed-by: Jun Lei Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 26 +++++++++++---- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 13 +++++++- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 39 ++++++++++++++--------- 3 files changed, 56 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/amd/display/dc/core') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f61eb296542a..760384561180 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -960,7 +960,7 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, { struct timing_generator *tg; struct dc_link *link = sink->link; - unsigned int inst; + unsigned int enc_inst, tg_inst; /* Check for enabled DIG to identify enabled display */ if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) @@ -972,13 +972,22 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, * current implementation always map 1-to-1, so this code makes * the same assumption and doesn't check OTG source. */ - inst = link->link_enc->funcs->get_dig_frontend(link->link_enc) - 1; + enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); /* Instance should be within the range of the pool */ - if (inst >= dc->res_pool->pipe_count) + if (enc_inst >= dc->res_pool->pipe_count) return false; - tg = dc->res_pool->timing_generators[inst]; + if (enc_inst >= dc->res_pool->stream_enc_count) + return false; + + tg_inst = dc->res_pool->stream_enc[enc_inst]->funcs->dig_source_otg( + dc->res_pool->stream_enc[enc_inst]); + + if (tg_inst >= dc->res_pool->timing_generator_count) + return false; + + tg = dc->res_pool->timing_generators[tg_inst]; if (!tg->funcs->is_matching_timing) return false; @@ -991,10 +1000,11 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz( dc->res_pool->dp_clock_source, - inst, &pix_clk_100hz); + tg_inst, &pix_clk_100hz); if (crtc_timing->pix_clk_100hz != pix_clk_100hz) return false; + } return true; @@ -1904,13 +1914,17 @@ static void commit_planes_do_stream_update(struct dc *dc, if (stream_update->dpms_off) { dc->hwss.pipe_control_lock(dc, pipe_ctx, true); + if (*stream_update->dpms_off) { core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE); dc->hwss.optimize_bandwidth(dc, dc->current_state); } else { - dc->hwss.prepare_bandwidth(dc, dc->current_state); + if (!dc->optimize_seamless_boot) + dc->hwss.prepare_bandwidth(dc, dc->current_state); + core_link_enable_stream(dc->current_state, pipe_ctx); } + dc->hwss.pipe_control_lock(dc, pipe_ctx, false); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 0a66a6f21f58..892542d28c46 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1421,6 +1421,16 @@ static enum dc_status enable_link_dp( #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT bool fec_enable; #endif + int i; + bool apply_seamless_boot_optimization = false; + + // check for seamless boot + for (i = 0; i < state->stream_count; i++) { + if (state->streams[i]->apply_seamless_boot_optimization) { + apply_seamless_boot_optimization = true; + break; + } + } /* get link settings for video mode timing */ decide_link_settings(stream, &link_settings); @@ -1442,7 +1452,8 @@ static enum dc_status enable_link_dp( pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; - state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); + if (!apply_seamless_boot_optimization) + state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); dp_enable_link_phy( link, 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 5956e70f573f..97e992e30d1a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1893,7 +1893,7 @@ static int acquire_resource_from_hw_enabled_state( struct dc_stream_state *stream) { struct dc_link *link = stream->link; - unsigned int inst; + unsigned int inst, tg_inst; /* Check for enabled DIG to identify enabled display */ if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) @@ -1905,28 +1905,37 @@ static int acquire_resource_from_hw_enabled_state( * current implementation always map 1-to-1, so this code makes * the same assumption and doesn't check OTG source. */ - inst = link->link_enc->funcs->get_dig_frontend(link->link_enc) - 1; + inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); /* Instance should be within the range of the pool */ if (inst >= pool->pipe_count) return -1; - if (!res_ctx->pipe_ctx[inst].stream) { - struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[inst]; + if (inst >= pool->stream_enc_count) + return -1; + + tg_inst = pool->stream_enc[inst]->funcs->dig_source_otg(pool->stream_enc[inst]); + + if (tg_inst >= pool->timing_generator_count) + return false; + + if (!res_ctx->pipe_ctx[tg_inst].stream) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[tg_inst]; + + pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst]; + pipe_ctx->plane_res.mi = pool->mis[tg_inst]; + pipe_ctx->plane_res.hubp = pool->hubps[tg_inst]; + pipe_ctx->plane_res.ipp = pool->ipps[tg_inst]; + pipe_ctx->plane_res.xfm = pool->transforms[tg_inst]; + pipe_ctx->plane_res.dpp = pool->dpps[tg_inst]; + pipe_ctx->stream_res.opp = pool->opps[tg_inst]; - pipe_ctx->stream_res.tg = pool->timing_generators[inst]; - pipe_ctx->plane_res.mi = pool->mis[inst]; - pipe_ctx->plane_res.hubp = pool->hubps[inst]; - pipe_ctx->plane_res.ipp = pool->ipps[inst]; - pipe_ctx->plane_res.xfm = pool->transforms[inst]; - pipe_ctx->plane_res.dpp = pool->dpps[inst]; - pipe_ctx->stream_res.opp = pool->opps[inst]; - if (pool->dpps[inst]) - pipe_ctx->plane_res.mpcc_inst = pool->dpps[inst]->inst; - pipe_ctx->pipe_idx = inst; + if (pool->dpps[tg_inst]) + pipe_ctx->plane_res.mpcc_inst = pool->dpps[tg_inst]->inst; + pipe_ctx->pipe_idx = tg_inst; pipe_ctx->stream = stream; - return inst; + return tg_inst; } return -1; -- cgit v1.2.3