OSDN Git Service

drm/amd/display: AUX will exit when HPD LOW detected
authorHersen Wu <hersenxs.wu@amd.com>
Mon, 23 Apr 2018 23:21:45 +0000 (19:21 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 15 Jun 2018 17:20:23 +0000 (12:20 -0500)
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.wu@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h
drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
drivers/gpu/drm/amd/display/dc/i2caux/engine.h
drivers/gpu/drm/amd/display/include/ddc_service_types.h

index bb526ad..1d73096 100644 (file)
@@ -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;
index 8e71324..b9e35d0 100644 (file)
@@ -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;
index 9053578..2b927f2 100644 (file)
@@ -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;
        }
 }
index 33de8a8..c110970 100644 (file)
@@ -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 {
index 019e7a0..d968956 100644 (file)
@@ -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 {