Skip to content

FROMLIST: drm/msm: split DPU core IRQ handler under CONFIG_PREEMPT_RT - #1800

Open
namathak wants to merge 67 commits into
qualcomm-linux:tech/mm/drmfrom
namathak:tech-mm-drm
Open

namathak wants to merge 67 commits into
qualcomm-linux:tech/mm/drmfrom
namathak:tech-mm-drm

Conversation

@namathak

@namathak namathak commented Sep 9, 2026

Copy link
Copy Markdown

On a PREEMPT_RT kernel, dpu_core_irq() runs as a true hardirq handler, but it dispatches per-encoder callbacks that take sleepable locks (spinlock_t becomes an rt_mutex on RT, and some DRM-core locks reached through vblank/CRC/writeback handling are sleepable as well). Sleeping inside a hardirq handler is not allowed and eventually crashes the display, which is what happens after running GLMark2 for a while.

Split dpu_core_irq() into a minimal hardirq handler that only acknowledges the hardware and records which interrupts fired, plus a new dpu_core_irq_thread() that performs the actual callback dispatch from a real, preemptible IRQ thread. This split only takes effect under CONFIG_PREEMPT_RT; non-RT kernels keep dispatching callbacks directly from dpu_core_irq() as before.

irq_lock is changed from spinlock_t to raw_spinlock_t unconditionally, since the hardirq handler needs a lock that never sleeps under RT, and raw_spinlock_t behaves the same as spinlock_t on non-RT kernels.

dpu_core_irq() itself now takes irq_lock with plain raw_spin_lock() instead of raw_spin_lock_irqsave(), dropping the irqsave/irqrestore pair it previously needed as a bottom-half-safe spinlock user. This is safe because dpu_core_irq() only ever runs as a primary IRQ handler (hardirq context on non-RT, forced-thread primary handler on RT), both of which are always entered with local IRQs already disabled by genirq before the handler is called, so there is nothing left for irqsave to save here. dpu_core_irq_read(), by contrast, is called from process context and still needs raw_spin_lock_irqsave().

Link: https://lore.kernel.org/r/20260909-drm-mis-next-split-irq-v1-1-89bc9c512c53@oss.qualcomm.com
Fixes: 25fdd59 ("drm/msm: Add SDM845 DPU support")
Cc: stable@vger.kernel.org
CRs-Fixed: 4642652

nlaad-qcom and others added 30 commits September 8, 2026 17:49
Currently edid_read has value from previous connect session
and resulting in drm using older edid before new edid is available
in lt9611uxc.
Reset edid_read so that correct status is updated and correct edid
is available for drm.

Link: https://lore.kernel.org/lkml/20260202-lt9611uxc-reset-edid-v2-1-b1e1d72edc90@oss.qualcomm.com/
Signed-off-by: Ravi Agola <raviagol@qti.qualcomm.com>
Signed-off-by: Nilesh Laad <nilesh.laad@oss.qualcomm.com>
…upport

Add binding for the Lontium LT9211C bridge chip.

Link: https://lore.kernel.org/all/20260904-add-lt9211c-bridge-v8-1-36d66168e176@oss.qualcomm.com/
Signed-off-by: Yi Zhang <zhanyi@qti.qualcomm.com>
Signed-off-by: Nilesh Laad <nilesh.laad@oss.qualcomm.com>
Signed-off-by: Gopi Botlagunta <venkata.botlagunta@oss.qualcomm.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
LT9211C is a Single/Dual-Link DSI/LVDS or Single DPI input to
Single-Link/Dual-Link DSI/LVDS or Single DPI output bridge chip.
Extend the existing lontium-lt9211 driver to support DSI-to-LVDS
bridge configuration by detecting and handling both LT9211 and LT9211C
variants from a single driver.

Chip detection in lt9211_read_chipid() is extended to identify the
LT9211C by its distinct chip ID registers, and cross-checked against
the chip type requested by the DT compatible string to catch a
mismatched board/compatible combination.

Add LT9211C-specific regmap support and use lt9211_chip_data with
i2c_get_match_data() to provide per-chip configuration.

Five new functions implement the LT9211C DSI-to-LVDS initialisation
sequence: lt9211c_configure_rx(), lt9211c_autodetect_rx(),
lt9211c_configure_timing(), lt9211c_configure_plls() and
lt9211c_configure_tx().

