[PATCH v2 16/23] drm/msm/dcp: Integrate the DSI bridge with KMS

From: Jayant Shekhar

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


Connect the DCP DSI host and panel bridge to the DCP KMS
pipeline. Without bridge integration, DRM cannot create display
sessions, attach connectors, or run the bridge enable and disable
sequence for atomic commits.

Set up and tear down the bridge and CRTC relationship, pass panel
configuration through KMS, and connect bridge-backed display operations
to the DCP HFI commands.

Assisted-by: LLM
Signed-off-by: Jayant Shekhar <jayant.shekhar@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/dcp/dcp_crtc.c | 14 ++++++++++++
drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c | 40 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h | 2 ++
3 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/msm/dcp/dcp_crtc.c b/drivers/gpu/drm/msm/dcp/dcp_crtc.c
index ec4f74c2920f..173a07df71c5 100644
--- a/drivers/gpu/drm/msm/dcp/dcp_crtc.c
+++ b/drivers/gpu/drm/msm/dcp/dcp_crtc.c
@@ -147,6 +147,12 @@ static void dcp_crtc_atomic_begin(struct drm_crtc *crtc,
return;
}

+ ret = dcp_dpu_kms_prepare_crtc_session(dcp_kms, crtc);
+ if (ret) {
+ cstate->hfi_error = ret;
+ return;
+ }
+
if (!dcp_crtc_get_session(crtc, &session_id)) {
cstate->hfi_error = -ENODEV;
return;
@@ -559,6 +565,7 @@ static int dcp_crtc_atomic_check(struct drm_crtc *crtc,
const struct drm_plane_state *pstate;
u32 max_width, max_height;
u32 mixer_count;
+ bool needs_dirtyfb;
int num_planes = 0;
int ret;

@@ -569,6 +576,8 @@ static int dcp_crtc_atomic_check(struct drm_crtc *crtc,
if (!crtc_state->enable || !crtc_state->active)
return 0;

+ needs_dirtyfb = dcp_dpu_kms_needs_dirtyfb(dcp_kms, crtc);
+
mixer_count = cstate->topology_mixer_count;
if (mixer_count < 1 || mixer_count > DCP_MAX_MIXERS) {
drm_err(crtc->dev,
@@ -598,8 +607,13 @@ static int dcp_crtc_atomic_check(struct drm_crtc *crtc,

/* Limit visible planes to the firmware blend-stage count. */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
+ struct dcp_plane_state *dcp_pstate;
+
if (!pstate || !pstate->visible)
continue;
+
+ dcp_pstate = to_dcp_plane_state((struct drm_plane_state *)pstate);
+ dcp_pstate->needs_dirtyfb = needs_dirtyfb;
num_planes++;
}

diff --git a/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c b/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c
index 44b1c2200aee..61a4d8565359 100644
--- a/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c
+++ b/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c
@@ -7,6 +7,27 @@
#include <drm/drm_crtc.h>

#include "dcp_dpu_kms.h"
+#include "dcp_dsi_bridge.h"
+
+int dcp_dpu_kms_prepare_crtc_session(struct dcp_dpu_kms *dcp_kms,
+ struct drm_crtc *crtc)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(dcp_kms->dsi_bridge); i++) {
+ struct dcp_dsi_bridge *bridge = dcp_kms->dsi_bridge[i];
+
+ if (!bridge)
+ continue;
+ if (dcp_dpu_kms_get_crtc(dcp_kms, bridge->fw_display_id) != crtc)
+ continue;
+
+ return dcp_dsi_bridge_prepare_session(bridge,
+ &crtc->state->adjusted_mode);
+ }
+
+ return -ENODEV;
+}

struct drm_crtc *dcp_dpu_kms_get_crtc(struct dcp_dpu_kms *dcp_kms,
u32 display_id)
@@ -19,3 +40,22 @@ struct drm_crtc *dcp_dpu_kms_get_crtc(struct dcp_dpu_kms *dcp_kms,

return NULL;
}
+
+bool dcp_dpu_kms_needs_dirtyfb(struct dcp_dpu_kms *dcp_kms,
+ struct drm_crtc *crtc)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(dcp_kms->dsi_bridge); i++) {
+ struct dcp_dsi_bridge *bridge = dcp_kms->dsi_bridge[i];
+
+ if (!bridge ||
+ dcp_dpu_kms_get_crtc(dcp_kms, bridge->fw_display_id) != crtc)
+ continue;
+
+ return bridge->dsi_device &&
+ !(bridge->dsi_device->mode_flags & MIPI_DSI_MODE_VIDEO);
+ }
+
+ return false;
+}
diff --git a/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h b/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h
index f8010fc5d32f..333567a78ad7 100644
--- a/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h
+++ b/drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h
@@ -44,6 +44,8 @@ struct dcp_dpu_kms {
#define to_dcp_dpu_kms(x) container_of(x, struct dcp_dpu_kms, base)
struct drm_crtc *dcp_dpu_kms_get_crtc(struct dcp_dpu_kms *dcp_kms,
u32 display_id);
+bool dcp_dpu_kms_needs_dirtyfb(struct dcp_dpu_kms *dcp_kms,
+ struct drm_crtc *crtc);
int dcp_dpu_kms_prepare_crtc_session(struct dcp_dpu_kms *dcp_kms,
struct drm_crtc *crtc);


--
2.43.0