[PATCH v2 00/23] drm/msm/dcp: Add Qualcomm DCP display support

From: Jayant Shekhar

Date: Mon Oct 26 2026 - 02:22:09 EST


On Qualcomm platforms using the Display Co-Processor (DCP), the display
hardware is owned and programmed by firmware. Linux does not access the
display controller, DSI controller, DSI PHY, display clocks, or other
display pipeline registers.

The display pipeline must nevertheless be exposed through the DRM/KMS
interfaces so userspace can perform modesetting, framebuffer updates,
panel control, and page flips.

This series adds a DCP KMS backend to MSM DRM. It represents the
firmware-owned display pipeline and translates DRM operations into HFI
commands.

DCP communicates with Linux over VirtIO and uses the HFI protocol for
command and response handling, capability discovery, and display events.

This series adds:

- Device-tree bindings for the Qualcomm DCP VirtIO transport wrapper,
firmware-visible IOVA ranges, separate transport and framebuffer IOMMU
contexts, IPCC power notification, interrupts, and the external DSI
display graph.

- HFI protocol definitions and packet helpers for capability discovery,
modesetting, plane and CRTC configuration, DSI, and panel control.

- A Qualcomm DCP transport wrapper which initializes the IPCC channel,
sends the required power notification, and registers the DCP VirtIO
device directly. The wrapper also implements the MMIO transport and
keeps VirtIO queue activity ordered with DCP power transitions.

- VirtIO command and response queues. HFI command, response, and
capability buffers are allocated through the DMA API in the address
space visible to DCP firmware.

- Synchronous command tracking, asynchronous response dispatch, timeout
handling, and queue teardown synchronization for safe device removal.

- Capability discovery for displays, CRTCs, mixers, VIG and DMA pipes,
DSI interfaces, and panel resources.

- DRM planes and CRTCs using the standard atomic-state model. DRM state is
translated into HFI properties for layer configuration, mixer limits,
bandwidth and clock properties, frame sequencing, and triggering.

- An MSM KMS backend, DCP encoder, and DSI bridge. The backend reuses the
existing MSM DRM device, GEM and framebuffer handling, atomic commit
infrastructure, encoder, bridge, and connector support.

- Asynchronous VSYNC, frame-scan completion, and error events propagated to
DRM for vblank and page-flip completion.

- IPCC power notifications to wake DCP firmware and coordinate HFI queue
activity across firmware power transitions.

DCP is integrated as an MSM KMS backend rather than a separate DRM device.
This preserves the userspace-visible MSM DRM device and allows Linux to
retain normal DRM/KMS semantics while display hardware remains owned by
firmware.

The initial implementation supports the DSI output described below and
uses resources reported by firmware. Split-pipe, multirect, cursor-pipe,
partial-update, DisplayPort, and writeback support are deferred.

Tested on the Qualcomm Hawi MTP with an NT37801 DSC command-mode panel:

- Display console at 1440x3200.
- Panel initialization and DCS transfers complete successfully.

Device Tree Topology
====================

qcom,dcp-virtio
├── transport IOMMU context
├── firmware-visible iommu-ranges
├── VirtIO and power-notify interrupts
├── dcp-power-tx mailbox
└── dcp-subsystem
├── compatible = "virtio,device34"
├── framebuffer IOMMU context
├── port@0
│ └── endpoint ─────────────── panel endpoint
└── dsi@0
└── panel@0

The DCP INTF endpoint connects directly to the panel endpoint. Firmware
internal paths, including the INTF-to-DSI connection, are not described in
the device tree.

Runtime Architecture
====================

Linux DRM/KMS
└── DCP MSM KMS backend
├── planes, CRTCs, encoder, connector, and DSI bridge
└── DRM atomic state and commit handling
│
▼
DCP VirtIO function driver
│
▼
VirtIO core
│
▼
qcom,dcp-virtio transport wrapper
├── IPCC initialization and power notification
├── MMIO register access
├── VirtIO queue setup and interrupt handling
├── VirtIO device registration
└── suspend/resume power sequencing
│
▼
DCP firmware
├── HFI command and response handling
├── display pipeline and VIG/DMA pipes
├── DSI PHY and controller
└── display clocks and resource handling

Probe and Initialization Order
=============================

qcom,dcp-virtio platform probe
│
▼
Initialize IPCC and send the DCP power notification
│
▼
Access VirtIO MMIO registers and register the virtio_device
│
▼
VirtIO core matches the DCP function driver
│
▼
Initialize HFI and create command/response virtqueues
│
▼
Send DEVICE_INIT and discover firmware capabilities
│
▼
Register the MSM DRM/KMS backend

