From: Yongqiang Sun <yongqiang....@amd.com>

[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

Signed-off-by: Yongqiang Sun <yongqiang....@amd.com>
Reviewed-by: Tony Cheng <tony.ch...@amd.com>
Acked-by: Eryk Brol <eryk.b...@amd.com>
---
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   | 19 ++++++++++++++-----
 1 file 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;
 }
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to