[PATCH v2 13/23] drm/msm/dcp: Route HFI display events

From: Jayant Shekhar

Date: Mon Oct 26 2026 - 02:26:47 EST


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 <jayant.shekhar@xxxxxxxxxxxxxxxx>
---
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