Re: [PATCH v5 4/6] drm/msm/dsi: Support dual panel use case with single CRTC
From: Jun Nie
Date: Wed Sep 30 2026 - 12:32:32 EST
Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxxxxxxxx> 于2026年9月30日周三 00:20写道:
>
> On Mon, Jul 27, 2026 at 04:08:43PM +0800, Jun Nie wrote:
> > Support a hardware configuration where two independent DSI panels are
> > driven by a single, synchronous CRTC. This configuration uses a bonded
> > DSI link to provide a unified vblank for both displays.
> >
> > This allows application software to treat the two displays as a single,
> > wide framebuffer with a synchronized refresh cycle, simplifying rendering
> > logic for side-by-side panel arrangements.
> >
> > At the DSI host level, the frame width for each link must be that of an
> > individual panel. The driver therefore halves the CRTC's horizontal
> > resolution before configuring the DSI host and any DSC encoders, ensuring
> > each panel receives the correct half of the framebuffer.
>
> I guess, the flag from the previous patch should be coming from the DT
> node of the DSI host. The DSI should then get the mode from a single
> panel and then set the adjusted_mode for the CRTC (note sure how this
> will work for the compositors though).
The original information comes from the panel. Panel driver exposes
the flag to dsi host. Because the panel driver hides all dual physical
panels stuff and exposes a single panel to DRM framework, so it exposes
the doubled mode to DRM framework level too. This simplifies the
handling of 2 physical panels in DRM level and compositors level.
>
>
> Also please note that the are other possible configurations. For
> example, for some time I've had a setup using two Raspberry panels
> attached to two DSI hosts for exactly the same purpose (please check, I
> think Neil might still have it, or maybe somebody else from the team).
> Each channel is an I2C-controlled DSI-to-DPI bridge + a DPI panel. I
> understand that it's not your target, but it's something to keep in
> mind. I'd say, the bare minimum would be to resolve a second bridge (be
> it a full bridge or a panel bridge), possibly create a second bridge
> chain (remember, bridges don't support branching, so you are a bit on
> your own here) and at least manually call the callbacks. This would
> ensure that the second panel (or a second bridge) is properly controlled
> (and thus would get rid of the second reset GPIO from your patches).
I asked Neil but he has no idea on this. Per your description, you have 2
DRM connectors/bridges for 2 physical panels. I guess you have topology:
1 CRTC + 2*(encoder / connector / bridge). The handling of 2 physical
panels falls into DRM level, not inside panel driver as this patch set.
This 2 methodology does not conflict in theory. Do you see and conflict in
implementation?
>
> > The pic_width is used to calculated DSC parameter for DPU DSC controller
> > together with panel's parameter. While panel driver that support dual
> > panel shall provide slice_width parameter of single panel. This patch
> > only impact DSC configuration, so crtc is not aware of it and not impacted
> > by it.
> >
> > While the DSI panel driver should manage two panels togehter.
> > 1. During probe, the driver finds the sibling dsi host via device tree
> > phandle and register the 2nd panel to get another mipi_dsi_device.
> > 2. Set dual_panel flag on both mipi_dsi_device.
> > 3. Prepare DSC data per requirement from single panel.
> > 4. All DSI commands should be send on every DSI link.
>
> broadcasting of DSI commands is controlled by the DT flag.
Do you mean the property, qcom,sync-dual-dsi? It is QCOM specific
feature to send DSI commands twice in host driver. It can be done
in panel side as well. The bonus to do in panel side is that the
panel driver is more generic and can work with other SoC in theory.
And the DSI commands can be handled together with regulators
etc for 2 physical panels in a centric way. The panel driver is
more self-contained, minimizing dependency on the dsi host.
>
> > 5. Handle power supply for 2 panels in one shot, the same is true to
> > brightness.
> > 6. From the CRTC's perspective, the two panels appear as one wide display.
> > The driver exposes a DRM mode where the horizontal timings (hdisplay,
> > hsync_start, etc.) are doubled, while the vertical timings remain those
> > of a single panel. Because 2 panels are expected to be mounted in
> > left/right position.
> >
> > To maintain synchronization, both DSI links are configured to share a
> > single clock source, with the DSI1 controller using the clock provided
> > to DSI0 as below.
> >
> > &mdss_dsi1 {
> > assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
> > <&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
> > assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>;
> > }
> >
> > Signed-off-by: Jun Nie <jun.nie@xxxxxxxxxx>
> > ---
> > drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +++++++++-
> > 1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index e39938fb0f502..a3c56c3dc7904 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -186,6 +186,7 @@ struct msm_dsi_host {
> > bool registered;
> > bool power_on;
> > bool enabled;
> > + bool is_dual_panel;
> > int irq;
> > };
> >
> > @@ -1024,7 +1025,10 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
> > return;
> > }
> >
> > - dsc->pic_width = mode->hdisplay;
> > + if (msm_host->is_dual_panel)
> > + dsc->pic_width = hdisplay;
> > + else
> > + dsc->pic_width = mode->hdisplay;
> > dsc->pic_height = mode->vdisplay;
> > DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
> >
> > @@ -1705,6 +1709,7 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
> > if (dsi->lanes > msm_host->num_data_lanes)
> > return -EINVAL;
> >
> > + msm_host->is_dual_panel = dsi->dual_panel;
> > msm_host->channel = dsi->channel;
> > msm_host->lanes = dsi->lanes;
> > msm_host->format = dsi->format;
> > @@ -2600,6 +2605,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
> > if (!msm_host->dsc)
> > return MODE_OK;
> >
> > + if (msm_host->is_dual_panel)
> > + pic_width = mode->hdisplay / 2;
> > +
> > if (pic_width % dsc->slice_width) {
> > pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
> > pic_width, dsc->slice_width);
> >
> > --
> > 2.43.0
> >
>
> --
> With best wishes
> Dmitry