diff options
author | Aric Cyr <aric.cyr@amd.com> | 2021-10-07 21:34:53 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-10-28 14:26:15 -0400 |
commit | 8df219bb7d4b14e4e82b3db6da4a73f1b0b767d3 (patch) | |
tree | 6d88532a226c6348217e31d59ee5cf0c532dadd6 /drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | |
parent | drm/amd/display: Add comment for preferred_training_settings (diff) | |
download | linux-dev-8df219bb7d4b14e4e82b3db6da4a73f1b0b767d3.tar.xz linux-dev-8df219bb7d4b14e4e82b3db6da4a73f1b0b767d3.zip |
drm/amd/display: Handle I2C-over-AUX write channel status update
[Why]
When writing long AUX commands some sinks will respond will write status
update requiring source to read status.
[How]
When a write request is replied with data (AUX_ACK_M), retry a read of
write status to determine when the write is completed.
Reviewed-by: Martin Leung <Martin.Leung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | 15 |
1 files changed, 8 insertions, 7 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 471a67a64299..60539b1f2a80 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 @@ -554,6 +554,7 @@ bool dal_ddc_service_query_ddc_data( payload.address = address; payload.reply = NULL; payload.defer_delay = get_defer_delay(ddc); + payload.write_status_update = false; if (write_size != 0) { payload.write = true; @@ -625,24 +626,24 @@ 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) >= - payload->length; + payload->length ? true : false; + uint32_t payload_length = is_end_of_payload ? + payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE; current_payload.address = payload->address; current_payload.data = &payload->data[retrieved]; current_payload.defer_delay = payload->defer_delay; current_payload.i2c_over_aux = payload->i2c_over_aux; - current_payload.length = is_end_of_payload ? - payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE; - /* set mot (middle of transaction) to false - * if it is the last payload - */ + current_payload.length = payload_length; + /* 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.write_status_update = false; current_payload.reply = payload->reply; current_payload.write = payload->write; ret = dc_link_aux_transfer_with_retries(ddc, ¤t_payload); - retrieved += current_payload.length; + retrieved += payload_length; } while (retrieved < payload->length && ret == true); return ret; |