[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <v3tfzspjck2oqppelx7bmi5uflhs47ixw6tjmq2d7inauzfo7k@gxebj3buyuni>
Date: Wed, 24 Sep 2025 22:21:46 +0300
From: Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>
To: Jun Nie <jun.nie@...aro.org>
Cc: Rob Clark <robin.clark@....qualcomm.com>,
Abhinav Kumar <abhinav.kumar@...ux.dev>,
Jessica Zhang <jessica.zhang@....qualcomm.com>,
Dmitry Baryshkov <lumag@...nel.org>, Sean Paul <sean@...rly.run>,
Marijn Suijten <marijn.suijten@...ainline.org>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>,
Thomas Zimmermann <tzimmermann@...e.de>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>,
Krishna Manikandan <quic_mkrishn@...cinc.com>,
linux-arm-msm@...r.kernel.org, dri-devel@...ts.freedesktop.org,
freedreno@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
devicetree@...r.kernel.org
Subject: Re: [PATCH v3 3/3] drm/msm/dsi: Support dual panel use case with
single CRTC
On Wed, Sep 24, 2025 at 11:08:12PM +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.
I'd like to understand how is it framed on the overall system design
level. If it's a panel controlled over the DSI interface, it's fine
since we can broadcast commands over two DSI links. What if the panel
(or bridge) is controlled via I2C / SPI?
>
> 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.
>
> 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.
> 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@...aro.org>
> ---
> 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 de51cb02f267205320c5a94fc4188413e05907e6..1fddcea7f86547258be18a51a0a3e3f96f6c3838 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -177,6 +177,7 @@ struct msm_dsi_host {
> bool registered;
> bool power_on;
> bool enabled;
> + bool is_dual_panel;
> int irq;
> };
>
> @@ -935,7 +936,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);
>
> @@ -1609,6 +1613,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;
> @@ -2492,6 +2497,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.34.1
>
--
With best wishes
Dmitry
Powered by blists - more mailing lists