Defer the remaining LT9211C initialization to a work item scheduled
from atomic_enable(), since RX auto-detection requires an active DSI
stream.

Link: https://lore.kernel.org/all/20260904-add-lt9211c-bridge-v8-2-36d66168e176@oss.qualcomm.com/
Signed-off-by: Yi Zhang <zhanyi@qti.qualcomm.com>
Signed-off-by: Nilesh Laad <nilesh.laad@oss.qualcomm.com>
Signed-off-by: Gopi Botlagunta <venkata.botlagunta@oss.qualcomm.com>
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Currently valid mode checks are only for hdisplay and vdisplay,
add htotal and vtotal to filter only specific modes.

Link:https://lore.kernel.org/lkml/20251126-lt9611uxc-modes-v2-1-34bf9b351921@oss.qualcomm.com/
Signed-off-by: Nilesh Laad <nilesh.laad@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
Add 3840x2160@30 mode in lt9611uxc modes to add support for
4K@30 resolution.

Link:https://lore.kernel.org/r/20251126-lt9611uxc-4k30-v2-1-3de0ea58c24e@oss.qualcomm.com
Signed-off-by: Nilesh Laad <nilesh.laad@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
…ster layout

Add the new DP-specific QSERDES COM v8 header file and update the
register layout to use DP-specific status register offsets for
C_READY_STATUS and CMN_STATUS registers.

Signed-off-by: Ritesh Kumar <ritesh.kumar@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
Fixes: 5b28991 ("phy: qualcomm: qmp-combo: Update QMP PHY with Glymur settings")
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260828-glymur-phy-v3-v3-1-8e73ce7c4636@oss.qualcomm.com
Update common DP PHY serdes and TX initialization tables with
corrected PLL control values (MODE0 instead of MODE1), updated
SSC step size, reset control, and various TX lane configuration
parameters including emphasis levels and driver enable settings.

Signed-off-by: Ritesh Kumar <ritesh.kumar@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260828-glymur-phy-v3-v3-2-8e73ce7c4636@oss.qualcomm.com
…tables

Update DP PHY initialization tables for all link rates (RBR, HBR,
HBR2, HBR3) with corrected VCO calibration codes, lock compare
values, SSC step sizes, clock forward config, and bias enable
settings for proper PLL programming across different data rates.

Signed-off-by: Ritesh Kumar <ritesh.kumar@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
Fixes: d10736d ("phy: qualcomm: qmp-combo: Add DP offsets and settings for Glymur platforms")
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260828-glymur-phy-v3-v3-3-8e73ce7c4636@oss.qualcomm.com
Rework the DP PHY runtime configuration by:
- Extracting common DP PHY initialization sequence into
  qmp_combo_configure_dp_phy_common() function that is shared
  between qmp_v456_configure_dp_phy() and qmp_v8_configure_dp_phy()
- Adding dp_aux_cfg2 field to qmp_phy_cfg structure to store the
  hardware-specific AUX_CFG2 register value
- Defining named constants (QSERDES_DP_PHY_AUX_CFG2_V456 and
  QSERDES_DP_PHY_AUX_CFG2_V8) for better code readability
  and maintainability
- Adding validation check to ensure dp_aux_cfg2 is properly
  configured for all hardware variants
- Updating qmp_v8_dp_aux_init() with corrected power-down control and
  bias enable settings
- Modifying qmp_v8_configure_dp_clocks() to add VCO divider programming
  and update auxless/LFPS timing parameters
- Refining qmp_v8_configure_dp_phy() with updated driver enable values,
  TSYNC override sequence, and additional status checks for proper
  PHY lock verification

Signed-off-by: Ritesh Kumar <ritesh.kumar@oss.qualcomm.com>
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260828-glymur-phy-v3-v3-4-8e73ce7c4636@oss.qualcomm.com
…o display_unprepare

msm_dp_display_disable() currently mixes stream-level shutdown
(disable VSC SDP, off pixel clk, clear power_on) with link-level
teardown (PSM config when sink_count==0, off_link, PHY re-init or
host PHY exit).

