From 660c54dae5f3de13f4a4ed6232575f3c598a5a6a Mon Sep 17 00:00:00 2001 From: Anthony Koo 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 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);*/ -- 2.7.4