aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0725-drm-amd-dal-Fix-issue-with-pipe-powergating-sequence.patch
diff options
context:
space:
mode:
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.patch152
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
+