For DP MST the same link is shared across multiple streams, so
disabling one stream must not tear down the link. Move the
link-level steps into msm_dp_display_unprepare() so that
display_disable() handles only the per-stream sequence, mirroring
the split already present on the prepare path
(display_prepare_link vs display_set_mode / display_enable).

SST behaviour is unchanged: atomic_post_disable() still calls
display_disable() followed by display_unprepare() in the same
order, and the cached dp->panel used inside unprepare is the same
panel that was previously passed in.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-1-c91d35d6fb9e@oss.qualcomm.com/
Replace the (rate, stream_rate_khz, is_ycbcr_420) parameter triple with
(panel, rate); both values are already derivable from panel->msm_dp_mode.

This lets config_msa() use panel->stream_id when writing
SOFTWARE_MVID/NVID for MST streams, added by a later patch.

No functional change.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-2-c91d35d6fb9e@oss.qualcomm.com/
…trl_on_stream()

REG_DP_CONFIGURATION_CTRL contains link-wide state and is already
programmed during link training.

Calling config_ctrl_link() from msm_dp_ctrl_on_stream() rewrites the
same configuration and is unnecessary. Remove the redundant call.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-3-c91d35d6fb9e@oss.qualcomm.com/
With MST, each DP controller can handle multiple streams. There shall be
one dp_panel for each stream but the dp_display object shall be shared
among them. To represent this abstraction, add a stream_id field to
struct msm_dp_panel and introduce the msm_dp_stream_id enum. For SST,
the field is initialized to DP_STREAM_0.

In the MST path, each panel will be assigned an actual stream_id at
stream-enable time by the MST layer (added in later patches).

Use the stream ID to control the pixel clock of that respective stream by
extending the clock handles and state tracking of the DP pixel clock to
an array of max supported streams. The maximum streams currently is 4.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-4-c91d35d6fb9e@oss.qualcomm.com/
…locks

Add support for additional pixel register blocks (p1, p2, p3) to enable
4‑stream MST pixel clocks. Introduce the helper functions msm_dp_read_pn
and msm_dp_write_pn for pixel register programming. All pixel clocks
share the same register layout but use different base addresses.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-5-c91d35d6fb9e@oss.qualcomm.com/
Add the stream-1 (DP1) and MST-link register definitions together with
msm_dp_stream_reg(), a helper that translates stream-0 register offsets
into their stream-specific equivalents.

Keeping the register definitions and translation helper together ensures
that all supported mappings are defined in one place.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-6-c91d35d6fb9e@oss.qualcomm.com/
DisplayPort MST uses multiple stream-specific register spaces. Streams
0 and 1 share the primary link register block with different register
offsets, while streams 2 and 3 use dedicated MST link register blocks.

Add stream-aware register access helpers that translate stream-specific
register offsets and route accesses to the appropriate register space
based on the stream id.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-7-c91d35d6fb9e@oss.qualcomm.com/
Whenever virtual channel slot allocation changes, the DP
source must send the action control trigger sequence to notify
the sink about the same. This would be applicable during the
start and stop of the pixel stream. Add the infrastructure
to be able to send ACT packets for the DP controller when
operating in MST mode.

Add REG_DP_MST_ACT, the ACT trigger register used by this sequence.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-8-c91d35d6fb9e@oss.qualcomm.com/
Add support to program the MST enable bit in the mainlink control
register when an MST session is active or being disabled.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-9-c91d35d6fb9e@oss.qualcomm.com/
DP stream is transmitted in transfer units only for SST
case, there is no need to calculate and program TU parameters
for MST case. Skip the TU programming for MST cases.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-10-c91d35d6fb9e@oss.qualcomm.com/
…se cases

As per the hardware programming guide, MST_FIFO_CONSTANT_FILL must
always be programmed when operating in MST mode. Ensure the register
is configured accordingly.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-11-c91d35d6fb9e@oss.qualcomm.com/
…roller

The VC Payload Fill (VCPF) sequence is inserted by the DP controller
when stream symbols are absent, typically before a stream is disabled.
Add support for triggering the VCPF sequence in the MSM DP controller.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-12-c91d35d6fb9e@oss.qualcomm.com/
DP MST streams share 64 MTP slots in a time-multiplexed manner. Add
support for calculating the rate governor, slot allocation, and slot
reservation in the DP controller.

