drm/amd/display: turn off the mst hub before we do detection
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn10 / dcn10_hw_sequencer.c
index a9a5a13..42fcfee 100644 (file)
@@ -48,8 +48,8 @@
 #include "dc_link_dp.h"
 #include "dccg.h"
 #include "clk_mgr.h"
-
-
+#include "link_hwss.h"
+#include "dpcd_defs.h"
 #include "dsc.h"
 
 #define DC_LOGGER_INIT(logger)
@@ -82,7 +82,7 @@ void print_microsec(struct dc_context *dc_ctx,
                        us_x10 % frac);
 }
 
-static void dcn10_lock_all_pipes(struct dc *dc,
+void dcn10_lock_all_pipes(struct dc *dc,
        struct dc_state *context,
        bool lock)
 {
@@ -93,6 +93,7 @@ static void dcn10_lock_all_pipes(struct dc *dc,
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                pipe_ctx = &context->res_ctx.pipe_ctx[i];
                tg = pipe_ctx->stream_res.tg;
+
                /*
                 * Only lock the top pipe's tg to prevent redundant
                 * (un)locking. Also skip if pipe is disabled.
@@ -103,9 +104,9 @@ static void dcn10_lock_all_pipes(struct dc *dc,
                        continue;
 
                if (lock)
-                       tg->funcs->lock(tg);
+                       dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
                else
-                       tg->funcs->unlock(tg);
+                       dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
        }
 }
 
@@ -900,6 +901,10 @@ static void dcn10_reset_back_end_for_pipe(
         * parent pipe.
         */
        if (pipe_ctx->top_pipe == NULL) {
+
+               if (pipe_ctx->stream_res.abm)
+                       pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm);
+
                pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
 
                pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
@@ -1317,6 +1322,24 @@ void dcn10_init_hw(struct dc *dc)
                if (hws->funcs.dsc_pg_control != NULL)
                        hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
 
+       /* we want to turn off all dp displays before doing detection */
+       if (dc->config.power_down_display_on_boot) {
+               uint8_t dpcd_power_state = '\0';
+               enum dc_status status = DC_ERROR_UNEXPECTED;
+
+               for (i = 0; i < dc->link_count; i++) {
+                       if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
+                               continue;
+                       }
+                       /* if any of the displays are lit up turn them off */
+                       status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
+                                                    &dpcd_power_state, sizeof(dpcd_power_state));
+                       if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
+                               dp_receiver_power_ctrl(dc->links[i], false);
+                       }
+               }
+       }
+
        /* If taking control over from VBIOS, we may want to optimize our first
         * mode set, so we need to skip powering down pipes until we know which
         * pipes we want to use.
@@ -1576,7 +1599,7 @@ void dcn10_pipe_control_lock(
        /* use TG master update lock to lock everything on the TG
         * therefore only top pipe need to lock
         */
-       if (pipe->top_pipe)
+       if (!pipe || pipe->top_pipe)
                return;
 
        if (dc->debug.sanity_checks)
@@ -2530,11 +2553,6 @@ void dcn10_apply_ctx_for_surface(
        if (underflow_check_delay_us != 0xFFFFFFFF && hws->funcs.did_underflow_occur)
                ASSERT(hws->funcs.did_underflow_occur(dc, top_pipe_to_program));
 
-       if (interdependent_update)
-               dcn10_lock_all_pipes(dc, context, true);
-       else
-               dcn10_pipe_control_lock(dc, top_pipe_to_program, true);
-
        if (underflow_check_delay_us != 0xFFFFFFFF)
                udelay(underflow_check_delay_us);
 
@@ -2554,19 +2572,6 @@ void dcn10_apply_ctx_for_surface(
 
                pipe_ctx->update_flags.raw = 0;
 
-               /*
-                * Powergate reused pipes that are not powergated
-                * fairly hacky right now, using opp_id as indicator
-                * TODO: After move dc_post to dc_update, this will
-                * be removed.
-                */
-               if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
-                       if (old_pipe_ctx->stream_res.tg == tg &&
-                           old_pipe_ctx->plane_res.hubp &&
-                           old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
-                               dc->hwss.disable_plane(dc, old_pipe_ctx);
-               }
-
                if ((!pipe_ctx->plane_state ||
                     pipe_ctx->stream_res.tg != old_pipe_ctx->stream_res.tg) &&
                    old_pipe_ctx->plane_state &&
@@ -2599,11 +2604,6 @@ void dcn10_apply_ctx_for_surface(
                                &pipe_ctx->dlg_regs,
                                &pipe_ctx->ttu_regs);
                }
-
-       if (interdependent_update)
-               dcn10_lock_all_pipes(dc, context, false);
-       else
-               dcn10_pipe_control_lock(dc, top_pipe_to_program, false);
 }
 
 void dcn10_post_unlock_program_front_end(