diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch b/common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch new file mode 100644 index 00000000..294bd40e --- /dev/null +++ b/common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch @@ -0,0 +1,152 @@ +From 660c54dae5f3de13f4a4ed6232575f3c598a5a6a Mon Sep 17 00:00:00 2001 +From: Anthony Koo <Anthony.Koo@amd.com> +Date: Wed, 20 Jan 2016 18:16:03 -0500 +Subject: [PATCH 0725/1110] drm/amd/dal: Fix issue with pipe powergating + sequence + +[Description] +It looks like pipe powergating was previously never working +properly and pipe0 was mostly always forced on. +After fixing the pipe powergating we find severe underflow +issues that is caused by bad sequence. + +We need to unpowergate the pipe early, before we program +watermarks. + +Signed-off-by: Anthony Koo <Anthony.Koo@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/dal/dc/core/dc_target.c | 46 +++++++++++++++++++--- + .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 21 ++++++++-- + 2 files changed, 58 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +index a71034c..7f4f2f3 100644 +--- a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c ++++ b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +@@ -193,6 +193,34 @@ gamma_param_fail: + return result; + } + ++static bool validate_surface_address( ++ struct dc_plane_address address) ++{ ++ bool is_valid_address = false; ++ ++ switch (address.type) { ++ case PLN_ADDR_TYPE_GRAPHICS: ++ if (address.grph.addr.quad_part != 0) ++ is_valid_address = true; ++ break; ++ case PLN_ADDR_TYPE_GRPH_STEREO: ++ if ((address.grph_stereo.left_addr.quad_part != 0) && ++ (address.grph_stereo.right_addr.quad_part != 0)) { ++ is_valid_address = true; ++ } ++ break; ++ case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: ++ case PLN_ADDR_TYPE_VIDEO_INTERLACED: ++ case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE_STEREO: ++ case PLN_ADDR_TYPE_VIDEO_INTERLACED_STEREO: ++ default: ++ /* not supported */ ++ BREAK_TO_DEBUGGER(); ++ } ++ ++ return is_valid_address; ++} ++ + bool dc_commit_surfaces_to_target( + struct dc *dc, + struct dc_surface *new_surfaces[], +@@ -200,12 +228,17 @@ bool dc_commit_surfaces_to_target( + struct dc_target *dc_target) + + { +- uint8_t i, j; ++ int i, j; + uint32_t prev_disp_clk = dc->current_context.bw_results.dispclk_khz; + struct core_target *target = DC_TARGET_TO_CORE(dc_target); + +- bool current_enabled_surface_count = 0; +- bool new_enabled_surface_count = 0; ++ int current_enabled_surface_count = 0; ++ int new_enabled_surface_count = 0; ++ ++ if (!dal_adapter_service_is_in_accelerated_mode( ++ dc->res_pool.adapter_srv)) { ++ return false; ++ } + + for (i = 0; i < target->status.surface_count; i++) + if (target->status.surfaces[i]->visible) +@@ -218,7 +251,7 @@ bool dc_commit_surfaces_to_target( + dal_logger_write(dc->ctx->logger, + LOG_MAJOR_INTERFACE_TRACE, + LOG_MINOR_COMPONENT_DC, +- "%s: commit %d surfaces to target 0x%x", ++ "%s: commit %d surfaces to target 0x%x\n", + __func__, + new_surface_count, + dc_target); +@@ -254,6 +287,8 @@ bool dc_commit_surfaces_to_target( + for (i = 0; i < new_surface_count; i++) { + struct dc_surface *surface = new_surfaces[i]; + struct core_surface *core_surface = DC_SURFACE_TO_CORE(surface); ++ bool is_valid_address = ++ validate_surface_address(surface->address); + + dal_logger_write(dc->ctx->logger, + LOG_MAJOR_INTERFACE_TRACE, +@@ -269,7 +304,8 @@ bool dc_commit_surfaces_to_target( + core_surface, + target); + +- dc->hwss.update_plane_address(core_surface, target); ++ if (is_valid_address) ++ dc->hwss.update_plane_address(core_surface, target); + } + + if (current_enabled_surface_count == 0 && new_enabled_surface_count > 0) +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +index 0eafe16..674e795 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +@@ -797,10 +797,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + context->res_ctx.pool.adapter_srv); + + if (timing_changed) { +- dce110_enable_display_power_gating( +- stream->ctx, controller_idx, dcb, +- PIPE_GATING_CONTROL_DISABLE); +- + /* Must blank CRTC after disabling power gating and before any + * programming, otherwise CRTC will be hung in bad state + */ +@@ -1280,6 +1276,23 @@ static enum dc_status apply_ctx_to_hw( + + update_bios_scratch_critical_state(context->res_ctx.pool.adapter_srv, + true); ++ ++ for (i = 0; i < pool->controller_count; i++) { ++ struct controller_ctx *ctlr_ctx ++ = &context->res_ctx.controller_ctx[i]; ++ struct dc_bios *dcb; ++ ++ if (ctlr_ctx->flags.unchanged || !ctlr_ctx->stream) ++ continue; ++ ++ dcb = dal_adapter_service_get_bios_parser( ++ context->res_ctx.pool.adapter_srv); ++ ++ dce110_enable_display_power_gating( ++ dc->ctx, i, dcb, ++ PIPE_GATING_CONTROL_DISABLE); ++ } ++ + set_safe_displaymarks(context); + /*TODO: when pplib works*/ + /*dc_set_clocks_and_clock_state(context);*/ +-- +2.7.4 + |