The transport must complete IPCC initialization and power notification
before it accesses the VirtIO MMIO registers. The DCP function driver is
matched only after the transport registers the virtio_device.

Dependencies
============

- The VPU IOMMU series provides the IOVA handling required by the DCP
VirtIO transport. The Hawi DT series provides the platform nodes and
IOMMU descriptions consumed by this series.

https://lore.kernel.org/all/20260926-vpu_iommu_iova_handling-v5-4-0322ca5dc10c@xxxxxxxxxxxxxxxx/

- The QPSFI VirtIO device ID used by the DCP transport is proposed in the
following virtio-comment discussion:

https://lore.kernel.org/virtio-comment/20261021180031.7175-1-peter.hilber@xxxxxxxxxxxxxxxx/T/#u

This series adds the corresponding device ID to
include/uapi/linux/virtio_ids.h and uses it to bind the DCP VirtIO function
driver.

Signed-off-by: Jayant Shekhar <jayant.shekhar@xxxxxxxxxxxxxxxx>
---
Changes in v2:
- Compared with v1, the series is split into smaller patches. (Dmitry)
- Reworked the VirtIO transport integration so the Qualcomm
`qcom,dcp-virtio` wrapper performs the required IPCC power
notification before accessing the VirtIO MMIO registers and
registering the virtio_device. The transport registers the device
directly.
- Reworked the DT topology so the DCP INTF output connects directly to
the panel endpoint. The firmware-internal INTF-to-DSI path is no
described in DT. (Dmitry)
- Updated the DCP VirtIO binding to document the Qualcomm VirtIO
transport and VirtIO MMIO register layout, Qualcomm power-notify
interrupt, IOMMU contexts, mailbox, and firmware-visible IOVA
range. (Dmitry)
- Removed the interrupt-names property and used the defined interrupt
ordering for the VirtIO and power-notify interrupts. (Dmitry)
- Added panel bridge and component integration so panel bridges are
resolved through the DCP DSI host before DRM registration. (Dmitry)
- Tracked CRTCs using firmware display IDs instead of DRM CRTC
iteration order. (Dmitry)
- Moved DSI DCS-buffer mapping into KMS hardware initialization,
after the IOMMU VM became available, with rollback unmapping on
failure and before VM teardown.
- Reworked IPCC resource handling to use managed IRQ and mailbox
cleanup. (Dmitry)
- Moved IRQ-wake handling to the suspend and resume paths. (Dmitry)
- Removed the ipcc_valid state and made IPCC initialization and teardown
follow the channel lifetime. (Dmitry)
- Embedded the HFI capability cache and removed unused capability fields,
feature flags, and callback state. (Dmitry)
- Removed VirtIO config-change capability re-query handling because
capabilities are consumed during initialization.
- Removed the temporary self-component shim and registered DCP DSI hosts
as components. (Dmitry)
- Added optional GPU component matching for the display-only DCP DRM
device. (Dmitry)
- Made HFI packet-ID allocation atomic across wraparound using cmpxchg().
(Dmitry)
- Updated bandwidth aggregation to ignore invisible planes and planes
without framebuffers. (Dmitry)
- Moved DSI topology values into atomic bridge state while keeping static
panel configuration separate from per-commit state. (Dmitry)
- Removed the unused DP catalog and resource path. (Dmitry)
- Removed unused HFI hotplug and error callback plumbing. (Dmitry)
- Simplified HFI buffer release paths for callers already holding the
command lock. (Dmitry)
- Exported the generic MSM GPU-component matching helper for the DCP
backend.
- Replaced deprecated DRM logging macros with DRM device logging helpers.
(Dmitry)
- Removed unused includes and fixed indentation, naming, logging, and
error-handling issues. (Dmitry)
- Removed status in DT bindings and commit subject. (Krzysztof)
- Documented the DSI host DT ABI: DSI hosts use the generic dsi@N node
naming convention, and their reg properties identify the corresponding
DCP output index. (Krzysztof)
- Fixed the Assisted-by trailer order. (Dmitry, Krzysztof)

- Link to v1: https://patch.msgid.link/20261015-jshekhar-drm-msm-dcp-v1-v1-0-48aad0fe4f72@xxxxxxxxxxxxxxxx

