drm/amd/display: make dm_dp_aux_transfer return payload bytes instead of size
authorShirish S <shirish.s@amd.com>
Fri, 23 Feb 2018 10:40:13 +0000 (16:10 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 28 Feb 2018 20:38:40 +0000 (15:38 -0500)
The drm layer expects aux->transfer() to return the payload bytes read.
Currently dm_dp_aux_transfer() returns the payload size which does not
gets updated during the read, hence not giving the right data for the
drm layer to pars edid. This leads to the drm layer to conclude as the
edid is BAD and hence some monitors/devices dont get detected properly.

This patch changes the return type of dm_dp_aux_transfer() to actual
bytes read during DP_AUX_NATIVE_READ & DP_AUX_I2C_READ.

Signed-off-by: Shirish S <shirish.s@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c
drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h

index 1e8a21b67df7fbe8d03ba4040d0c4b297edf718f..39cfe0fbf1b97c555b9e69a5719d64912412a665 100644 (file)
@@ -83,17 +83,18 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
        enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ?
                I2C_MOT_TRUE : I2C_MOT_FALSE;
        enum ddc_result res;
+       ssize_t read_bytes;
 
        switch (msg->request & ~DP_AUX_I2C_MOT) {
        case DP_AUX_NATIVE_READ:
-               res = dal_ddc_service_read_dpcd_data(
+               read_bytes = dal_ddc_service_read_dpcd_data(
                                TO_DM_AUX(aux)->ddc_service,
                                false,
                                I2C_MOT_UNDEF,
                                msg->address,
                                msg->buffer,
                                msg->size);
-               break;
+               return read_bytes;
        case DP_AUX_NATIVE_WRITE:
                res = dal_ddc_service_write_dpcd_data(
                                TO_DM_AUX(aux)->ddc_service,
@@ -104,14 +105,14 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
                                msg->size);
                break;
        case DP_AUX_I2C_READ:
-               res = dal_ddc_service_read_dpcd_data(
+               read_bytes = dal_ddc_service_read_dpcd_data(
                                TO_DM_AUX(aux)->ddc_service,
                                true,
                                mot,
                                msg->address,
                                msg->buffer,
                                msg->size);
-               break;
+               return read_bytes;
        case DP_AUX_I2C_WRITE:
                res = dal_ddc_service_write_dpcd_data(
                                TO_DM_AUX(aux)->ddc_service,
index d5294798b0a54f4fc66a3dca381a40e2dd28944c..49c2face1e7a869e07e94da881e7ed33acbe483e 100644 (file)
@@ -629,7 +629,7 @@ bool dal_ddc_service_query_ddc_data(
        return ret;
 }
 
-enum ddc_result dal_ddc_service_read_dpcd_data(
+ssize_t dal_ddc_service_read_dpcd_data(
        struct ddc_service *ddc,
        bool i2c,
        enum i2c_mot_mode mot,
@@ -660,8 +660,9 @@ enum ddc_result dal_ddc_service_read_dpcd_data(
        if (dal_i2caux_submit_aux_command(
                ddc->ctx->i2caux,
                ddc->ddc_pin,
-               &command))
-               return DDC_RESULT_SUCESSFULL;
+               &command)) {
+               return (ssize_t)command.payloads->length;
+       }
 
        return DDC_RESULT_FAILED_OPERATION;
 }
index 0b1db48fef36aea9a60d64df19f54f777635d59e..9c42fe5a0f27176884023c23cc73886f5930b377 100644 (file)
@@ -126,20 +126,8 @@ static void process_read_reply(
                        ctx->status =
                                I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
                        ctx->operation_succeeded = false;
-               } else if (ctx->returned_byte < ctx->current_read_length) {
-                       ctx->current_read_length -= ctx->returned_byte;
-
-                       ctx->offset += ctx->returned_byte;
-
-                       ++ctx->invalid_reply_retry_aux_on_ack;
-
-                       if (ctx->invalid_reply_retry_aux_on_ack >
-                               AUX_INVALID_REPLY_RETRY_COUNTER) {
-                               ctx->status =
-                               I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-                               ctx->operation_succeeded = false;
-                       }
                } else {
+                       ctx->current_read_length = ctx->returned_byte;
                        ctx->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
                        ctx->transaction_complete = true;
                        ctx->operation_succeeded = true;
@@ -292,6 +280,7 @@ static bool read_command(
                                ctx.operation_succeeded);
        }
 
+       request->payload.length = ctx.reply.length;
        return ctx.operation_succeeded;
 }
 
index e1593ffe5a2bd1753c1cbdc9a5dfac1120341a89..5cbf6626b8d40cb896d371518b2790433e952066 100644 (file)
@@ -253,6 +253,7 @@ bool dal_i2caux_submit_aux_command(
                        break;
                }
 
+               cmd->payloads->length = request.payload.length;
                ++index_of_payload;
        }
 
index 0bf73b742f1f7262ba1a179965feec7e2572e3ec..090b7a8dd67bde2bdfdaf243c04d175abf82112c 100644 (file)
@@ -102,7 +102,7 @@ bool dal_ddc_service_query_ddc_data(
                uint8_t *read_buf,
                uint32_t read_size);
 
-enum ddc_result dal_ddc_service_read_dpcd_data(
+ssize_t dal_ddc_service_read_dpcd_data(
                struct ddc_service *ddc,
                bool i2c,
                enum i2c_mot_mode mot,