From: Michael Strauss <michael.stra...@amd.com>

[WHY]
Need to fix some broken logic and sequencing in initial commit

[HOW]
Fix logic handling override deprogramming when exiting SQ128.

Don't exit early from dp_set_hw_lane_settings for DP2/FIXED_VS case.

Move LTTPR 128b/132b check out of  requires_hwss and check during
runtime, as LTTPR caps are not populated on initial call.

Add pending_test_pattern to link state to allow HWSS to set FFE overrides
on retimer TX and/or skip setting APU TX FFE depending on requested pattern.

Use updated clock source for SQ128 override sequence.

Skip HW FFE preset programming when performing test pattern overrides.

Reviewed-by: Wenjing Liu <wenjing....@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pil...@amd.com>
Signed-off-by: Michael Strauss <michael.stra...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h           | 12 +++++
 .../display/dc/link/accessories/link_dp_cts.c | 27 +++-------
 .../hwss/link_hwss_dio_fixed_vs_pe_retimer.c  | 16 +++---
 .../link_hwss_hpo_fixed_vs_pe_retimer_dp.c    | 51 +++++++++----------
 .../display/dc/link/protocols/link_dp_phy.c   |  6 ++-
 .../amd/display/include/link_service_types.h  |  9 ++++
 6 files changed, 65 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index f2c27964ec1c..181144541657 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1572,7 +1572,19 @@ struct dc_link {
        enum engine_id dpia_preferred_eng_id;
 
        bool test_pattern_enabled;
+       /* Pending/Current test pattern are only used to perform and track
+        * FIXED_VS retimer test pattern/lane adjustment override state.
+        * Pending allows link HWSS to differentiate PHY vs non-PHY pattern,
+        * to perform specific lane adjust overrides before setting certain
+        * PHY test patterns. In cases when lane adjust and set test pattern
+        * calls are not performed atomically (i.e. performing link training),
+        * pending_test_pattern will be invalid or contain a non-PHY test 
pattern
+        * and current_test_pattern will contain required context for any future
+        * set pattern/set lane adjust to transition between override state(s).
+        * */
        enum dp_test_pattern current_test_pattern;
+       enum dp_test_pattern pending_test_pattern;
+
        union compliance_test_state compliance_test_state;
 
        void *priv;
diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c 
b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
index 2d152b68a501..22b24749c9d2 100644
--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
@@ -61,22 +61,6 @@ static enum dc_link_rate 
get_link_rate_from_test_link_rate(uint8_t test_rate)
        }
 }
 
-static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)
-{
-       return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&
-                       test_pattern <= DP_TEST_PATTERN_SQUARE_END);
-}
-
-static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
-{
-       if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
-                       test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
-                       test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
-               return true;
-       else
-               return false;
-}
-
 static void dp_retrain_link_dp_test(struct dc_link *link,
                        struct dc_link_settings *link_setting,
                        bool skip_video_pattern)
@@ -361,7 +345,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link 
*link)
                                test_pattern_size);
        }
 
