diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0580-drm-amd-dal-Fix-issue-where-unused-HW-is-not-powered.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0580-drm-amd-dal-Fix-issue-where-unused-HW-is-not-powered.patch | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0580-drm-amd-dal-Fix-issue-where-unused-HW-is-not-powered.patch b/common/recipes-kernel/linux/files/0580-drm-amd-dal-Fix-issue-where-unused-HW-is-not-powered.patch new file mode 100644 index 00000000..605db313 --- /dev/null +++ b/common/recipes-kernel/linux/files/0580-drm-amd-dal-Fix-issue-where-unused-HW-is-not-powered.patch @@ -0,0 +1,278 @@ +From a174d4b05bfe7554d77c1c3be0ad56fbbb8b2fd9 Mon Sep 17 00:00:00 2001 +From: Anthony Koo <Anthony.Koo@amd.com> +Date: Sat, 5 Dec 2015 01:57:27 -0500 +Subject: [PATCH 0580/1110] drm/amd/dal: Fix issue where unused HW is not + powered down after boot + +[Description] +init_hw is called on dc create and on set power state call, +but what appears incorrect is that it is setting accelerated +mode bit in scratch register. + +We actually expect accelerated mode bit to be set on first commit, +when we actually enter accelerated mode. Entering accelerated +mode actually involves a handoff between VBIOS controlled +programming of display pipe to Driver control. During this process, +we want to init and power down all existing HW. + +Power down of HW in enter accelerated mode was also not very +correct, since it currently takes the first commit context. But what +we really wanted to do is power everything off. + +Finally, we need to do power gate of pipe when unused, but also +ungate when enabling the pipe. + +Signed-off-by: Harry Wentland <harry.wentland@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/dal/dc/core/dc.c | 6 +- + .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 97 +++++++++++----------- + drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h | 4 +- + 3 files changed, 53 insertions(+), 54 deletions(-) + +diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c +index 50505f4..7fc9f17 100644 +--- a/drivers/gpu/drm/amd/dal/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c +@@ -167,8 +167,6 @@ static void init_hw(struct dc *dc) + dc->hwss.encoder_power_up(link->link_enc); + } + +- dal_bios_parser_set_scratch_acc_mode_change(bp); +- + for(i = 0; i < dc->res_pool.controller_count; i++) { + struct timing_generator *tg = dc->res_pool.timing_generators[i]; + +@@ -653,7 +651,7 @@ bool dc_commit_targets( + + if (!dal_adapter_service_is_in_accelerated_mode( + dc->res_pool.adapter_srv)) { +- dc->hwss.enable_accelerated_mode(context); ++ dc->hwss.enable_accelerated_mode(dc); + } + + for (i = 0; i < dc->current_context.target_count; i++) { +@@ -859,7 +857,7 @@ void dc_set_power_state( + /* NULL means "reset/release all DC targets" */ + dc_commit_targets(dc, NULL, 0); + +- dc->hwss.power_down(&dc->current_context); ++ dc->hwss.power_down(dc); + break; + } + +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 81935e5..edbf3ce 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 +@@ -785,8 +785,21 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + bool timing_changed = context->res_ctx.controller_ctx[controller_idx] + .flags.timing_changed; + enum color_space color_space; ++ struct bios_parser *bp; ++ ++ bp = dal_adapter_service_get_bios_parser( ++ context->res_ctx.pool.adapter_srv); + + if (timing_changed) { ++ dce110_enable_display_power_gating( ++ stream->ctx, controller_idx, bp, ++ PIPE_GATING_CONTROL_DISABLE); ++ ++ /* Must blank CRTC after disabling power gating and before any ++ * programming, otherwise CRTC will be hung in bad state ++ */ ++ dce110_timing_generator_blank_crtc(stream->tg); ++ + core_link_disable_stream( + stream->sink->link, stream); + +@@ -898,47 +911,34 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + + /******************************************************************************/ + +-static void power_down_encoders(struct validate_context *context) ++static void power_down_encoders(struct dc *dc) + { + int i; +- struct core_target *target; +- struct core_stream *stream; + +- for (i = 0; i < context->target_count; i++) { +- target = context->targets[i]; +- stream = DC_STREAM_TO_CORE(target->public.streams[0]); +- +- core_link_disable_stream(stream->sink->link, stream); ++ for (i = 0; i < dc->link_count; i++) { ++ dce110_link_encoder_disable_output( ++ dc->links[i]->link_enc, SIGNAL_TYPE_NONE); + } + } + +-static void power_down_controllers(struct validate_context *context) ++static void power_down_controllers(struct dc *dc) + { + int i; +- struct core_target *target; +- struct core_stream *stream; +- +- for (i = 0; i < context->target_count; i++) { +- target = context->targets[i]; +- stream = DC_STREAM_TO_CORE(target->public.streams[0]); + +- dce110_timing_generator_disable_crtc(stream->tg); ++ for (i = 0; i < dc->res_pool.controller_count; i++) { ++ dce110_timing_generator_disable_crtc( ++ dc->res_pool.timing_generators[i]); + } + } + +-static void power_down_clock_sources(struct validate_context *context) ++static void power_down_clock_sources(struct dc *dc) + { + int i; +- struct core_target *target; +- struct core_stream *stream; +- +- for (i = 0; i < context->target_count; i++) { +- target = context->targets[i]; +- stream = DC_STREAM_TO_CORE(target->public.streams[0]); + ++ for (i = 0; i < dc->res_pool.clk_src_count; i++) { + if (false == dal_clock_source_power_down_pll( +- stream->clock_source, +- stream->controller_idx + 1)) { ++ dc->res_pool.clock_sources[i], ++ i+1)) { + dal_error( + "Failed to power down pll! (clk src index=%d)\n", + i); +@@ -946,35 +946,29 @@ static void power_down_clock_sources(struct validate_context *context) + } + } + +-static void power_down_all_hw_blocks(struct validate_context *context) ++static void power_down_all_hw_blocks(struct dc *dc) + { +- power_down_encoders(context); ++ power_down_encoders(dc); + +- power_down_controllers(context); ++ power_down_controllers(dc); + +- power_down_clock_sources(context); ++ power_down_clock_sources(dc); + } + + static void disable_vga_and_power_gate_all_controllers( +- struct validate_context *context) ++ struct dc *dc) + { + int i; +- struct core_target *target; +- struct core_stream *stream; + struct timing_generator *tg; + struct bios_parser *bp; + struct dc_context *ctx; +- uint8_t controller_id; + + bp = dal_adapter_service_get_bios_parser( +- context->res_ctx.pool.adapter_srv); ++ dc->res_pool.adapter_srv); + +- for (i = 0; i < context->target_count; i++) { +- target = context->targets[i]; +- stream = DC_STREAM_TO_CORE(target->public.streams[0]); +- tg = stream->tg; +- ctx = stream->ctx; +- controller_id = stream->controller_idx; ++ for (i = 0; i < dc->res_pool.controller_count; i++) { ++ tg = dc->res_pool.timing_generators[i]; ++ ctx = dc->ctx; + + dce110_timing_generator_disable_vga(tg); + +@@ -982,7 +976,7 @@ static void disable_vga_and_power_gate_all_controllers( + * powergating. */ + dce110_enable_display_pipe_clock_gating(ctx, + true); +- dce110_enable_display_power_gating(ctx, controller_id, bp, ++ dce110_enable_display_power_gating(ctx, i+1, bp, + PIPE_GATING_CONTROL_ENABLE); + } + } +@@ -994,16 +988,16 @@ static void disable_vga_and_power_gate_all_controllers( + * 3. Enable power gating for controller + * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) + */ +-static void enable_accelerated_mode(struct validate_context *context) ++static void enable_accelerated_mode(struct dc *dc) + { + struct bios_parser *bp; + + bp = dal_adapter_service_get_bios_parser( +- context->res_ctx.pool.adapter_srv); ++ dc->res_pool.adapter_srv); + +- power_down_all_hw_blocks(context); ++ power_down_all_hw_blocks(dc); + +- disable_vga_and_power_gate_all_controllers(context); ++ disable_vga_and_power_gate_all_controllers(dc); + + dal_bios_parser_set_scratch_acc_mode_change(bp); + } +@@ -1565,6 +1559,10 @@ static bool update_plane_address( + static void reset_single_stream_hw_ctx(struct core_stream *stream, + struct validate_context *context) + { ++ struct bios_parser *bp; ++ ++ bp = dal_adapter_service_get_bios_parser( ++ context->res_ctx.pool.adapter_srv); + if (stream->audio) { + dal_audio_disable_output(stream->audio, + stream->stream_enc->id, +@@ -1580,6 +1578,9 @@ static void reset_single_stream_hw_ctx(struct core_stream *stream, + dce110_transform_set_scaler_bypass(stream->xfm); + disable_stereo_mixer(stream->ctx); + unreference_clock_source(&context->res_ctx, stream->clock_source); ++ dce110_enable_display_power_gating( ++ stream->ctx, stream->controller_idx, bp, ++ PIPE_GATING_CONTROL_ENABLE); + } + + static void reset_hw_ctx(struct dc *dc, +@@ -1604,10 +1605,10 @@ static void reset_hw_ctx(struct dc *dc, + } + } + +-static void power_down(struct validate_context *context) ++static void power_down(struct dc *dc) + { +- power_down_all_hw_blocks(context); +- disable_vga_and_power_gate_all_controllers(context); ++ power_down_all_hw_blocks(dc); ++ disable_vga_and_power_gate_all_controllers(dc); + + } + +diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h +index 67cc020..b9f21bb 100644 +--- a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h +@@ -65,9 +65,9 @@ struct hw_sequencer_funcs { + const struct gamma_ramp *ramp, + const struct gamma_parameters *params); + +- void (*power_down)(struct validate_context *context); ++ void (*power_down)(struct dc *dc); + +- void (*enable_accelerated_mode)(struct validate_context *context); ++ void (*enable_accelerated_mode)(struct dc *dc); + + void (*get_crtc_positions)( + struct timing_generator *tg, +-- +2.7.4 + |