drm/amd/display: Fix link retraining hw sequence
authorZeyu Fan <Zeyu.Fan@amd.com>
Fri, 23 Dec 2016 21:53:12 +0000 (16:53 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 21:08:05 +0000 (17:08 -0400)
Signed-off-by: Zeyu Fan <Zeyu.Fan@amd.com>
Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/inc/link_hwss.h

index 69819d8345432bb5bb89db14a41828ee6953ed29..ad1ce600a165be8575fb510687caf5bca7841714 100644 (file)
@@ -357,17 +357,18 @@ static void perform_link_training(struct dc *dc,
 }
 
 static void set_preferred_link_settings(struct dc *dc,
-               struct dc_link_settings *link_setting)
+               struct dc_link_settings *link_setting,
+               const struct dc_link *link)
 {
-       struct core_dc *core_dc = DC_TO_CORE(dc);
-       int i;
+       struct core_link *core_link = DC_LINK_TO_CORE(link);
 
-       for (i = 0; i < core_dc->link_count; i++) {
-               core_dc->links[i]->public.verified_link_cap.lane_count =
+       core_link->public.verified_link_cap.lane_count =
                                link_setting->lane_count;
-               core_dc->links[i]->public.verified_link_cap.link_rate =
+       core_link->public.verified_link_cap.link_rate =
                                link_setting->link_rate;
-       }
+       dp_retrain_link_physi(core_link,
+                       link_setting,
+                       false);
 }
 
 static void enable_hpd(const struct dc_link *link)
index 4febc8d2a96d4c9a9a6455468f22b51318f54dc9..f870a0e72074a6a8360e84585b208915ab404583 100644 (file)
@@ -200,7 +200,6 @@ void dp_set_hw_test_pattern(
        encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
 }
 
-
 void dp_retrain_link(struct core_link *link)
 {
        struct pipe_ctx *pipes = link->dc->current_context->res_ctx.pipe_ctx;
@@ -221,3 +220,51 @@ void dp_retrain_link(struct core_link *link)
                }
        }
 }
+
+void dp_retrain_link_physi(struct core_link *link,
+                       struct dc_link_settings *link_setting,
+                       bool skip_video_pattern)
+{
+       struct pipe_ctx *pipes =
+                       &link->dc->current_context->res_ctx.pipe_ctx[0];
+       unsigned int i;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (pipes[i].stream != NULL &&
+                       pipes[i].stream->sink != NULL &&
+                       pipes[i].stream->sink->link != NULL &&
+                       pipes[i].stream_enc != NULL &&
+                       pipes[i].stream->sink->link == link) {
+                       dm_delay_in_microseconds(link->ctx, 100);
+
+                       pipes[i].stream_enc->funcs->dp_blank(
+                                       pipes[i].stream_enc);
+
+                       dp_receiver_power_ctrl(link, false);
+
+                       link->link_enc->funcs->disable_output(
+                                       link->link_enc,
+                                       SIGNAL_TYPE_DISPLAY_PORT);
+
+                       /* Clear current link setting.
+                        * memset(&link->public.cur_link_settings, 0,
+                        *      sizeof(link->public.cur_link_settings));
+                        */
+
+                       link->link_enc->funcs->enable_dp_output(
+                                               link->link_enc,
+                                               link_setting,
+                                               pipes[i].clock_source->id);
+
+                       dp_receiver_power_ctrl(link, true);
+
+                       dc_link_dp_perform_link_training(
+                                       &link->public,
+                                       link_setting,
+                                       skip_video_pattern);
+
+                       link->dc->hwss.unblank_stream(&pipes[i],
+                                       link_setting);
+               }
+       }
+}
index 599f8b0894c26f791ffaf1782ed5005ac47513e7..83d78c2dc24d1526f95e36a5701c8cc72d516ea2 100644 (file)
@@ -117,7 +117,8 @@ struct dc_link_funcs {
                        struct dc_link_settings *link_setting,
                        bool skip_video_pattern);
        void (*set_preferred_link_settings)(struct dc *dc,
-                       struct dc_link_settings *link_setting);
+                       struct dc_link_settings *link_setting,
+                       const struct dc_link *link);
        void (*enable_hpd)(const struct dc_link *link);
        void (*disable_hpd)(const struct dc_link *link);
        void (*set_test_pattern)(
index 662fa30d45f77cf61d01f0473be38bc44b62fe71..30831c54878b533b418ff9e9b5ff8c1ced2c33cc 100644 (file)
@@ -70,4 +70,8 @@ enum dp_panel_mode dp_get_panel_mode(struct core_link *link);
 
 void dp_retrain_link(struct core_link *link);
 
+void dp_retrain_link_physi(struct core_link *link,
+               struct dc_link_settings *link_setting,
+               bool skip_video_pattern);
+
 #endif /* __DC_LINK_HWSS_H__ */