]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/ast: astdp: Perform link training during atomic_enable
authorThomas Zimmermann <tzimmermann@suse.de>
Wed, 17 Jul 2024 14:24:19 +0000 (16:24 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 30 Jul 2024 10:15:37 +0000 (12:15 +0200)
The place for link training is in the encoder's atomic_enable
helper. Remove all related tests from other helper ASTDP functions;
especially ast_astdp_is_connected(), which tests HPD status.

DP link training is controlled by the firmware. A status flag reports
success or failure. The process can be fragile on Aspeed hardware. Moving
the test from connector detection to the atomic_enable allows for several
retries and a longer timeout.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240717143319.104012-5-tzimmermann@suse.de
drivers/gpu/drm/ast/ast_dp.c
drivers/gpu/drm/ast/ast_drv.h
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/ast/ast_reg.h

index 4bd98c720d4a2be0e54be10d5b53cbbadb073041..0d96156565398acb4a7e6e3daa2383574e5bad17 100644 (file)
@@ -11,8 +11,6 @@ bool ast_astdp_is_connected(struct ast_device *ast)
 {
        if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, AST_IO_VGACRDF_HPD))
                return false;
-       if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS))
-               return false;
        return true;
 }
 
@@ -22,14 +20,10 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
        u8 i = 0, j = 0;
 
        /*
-        * CRDC[b0]: DP link success
         * CRE5[b0]: Host reading EDID process is done
         */
-       if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) &&
-               ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5,
-                                                               ASTDP_HOST_EDID_READ_DONE_MASK))) {
+       if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
                goto err_astdp_edid_not_ready;
-       }
 
        ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
                                                        0x00);
@@ -58,11 +52,6 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
                         */
                        mdelay(j+1);
 
-                       if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC,
-                                                       ASTDP_LINK_SUCCESS))) {
-                               goto err_astdp_jump_out_loop_of_edid;
-                       }
-
                        j++;
                        if (j > 200)
                                goto err_astdp_jump_out_loop_of_edid;
@@ -106,8 +95,6 @@ err_astdp_jump_out_loop_of_edid:
        return (~(j+256) + 1);
 
 err_astdp_edid_not_ready:
-       if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)))
-               return (~0xDC + 1);
        if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
                return (~0xE5 + 1);
 
@@ -158,7 +145,22 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on)
        ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
 }
 
+void ast_dp_link_training(struct ast_device *ast)
+{
+       struct drm_device *dev = &ast->base;
+       unsigned int i = 10;
+
+       while (i--) {
+               u8 vgacrdc = ast_get_index_reg(ast, AST_IO_VGACRI, 0xdc);
 
+               if (vgacrdc & AST_IO_VGACRDC_LINK_SUCCESS)
+                       break;
+               if (i)
+                       msleep(100);
+       }
+       if (!i)
+               drm_err(dev, "Link training failed\n");
+}
 
 void ast_dp_set_on_off(struct drm_device *dev, bool on)
 {
@@ -169,16 +171,13 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on)
        // Video On/Off
        ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
 
-       // If DP plug in and link successful then check video on / off status
-       if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)) {
-               video_on_off <<= 4;
-               while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF,
+       video_on_off <<= 4;
+       while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF,
                                                ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) {
-                       // wait 1 ms
-                       mdelay(1);
-                       if (++i > 200)
-                               break;
-               }
+               // wait 1 ms
+               mdelay(1);
+               if (++i > 200)
+                       break;
        }
 }
 
index 80e968f15fc9eebcd7f8b62f2337eff5e66883bb..b54a89676e9f78f1df520f356bf8b0e7269570f0 100644 (file)
@@ -473,6 +473,7 @@ bool ast_astdp_is_connected(struct ast_device *ast);
 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
 int ast_dp_launch(struct ast_device *ast);
 void ast_dp_power_on_off(struct drm_device *dev, bool no);
+void ast_dp_link_training(struct ast_device *ast);
 void ast_dp_set_on_off(struct drm_device *dev, bool no);
 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode);
 
index dc8f639e82fdf5dadfec93f4ad6faa53728d00be..0a206b17e22b726d1de9b0bf4f583bd05f6e7f94 100644 (file)
@@ -1621,6 +1621,8 @@ static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder,
        struct ast_device *ast = to_ast_device(dev);
 
        ast_dp_power_on_off(dev, AST_DP_POWER_ON);
+       ast_dp_link_training(ast);
+
        ast_wait_for_vretrace(ast);
        ast_dp_set_on_off(dev, 1);
 }
index e61954dabf1a65af349a28bc1a9c0c38d9cb2b35..28bb43f6795b6cbd3fe2935484a339f78c548b44 100644 (file)
@@ -38,6 +38,7 @@
 #define AST_IO_VGACRCB_HWC_ENABLED     BIT(1)
 
 #define AST_IO_VGACRD1_MCU_FW_EXECUTING        BIT(5)
+#define AST_IO_VGACRDC_LINK_SUCCESS    BIT(0)
 #define AST_IO_VGACRDF_HPD             BIT(0)
 
 #define AST_IO_VGAIR1_R                        (0x5A)
 #define AST_DP_VIDEO_ENABLE            BIT(0)
 
 /*
- * CRDC[b0]: DP link success
  * CRE5[b0]: Host reading EDID process is done
  */
-#define ASTDP_LINK_SUCCESS             BIT(0)
 #define ASTDP_HOST_EDID_READ_DONE      BIT(0)
 #define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0)