From: Wenjing Liu <wenjing.liu@xxxxxxx> [ Upstream commit 26b4750d6cf84cb2b3f0a84c9b345e7b71886410 ] [why] Two issues: 1. Add read only operation support for query ddc data over aux. 2. Fix a bug where if read size is multiple of 16, mot of the last read transaction will not be set to 0. Signed-off-by: Wenjing Liu <wenjing.liu@xxxxxxx> Reviewed-by: Jun Lei <Jun.Lei@xxxxxxx> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@xxxxxxx> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index aefd29a440b52..be8f265976b09 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -503,7 +503,7 @@ bool dal_ddc_service_query_ddc_data( uint8_t *read_buf, uint32_t read_size) { - bool ret = false; + bool success = true; uint32_t payload_size = dal_ddc_service_is_in_aux_transaction_mode(ddc) ? DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE; @@ -527,7 +527,6 @@ bool dal_ddc_service_query_ddc_data( * but we want to read 256 over i2c!!!!*/ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) { struct aux_payload payload; - bool read_available = true; payload.i2c_over_aux = true; payload.address = address; @@ -536,21 +535,26 @@ bool dal_ddc_service_query_ddc_data( if (write_size != 0) { payload.write = true; - payload.mot = false; + /* should not set mot (middle of transaction) to 0 + * if there are pending read payloads + */ + payload.mot = read_size == 0 ? false : true; payload.length = write_size; payload.data = write_buf; - ret = dal_ddc_submit_aux_command(ddc, &payload); - read_available = ret; + success = dal_ddc_submit_aux_command(ddc, &payload); } - if (read_size != 0 && read_available) { + if (read_size != 0 && success) { payload.write = false; + /* should set mot (middle of transaction) to 0 + * since it is the last payload to send + */ payload.mot = false; payload.length = read_size; payload.data = read_buf; - ret = dal_ddc_submit_aux_command(ddc, &payload); + success = dal_ddc_submit_aux_command(ddc, &payload); } } else { struct i2c_command command = {0}; @@ -573,7 +577,7 @@ bool dal_ddc_service_query_ddc_data( command.number_of_payloads = dal_ddc_i2c_payloads_get_count(&payloads); - ret = dm_helpers_submit_i2c( + success = dm_helpers_submit_i2c( ddc->ctx, ddc->link, &command); @@ -581,7 +585,7 @@ bool dal_ddc_service_query_ddc_data( dal_ddc_i2c_payloads_destroy(&payloads); } - return ret; + return success; } bool dal_ddc_submit_aux_command(struct ddc_service *ddc, @@ -598,7 +602,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc, do { struct aux_payload current_payload; - bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) > + bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >= payload->length; current_payload.address = payload->address; @@ -607,7 +611,10 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc, current_payload.i2c_over_aux = payload->i2c_over_aux; current_payload.length = is_end_of_payload ? payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE; - current_payload.mot = !is_end_of_payload; + /* set mot (middle of transaction) to false + * if it is the last payload + */ + current_payload.mot = is_end_of_payload ? payload->mot:true; current_payload.reply = payload->reply; current_payload.write = payload->write; -- 2.25.1