diff options
author | Yongqiang Sun <yongqiang.sun@amd.com> | 2021-02-23 15:16:44 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-03-23 23:02:38 -0400 |
commit | 3c934f454dae53c56a983226516acb014244a8d0 (patch) | |
tree | eecd268c08f3804c84e567ffc6f309c7e3ae4cf0 /drivers/gpu/drm/amd/display/dmub | |
parent | 0c66824be8f459f3f7010bb90c236d3142006e37 (diff) |
drm/amd/display: Read all the trace entry if it is not empty
[Why]
If interval of two interrupt from dmub outbox0 is too short,
some event might be skipped
[How]
Compare read pointer and write pointer until all the event
entry is processed
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Eryk Brol <eryk.brol@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 2522492dcd42..1f1375c49aa5 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -517,7 +517,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, dmub_memset(&outbox0_rb_params, 0, sizeof(outbox0_rb_params)); outbox0_rb_params.ctx = dmub; outbox0_rb_params.base_address = (void *)((uint64_t)(tracebuff_fb->cpu_addr) + TRACE_BUFFER_ENTRY_OFFSET); - outbox0_rb_params.capacity = tracebuff_fb->size - TRACE_BUFFER_ENTRY_OFFSET; + outbox0_rb_params.capacity = tracebuff_fb->size - dmub_align(TRACE_BUFFER_ENTRY_OFFSET, 64); dmub_rb_init(&dmub->outbox0_rb, &outbox0_rb_params); if (dmub->hw_funcs.reset_release) @@ -719,10 +719,10 @@ enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub, return status; } -static inline void dmub_rb_out_trace_buffer_front(struct dmub_rb *rb, +static inline bool dmub_rb_out_trace_buffer_front(struct dmub_rb *rb, void *entry) { - const uint64_t *src = (const uint64_t *)(rb->base_address) + rb->wrpt / sizeof(uint64_t); + const uint64_t *src = (const uint64_t *)(rb->base_address) + rb->rptr / sizeof(uint64_t); uint64_t *dst = (uint64_t *)entry; uint8_t i; @@ -730,13 +730,22 @@ static inline void dmub_rb_out_trace_buffer_front(struct dmub_rb *rb, for (i = 0; i < sizeof(struct dmcub_trace_buf_entry) / sizeof(uint64_t); i++) *dst++ = *src++; + rb->rptr += sizeof(struct dmcub_trace_buf_entry); + + rb->rptr %= rb->capacity; + + if (rb->rptr == rb->wrpt) + return true; + + return false; } enum dmub_status dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry) { dmub->outbox0_rb.wrpt = dmub->hw_funcs.get_outbox0_wptr(dmub); - dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry); + if (dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry)) + return DMUB_STATUS_OK; - return DMUB_STATUS_OK; + return DMUB_STATUS_QUEUE_FULL; } |