-       if (is_dp_phy_sqaure_pattern(test_pattern)) {
+       if (IS_DP_PHY_SQUARE_PATTERN(test_pattern)) {
                test_pattern_size = 1; // Square pattern data is 1 byte (DP 
spec)
                core_link_read_dpcd(
                                link,
@@ -623,6 +607,8 @@ bool dp_set_test_pattern(
        if (pipe_ctx == NULL)
                return false;
 
+       link->pending_test_pattern = test_pattern;
+
        /* Reset CRTC Test Pattern if it is currently running and request is 
VideoMode */
        if (link->test_pattern_enabled && test_pattern ==
                        DP_TEST_PATTERN_VIDEO_MODE) {
@@ -643,12 +629,13 @@ bool dp_set_test_pattern(
                /* Reset Test Pattern state */
                link->test_pattern_enabled = false;
                link->current_test_pattern = test_pattern;
+               link->pending_test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
 
                return true;
        }
 
        /* Check for PHY Test Patterns */
-       if (is_dp_phy_pattern(test_pattern)) {
+       if (IS_DP_PHY_PATTERN(test_pattern)) {
                /* Set DPCD Lane Settings before running test pattern */
                if (p_link_settings != NULL) {
                        if ((link->chip_caps & 
EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
@@ -681,6 +668,7 @@ bool dp_set_test_pattern(
                        /* Set Test Pattern state */
                        link->test_pattern_enabled = true;
                        link->current_test_pattern = test_pattern;
+                       link->pending_test_pattern = 
DP_TEST_PATTERN_UNSUPPORTED;
                        if (p_link_settings != NULL)
                                dpcd_set_link_settings(link,
                                                p_link_settings);
@@ -756,7 +744,7 @@ bool dp_set_test_pattern(
                        return false;
 
                if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
-                       if (is_dp_phy_sqaure_pattern(test_pattern))
+                       if (IS_DP_PHY_SQUARE_PATTERN(test_pattern))
                                core_link_write_dpcd(link,
                                                DP_LINK_SQUARE_PATTERN,
                                                p_custom_pattern,
@@ -884,6 +872,7 @@ bool dp_set_test_pattern(
                /* Set Test Pattern state */
                link->test_pattern_enabled = true;
                link->current_test_pattern = test_pattern;
+               link->pending_test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
        }
 
        return true;
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c
index b659baa23147..348ea4cb832d 100644
--- 
a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c
+++ 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c
@@ -80,21 +80,23 @@ static bool 
set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override(struct dc_
        const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0};
        const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 
0x0, 0x06};
 
+       if 
(!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED)
+               return false;
 
        if (tp_params == NULL)
                return false;
 
-       if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN &&
-                       link->current_test_pattern <= 
DP_TEST_PATTERN_SQUARE_END) {
+       if (IS_DP_PHY_SQUARE_PATTERN(link->current_test_pattern))
                // Deprogram overrides from previous test pattern
                dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link);
-       }
 
        switch (tp_params->dp_phy_pattern) {
        case DP_TEST_PATTERN_80BIT_CUSTOM:
                if (tp_params->custom_pattern_size == 0 || 
memcmp(tp_params->custom_pattern,
                                pltpat_custom, tp_params->custom_pattern_size) 
!= 0)
                        return false;
+               hw_tp_params.custom_pattern = tp_params->custom_pattern;
+               hw_tp_params.custom_pattern_size = 
tp_params->custom_pattern_size;
                break;
        case DP_TEST_PATTERN_D102:
                break;
@@ -185,13 +187,7 @@ static const struct link_hwss 
dio_fixed_vs_pe_retimer_link_hwss = {
 
 bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link)
 {
-       if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN))
-               return false;
-
-       if 
(!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED)
-               return false;
-
-       return true;
+       return (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN);
 }
 
 const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void)
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
index b621b97711b6..3e6c7be7e278 100644
--- 
a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
+++ 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
@@ -74,13 +74,16 @@ static void dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(struct 
dc_link *link,
 static void dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(struct 
dc_link *link,
                struct encoder_set_dp_phy_pattern_param *tp_params)
 {
+       uint8_t clk_src = 0x4C;
+       uint8_t pattern = 0x4F; /* SQ128 */
+
        const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0};
-       const uint8_t vendor_lttpr_write_data_pg1[4] = {0x1, 0x50, 0x50, 0x0};
-       const uint8_t vendor_lttpr_write_data_pg2[4] = {0x1, 0x51, 0x50, 0x0};
+       const uint8_t vendor_lttpr_write_data_pg1[4] = {0x1, 0x50, 0x50, 
clk_src};
+       const uint8_t vendor_lttpr_write_data_pg2[4] = {0x1, 0x51, 0x50, 
clk_src};
        const uint8_t vendor_lttpr_write_data_pg3[4]  = {0x1, 0x10, 0x58, 0x21};
        const uint8_t vendor_lttpr_write_data_pg4[4]  = {0x1, 0x10, 0x59, 0x21};
-       const uint8_t vendor_lttpr_write_data_pg5[4] = {0x1, 0x1C, 0x58, 0x4F};
-       const uint8_t vendor_lttpr_write_data_pg6[4] = {0x1, 0x1C, 0x59, 0x4F};
+       const uint8_t vendor_lttpr_write_data_pg5[4] = {0x1, 0x1C, 0x58, 
pattern};
+       const uint8_t vendor_lttpr_write_data_pg6[4] = {0x1, 0x1C, 0x59, 
pattern};
        const uint8_t vendor_lttpr_write_data_pg7[4]  = {0x1, 0x30, 0x51, 0x20};
        const uint8_t vendor_lttpr_write_data_pg8[4]  = {0x1, 0x30, 0x52, 0x20};
        const uint8_t vendor_lttpr_write_data_pg9[4]  = {0x1, 0x30, 0x54, 0x20};
@@ -123,18 +126,20 @@ static bool 
dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern(struct dc_link
        struct encoder_set_dp_phy_pattern_param hw_tp_params = { 0 };
        const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 
0x0, 0x06};
 
+       if 
(!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED)
+               return false;
+
        if (tp_params == NULL)
                return false;
 
-       if (tp_params->dp_phy_pattern < DP_TEST_PATTERN_SQUARE_BEGIN ||
-                       tp_params->dp_phy_pattern > DP_TEST_PATTERN_SQUARE_END) 
{
+       if (!IS_DP_PHY_SQUARE_PATTERN(tp_params->dp_phy_pattern)) {
                // Deprogram overrides from previously set square wave override
                if (link->current_test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM 
||
                                link->current_test_pattern == 
DP_TEST_PATTERN_D102)
                        
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
                                        
&vendor_lttpr_exit_manual_automation_0[0],
                                        
sizeof(vendor_lttpr_exit_manual_automation_0));
-               else
+               else if (IS_DP_PHY_SQUARE_PATTERN(link->current_test_pattern))
                        dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link);
 
                return false;
@@ -148,8 +153,6 @@ static bool 
dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern(struct dc_link
 
        dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(link, 
tp_params);
 
-       dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &link->cur_lane_setting[0]);
-
        return true;
 }
 
@@ -170,16 +173,18 @@ static void 
set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link,
                const struct dc_link_settings *link_settings,
                const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
 {
-       link_res->hpo_dp_link_enc->funcs->set_ffe(
-                       link_res->hpo_dp_link_enc,
-                       link_settings,
-                       lane_settings[0].FFE_PRESET.raw);
-
-       // FFE is programmed when retimer is programmed for SQ128, but explicit
-       // programming needed here as well in case FFE-only update is requested
-       if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN &&
-                       link->current_test_pattern <= 
DP_TEST_PATTERN_SQUARE_END)
-               dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &lane_settings[0]);
+       // Don't update our HW FFE when outputting phy test patterns
+       if (IS_DP_PHY_PATTERN(link->pending_test_pattern)) {
+               // Directly program FIXED_VS retimer FFE for SQ128 override
+               if (IS_DP_PHY_SQUARE_PATTERN(link->pending_test_pattern)) {
+                       dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, 
&lane_settings[0]);
+               }
+       } else {
+               link_res->hpo_dp_link_enc->funcs->set_ffe(
+                               link_res->hpo_dp_link_enc,
+                               link_settings,
+                               lane_settings[0].FFE_PRESET.raw);
+       }
 }
 
 static void enable_hpo_fixed_vs_pe_retimer_dp_link_output(struct dc_link *link,
@@ -214,13 +219,7 @@ static const struct link_hwss 
hpo_fixed_vs_pe_retimer_dp_link_hwss = {
 
 bool requires_fixed_vs_pe_retimer_hpo_link_hwss(const struct dc_link *link)
 {
-       if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN))
-               return false;
-
-       if 
(!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED)
-               return false;
-
-       return true;
+       return requires_fixed_vs_pe_retimer_dio_link_hwss(link);
 }
 
 const struct link_hwss *get_hpo_fixed_vs_pe_retimer_dp_link_hwss(void)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c
index 0050e0a06cbc..2fa4e64e2430 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c
@@ -37,6 +37,7 @@
 #include "clk_mgr.h"
 #include "resource.h"
 #include "link_enc_cfg.h"
+#include "atomfirmware.h"
 #define DC_LOGGER \
        link->ctx->logger
 
@@ -100,8 +101,11 @@ void dp_set_hw_lane_settings(
 {
        const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
 
+       // Don't return here if using FIXED_VS link HWSS and encoding is 
128b/132b
        if ((link_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) &&
-                       !is_immediate_downstream(link, offset))
+                       !is_immediate_downstream(link, offset) &&
+                       (!(link->chip_caps & 
EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) ||
+                       
link_dp_get_encoding_format(&link_settings->link_settings) == 
DP_8b_10b_ENCODING))
                return;
 
        if (link_hwss->ext.set_dp_lane_settings)
diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h 
b/drivers/gpu/drm/amd/display/include/link_service_types.h
index 1b8ab20f1715..92dbff22a7c6 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -169,6 +169,15 @@ enum dp_test_pattern {
        DP_TEST_PATTERN_UNSUPPORTED
 };
 
+#define IS_DP_PHY_SQUARE_PATTERN(test_pattern)\
+               (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&\
+               test_pattern <= DP_TEST_PATTERN_SQUARE_END)
+
+#define IS_DP_PHY_PATTERN(test_pattern)\
+               ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&\
+               test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||\
+               test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
+
 enum dp_test_pattern_color_space {
        DP_TEST_PATTERN_COLOR_SPACE_RGB,
        DP_TEST_PATTERN_COLOR_SPACE_YCBCR601,
-- 
2.43.0

Reply via email to