To: Rob Clark <robin.clark@xxxxxxxxxxxxxxxx>
To: Dmitry Baryshkov <lumag@xxxxxxxxxx>
To: Abhinav Kumar <abhinav.kumar@xxxxxxxxx>
To: Jessica Zhang <jesszhan0024@xxxxxxxxx>
To: Sean Paul <sean@xxxxxxxxxx>
To: Marijn Suijten <marijn.suijten@xxxxxxxxxxxxxx>
To: David Airlie <airlied@xxxxxxxxx>
To: Simona Vetter <simona@xxxxxxxx>
To: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx>
To: Maxime Ripard <mripard@xxxxxxxxxx>
To: Thomas Zimmermann <tzimmermann@xxxxxxx>
To: Rob Herring <robh@xxxxxxxxxx>
To: Krzysztof Kozlowski <krzk+dt@xxxxxxxxxx>
To: Conor Dooley <conor+dt@xxxxxxxxxx>
To: "Michael S. Tsirkin" <mst@xxxxxxxxxx>
To: Jason Wang <jasowangio@xxxxxxxxx>
To: Eugenio Pérez <eperezma@xxxxxxxxxx>
To: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx>
To: Jayant Shekhar <jayant.shekhar@xxxxxxxxxxxxxxxx>
To: Sumit Semwal <sumit.semwal@xxxxxxxxxx>
To: Christian König <christian.koenig@xxxxxxx>
To: Philipp Stanner <phasta@xxxxxxxxxx>
To: Bjorn Andersson <andersson@xxxxxxxxxx>
To: Konrad Dybcio <konradybcio@xxxxxxxxxx>
To: Abel Vesa <abelvesa@xxxxxxxxxx>
To: "Joerg Roedel (AMD)" <joro@xxxxxxxxxx>
To: Will Deacon <will@xxxxxxxxxx>
To: Robin Murphy <robin.murphy@xxxxxxx>
To: Flemin Jose <flemin.jose@xxxxxxxxxxxxxxxx>
To: Mahadevan P <mahap@xxxxxxxxxxxxxxxx>
To: Michael S. Tsirkin <mst@xxxxxxxxxx>
To: Jason Wang <jasowangio@xxxxxxxxx>
To: Eugenio Pérez <eperezma@xxxxxxxxxx>
Cc: virtualization@xxxxxxxxxxxxxxx
Cc: linux-arm-msm@xxxxxxxxxxxxxxx
Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx
Cc: freedreno@xxxxxxxxxxxxxxxxxxxxx
Cc: devicetree@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: virtualization@xxxxxxxxxxxxxxx
Cc: linux-media@xxxxxxxxxxxxxxx
Cc: linaro-mm-sig@xxxxxxxxxxxxxxxx
Cc: iommu@xxxxxxxxxxxxxxx

---
Jayant Shekhar (23):
dt-bindings: display: msm: Add Qualcomm DCP
drm/msm/dcp: Add HFI packet helpers
drm/msm/dcp: Add HFI device definitions
drm/msm/dcp: Add HFI display definitions
drm/msm/dcp: Add HFI panel definitions
drm/msm/dcp: Add HFI VirtIO transport
drm/msm/dcp: Handle asynchronous HFI responses
drm/msm/dcp: Add IPCC power notifications
drm/msm/dcp: Add generic HFI display commands
drm/msm/dcp: Add HFI DSI and panel commands
drm/msm/dcp: Add DCP CRTCs and shared plane state
drm/msm/dcp: Add DCP planes
drm/msm/dcp: Route HFI display events
drm/msm/dcp: Add DCP encoder
drm/msm/dcp: Add DCP DSI host and panel support
drm/msm/dcp: Integrate the DSI bridge with KMS
drm/msm/dcp: Register DCP display pipeline
virtio: Add Qualcomm Platform Services Firmware Interface ID
drm/msm/dcp: Add Qualcomm VirtIO transport wrapper
drm/msm/dcp: Add DCP VirtIO driver
drm/msm: Support KMS backends without a display IRQ
drm/msm: Register the DCP backend
arm64: dts: qcom: hawi: Add DCP support

