summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dmub/src
diff options
context:
space:
mode:
authorYongqiang Sun <yongqiang.sun@amd.com>2021-02-26 11:07:37 -0500
committerAlex Deucher <alexander.deucher@amd.com>2021-03-23 23:02:46 -0400
commit6804287bd1421f290065081db4b1a93c2fd2c591 (patch)
treeee108a9c241a21d31b6939805636dffabd264358 /drivers/gpu/drm/amd/display/dmub/src
parent61a74712c8302eaacd86b55f4ea7e3c7d9ea27f8 (diff)
drm/amd/display: Fixed read/write pointer issue for get dmub trace
[Why] Driver get wrap around dmub trace data due to read pointer being increased incorrectly when there are multiple interrupt queues with very short interval [How] Check read/write pointer before copying data from ring buffer 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/src')
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c19
1 files changed, 9 insertions, 10 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 1f1375c49aa5..1ee2000ad099 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -725,27 +725,26 @@ static inline bool dmub_rb_out_trace_buffer_front(struct dmub_rb *rb,
const uint64_t *src = (const uint64_t *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
uint64_t *dst = (uint64_t *)entry;
uint8_t i;
+ uint8_t loop_count;
+ if (rb->rptr == rb->wrpt)
+ return false;
+
+ loop_count = sizeof(struct dmcub_trace_buf_entry) / sizeof(uint64_t);
// copying data
- for (i = 0; i < sizeof(struct dmcub_trace_buf_entry) / sizeof(uint64_t); i++)
+ for (i = 0; i < loop_count; i++)
*dst++ = *src++;
rb->rptr += sizeof(struct dmcub_trace_buf_entry);
rb->rptr %= rb->capacity;
- if (rb->rptr == rb->wrpt)
- return true;
-
- return false;
+ return true;
}
-enum dmub_status dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry)
+bool 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);
- if (dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry))
- return DMUB_STATUS_OK;
-
- return DMUB_STATUS_QUEUE_FULL;
+ return dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry);
}