From: Hersen Wu <hersenxs...@amd.com>

This change shorten wait time when HPD LOW. With HPD LOW, without this
change, AUX routine delay is 450us. With this change, it is 42us.

Signed-off-by: Hersen Wu <hersenxs...@amd.com>
Reviewed-by: Tony Cheng <tony.ch...@amd.com>
Reviewed-by: Harry Wentland <harry.wentl...@amd.com>
---
 .../drm/amd/display/dc/i2caux/aux_engine.c    | 16 ++++++++++++++
 .../drm/amd/display/dc/i2caux/aux_engine.h    |  5 ++++-
 .../dc/i2caux/dce110/aux_engine_dce110.c      | 22 ++++++++++++++-----
 .../gpu/drm/amd/display/dc/i2caux/engine.h    |  3 ++-
 .../amd/display/include/ddc_service_types.h   |  3 ++-
 5 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c 
b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
index bb526ad326e5..1d7309611978 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
@@ -157,6 +157,10 @@ static void process_read_reply(
                        ctx->operation_succeeded = false;
                }
        break;
+       case AUX_TRANSACTION_REPLY_HPD_DISCON:
+               ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON;
+               ctx->operation_succeeded = false;
+       break;
        default:
                ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
                ctx->operation_succeeded = false;
@@ -215,6 +219,10 @@ static void process_read_request(
                         * so we should not wait here */
                }
        break;
+       case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
+               ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON;
+               ctx->operation_succeeded = false;
+       break;
        default:
                ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
                ctx->operation_succeeded = false;
@@ -370,6 +378,10 @@ static void process_write_reply(
                        ctx->operation_succeeded = false;
                }
        break;
+       case AUX_TRANSACTION_REPLY_HPD_DISCON:
+               ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON;
+               ctx->operation_succeeded = false;
+       break;
        default:
                ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
                ctx->operation_succeeded = false;
@@ -422,6 +434,10 @@ static void process_write_request(
                         * so we should not wait here */
                }
        break;
+       case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
+               ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON;
+               ctx->operation_succeeded = false;
+       break;
        default:
                ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
                ctx->operation_succeeded = false;
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h 
b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h
index 8e71324ccb10..b9e35d0474c6 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h
@@ -51,6 +51,8 @@ enum aux_transaction_reply {
        AUX_TRANSACTION_REPLY_I2C_NACK = 0x10,
        AUX_TRANSACTION_REPLY_I2C_DEFER = 0x20,
 
+       AUX_TRANSACTION_REPLY_HPD_DISCON = 0x40,
+
        AUX_TRANSACTION_REPLY_INVALID = 0xFF
 };
 
@@ -64,7 +66,8 @@ enum aux_channel_operation_result {
        AUX_CHANNEL_OPERATION_SUCCEEDED,
        AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
        AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
-       AUX_CHANNEL_OPERATION_FAILED_TIMEOUT
+       AUX_CHANNEL_OPERATION_FAILED_TIMEOUT,
+       AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON
 };
 
 struct aux_engine;
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c 
b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
index 90535787a461..2b927f25937b 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
@@ -291,6 +291,12 @@ static void process_channel_reply(
        value = REG_GET(AUX_SW_STATUS,
                        AUX_SW_REPLY_BYTE_COUNT, &bytes_replied);
 
+       /* in case HPD is LOW, exit AUX transaction */
+       if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) {
+               reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON;
+               return;
+       }
+
        if (bytes_replied) {
                uint32_t reply_result;
 
@@ -347,8 +353,10 @@ static void process_channel_reply(
                 * because there was surely an error that was asserted
                 * that should have been handled
                 * for hot plug case, this could happens*/
-               if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
+               if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) {
+                       reply->status = AUX_TRANSACTION_REPLY_INVALID;
                        ASSERT_CRITICAL(false);
+               }
        }
 }
 
@@ -371,6 +379,10 @@ static enum aux_channel_operation_result 
get_channel_status(
        value = REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
                                10, aux110->timeout_period/10);
 
+       /* in case HPD is LOW, exit AUX transaction */
+       if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
+               return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON;
+
        /* Note that the following bits are set in 'status.bits'
         * during CTS 4.2.1.2 (FW 3.3.1):
         * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP,
@@ -402,10 +414,10 @@ static enum aux_channel_operation_result 
get_channel_status(
                        return AUX_CHANNEL_OPERATION_SUCCEEDED;
                }
        } else {
-               /*time_elapsed >= aux_engine->timeout_period */
-               if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
-                       ASSERT_CRITICAL(false);
-
+               /*time_elapsed >= aux_engine->timeout_period
+                *  AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point
+                */
+               ASSERT_CRITICAL(false);
                return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
        }
 }
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/engine.h 
b/drivers/gpu/drm/amd/display/dc/i2caux/engine.h
index 33de8a8834dc..c1109706a880 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/engine.h
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/engine.h
@@ -53,7 +53,8 @@ enum i2caux_transaction_status {
        I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE,
        I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION,
        I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
-       I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW
+       I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW,
+       I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON
 };
 
 struct i2caux_transaction_request {
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h 
b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index 019e7a095ea1..d968956a10cd 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -40,7 +40,8 @@ enum ddc_result {
        DDC_RESULT_FAILED_INCOMPLETE,
        DDC_RESULT_FAILED_OPERATION,
        DDC_RESULT_FAILED_INVALID_OPERATION,
-       DDC_RESULT_FAILED_BUFFER_OVERFLOW
+       DDC_RESULT_FAILED_BUFFER_OVERFLOW,
+       DDC_RESULT_FAILED_HPD_DISCON
 };
 
 enum ddc_service_type {
-- 
2.17.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to