Each MST stream can reserve its slots by calling
msm_dp_display_set_stream_info() from its bridge callbacks.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-13-c91d35d6fb9e@oss.qualcomm.com/
The power_on boolean cannot represent DP MST, where multiple streams
share a single link and its associated resources.

Replace power_on with active_stream_cnt and use it to track the lifetime
of the shared link. Link initialization is performed when enabling the
first stream, while link teardown is deferred until the last stream is
disabled.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-14-c91d35d6fb9e@oss.qualcomm.com/
…ting a panel

The atomic bridge callbacks (set_mode / enable / disable /
post_disable) on dp_display currently hard-code dp->panel. For
DP MST every stream has its own msm_dp_panel that the MST
encoder owns, so the same enable/disable sequence needs to be
invokable against an arbitrary panel.

Introduce *_helper variants that take struct msm_dp_panel * and
reduce the existing atomic_* callbacks to thin wrappers that
pass dp->panel. No SST-path behaviour change.

Also drop the static qualifier from msm_dp_display_prepare_link()
and msm_dp_display_unprepare() and change them to take
struct msm_dp * so the upcoming MST encoder code can drive
link-level prepare/unprepare uniformly through the public API.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-15-c91d35d6fb9e@oss.qualcomm.com/
In MST mode, multiple streams share the same DP link. Track a link_ready
state so msm_dp_display_prepare_link() runs only once per link and
repeated calls are skipped.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-16-c91d35d6fb9e@oss.qualcomm.com/
… panel

Add an API msm_dp_display_get_panel() to initialize and return a DP
panel to be used by DP MST module. Since some of the fields of
DP panel are private, dp_display module needs to initialize these
parts and return the panel back.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-17-c91d35d6fb9e@oss.qualcomm.com/
Add the dp_mst_drm module and the core MST manager data structures.

Introduce the MST manager object, per-stream encoder state and the
initialization path for creating a DRM MST topology manager associated
with a DP controller.

Also add the registration hooks used to initialize the MST manager
during DP device setup.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-18-c91d35d6fb9e@oss.qualcomm.com/
Register the add_connector topology callback with the DRM MST manager
to create DRM connectors dynamically for MST ports as they appear.

Each MST port is represented by a DRM connector. The connectors are
attached to all available MST stream encoders, allowing encoder
assignment to be determined dynamically rather than being permanently
associated with a specific stream.

This enables MST sink ports to be exposed as DRM connectors.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-19-c91d35d6fb9e@oss.qualcomm.com/
Derive the controller ID from disp_info->h_tile_instance[index] instead
of passing it separately to dpu_encoder_get_intf().

This removes a redundant argument and keeps all interface selection
parameters in msm_display_info.

No functional change.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-20-c91d35d6fb9e@oss.qualcomm.com/
For MST, multiple streams can share the same DP controller, making
(controller_id, intf_type) insufficient to uniquely identify a DPU
interface.

Add stream_id to msm_display_info and use it to select the matching
interface for a stream.

For DSI, eDP and SST configurations, stream_id remains zero and
behavior is unchanged.

Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260831-msm-dp-mst-v6-21-c91d35d6fb9e@oss.qualcomm.com/
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side.

Pass IRQ_HPD events from the firmware to the HPD bridge, letting those
to be delivered to the DisplayPort driver.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Acked-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260608-hpd-irq-events-v4-7-30b62b335487@oss.qualcomm.com/
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side.

Pass IRQ_HPD events from the EC to the HPD bridge, letting those
to be delivered to the DisplayPort driver.

Reviewed-by: Pengyu Luo <mitltlatltl@gmail.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260608-hpd-irq-events-v4-8-30b62b335487@oss.qualcomm.com/
…g events

The bridge connector framework currently invokes all bridge
hpd_notify() callbacks and unconditionally emits a connector hotplug
event afterwards.

However, not every HPD notification requires a userspace hotplug event.

In particular, DP MST bridges may use hpd_notify() to propagate HPD and
IRQ notifications through the bridge chain while the actual hotplug
handling is performed by the DRM DP MST core. Connector creation,
removal and userspace hotplug events are already managed by the MST
topology framework.

