Route asynchronous display events from DCP firmware into the DRM CRTC
objects. Without this mapping, VSYNC and frame-scan completion cannot
drive DRM vblank and page-flip completion.

Match firmware display events to the corresponding CRTC session and
deliver VSYNC and frame-scan completion notifications through the
MSM DRM callbacks.

Assisted-by: LLM
Signed-off-by: Jayant Shekhar <[email protected]>
---
 drivers/gpu/drm/msm/dcp/dcp_hfi_core.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/msm/dcp/dcp_hfi_core.c 
b/drivers/gpu/drm/msm/dcp/dcp_hfi_core.c
index 774a5afac0f0..e54ccfafdae0 100644
--- a/drivers/gpu/drm/msm/dcp/dcp_hfi_core.c
+++ b/drivers/gpu/drm/msm/dcp/dcp_hfi_core.c
@@ -19,6 +19,7 @@
 #include "dcp_hfi.h"
 #include "dcp_hfi_priv.h"
 #include "dcp_drv.h"
+#include "dcp_crtc.h"
 #include "hfi/hfi_packet.h"
 #include "hfi/hfi_packer.h"
 #include "hfi/hfi_unpacker.h"
@@ -260,18 +261,35 @@ static void dcp_hfi_store_caps_payload(struct dcp_hfi 
*hfi,
        dev_dbg(hfi->dev, "%s: stored %u bytes\n", name, n);
 }
 
+static void dcp_hfi_dispatch_frame_done(struct dcp_hfi *hfi,
+                                       const struct hfi_packet_info *pkt_info)
+{
+       const struct hfi_display_frame_event_data *frame = NULL;
+       u32 sequence_id = 0;
+
+       if (pkt_info->payload_ptr &&
+           pkt_info->payload_size >= sizeof(*frame)) {
+               frame = pkt_info->payload_ptr;
+               sequence_id = frame->bufferflip_index;
+       }
+       dcp_crtc_hfi_frame_done_cb(hfi->drv, pkt_info->id & 0xFFFF,
+                                  sequence_id);
+}
+
 /* Route asynchronous events and capability packets before flag handling. */
 static bool dcp_hfi_dispatch_event(struct dcp_hfi *hfi,
                                   const struct hfi_packet_info *pkt_info)
 {
        switch (pkt_info->cmd) {
        case HFI_COMMAND_DISPLAY_EVENT_VSYNC:
+               dcp_crtc_hfi_vblank_cb(hfi->drv, pkt_info->id & 0xFFFF);
                return true;
 
        case HFI_COMMAND_DISPLAY_EVENT_FRAME_SCAN_START:
                return true;
 
        case HFI_COMMAND_DISPLAY_EVENT_FRAME_SCAN_COMPLETE:
+               dcp_hfi_dispatch_frame_done(hfi, pkt_info);
                return true;
 
        case HFI_COMMAND_DISPLAY_EVENT_HPD_STATUS:
@@ -975,6 +993,9 @@ int dcp_hfi_init(struct dcp_drv *drv,
        struct dcp_hfi *hfi;
        int i, ret;
 
+       if (!dma_dev)
+               return -ENODEV;
+
        hfi = devm_kzalloc(&vdev->dev, sizeof(*hfi), GFP_KERNEL);
        if (!hfi)
                return -ENOMEM;

-- 
2.43.0


Reply via email to