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 bb526ad326e597a449a1c4d38a9fb134e4ba33a7..1d7309611978e9f07162e919879414618c45e4e0 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 8e71324ccb1094435e51d14134c7d42d5a97f163..b9e35d0474c6ad49eb4e671f004efcc3cfad5d69 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 90535787a46186993ca7cacaa8e7ec3d3b8ab70c..2b927f25937b4f48ccf4abbe6a58a97017041f71 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 33de8a8834dc1a71e9f898b81c6a2818549f13e6..c1109706a880840477ff64636f330c2d2e380b1b 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 019e7a095ea103062a78fb20d65a8391ff0016fe..d968956a10cd5de232f610a2fe6eaa4028340315 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 {