Allow hpd_notify() implementations to suppress the bridge connector
hotplug event by introducing a bool *send_hotplug parameter. Drivers
can clear this flag when HPD processing should not result in a
connector hotplug notification.

A NULL pointer indicates that hotplug suppression is not supported by
the caller, such as the connector detect polling path.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260629-msm-dp-msttypec-v1-1-646a10256233@oss.qualcomm.com/
…y HPD events

The bridge connector HPD handling path currently updates
connector->status for every hpd_notify() invocation.

This does not work well for IRQ-only notifications where the event being
reported is carried by extra_status and no connector status transition is
associated with it.

One example is DP MST. HPD IRQs are propagated through
drm_bridge_hpd_notify_*() so that bridge drivers can process the
notification. During MST operation, however, the SST connector attached
to the bridge connector is intentionally kept disconnected while the MST
topology manager handles all connector creation, removal and hotplug
processing.

Updating connector->status for an IRQ-only MST notification may cause
the SST connector state to oscillate between connected and disconnected
depending on the notification path. These artificial state transitions
can later be detected by the polling logic and result in unnecessary
hotplug events being generated. Userspace then re-probes connector
status, potentially triggering the same sequence again.

Treat notifications with status == connector_status_unknown and a valid
extra_status as IRQ-only events. Forward the notification to bridge
drivers without modifying connector->status.

This keeps IRQ delivery working while leaving connector state management
to the component that actually owns it, such as the DP MST topology
framework.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260629-msm-dp-msttypec-v1-2-646a10256233@oss.qualcomm.com/
…tion

The DP MST framework already generates the required hotplug events for
MST topology changes.

Suppress connector hotplug event generation from the bridge connector
path while MST is active, and continue propagating HPD notifications to
the DP driver.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260629-msm-dp-msttypec-v1-3-646a10256233@oss.qualcomm.com/
MST reuses the SST connector bridge to propagate HPD IRQ events through
the bridge chain.

For IRQ_HPD notifications there is no connector state transition to
report. Use connector_status_unknown together with
DRM_CONNECTOR_DP_IRQ_HPD so that the bridge connector framework treats
them as IRQ-only notifications and forwards them without modifying
connector state.

The DP driver handles IRQ_HPD events based on
DRM_CONNECTOR_DP_IRQ_HPD rather than connector status transitions.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260629-msm-dp-msttypec-v1-4-646a10256233@oss.qualcomm.com/
…locks

The LT9611UXC bridge can fetch only 2 EDID blocks at a time, which
previously limited EDID reading to 2 blocks and prevented support
for displays exposing more than 2 EDID blocks.

Add driver support to fetch up to 4 EDID blocks by re-triggering
EDID access after the first 2 blocks are read. For block 0 and 2,
set the EDID ready flag in 0xb028 so the bridge can expose the
corresponding EDID blocks, then retry the read until the expected
EDID is fetched.

Reset the edid_read flag on HPD disconnect so that the next
connect event triggers a fresh EDID fetch.

Increase EDID wait time from 500ms to 1000ms, On Qualcomm rb3gen2
platform sometimes edid read interrupt is coming 600-650 ms after
HPD interrupt resulting in edid read failure.

Signed-off-by: Ravi Agola <raviagol@qti.qualcomm.com>
Link: https://lore.kernel.org/all/20260722-lt9611usc_edid34_misc_next-v3-1-7ec2bba6ff8e@oss.qualcomm.com/
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
Kaanapali (SM8750) and Glymur use two display power domains.
CORE_GDSC powers the main display hardware while INT2_GDSC powers
a subset of SSPP blocks (VIG2/VIG3/DMA5/DMA6).

The MDSS driver currently relies on the default runtime PM handling
and does not enable the secondary INT2_GDSC. As a result, display
pipes backed by INT2_GDSC remain inaccessible.

Attach and manage both power domains explicitly and enable them
during MDSS runtime PM activation.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260720-msm_gdsc2-v1-2-4687866d6cb0@oss.qualcomm.com/
Kaanapali (SM8750) and Glymur use two display power domains.
CORE_GDSC powers the main display hardware while INT2_GDSC
powers a subset of SSPP blocks.

Allow the MDSS bindings to describe both power domains and
their corresponding power-domain-names values.

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260720-msm_gdsc2-v1-1-4687866d6cb0@oss.qualcomm.com/
…o HDMI driver