.../bindings/display/msm/qcom,dcp-dsi.yaml | 79 ++
.../devicetree/bindings/display/msm/qcom,dcp.yaml | 123 +++
.../bindings/virtio/qcom,dcp-virtio.yaml | 132 +++
arch/arm64/boot/dts/qcom/hawi-mtp.dts | 129 +++
arch/arm64/boot/dts/qcom/hawi.dtsi | 40 +
drivers/gpu/drm/msm/Kconfig | 25 +
drivers/gpu/drm/msm/Makefile | 22 +
drivers/gpu/drm/msm/dcp/dcp_crtc.c | 739 +++++++++++++
drivers/gpu/drm/msm/dcp/dcp_crtc.h | 104 ++
drivers/gpu/drm/msm/dcp/dcp_dpu_kms.c | 686 ++++++++++++
drivers/gpu/drm/msm/dcp/dcp_dpu_kms.h | 59 +
drivers/gpu/drm/msm/dcp/dcp_drv.c | 191 ++++
drivers/gpu/drm/msm/dcp/dcp_drv.h | 46 +
drivers/gpu/drm/msm/dcp/dcp_dsi_bridge.c | 1110 +++++++++++++++++++
drivers/gpu/drm/msm/dcp/dcp_dsi_bridge.h | 76 ++
drivers/gpu/drm/msm/dcp/dcp_dsi_panel.h | 94 ++
drivers/gpu/drm/msm/dcp/dcp_encoder.c | 29 +
drivers/gpu/drm/msm/dcp/dcp_encoder.h | 16 +
drivers/gpu/drm/msm/dcp/dcp_hfi.h | 275 +++++
drivers/gpu/drm/msm/dcp/dcp_hfi_core.c | 1155 ++++++++++++++++++++
drivers/gpu/drm/msm/dcp/dcp_hfi_crtc.c | 191 ++++
drivers/gpu/drm/msm/dcp/dcp_hfi_dsi.c | 252 +++++
drivers/gpu/drm/msm/dcp/dcp_hfi_dsi_panel.c | 592 ++++++++++
drivers/gpu/drm/msm/dcp/dcp_hfi_encoder.c | 64 ++
drivers/gpu/drm/msm/dcp/dcp_hfi_kms.c | 366 +++++++
drivers/gpu/drm/msm/dcp/dcp_hfi_plane.c | 63 ++
drivers/gpu/drm/msm/dcp/dcp_hfi_priv.h | 48 +
drivers/gpu/drm/msm/dcp/dcp_ipcc.c | 173 +++
drivers/gpu/drm/msm/dcp/dcp_ipcc.h | 42 +
drivers/gpu/drm/msm/dcp/dcp_plane.c | 1056 ++++++++++++++++++
drivers/gpu/drm/msm/dcp/dcp_plane.h | 36 +
drivers/gpu/drm/msm/dcp/dcp_plane_state.h | 37 +
drivers/gpu/drm/msm/dcp/dcp_virtio.c | 258 +++++
drivers/gpu/drm/msm/dcp/dcp_virtio.h | 25 +
drivers/gpu/drm/msm/dcp/dcp_virtio_transport.c | 643 +++++++++++
drivers/gpu/drm/msm/dcp/hfi/hfi_commands_device.h | 78 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_commands_display.h | 105 ++
.../drm/msm/dcp/hfi/hfi_commands_display_events.h | 90 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_commands_panel.h | 27 +
drivers/gpu/drm/msm/dcp/hfi/hfi_defs_common.h | 182 +++
drivers/gpu/drm/msm/dcp/hfi/hfi_defs_device.h | 61 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_defs_display.h | 464 ++++++++
.../gpu/drm/msm/dcp/hfi/hfi_defs_display_color.h | 247 +++++
drivers/gpu/drm/msm/dcp/hfi/hfi_defs_panel.h | 287 +++++
.../gpu/drm/msm/dcp/hfi/hfi_pack_unpack_common.h | 79 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_packer.c | 106 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_packer.h | 65 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_packet.h | 76 ++
.../gpu/drm/msm/dcp/hfi/hfi_properties_device.h | 102 ++
.../gpu/drm/msm/dcp/hfi/hfi_properties_display.h | 480 ++++++++
drivers/gpu/drm/msm/dcp/hfi/hfi_properties_panel.h | 198 ++++
drivers/gpu/drm/msm/dcp/hfi/hfi_unpacker.c | 157 +++
drivers/gpu/drm/msm/dcp/hfi/hfi_unpacker.h | 77 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_utils.c | 62 ++
drivers/gpu/drm/msm/dcp/hfi/hfi_utils.h | 56 +
drivers/gpu/drm/msm/msm_drv.c | 8 +-
drivers/gpu/drm/msm/msm_drv.h | 10 +
drivers/gpu/drm/msm/msm_kms.c | 2 +-
include/uapi/linux/virtio_ids.h | 1 +
59 files changed, 11992 insertions(+), 4 deletions(-)
---
base-commit: 9a482184d910775cf648863148944945b74e2815
change-id: 20261022-jshekhar-dcp-hlos-c7c22b0ff7e4
prerequisite-patch-id: eecfd66a55b8f2b7b2fc7d76d815facca0489d00

Best regards,
--
Jayant Shekhar <jayant.shekhar@xxxxxxxxxxxxxxxx>