summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYongqiang Sun <yongqiang.sun@amd.com>2021-02-23 15:16:44 -0500
committerAlex Deucher <alexander.deucher@amd.com>2021-03-23 23:02:38 -0400
commit3c934f454dae53c56a983226516acb014244a8d0 (patch)
treeeecd268c08f3804c84e567ffc6f309c7e3ae4cf0 /drivers
parent0c66824be8f459f3f7010bb90c236d3142006e37 (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')
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c19
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;
}