LT9611C(EX/UXD) is an I2C-controlled chip that Receiver signal/dual port
mipi dsi and output hdmi, differences in hardware features:
- LT9611C: supports 1-port mipi dsi to hdmi 1.4
- LT9611EX: supports 2-port mipi dsi to hdmi 1.4
- LT9611UXD: supports 2-port mipi dsi to hdmi 1.4/2.0

Link: https://lore.kernel.org/all/20260808-lt9611c-v7-v10-1-ee90a136d82a@oss.qualcomm.com/
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Sunyun Yang <syyang@lontium.com>
Signed-off-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
…iver

LT9611C(EX/UXD) is an I2C-controlled chip that Receiver signal/dual port
mipi dsi and output hdmi, differences in hardware features:
- LT9611C: supports 1-port mipi dsi to hdmi 1.4
- LT9611EX: supports 2-port mipi dsi to hdmi 1.4
- LT9611UXD: supports 2-port mipi dsi to hdmi 1.4/2.0

Link: https://lore.kernel.org/all/20260808-lt9611c-v7-v10-2-ee90a136d82a@oss.qualcomm.com/
Signed-off-by: Sunyun Yang <syyang@lontium.com>
Co-developed-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
Signed-off-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
…er_shutdown()

drm_atomic_helper_shutdown() disables all CRTCs but leaves output
polling and IRQ-driven hot-plug detection running. On reboot, a late
DP hot-plug-detect (HPD) IRQ can fire after apps_smmu has already
disabled translation for the display subsystem, causing the HPD
thread to kick off a new modeset that drives DPU/DP hardware and DMA
through a stale IOMMU mapping.

drm_atomic_helper_shutdown() disables all CRTCs first, but a pending
HPD IRQ thread wakes up afterwards, reads the DPCD, and fires an
unsolicited hotplug event that triggers a second atomic commit
turning the display back on -- right as the IOMMU is disabling
translation:

  systemd-shutdown[1]: Rebooting.
  msm_dpu: drm_atomic_commit: committing (shutdown disabling CRTCs)
  arm-smmu 3da0000.iommu: disabling translation
  msm_dpu: drm_dp_read_dpcd_caps (late HPD IRQ thread wakes up)
  msm_dpu: drm_sysfs_connector_hotplug_event: DP-1 hotplug event
  msm_dpu: drm_client_modeset_probe: DP-1 found preferred mode
  msm_dpu: drm_atomic_commit: committing (unsolicited, re-enables display)
  dpu_crtc_commit_kickoff: crtc94 first commit
  arm-smmu 15200000.iommu: disabling translation

drm_kms_helper_poll_fini() tears down this: it stops the output poll
worker and calls each connector's &drm_connector_helper_funcs.disable_hpd,
which for HPD-capable bridges masks the interrupt in hardware.

Reported on Qualcomm platforms such as lemans-evk and monaco-evk
during reboot stress testing.

Assisted-by: Claude:claude-sonnet-5
Link: https://lore.kernel.org/all/20260730-dpshutdown-v2-1-441fc5543bed@oss.qualcomm.com/
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
…ithout UBWC

Certain Qualcomm targets like QCM2290 and Shikra do not have UBWC
support. On such targets, advertising DRM_FORMAT_MOD_QCOM_COMPRESSED
in the supported modifier list causes userspace to attempt UBWC
allocations that the kernel rejects:

  msm_dpu: [drm] *ERROR* unsupported format modifier 500000000000003
  msm_dpu: [drm] *ERROR* unsupported pixel format: AR24 little-endian

On platforms without UBWC, only advertise DRM_FORMAT_MOD_LINEAR to
avoid exposing formats that the hardware cannot handle.

Fixes: 71c5c23 ("drm/msm/dpu: check ubwc support before adding compressed formats")
Link: https://lore.kernel.org/r/20260819-remove_ubwc-v1-1-5357d5cc517f@oss.qualcomm.com
Signed-off-by: Mahadevan P <mahadevan.p@oss.qualcomm.com>
…is initializing

