On Thu, Sep 25, 2025 at 12:43:43PM +0800, Jun Nie wrote: > Dmitry Baryshkov <dmitry.barysh...@oss.qualcomm.com> 于2025年9月25日周四 03:21写道: > > > > 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? > > You mean there is only DSI data and all configuration is done via I2C/SPI, > right? I do not have a real use case so far, but it can be supported in the > same way. Panel driver finds the sibling panel via device tree to get the > peer I2C/SPI first. All commands are send to every bus in panel driver.
Not quite, because why and how should a normal DSI bridge driver know and care about the 'peer' device? How would you describe that in DT and in the DRM bridge chains framework? > > > > > > > > > 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....@linaro.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 -- With best wishes Dmitry