From 30bd5bd9ed09f7524c7cc19edea0d1279c6017e7 Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Wed, 20 Jan 2016 18:16:03 -0500 Subject: [PATCH 1291/1565] 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. Change-Id: I734e82f7504d3a56eaf4b347c624567d0a7195e6 Signed-off-by: Anthony Koo Acked-by: Harry Wentland --- 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);*/ -- 1.9.1