The Type-C mux switch guard only checked dp_powered_on, which is set in
qmp_combo_dp_power_on(). However there is a race window between
qmp_combo_dp_init() and qmp_combo_dp_power_on() during which dp_init_count
is non-zero but dp_powered_on is still false. A Type-C orientation change
arriving in this window would proceed with the mux switch while the DP PHY
is mid-initialization, corrupting the PHY state.

Extend the guard to also block the mux switch when dp_init_count is
non-zero, covering the full period from dp_init through dp_power_on.
Link: https://lore.kernel.org/all/20260824-qcom-dp-typec-reconnect-fixes-v1-1-2825e5bf8a96@oss.qualcomm.com/

Signed-off-by: Saurabh Anand <saurabh.anand@oss.qualcomm.com>
…succeeds

msm_dp_display_prepare_link() sets force_link_train = true before calling
msm_dp_ctrl_on_link(). On success the flag was never cleared, so
msm_dp_ctrl_prepare_stream_on() would unconditionally trigger a second
link retrain even though the link was already trained.

Clear force_link_train on the success path so that
msm_dp_ctrl_prepare_stream_on() only retrains when the channel EQ check
fails, as intended.
Link: https://lore.kernel.org/all/20260824-qcom-dp-typec-reconnect-fixes-v1-2-2825e5bf8a96@oss.qualcomm.com/

Signed-off-by: Saurabh Anand <saurabh.anand@oss.qualcomm.com>
drm_dp_lttpr_count() returns 0 when no LTTPRs are detected and a
negative value on error. The previous code passed the result directly
to drm_dp_lttpr_init() without checking, which would call into the
LTTPR transparency-mode setup with a zero or negative repeater count.

Add an early return for lttpr_count <= 0 to skip the init entirely
when there are no repeaters in the link, matching the expected usage
of drm_dp_lttpr_init().
Link: https://lore.kernel.org/all/20260824-qcom-dp-typec-reconnect-fixes-v1-3-2825e5bf8a96@oss.qualcomm.com/

Signed-off-by: Saurabh Anand <saurabh.anand@oss.qualcomm.com>
…still plugged

During a Type-C reconnect the AUX channel may report link-disconnected
transiently while the physical cable is still present. The link training
retry loop in msm_dp_ctrl_on_link() was aborting immediately on any
msm_dp_aux_is_link_connected() failure, preventing the rate/lane downgrade
path from running.

When the display is known to be plugged (msm_dp_ctrl->plugged), an AUX
link-disconnected status is likely a transient glitch rather than a true
unplug. Allow the downgrade loop to continue in that case by requiring both
conditions before breaking out of the retry loop: AUX reports disconnected
and the display is not plugged.

The plugged state is snapshotted from dp_display into msm_dp_ctrl just
before msm_dp_ctrl_on_link() is called, so the retry loop has an accurate
view of cable presence at the time link training started.
Link: https://lore.kernel.org/all/20260824-qcom-dp-typec-reconnect-fixes-v1-4-2825e5bf8a96@oss.qualcomm.com/

Signed-off-by: Saurabh Anand <saurabh.anand@oss.qualcomm.com>
…0NB-A001

Add the BOE 0x0b21 panel entry used in the K&D Technology
KD116N36-30NB-A001 eDP LCM, place the EDID here for subsequent
reference. Timing values come from the KD116N36-30NB-A001 spec.

00 ff ff ff ff ff ff 00 09 e5 21 0b 00 00 00 00
01 1e 01 04 a5 1a 0e 78 0a 24 10 97 59 54 8e 27
1e 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 b2 39 80 d4 70 38 4b 40 30 20
36 00 04 8c 10 00 00 1a 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 1a 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe
00 51 56 31 31 36 46 48 42 2d 4e 38 31 0a 00 b3

Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260901-edp-id-boe-v1-1-f5e2c44255f7@oss.qualcomm.com
…nable

If a downstream consumer (e.g. drm_bridge_connector attached by the
msm/dp driver) registers its HPD callback after an upstream driver
has already reported a HPD event through drm_aux_hpd_bridge_notify(),
the notification is dropped because bridge->hpd_cb is still NULL.
This can affect any user of drm_aux_hpd_bridge_notify() whose
downstream consumer arms HPD only after upstream events have started.

The race has been observed on Qualcomm X1E-based laptops during boot,
when pmic_glink_altmode reports the initial USB-C DP connection state
before the DP driver has finished probing and enabled HPD handling on
the bridge. The consumer then never observes the initial connected
state and the external display remains dark.

Cache the last HPD status reported through drm_aux_hpd_bridge_notify()
and replay it when HPD is enabled by the downstream consumer.

The replay is deferred to a work item so that the replayed HPD
notification is delivered outside drm_bridge_hpd_enable()'s call
context.

This follows the same pattern as display-connector, which also defers
an initial HPD notification from .hpd_enable(), but reuses the cached
status since aux-hpd-bridge cannot re-detect sink presence on its own.

Fixes: e560518 ("drm/bridge: implement generic DP HPD bridge")
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Link: https://lore.kernel.org/all/20260803-drm-usbdp-preboot-v1-1-2539b362be00@oss.qualcomm.com/
Add BOE DV215FHM-R01 21.5" FHD (1920x1080) dual-channel LVDS panel
compatible string to the panel-simple-lvds-dual-ports binding.

Link: https://lore.kernel.org/all/20260903-b4-lvds-panel-doc-v4-1-861738a0d5de@oss.qualcomm.com/
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Acked-by: Liu Ying <victor.liu@nxp.com>
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
Add the BOE DV215FHM-R01 21.5" FHD (1920x1080) dual-channel
LVDS panel.

Link: https://lore.kernel.org/all/20260903-b4-lvds-panel-doc-v4-2-861738a0d5de@oss.qualcomm.com/
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
Lontium LT9211 driver is extended to support LT9211C bridge,
which is available on qualcomm ifp mezzanine boards of lemans/monaco
and QCS6490 RB3GEN2 Industrial Kit.

Link: https://lore.kernel.org/all/20260907-for-next-lt9211-defconfig-v2-1-c9af0c085b78@oss.qualcomm.com/
Signed-off-by: Vishnu Saini <vishnu.saini@oss.qualcomm.com>
On a PREEMPT_RT kernel, dpu_core_irq() runs as a true hardirq handler,
but it dispatches per-encoder callbacks that take sleepable locks
(spinlock_t becomes an rt_mutex on RT, and some DRM-core locks reached
through vblank/CRC/writeback handling are sleepable as well). Sleeping
inside a hardirq handler is not allowed and eventually crashes the
display, which is what happens after running GLMark2 for a while.

Split dpu_core_irq() into a minimal hardirq handler that only
acknowledges the hardware and records which interrupts fired, plus a
new dpu_core_irq_thread() that performs the actual callback dispatch
from a real, preemptible IRQ thread. This split only takes effect
under CONFIG_PREEMPT_RT; non-RT kernels keep dispatching callbacks
directly from dpu_core_irq() as before.

irq_lock is changed from spinlock_t to raw_spinlock_t unconditionally,
since the hardirq handler needs a lock that never sleeps under RT, and
raw_spinlock_t behaves the same as spinlock_t on non-RT kernels.

dpu_core_irq() itself now takes irq_lock with plain raw_spin_lock()
instead of raw_spin_lock_irqsave(), dropping the irqsave/irqrestore
pair it previously needed as a bottom-half-safe spinlock user. This is
safe because dpu_core_irq() only ever runs as a primary IRQ handler
(hardirq context on non-RT, forced-thread primary handler on RT), both
of which are always entered with local IRQs already disabled by genirq
before the handler is called, so there is nothing left for irqsave to
save here. dpu_core_irq_read(), by contrast, is called from process
context and still needs raw_spin_lock_irqsave().

Link: https://lore.kernel.org/r/20260909-drm-mis-next-split-irq-v1-1-89bc9c512c53@oss.qualcomm.com
Fixes: 25fdd59 ("drm/msm: Add SDM845 DPU support")
Cc: stable@vger.kernel.org
Signed-off-by: Naman S Thaker <namathak@qti.qualcomm.com>
@qswat-orbit-external

Copy link
Copy Markdown

Dev Completion validation failed

CR: 4642652
Change Task: kernel.qli.0.0
Error: GenAI Assisted field must be set before moving change tasks to Development Complete. Please provide GenAI information.

The change task for this CR could not be moved to Dev Complete because of the error above. Please resolve the issue in Orbit and re-run the failed Orbit check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants