Devicetree
 help / color / mirror / Atom feed
* [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode
@ 2026-05-21 14:46 Jun Nie
  2026-05-21 14:46 ` [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1 Jun Nie
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie, Jonathan Marek

The 2 DSI interfaces may be connected to 2 independent panels in bonded-DSI
mode. Horizontal timing and DSC configuration are adjusted per individual
panel in DSI host side. Support to multiple slice per packet is added for
the device setup to test the usage case. A panel driver is included as an
use case example.

Changes vs v3:
- A panel driver is added as an use case example.
- Move dsc_slice_per_pkt to struct drm_dsc_config.
- Polish commit messages.
- Link to v3: https://lore.kernel.org/all/20250924-dsi-dual-panel-upstream-v3-0-6927284f1098@linaro.org

Changes vs v2:
- Polish commit message to describe usage case and requirements to
  panel driver.
- Remove changes in device tree and add dual_panel flag in mipi_dsi_device
  to pass information from panel to dsi host.
- Drop the register programming to DSI_VBIF_CTRL, as no issue is seen
  in latest test.
- Link to v2: https://lore.kernel.org/r/20250220-dual-dsi-v2-0-6c0038d5a2ef@linaro.org

Change vs v1:
- Add device tree binding for dual panel case in handling frame width for
  DSC to avoid breaking existing dual-DSI case.
- Leverage Marijn's patch to configure proper slice per interface in
  dsi_update_dsc_timing().
- Polish commit comments.
- Link to v1: https://lore.kernel.org/all/20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-v1-0-bdb05b4b5a2e@linaro.org/

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
Jun Nie (5):
      drm/msm/dsi: support DSC configurations with slice_per_pkt > 1
      drm/mipi-dsi: Add flag to support dual-panel configurations
      drm/msm/dsi: Support dual panel use case with single CRTC
      dt-bindings: display: Add Synaptics R63455 panel support
      drm/panel: Add driver for Synaptics R63455 DSI panel

 .../bindings/display/panel/synaptics,r63455.yaml   | 125 ++++
 drivers/gpu/drm/msm/dsi/dsi_host.c                 |  33 +-
 drivers/gpu/drm/panel/Kconfig                      |   9 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-synaptics-r63455.c     | 631 +++++++++++++++++++++
 include/drm/display/drm_dsc.h                      |   7 +
 include/drm/drm_mipi_dsi.h                         |   2 +
 7 files changed, 792 insertions(+), 16 deletions(-)
---
base-commit: 6654f8f33aa6229a90d4401519a62a2bf96cb851
change-id: 20260521-sm8650-7-1-bonded-dsi-7a7d5b70f687

Best regards,
-- 
Jun Nie <jun.nie@linaro.org>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1
  2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
@ 2026-05-21 14:46 ` Jun Nie
  2026-05-21 15:08   ` sashiko-bot
  2026-05-21 14:46 ` [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations Jun Nie
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie, Jonathan Marek

Some panels require multiple slice to be sent in a single DSC packet. And
this feature is a must for specific panels, such as Sharp ls026b3sa06. Add
a dsc_slice_per_pkt member into struct drm_dsc_config and support the
feature in msm mdss driver.

Co-developed-by: Jonathan Marek <jonathan@marek.ca>
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 23 ++++++++---------------
 include/drm/display/drm_dsc.h      |  7 +++++++
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 53ff23f4f68ab..d14b6e41dcd90 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -166,6 +166,7 @@ struct msm_dsi_host {
 
 	struct drm_display_mode *mode;
 	struct drm_dsc_config *dsc;
+	unsigned int dsc_slice_per_pkt;
 
 	/* connected device info */
 	unsigned int channel;
@@ -938,17 +939,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
 	slice_per_intf = dsc->slice_count;
 
 	total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
-	bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+	bytes_per_pkt = dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt;
 
 	eol_byte_num = total_bytes_per_intf % 3;
-
-	/*
-	 * Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
-	 *
-	 * Since the current driver only supports slice_per_pkt = 1,
-	 * pkt_per_line will be equal to slice per intf for now.
-	 */
-	pkt_per_line = slice_per_intf;
+	pkt_per_line = slice_per_intf / msm_host->dsc_slice_per_pkt;
 
 	if (is_cmd_mode) /* packet data type */
 		reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
@@ -1104,12 +1098,8 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
 		else
 			/*
 			 * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1.
-			 * Currently, the driver only supports default value of slice_per_pkt = 1
-			 *
-			 * TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info
-			 *       and adjust DSC math to account for slice_per_pkt.
 			 */
-			wc = msm_host->dsc->slice_chunk_size + 1;
+			wc = msm_host->dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt + 1;
 
 		dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
 			DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1719,8 +1709,11 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
 	msm_host->lanes = dsi->lanes;
 	msm_host->format = dsi->format;
 	msm_host->mode_flags = dsi->mode_flags;
-	if (dsi->dsc)
+	if (dsi->dsc) {
 		msm_host->dsc = dsi->dsc;
+		/* for backwards compatibility, assume 1 if not set */
+		msm_host->dsc_slice_per_pkt = dsi->dsc->dsc_slice_per_pkt ?: 1;
+	}
 
 	if (msm_host->format == MIPI_DSI_FMT_RGB101010) {
 		if (!msm_dsi_host_version_geq(msm_host, MSM_DSI_VER_MAJOR_6G,
diff --git a/include/drm/display/drm_dsc.h b/include/drm/display/drm_dsc.h
index bbbe7438473d3..c522ab3d71853 100644
--- a/include/drm/display/drm_dsc.h
+++ b/include/drm/display/drm_dsc.h
@@ -267,6 +267,13 @@ struct drm_dsc_config {
 	 * Offset adjustment for second line in Native 4:2:0 mode
 	 */
 	u16 second_line_offset_adj;
+
+	/**
+	 * @dsc_slice_per_pkt:
+	 * Number of DSC slices to be sent in a single packet. This is not
+	 * part of DSC standard, and only used in some DSI panels so far.
+	 */
+	unsigned int dsc_slice_per_pkt;
 };
 
 /**

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations
  2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
  2026-05-21 14:46 ` [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1 Jun Nie
@ 2026-05-21 14:46 ` Jun Nie
  2026-05-21 15:20   ` sashiko-bot
  2026-05-21 14:46 ` [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC Jun Nie
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie

Some devices treat two independent physical DSI panels as a single
logical panel from the CRTC's perspective. However, two separate DSI
hosts are still required to drive the panels individually.

Introduce a `dual_panel` flag to the `mipi_dsi_device` struct. This
allows a panel driver to inform the DSI host that it is part of a
dual-panel setup, enabling the host to coordinate both physical
displays as one.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 include/drm/drm_mipi_dsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 2ab651a36115d..889ef1421207a 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -169,6 +169,7 @@ struct mipi_dsi_device_info {
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
  * @attached: the DSI device has been successfully attached
+ * @dual_panel: the DSI device is one instance of dual panel
  * @name: DSI peripheral chip type
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
@@ -186,6 +187,7 @@ struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
 	struct device dev;
 	bool attached;
+	bool dual_panel;
 
 	char name[DSI_DEV_NAME_SIZE];
 	unsigned int channel;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC
  2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
  2026-05-21 14:46 ` [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1 Jun Nie
  2026-05-21 14:46 ` [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations Jun Nie
@ 2026-05-21 14:46 ` Jun Nie
  2026-05-21 15:50   ` sashiko-bot
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
  2026-05-21 14:46 ` [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel Jun Nie
  4 siblings, 1 reply; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie

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.

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@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 d14b6e41dcd90..4d7ac01aa393d 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;
@@ -2596,6 +2601,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


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support
  2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
                   ` (2 preceding siblings ...)
  2026-05-21 14:46 ` [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC Jun Nie
@ 2026-05-21 14:46 ` Jun Nie
  2026-05-21 16:07   ` sashiko-bot
                     ` (3 more replies)
  2026-05-21 14:46 ` [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel Jun Nie
  4 siblings, 4 replies; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie

Add support for the dual-panel system found in the virtual reality device.
This system consists of two physical 2160x2160 panels, each connected via
a MIPI DSI interface. The backlight is managed through DSI link.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 .../bindings/display/panel/synaptics,r63455.yaml   | 125 +++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
new file mode 100644
index 0000000000000..a94b355ed9557
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/synaptics,r63455.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synaptics R63455 based dual 2160x2160 MIPI-DSI Panel
+
+maintainers:
+  - Jun Nie <jun.nie@linaro.org>
+
+description:
+  Synaptics R63455 is a Virtual Reality Display Driver and VR Bridge, used in
+  pair in Headset devices. The Virtual Reality Display complex is composed of
+  two strictly identical display panels, each driven by its own DSI interface
+  but forms a single virtual display for the human eye perception and thus
+  requires a strict synchronization of the two display panel content update.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - sharp,ls026b3sa06
+        - boe,vs026c4m-n52-6000
+      - const: synaptics,r63455
+
+  reset-gpios:
+    maxItems: 2
+    description: 2 reset pins for 2 physical panels
+
+  left-pos-supply:
+    description: Positive 5.7V supply for left panel
+
+  right-pos-supply:
+    description: Positive 5.7V supply for right panel
+
+  left-neg-supply:
+    description: Negative 5.7V supply for left panel
+
+  right-neg-supply:
+    description: Negative 5.7V supply for right panel
+
+  left-backlight-supply:
+    description: Backlight 21V supply for left panel
+
+  right-backlight-supply:
+    description: Backlight 21V supply for right panel
+
+  vdda-supply:
+    description: core 1.8V supply for panels
+
+  ports: $ref: /schemas/graph.yaml#/properties/ports
+
+required:
+  - compatible
+  - reset-gpios
+  - left-pos-supply
+  - left-neg-supply
+  - right-pos-supply
+  - right-neg-supply
+  - left-backlight-supply
+  - right-backlight-supply
+  - vdda-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    &mdss_dsi0 {
+        vdda-supply = <&vreg_l3i_1p2>;
+        status = "okay";
+
+        qcom,dual-dsi-mode;
+        qcom,master-dsi;
+
+        panel: panel@0 {
+            compatible = "sharp,ls026b3sa06", "synaptics,r63455";
+            reg = <0>;
+
+            reset-gpios = <&pm8550_gpios 3 GPIO_ACTIVE_HIGH>,
+                          <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
+
+            left-pos-supply = <&vpos_left>;
+            left-neg-supply = <&vneg_left>;
+            right-pos-supply = <&vpos_right>;
+            right-neg-supply = <&vneg_right>;
+            left-backlight-supply = <&backlight_left>;
+            right-backlight-supply = <&backlight_right>;
+
+            vdda-supply = <&vreg_l12b_1p8>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                port@0 {
+                    reg = <0>;
+                    panel0_in: endpoint {
+                        remote-endpoint = <&mdss_dsi0_out>;
+                    };
+                };
+
+                port@1 {
+                    reg = <1>;
+                    panel1_in: endpoint {
+                        remote-endpoint = <&mdss_dsi1_out>;
+                    };
+                };
+            };
+    };
+
+    &mdss_dsi0_out {
+            remote-endpoint = <&panel0_in>;
+            data-lanes = <0 1 2>;
+    };
+
+    &mdss_dsi1_out {
+            remote-endpoint = <&panel1_in>;
+            data-lanes = <0 1 2>;
+    };
+...

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel
  2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
                   ` (3 preceding siblings ...)
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
@ 2026-05-21 14:46 ` Jun Nie
  2026-05-21 16:30   ` sashiko-bot
  4 siblings, 1 reply; 14+ messages in thread
From: Jun Nie @ 2026-05-21 14:46 UTC (permalink / raw)
  To: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree,
	Jun Nie

Add support for the DSI panels used in the virtual reality device.
The device features two physical panels, each providing a MIPI DSI
interface and a built-in LED backlight and expose a single logical
panel to the DRM framework.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 drivers/gpu/drm/panel/Kconfig                  |   9 +
 drivers/gpu/drm/panel/Makefile                 |   1 +
 drivers/gpu/drm/panel/panel-synaptics-r63455.c | 631 +++++++++++++++++++++++++
 3 files changed, 641 insertions(+)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 7c2d9feb4064e..1ef3f51ec6593 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -1227,6 +1227,15 @@ config DRM_PANEL_SYNAPTICS_TDDI
 	  namesake, with varying resolutions and data lanes. They also have a
 	  built-in LED backlight and a touch controller.
 
+config DRM_PANEL_SYNAPTICS_R63455
+	tristate "Synaptics R63455-based panels"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y if you want to enable support for panels based on the
+	  Synaptics R63455 controller.
+
 config DRM_PANEL_TDO_TL070WSH30
 	tristate "TDO TL070WSH30 DSI panel"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index dc8a05f2c34d9..ee6b41151804c 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
 obj-$(CONFIG_DRM_PANEL_SUMMIT) += panel-summit.o
 obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63353) += panel-synaptics-r63353.o
 obj-$(CONFIG_DRM_PANEL_SYNAPTICS_TDDI) += panel-synaptics-tddi.o
+obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63455) += panel-synaptics-r63455.o
 obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o
 obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o
diff --git a/drivers/gpu/drm/panel/panel-synaptics-r63455.c b/drivers/gpu/drm/panel/panel-synaptics-r63455.c
new file mode 100644
index 0000000000000..e429c28c7efc9
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-synaptics-r63455.c
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026, Linaro Ltd. All rights reserved.
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dsc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#define R63455_MF_CMD_ACCESS_PROTECT	0xb0
+#define R63455_SEQ_CTL			0xd6
+#define R63455_DSI_CTL			0xb6
+#define R63455_DISP_MODE		0xb7
+#define R63455_GEN_OUTPIN_SET		0xb9
+#define R63455_DISP_SET1		0xc0
+#define R63455_DISP_SET2		0xf1
+#define R63455_DISP_SET3		0xc6
+#define R63455_DISP_SET3_2		0xcd
+#define R63455_DISP_SET4		0xcf
+#define R63455_DISP_SET5		0xec
+#define R63455_DISP_SET6		0xef
+#define R63455_TE_GPIO_CTL		0xbe
+#define R63455_PPS_SET			0xe6
+
+#define BRIGHTNESS_DEFAULT		256
+#define BRIGHTNESS_MAX_120		367
+
+#define VBP				100
+#define VFP				700
+#define VID_VS_DELAY			1112
+#define GPO1_TES1			4068
+#define RTN				59
+
+static const char * const vdda_driver[] = {
+	"vdda",
+};
+
+static const char * const dual_backlight_driver[] = {
+	"left-backlight",
+	"right-backlight",
+};
+
+static const char * const dual_lcd_bias_pos[] = {
+	"left-pos",
+	"right-pos",
+};
+
+static const char * const dual_lcd_bias_neg[] = {
+	"left-neg",
+	"right-neg"
+};
+
+struct r63455_ctx {
+	struct device *dev;
+	struct drm_panel panel;
+
+	struct regulator_bulk_data reg_vdda[ARRAY_SIZE(vdda_driver)];
+	struct regulator_bulk_data reg_bl[ARRAY_SIZE(dual_backlight_driver)];
+	struct regulator_bulk_data reg_lcd_bias_pos[ARRAY_SIZE(dual_lcd_bias_pos)];
+	struct regulator_bulk_data reg_lcd_bias_neg[ARRAY_SIZE(dual_lcd_bias_neg)];
+
+	struct gpio_descs *reset_gpios;
+	int (*dsi_init_seq)(struct drm_panel *panel);
+	struct backlight_device *backlight;
+	struct mipi_dsi_device *dsi[2];
+	struct drm_dsc_config dsc_cfg;
+};
+
+static inline struct r63455_ctx *panel_to_ctx(struct drm_panel *panel)
+{
+	return container_of(panel, struct r63455_ctx, panel);
+}
+
+static const struct drm_display_mode modes = {
+	.name = "4320x2160_120",
+	.clock = (2160 + 24 + 20 + 20) * (2160 + 404 + 1 + 20) * 120 * 2 / 1000,
+	.hdisplay = 2160 * 2,
+	.hsync_start = (2160 + 24) * 2,
+	.hsync_end = (2160 + 24 + 20) * 2,
+	.htotal = (2160 + 24 + 20 + 20) * 2,
+	.vdisplay = 2160,
+	.vsync_start = 2160 + 404,
+	.vsync_end = 2160 + 404 + 1,
+	.vtotal = 2160 + 404 + 1 + 20,
+	.width_mm = 50 * 2,
+	.height_mm = 50,
+	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+#define r63455_dsi_write_seq(ctx, dsi_ctx, cmd, seq...)					\
+	do {										\
+		u8 d[] = {cmd, seq};							\
+		dsi_ctx.dsi = ctx->dsi[0];						\
+		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
+		dsi_ctx.dsi = ctx->dsi[1];						\
+		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
+	} while (0)
+
+#define r63455_dsi_write_buffer(ctx, dsi_ctx, d)					\
+	do {										\
+		dsi_ctx.dsi = ctx->dsi[0];						\
+		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
+		dsi_ctx.dsi = ctx->dsi[1];						\
+		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
+	} while (0)
+
+#define LE16_BYTE0(val) (le16_to_cpu(val) & 0xff)
+#define LE16_BYTE1(val) ((le16_to_cpu(val) >> 8) & 0xff)
+#define BE16_BYTE0(val) (be16_to_cpu(val) & 0xff)
+#define BE16_BYTE1(val) ((be16_to_cpu(val) >> 8) & 0xff)
+
+static int r63455_dsi_populate_dsc_params(struct r63455_ctx *ctx)
+{
+	int ret;
+	struct drm_dsc_config *dsc = &ctx->dsc_cfg;
+
+	dsc->simple_422 = 0;
+	dsc->convert_rgb = 1;
+	dsc->vbr_enable = 0;
+
+	drm_dsc_set_const_params(dsc);
+	drm_dsc_set_rc_buf_thresh(dsc);
+
+	/* handle only bpp = bpc = 8, pre-SCR panels */
+	ret = drm_dsc_setup_rc_params(dsc, DRM_DSC_1_1_PRE_SCR);
+	if (ret < 0)
+		DRM_DEV_ERROR(ctx->dev, "failed to setup dsc params\n");
+
+	dsc->initial_scale_value = drm_dsc_initial_scale_value(dsc);
+	dsc->line_buf_depth = dsc->bits_per_component + 1;
+
+	return drm_dsc_compute_rc_parameters(dsc);
+}
+
+static int r63455_init_dsc_config(struct r63455_ctx *ctx)
+{
+	ctx->dsc_cfg = (struct drm_dsc_config) {
+		.dsc_version_major = 0x1,
+		.dsc_version_minor = 0x2,
+		.dsc_slice_per_pkt = 4,
+		.slice_height = 48,
+		.slice_width = 540,
+		.slice_count = 4,
+		.bits_per_component = 8,
+		.bits_per_pixel = 8 << 4,
+		.block_pred_enable = true,
+
+		.pic_width = 2160,
+		.pic_height = 2160,
+	};
+
+	return r63455_dsi_populate_dsc_params(ctx);
+}
+
+static int r63455_panel_on_sharp_ls026b3sa06(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { 0 };
+
+	u8 pps_cmd[1 + sizeof(struct drm_dsc_picture_parameter_set)];
+
+	drm_dsc_pps_payload_pack((void *)&pps_cmd[1], &ctx->dsc_cfg);
+	pps_cmd[0] = R63455_PPS_SET;
+
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_MF_CMD_ACCESS_PROTECT, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_SEQ_CTL, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx,
+			     R63455_DSI_CTL,
+			     0x20, 0x6b, 0x80, 0x06, 0x33, 0x9a, 0x00, 0x1a,
+			     0x7a);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_MODE,
+			     0x54, 0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_GEN_OUTPIN_SET,
+			     0xf, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0xf, 0xb2, 0x00, 0x64);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET3,
+			     0x08, 0x70, 0x28, 0x48, 0x00, 0x00, 0x13, 0x21,
+			     0xff, 0x00, 0x0f, 0x01, 0x14, 0x17, 0x00, 0x00,
+			     0x00, 0x02, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x20,
+			     0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x08,
+			     0xD0, 0x02, 0x21, 0x6F, 0x08, 0x5A, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET1,
+			     RTN, 0x86, LE16_BYTE0(VBP), LE16_BYTE1(VBP), 0x08,
+			     0x70, BE16_BYTE0(VFP), BE16_BYTE1(VFP), 0x00,
+			     0x00, 0x08, 0x3B, 0x00, 0x00, 0x19, 0x01, 0x22);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET3_2, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET4,
+			     0x8b, 0x00, 0x80, 0x46, 0x61, 0x00, 0x8b);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET5,
+			     BE16_BYTE0(VID_VS_DELAY),
+			     BE16_BYTE1(VID_VS_DELAY),
+			     0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET6,
+			     0x00, 0x24, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x00, 0x03,
+			     0x1D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+			     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_TE_GPIO_CTL,
+			     0x00, 0x6A, 0x02);
+	r63455_dsi_write_buffer(ctx, dsi_ctx, pps_cmd);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_TEAR_ON, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x40);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_EXIT_SLEEP_MODE);
+	mipi_dsi_msleep(&dsi_ctx, 170);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_DISPLAY_ON);
+	mipi_dsi_msleep(&dsi_ctx, 200);
+
+	return dsi_ctx.accum_err;
+}
+
+static int r63455_panel_on_boe_vs026c4m_n52_26000(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { 0 };
+
+	u8 pps_cmd[1 + sizeof(struct drm_dsc_picture_parameter_set)];
+
+	drm_dsc_pps_payload_pack((void *)&pps_cmd[1], &ctx->dsc_cfg);
+	pps_cmd[0] = R63455_PPS_SET;
+
+	r63455_dsi_write_seq(ctx, dsi_ctx,
+			     R63455_MF_CMD_ACCESS_PROTECT, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_SEQ_CTL, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DSI_CTL,
+			     0x20, 0x6b, 0x80, 0x06, 0x33, 0x9A, 0x00,
+			     0x1a, 0x7a);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_MODE,
+			     0x54, 0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_GEN_OUTPIN_SET,
+			     0xf, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0xf, 0xb2,
+			     0xf, 0xb2, 0x00, 0x64);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET3,
+			     0x0B, 0x70, 0x08, 0x48, 0x00, 0x00, 0x13, 0x01,
+			     0xFF, 0x00, 0x01, 0x09, 0x16, 0x16, 0x00, 0x00,
+			     0x00, 0x01, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x08,
+			     0xD0, 0x02, 0x21, 0x6F, 0x08, 0x5A, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET1,
+			     RTN, 0x86, LE16_BYTE0(VBP), LE16_BYTE1(VBP), 0x08,
+			     0x70, BE16_BYTE0(VFP), BE16_BYTE1(VFP), 0x00,
+			     0x00, 0x08, 0x3A, 0x00, 0x00, 0x17, 0x00, 0x17);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET3_2, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET4,
+			     0x8b, 0x00, 0x80, 0x46, 0x61, 0x00, 0x8b);
+	r63455_dsi_write_seq(ctx, dsi_ctx, R63455_DISP_SET5,
+			     BE16_BYTE0(VID_VS_DELAY), BE16_BYTE1(VID_VS_DELAY),
+			     0x00, 0x00, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx,
+			     R63455_TE_GPIO_CTL, 0x00, 0x6A, 0x02);
+	r63455_dsi_write_buffer(ctx, dsi_ctx, pps_cmd);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_TEAR_ON, 0x00);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_EXIT_SLEEP_MODE);
+	mipi_dsi_msleep(&dsi_ctx, 170);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_DISPLAY_ON);
+	mipi_dsi_msleep(&dsi_ctx, 200);
+
+	return dsi_ctx.accum_err;
+}
+
+static int r63455_set_brightness(struct r63455_ctx *ctx, u16 brightness,
+				  u16 pulse_offset_rows)
+{
+	struct mipi_dsi_multi_context dsi_ctx = { 0 };
+	u16 gpo1_tew1;
+
+	gpo1_tew1 = brightness > BRIGHTNESS_MAX_120 ?
+		    BRIGHTNESS_MAX_120 : brightness;
+
+	ctx->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;
+	ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	r63455_dsi_write_seq(ctx, dsi_ctx,
+			     R63455_GEN_OUTPIN_SET,
+			     0x0f, 0xe4,
+			     BE16_BYTE0(gpo1_tew1),
+			     BE16_BYTE1(gpo1_tew1),
+			     0x00, 0x00, 0x00, 0x00, 0x0f, 0xb2,
+			     BE16_BYTE0(brightness),
+			     BE16_BYTE1(brightness));
+
+	ctx->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
+	ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	return dsi_ctx.accum_err;
+}
+
+static int r63455_disable(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { 0 };
+
+	ctx->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;
+	ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_DISPLAY_OFF);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_TEAR_OFF);
+	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_ENTER_SLEEP_MODE);
+
+	mipi_dsi_msleep(&dsi_ctx, 200);
+
+	if (dsi_ctx.accum_err)
+		return dsi_ctx.accum_err;
+
+	return backlight_disable(ctx->backlight);
+}
+
+static int r63455_unprepare(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	int ret;
+
+	gpiod_set_value(ctx->reset_gpios->desc[0], 0);
+	gpiod_set_value(ctx->reset_gpios->desc[1], 0);
+
+	msleep(25);
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->reg_lcd_bias_neg),
+				     ctx->reg_lcd_bias_neg);
+	if (ret)
+		dev_err(ctx->dev, "Could not disable bias negative\n");
+
+	usleep_range(1000, 2000);
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->reg_lcd_bias_pos),
+				     ctx->reg_lcd_bias_pos);
+	if (ret)
+		dev_err(ctx->dev, "Could not disable bias positive\n");
+
+	msleep(20);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->reg_vdda), ctx->reg_vdda);
+	if (ret)
+		dev_err(ctx->dev, "Could not disable vdda\n");
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->reg_bl), ctx->reg_bl);
+	if (ret)
+		dev_err(ctx->dev,
+			"failed to disable regulator backlight: %d\n", ret);
+
+	return ret;
+}
+
+static int r63455_enable(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	int ret;
+
+	ctx->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
+	ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	msleep(20);
+	ret = ctx->dsi_init_seq(panel);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "dsi init failed\n");
+		return ret;
+	}
+	ctx->backlight->props.pulse_offset_rows = GPO1_TES1;
+
+	ret = backlight_enable(ctx->backlight);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to enable backlight\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int r63455_prepare(struct drm_panel *panel)
+{
+	struct r63455_ctx *ctx = panel_to_ctx(panel);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->reg_bl), ctx->reg_bl);
+	if (ret) {
+		dev_err(ctx->dev, "Could not enable backlight\n");
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->reg_vdda), ctx->reg_vdda);
+	if (ret) {
+		dev_err(ctx->dev, "Could not enable vdda\n");
+		goto bl_off;
+	}
+
+	usleep_range(1000, 2000);
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->reg_lcd_bias_pos),
+				    ctx->reg_lcd_bias_pos);
+	if (ret) {
+		dev_err(ctx->dev, "Could not enable bias positive\n");
+		goto vdda_off;
+	}
+	usleep_range(1000, 2000);
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->reg_lcd_bias_neg),
+				    ctx->reg_lcd_bias_neg);
+	if (ret) {
+		dev_err(ctx->dev, "Could not enable bias negative\n");
+		goto bias_off;
+	}
+
+	msleep(20);
+	gpiod_set_value(ctx->reset_gpios->desc[0], 1);
+	gpiod_set_value(ctx->reset_gpios->desc[1], 1);
+
+	return 0;
+
+bl_off:
+	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_bl), ctx->reg_bl);
+vdda_off:
+	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_vdda), ctx->reg_vdda);
+bias_off:
+	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_lcd_bias_pos),
+			       ctx->reg_lcd_bias_pos);
+	return ret;
+}
+
+static int r63455_bl_update_status(struct backlight_device *bl)
+{
+	struct mipi_dsi_device *dsi = bl_get_data(bl);
+	struct r63455_ctx *r63455_ctx = mipi_dsi_get_drvdata(dsi);
+
+	return r63455_set_brightness(r63455_ctx, bl->props.brightness,
+				     bl->props.pulse_offset_rows);
+}
+
+static const struct backlight_ops r63455_bl_ops = {
+	.update_status = r63455_bl_update_status,
+};
+
+static int r63455_get_modes(struct drm_panel *panel,
+				 struct drm_connector *connector)
+{
+	return drm_connector_helper_get_modes_fixed(connector, &modes);
+}
+
+static const struct drm_panel_funcs r63455_drm_funcs = {
+	.disable = r63455_disable,
+	.enable = r63455_enable,
+	.unprepare = r63455_unprepare,
+	.prepare = r63455_prepare,
+	.get_modes = r63455_get_modes,
+};
+
+static int r63455_panel_add(struct r63455_ctx *ctx)
+{
+	struct device *dev = ctx->dev;
+	struct backlight_properties bl_props;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->reg_vdda); i++)
+		ctx->reg_vdda[i].supply = vdda_driver[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->reg_vdda),
+				      ctx->reg_vdda);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(dual_backlight_driver); i++)
+		ctx->reg_bl[i].supply = dual_backlight_driver[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->reg_bl),
+				      ctx->reg_bl);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->reg_lcd_bias_pos); i++)
+		ctx->reg_lcd_bias_pos[i].supply = dual_lcd_bias_pos[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->reg_lcd_bias_pos),
+				      ctx->reg_lcd_bias_pos);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->reg_lcd_bias_neg); i++)
+		ctx->reg_lcd_bias_neg[i].supply = dual_lcd_bias_neg[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->reg_lcd_bias_neg),
+				      ctx->reg_lcd_bias_neg);
+	if (ret < 0)
+		return ret;
+
+	ctx->reset_gpios = devm_gpiod_get_array(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->reset_gpios))
+		return PTR_ERR(ctx->reset_gpios);
+
+	memset(&bl_props, 0, sizeof(bl_props));
+	bl_props.type = BACKLIGHT_RAW;
+	bl_props.brightness = BRIGHTNESS_DEFAULT;
+	bl_props.max_brightness = BRIGHTNESS_MAX_120;
+
+	ctx->backlight = devm_backlight_device_register(dev, dev_name(dev),
+							dev, ctx->dsi[0],
+							&r63455_bl_ops,
+							&bl_props);
+	if (IS_ERR(ctx->backlight)) {
+		ret = PTR_ERR(ctx->backlight);
+		dev_err(dev, "Failed to register backlight (%d)\n", ret);
+		return ret;
+	}
+
+	ctx->panel.prepare_prev_first = true;
+	return devm_drm_panel_add(dev, &ctx->panel);
+}
+
+static int r63455_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct r63455_ctx *ctx;
+	struct mipi_dsi_device *dsi1_device;
+	struct device_node *dsi1;
+	struct mipi_dsi_host *dsi1_host;
+	struct mipi_dsi_device *dsi_dev;
+	int ret = 0;
+	int i;
+
+	const struct mipi_dsi_device_info info = {
+		.type = "r63455-dsi-panel",
+		.channel = 0,
+		.node = NULL,
+	};
+
+	ctx = devm_drm_panel_alloc(&dsi->dev, __typeof(*ctx), panel,
+				   &r63455_drm_funcs, DRM_MODE_CONNECTOR_DSI);
+
+	ctx->dsi_init_seq = of_device_get_match_data(dev);
+	if (!ctx->dsi_init_seq)
+		return -ENODEV;
+
+	dsi1 = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
+	if (!dsi1) {
+		DRM_DEV_ERROR(dev, "failed to get secondary dsi\n");
+		return -ENODEV;
+	}
+
+	dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
+	of_node_put(dsi1);
+	if (!dsi1_host) {
+		DRM_DEV_ERROR(dev, "failed to find secondary dsi host\n");
+		return -EPROBE_DEFER;
+	}
+
+	dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);
+	if (IS_ERR(dsi1_device)) {
+		DRM_DEV_ERROR(dev, "failed to create dsi device\n");
+		return PTR_ERR(dsi1_device);
+	}
+
+	ctx->dsi[1] = dsi1_device;
+	mipi_dsi_set_drvdata(dsi, ctx);
+	ctx->dev = dev;
+	ctx->dsi[0] = dsi;
+
+	ret = r63455_init_dsc_config(ctx);
+	if (ret)
+		return ret;
+
+	ctx->dsi[0]->dsc = &ctx->dsc_cfg;
+	ctx->dsi[0]->dual_panel = true;
+	ctx->dsi[1]->dual_panel = true;
+	ctx->dsi[1]->dsc = &ctx->dsc_cfg;
+
+	ret = r63455_panel_add(ctx);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to add panel %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < 2; i++) {
+		dsi_dev = ctx->dsi[i];
+		dsi_dev->lanes = 3;
+		dsi_dev->format = MIPI_DSI_FMT_RGB888;
+		dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM |
+			MIPI_DSI_CLOCK_NON_CONTINUOUS;
+		ret = devm_mipi_dsi_attach(dev, dsi_dev);
+		if (ret < 0) {
+			DRM_DEV_ERROR(dev, "dsi attach failed i = %d\n", i);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct of_device_id r63455_of_match[] = {
+	{
+		.compatible = "sharp,ls026b3sa06",
+		.data = r63455_panel_on_sharp_ls026b3sa06,
+	},
+	{
+		.compatible = "boe,vs026c4m-n52-6000",
+		.data = r63455_panel_on_boe_vs026c4m_n52_26000,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, r63455_of_match);
+
+static struct mipi_dsi_driver r63455_driver = {
+	.driver = {
+		.name = "panel-synaptics-r63455",
+		.of_match_table = r63455_of_match,
+	},
+	.probe = r63455_probe,
+};
+module_mipi_dsi_driver(r63455_driver);
+
+MODULE_DESCRIPTION("Synaptics R63455 DSI Panel Driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1
  2026-05-21 14:46 ` [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1 Jun Nie
@ 2026-05-21 15:08   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-05-21 15:08 UTC (permalink / raw)
  To: Jun Nie; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Failure to clear `msm_host->dsc` and `dsc_slice_per_pkt` when a panel without DSC is attached leads to a potential use-after-free.
--

commit 4b3fdd757a84f263ad4c869c8ef48cdc07ee2b22
Author: Jun Nie <jun.nie@linaro.org>

drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

This commit adds support for sending multiple DSC slices in a single packet
for the MSM DSI driver. It introduces a dsc_slice_per_pkt member into struct
drm_dsc_config and updates the relevant timing calculations.

> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 565d425f88b86..10589389650fc 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c

[ ... ]

> @@ -1718,8 +1708,11 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
>  	msm_host->lanes = dsi->lanes;
>  	msm_host->format = dsi->format;
>  	msm_host->mode_flags = dsi->mode_flags;
> -	if (dsi->dsc)
> +	if (dsi->dsc) {
>  		msm_host->dsc = dsi->dsc;
> +		/* for backwards compatibility, assume 1 if not set */
> +		msm_host->dsc_slice_per_pkt = dsi->dsc->dsc_slice_per_pkt ?: 1;
> +	}

[Severity: High]
This is a pre-existing issue, but does failing to clear msm_host->dsc and
dsc_slice_per_pkt when a panel without DSC is attached lead to a potential
use-after-free?

When a panel driver is unbound, the DRM pipeline is torn down, and the panel's
memory (including the embedded drm_dsc_config structure) is freed.

However, the msm_dsi_host structure persists in memory because it belongs
to the DSI host controller driver. If a new panel without DSC is subsequently
bound, dsi->dsc will be NULL, causing dsi_host_attach() to skip the assignment
and leave msm_host->dsc pointing to the freed memory.

When the display is later enabled, dsi_timing_setup() executes
if (msm_host->dsc) and performs a use-after-free write
(dsc->pic_width = mode->hdisplay;).

Since this patch extends this pattern to the newly added dsc_slice_per_pkt
field, should there be an else branch to clear these fields when dsi->dsc
is NULL?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-sm8650-7-1-bonded-dsi-v4-0-a4dd5e0850f1@linaro.org?part=1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations
  2026-05-21 14:46 ` [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations Jun Nie
@ 2026-05-21 15:20   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-05-21 15:20 UTC (permalink / raw)
  To: Jun Nie; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Adding a `dual_panel` flag to `mipi_dsi_device` forces individual panel drivers to handle system-level display topology, violating the separation of concerns.
--

commit f6f95d24bc09251a7384b7ecd49f09b146258523
Author: Jun Nie <jun.nie@linaro.org>

drm/mipi-dsi: Add flag to support dual-panel configurations

This commit introduces a dual_panel flag to the mipi_dsi_device struct.
This allows a panel driver to inform the DSI host that it is part of a
dual-panel setup, treating two independent physical panels as a single
logical display.

> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 2ab651a36115d..889ef1421207a 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h

[ ... ]

> @@ -186,6 +187,7 @@ struct mipi_dsi_device {
>  	struct mipi_dsi_host *host;
>  	struct device dev;
>  	bool attached;
> +	bool dual_panel;

[Severity: Low]
Does introducing this flag to the mipi_dsi_device struct force individual
panel drivers to manage system-level display topology? 

Grouping two independent physical panels into a single logical display is a
system-level integration detail. Typically, panel drivers should not be
responsible for understanding system-wide topologies. 

Could this information be determined by the display framework instead,
such as by parsing the Device Tree graph to see if two DSI hosts are
routed to a single CRTC? This might prevent an architectural layering
violation and maintain driver reusability across different system
configurations.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-sm8650-7-1-bonded-dsi-v4-0-a4dd5e0850f1@linaro.org?part=2

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC
  2026-05-21 14:46 ` [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC Jun Nie
@ 2026-05-21 15:50   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-05-21 15:50 UTC (permalink / raw)
  To: Jun Nie; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Halving `dsc->pic_width` for dual panels causes the DPU DSC encoder to incorrectly program the DSC hardware, resulting in a halved processing width and hardware underflow.
--

commit d23a05783cbe32106f4e17b417f7304f721a2609
Author: Jun Nie <jun.nie@linaro.org>

drm/msm/dsi: Support dual panel use case with single CRTC

This commit adds support for a hardware configuration where two independent
DSI panels are driven by a single, synchronous CRTC. The driver halves the
CRTC's horizontal resolution before configuring the DSI host and any DSC
encoders to ensure each panel receives the proper half of the framebuffer.

> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 10589389650fc..4a391cdd4030a 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
[ ... ]
> @@ -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;

[Severity: High]
Can setting dsc->pic_width to the halved hdisplay cause the DPU DSC encoder
to incorrectly program the hardware?

The struct drm_dsc_config is shared with the DPU encoder driver, which expects
dsc->pic_width to represent the total picture width across all DSC encoders
for the CRTC.

If the DPU driver calculates the encoder processing width by dividing this
value by num_dsc (which is 2 for a dual DSI setup), won't this result in a
processing width that is a quarter of the total CRTC width? 

This looks like it could lead to incorrect pipeline delay calculations and
cause the hardware to process only half the intended width, potentially
leading to display corruption and hardware pipeline underflows.

>  		dsc->pic_height = mode->vdisplay;
>  		DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-sm8650-7-1-bonded-dsi-v4-0-a4dd5e0850f1@linaro.org?part=3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
@ 2026-05-21 16:07   ` sashiko-bot
  2026-05-21 19:45   ` Conor Dooley
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-05-21 16:07 UTC (permalink / raw)
  To: Jun Nie; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Low] Invalid inline mapping for `$ref` under `ports` property.
- [Low] The `reg` property is used in the device tree example but omitted from the schema definitions.
- [Low] Missing closing brace for the panel device node in the DTS example.
- [Low] The `reset-gpios` property's `maxItems: 2` constraint conflicts with the strictly enforced `maxItems: 1` inherited from `panel-common.yaml`.
--

commit 5bb531a3ba9addcc1e532a73333c359429ef1ea6
Author: Jun Nie <jun.nie@linaro.org>
Subject: dt-bindings: display: Add Synaptics R63455 panel support

Add support for the dual-panel system found in the virtual reality device.
This system consists of two physical 2160x2160 panels, each connected via
a MIPI DSI interface.

> diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
> new file mode 100644
> index 0000000000000..a94b355ed9557
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
[ ... ]
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +        - sharp,ls026b3sa06
> +        - boe,vs026c4m-n52-6000
> +      - const: synaptics,r63455
> +
> +  reset-gpios:
> +    maxItems: 2

[Severity: Low]
Will this conflict with panel-common.yaml? Since panel-common.yaml is
included via allOf, and it restricts reset-gpios to maxItems: 1, a device
tree providing two GPIOs will fail validation against the inherited schema.
The local relaxation to maxItems: 2 cannot override the stricter requirement
from panel-common.yaml.

> +    description: 2 reset pins for 2 physical panels
[ ... ]
> +  vdda-supply:
> +    description: core 1.8V supply for panels
> +
> +  ports: $ref: /schemas/graph.yaml#/properties/ports

[Severity: Low]
Does this syntax cause a YAML parser error? In YAML, a colon followed by a
space indicates a mapping value, and a plain scalar cannot contain an
unquoted colon-space sequence. Should the $ref be placed on a new line with
proper indentation?

> +
> +required:
> +  - compatible
[ ... ]
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    &mdss_dsi0 {
> +        vdda-supply = <&vreg_l3i_1p2>;
> +        status = "okay";
> +
> +        qcom,dual-dsi-mode;
> +        qcom,master-dsi;
> +
> +        panel: panel@0 {
> +            compatible = "sharp,ls026b3sa06", "synaptics,r63455";
> +            reg = <0>;

[Severity: Low]
Should the reg property be explicitly defined in the local schema
properties block? It is used here in the example but omitted from the
schema definitions. Since additionalProperties is false, dt_binding_check
will fail with an undocumented property error.

> +
> +            reset-gpios = <&pm8550_gpios 3 GPIO_ACTIVE_HIGH>,
[ ... ]
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +                port@0 {
> +                    reg = <0>;
> +                    panel0_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi0_out>;
> +                    };
> +                };
> +
> +                port@1 {
> +                    reg = <1>;
> +                    panel1_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi1_out>;
> +                    };
> +                };
> +            };
> +    };

[Severity: Low]
Is there a missing closing brace for the panel node here? The brace
indented at 12 spaces closes the ports subnode, and the next brace indented
at 4 spaces closes the root mdss_dsi0 node. The lack of an 8-space indented
closing brace for the panel node will cause a syntax error from the Device
Tree Compiler.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-sm8650-7-1-bonded-dsi-v4-0-a4dd5e0850f1@linaro.org?part=4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel
  2026-05-21 14:46 ` [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel Jun Nie
@ 2026-05-21 16:30   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-05-21 16:30 UTC (permalink / raw)
  To: Jun Nie; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 10 potential issue(s) to consider:
- [High] Incorrect order of error unwinding labels in `r63455_prepare` causes resource leaks and unbalanced regulator operations.
- [High] The secondary DSI device registered during probe is never unregistered, causing a memory and device leak.
- [High] Endianness extraction macros misuse host-endian functions, resulting in reversed byte order on Big Endian architectures.
- [High] Unconditional access to `ctx->reset_gpios->desc[1]` leads to an out-of-bounds array read if only one reset GPIO is provided.
- [High] Failure of `drm_dsc_setup_rc_params` is logged but ignored, leading to division by zero and uninitialized data usage.
- [High] Backlight updates send DSI commands after the panel has entered sleep mode, risking hardware timeouts.
- [High] Premature publication of backlight and panel interfaces leads to use-before-initialization races.
- [High] Unprotected concurrent read-modify-write on `mode_flags` causes data races.
- [High] Unaligned pointer cast causes unaligned memory access when packing DSC PPS payload.
- [Low] Missing Kconfig dependencies for DRM DSC helpers causes build failures.
--

commit b5b6e09241eeff17cb03a31aac27b70f4e5ca911
Author: Jun Nie <jun.nie@linaro.org>
Subject: drm/panel: Add driver for Synaptics R63455 DSI panel

This commit adds support for the DSI panels used in the virtual reality
device. The device features two physical panels, each providing a MIPI DSI
interface and a built-in LED backlight, and exposes a single logical panel
to the DRM framework.

> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
[ ... ]
> @@ -1185,6 +1185,15 @@ config DRM_PANEL_SYNAPTICS_TDDI
>  	  namesake, with varying resolutions and data lanes. They also have a
>  	  built-in LED backlight and a touch controller.
>  
> +config DRM_PANEL_SYNAPTICS_R63455
> +	tristate "Synaptics R63455-based panels"
> +	depends on OF
> +	depends on DRM_MIPI_DSI
> +	depends on BACKLIGHT_CLASS_DEVICE
> +	help
> +	  Say Y if you want to enable support for panels based on the
> +	  Synaptics R63455 controller.

[Severity: Low]
Does this need to select DRM_DISPLAY_DSC_HELPER or DRM_DISPLAY_HELPER?
The driver calls drm_dsc_set_const_params and other DSC helpers, which
might cause link-time failures if the helper infrastructure is not built.

[ ... ]
> diff --git a/drivers/gpu/drm/panel/panel-synaptics-r63455.c b/drivers/gpu/drm/panel/panel-synaptics-r63455.c
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-synaptics-r63455.c
[ ... ]
> +#define r63455_dsi_write_buffer(ctx, dsi_ctx, d)					\
> +	do {										\
> +		dsi_ctx.dsi = ctx->dsi[0];						\
> +		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
> +		dsi_ctx.dsi = ctx->dsi[1];						\
> +		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, d, ARRAY_SIZE(d));		\
> +	} while (0)
> +
> +#define LE16_BYTE0(val) (le16_to_cpu(val) & 0xff)
> +#define LE16_BYTE1(val) ((le16_to_cpu(val) >> 8) & 0xff)

[Severity: High]
Are these macros extracting the correct bytes on big endian architectures?
Using le16_to_cpu() on a native integer constant swaps the bytes on big
endian systems. Applying the bitwise operations afterward will extract the
most significant byte instead of the least significant byte. Would standard
bitwise shifts be safer here?

[ ... ]
> +static int r63455_dsi_populate_dsc_params(struct r63455_ctx *ctx)
> +{
> +	int ret;
> +	struct drm_dsc_config *dsc = &ctx->dsc_cfg;
[ ... ]
> +	/* handle only bpp = bpc = 8, pre-SCR panels */
> +	ret = drm_dsc_setup_rc_params(dsc, DRM_DSC_1_1_PRE_SCR);
> +	if (ret < 0)
> +		DRM_DEV_ERROR(ctx->dev, "failed to setup dsc params\n");
> +
> +	dsc->initial_scale_value = drm_dsc_initial_scale_value(dsc);

[Severity: High]
Should this return early if drm_dsc_setup_rc_params() fails? If execution
continues, the driver will use uninitialized DSC configuration parameters.
Because values like initial_xmit_delay might remain zero, it can result in
a division by zero when calculating final_scale inside
drm_dsc_compute_rc_parameters().

> +	dsc->line_buf_depth = dsc->bits_per_component + 1;
> +
> +	return drm_dsc_compute_rc_parameters(dsc);
> +}
[ ... ]
> +static int r63455_panel_on_sharp_ls026b3sa06(struct drm_panel *panel)
> +{
> +	struct r63455_ctx *ctx = panel_to_ctx(panel);
> +	struct mipi_dsi_multi_context dsi_ctx = { 0 };
> +
> +	u8 pps_cmd[1 + sizeof(struct drm_dsc_picture_parameter_set)];
> +
> +	drm_dsc_pps_payload_pack((void *)&pps_cmd[1], &ctx->dsc_cfg);

[Severity: High]
Can this unaligned pointer cause alignment faults? Passing &pps_cmd[1] forces
the base address to be odd. Since drm_dsc_pps_payload_pack() treats the
pointer as a struct and performs 16-bit stores to its fields, this might
trigger alignment panics on architectures that strictly enforce memory
alignment.

[ ... ]
> +static int r63455_set_brightness(struct r63455_ctx *ctx, u16 brightness,
> +				  u16 pulse_offset_rows)
> +{
> +	struct mipi_dsi_multi_context dsi_ctx = { 0 };
> +	u16 gpo1_tew1;
> +
> +	gpo1_tew1 = brightness > BRIGHTNESS_MAX_120 ?
> +		    BRIGHTNESS_MAX_120 : brightness;
> +
> +	ctx->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;

[Severity: High]
Can this read-modify-write of mode_flags race with the similar modifications
in r63455_enable() and r63455_disable()? Because set_brightness() is called
from sysfs context and enable/disable from DRM commit context, concurrent
access might corrupt mode_flags and drop critical settings like
MIPI_DSI_MODE_VIDEO.

> +	ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
[ ... ]
> +static int r63455_disable(struct drm_panel *panel)
> +{
> +	struct r63455_ctx *ctx = panel_to_ctx(panel);
> +	struct mipi_dsi_multi_context dsi_ctx = { 0 };
> +
> +	ctx->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;
> +	ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
> +
> +	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_DISPLAY_OFF);
> +	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_SET_TEAR_OFF);
> +	r63455_dsi_write_seq(ctx, dsi_ctx, MIPI_DCS_ENTER_SLEEP_MODE);
> +
> +	mipi_dsi_msleep(&dsi_ctx, 200);
> +
> +	if (dsi_ctx.accum_err)
> +		return dsi_ctx.accum_err;
> +
> +	return backlight_disable(ctx->backlight);

[Severity: High]
Is it safe to disable the backlight here? The backlight_disable() function
calls r63455_set_brightness(), which will send DSI configuration commands to
the panel. Doing so after sending MIPI_DCS_ENTER_SLEEP_MODE violates the DSI
hardware contracts and might cause bus timeouts or hardware crashes.

> +}
> +
> +static int r63455_unprepare(struct drm_panel *panel)
> +{
> +	struct r63455_ctx *ctx = panel_to_ctx(panel);
> +	int ret;
> +
> +	gpiod_set_value(ctx->reset_gpios->desc[0], 0);
> +	gpiod_set_value(ctx->reset_gpios->desc[1], 0);

[Severity: High]
What happens if the device tree only provides a single reset GPIO? If ndescs
is 1, accessing desc[1] will read past the end of the flexible array,
resulting in a garbage pointer dereference.

[ ... ]
> +static int r63455_prepare(struct drm_panel *panel)
> +{
> +	struct r63455_ctx *ctx = panel_to_ctx(panel);
> +	int ret;
[ ... ]
> +	msleep(20);
> +	gpiod_set_value(ctx->reset_gpios->desc[0], 1);
> +	gpiod_set_value(ctx->reset_gpios->desc[1], 1);
> +
> +	return 0;
> +
> +bl_off:
> +	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_bl), ctx->reg_bl);
> +vdda_off:
> +	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_vdda), ctx->reg_vdda);
> +bias_off:
> +	regulator_bulk_disable(ARRAY_SIZE(ctx->reg_lcd_bias_pos),
> +			       ctx->reg_lcd_bias_pos);
> +	return ret;

[Severity: High]
Are these error labels in the correct order? They appear to fall through
sequentially rather than unwinding in reverse. If reg_vdda fails to enable,
the jump to bl_off will disable the backlight, but then incorrectly fall
through to vdda_off and bias_off. This causes regulators that were never
enabled to be disabled, and completely skips disabling regulators that were
actually enabled.

> +}
[ ... ]
> +static int r63455_probe(struct mipi_dsi_device *dsi)
> +{
> +	struct device *dev = &dsi->dev;
> +	struct r63455_ctx *ctx;
> +	struct mipi_dsi_device *dsi1_device;
[ ... ]
> +	dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
> +	of_node_put(dsi1);
> +	if (!dsi1_host) {
> +		DRM_DEV_ERROR(dev, "failed to find secondary dsi host\n");
> +		return -EPROBE_DEFER;
> +	}
> +
> +	dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);

[Severity: High]
Does this dynamically allocated dsi1_device need to be unregistered? There
is no call to mipi_dsi_device_unregister() in the error paths below or in a
remove callback for the driver, which could cause a permanent device and
memory leak when the module is unloaded or fails to probe.

> +	if (IS_ERR(dsi1_device)) {
> +		DRM_DEV_ERROR(dev, "failed to create dsi device\n");
> +		return PTR_ERR(dsi1_device);
> +	}
[ ... ]
> +	ret = r63455_panel_add(ctx);
> +	if (ret) {
> +		DRM_DEV_ERROR(dev, "failed to add panel %d\n", ret);
> +		return ret;
> +	}
> +
> +	for (i = 0; i < 2; i++) {
> +		dsi_dev = ctx->dsi[i];
> +		dsi_dev->lanes = 3;
> +		dsi_dev->format = MIPI_DSI_FMT_RGB888;
> +		dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM |
> +			MIPI_DSI_CLOCK_NON_CONTINUOUS;
> +		ret = devm_mipi_dsi_attach(dev, dsi_dev);

[Severity: High]
Does calling r63455_panel_add() before devm_mipi_dsi_attach() expose the
backlight sysfs interface too early? If userspace writes to the brightness
node before the DSI lanes and formats are configured and attached, it could
trigger a DSI transfer on an unattached device and crash the system.

> +		if (ret < 0) {
> +			DRM_DEV_ERROR(dev, "dsi attach failed i = %d\n", i);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-sm8650-7-1-bonded-dsi-v4-0-a4dd5e0850f1@linaro.org?part=5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
  2026-05-21 16:07   ` sashiko-bot
@ 2026-05-21 19:45   ` Conor Dooley
  2026-05-21 20:24   ` Dmitry Baryshkov
  2026-05-21 20:46   ` Rob Herring (Arm)
  3 siblings, 0 replies; 14+ messages in thread
From: Conor Dooley @ 2026-05-21 19:45 UTC (permalink / raw)
  To: Jun Nie
  Cc: Rob Clark, Dmitry Baryshkov, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Neil Armstrong, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 4787 bytes --]

On Thu, May 21, 2026 at 10:46:06PM +0800, Jun Nie wrote:
> Add support for the dual-panel system found in the virtual reality device.
> This system consists of two physical 2160x2160 panels, each connected via
> a MIPI DSI interface. The backlight is managed through DSI link.
> 
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
>  .../bindings/display/panel/synaptics,r63455.yaml   | 125 +++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
> new file mode 100644
> index 0000000000000..a94b355ed9557
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/synaptics,r63455.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Synaptics R63455 based dual 2160x2160 MIPI-DSI Panel
> +
> +maintainers:
> +  - Jun Nie <jun.nie@linaro.org>
> +
> +description:
> +  Synaptics R63455 is a Virtual Reality Display Driver and VR Bridge, used in
> +  pair in Headset devices. The Virtual Reality Display complex is composed of
> +  two strictly identical display panels, each driven by its own DSI interface
> +  but forms a single virtual display for the human eye perception and thus
> +  requires a strict synchronization of the two display panel content update.
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +        - sharp,ls026b3sa06
> +        - boe,vs026c4m-n52-6000
> +      - const: synaptics,r63455
> +
> +  reset-gpios:
> +    maxItems: 2
> +    description: 2 reset pins for 2 physical panels
> +
> +  left-pos-supply:
> +    description: Positive 5.7V supply for left panel
> +
> +  right-pos-supply:
> +    description: Positive 5.7V supply for right panel
> +
> +  left-neg-supply:
> +    description: Negative 5.7V supply for left panel
> +
> +  right-neg-supply:
> +    description: Negative 5.7V supply for right panel
> +
> +  left-backlight-supply:
> +    description: Backlight 21V supply for left panel
> +
> +  right-backlight-supply:
> +    description: Backlight 21V supply for right panel
> +
> +  vdda-supply:
> +    description: core 1.8V supply for panels
> +
> +  ports: $ref: /schemas/graph.yaml#/properties/ports

Missing a newline in this, but also probably missing going into more
detail about the ports themselves.

Sashiko complaints look valid.
pw-bot: changes-requested

Thanks,
Conor.

> +
> +required:
> +  - compatible
> +  - reset-gpios
> +  - left-pos-supply
> +  - left-neg-supply
> +  - right-pos-supply
> +  - right-neg-supply
> +  - left-backlight-supply
> +  - right-backlight-supply
> +  - vdda-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    &mdss_dsi0 {
> +        vdda-supply = <&vreg_l3i_1p2>;
> +        status = "okay";
> +
> +        qcom,dual-dsi-mode;
> +        qcom,master-dsi;
> +
> +        panel: panel@0 {
> +            compatible = "sharp,ls026b3sa06", "synaptics,r63455";
> +            reg = <0>;
> +
> +            reset-gpios = <&pm8550_gpios 3 GPIO_ACTIVE_HIGH>,
> +                          <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
> +
> +            left-pos-supply = <&vpos_left>;
> +            left-neg-supply = <&vneg_left>;
> +            right-pos-supply = <&vpos_right>;
> +            right-neg-supply = <&vneg_right>;
> +            left-backlight-supply = <&backlight_left>;
> +            right-backlight-supply = <&backlight_right>;
> +
> +            vdda-supply = <&vreg_l12b_1p8>;
> +
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +                port@0 {
> +                    reg = <0>;
> +                    panel0_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi0_out>;
> +                    };
> +                };
> +
> +                port@1 {
> +                    reg = <1>;
> +                    panel1_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi1_out>;
> +                    };
> +                };
> +            };
> +    };
> +
> +    &mdss_dsi0_out {
> +            remote-endpoint = <&panel0_in>;
> +            data-lanes = <0 1 2>;
> +    };
> +
> +    &mdss_dsi1_out {
> +            remote-endpoint = <&panel1_in>;
> +            data-lanes = <0 1 2>;
> +    };
> +...
> 
> -- 
> 2.43.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
  2026-05-21 16:07   ` sashiko-bot
  2026-05-21 19:45   ` Conor Dooley
@ 2026-05-21 20:24   ` Dmitry Baryshkov
  2026-05-21 20:46   ` Rob Herring (Arm)
  3 siblings, 0 replies; 14+ messages in thread
From: Dmitry Baryshkov @ 2026-05-21 20:24 UTC (permalink / raw)
  To: Jun Nie
  Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
	Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-arm-msm, dri-devel, freedreno, linux-kernel, devicetree

On Thu, May 21, 2026 at 10:46:06PM +0800, Jun Nie wrote:
> Add support for the dual-panel system found in the virtual reality device.
> This system consists of two physical 2160x2160 panels, each connected via
> a MIPI DSI interface. The backlight is managed through DSI link.
> 
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
>  .../bindings/display/panel/synaptics,r63455.yaml   | 125 +++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
> new file mode 100644
> index 0000000000000..a94b355ed9557
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/synaptics,r63455.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Synaptics R63455 based dual 2160x2160 MIPI-DSI Panel
> +
> +maintainers:
> +  - Jun Nie <jun.nie@linaro.org>
> +
> +description:
> +  Synaptics R63455 is a Virtual Reality Display Driver and VR Bridge, used in
> +  pair in Headset devices. The Virtual Reality Display complex is composed of
> +  two strictly identical display panels, each driven by its own DSI interface
> +  but forms a single virtual display for the human eye perception and thus
> +  requires a strict synchronization of the two display panel content update.
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +        - sharp,ls026b3sa06
> +        - boe,vs026c4m-n52-6000
> +      - const: synaptics,r63455
> +
> +  reset-gpios:
> +    maxItems: 2
> +    description: 2 reset pins for 2 physical panels
> +
> +  left-pos-supply:
> +    description: Positive 5.7V supply for left panel

So, is the R63455 driving both panels or are there two panels, each
having R63455 controller? What if somebody gets a single Sharp panel and
wants to use it in their device? How will it match these bindings?

> +
> +  right-pos-supply:
> +    description: Positive 5.7V supply for right panel
> +
> +  left-neg-supply:
> +    description: Negative 5.7V supply for left panel
> +
> +  right-neg-supply:
> +    description: Negative 5.7V supply for right panel
> +
> +  left-backlight-supply:
> +    description: Backlight 21V supply for left panel
> +
> +  right-backlight-supply:
> +    description: Backlight 21V supply for right panel
> +
> +  vdda-supply:
> +    description: core 1.8V supply for panels
> +
> +  ports: $ref: /schemas/graph.yaml#/properties/ports
> +
> +required:
> +  - compatible
> +  - reset-gpios
> +  - left-pos-supply
> +  - left-neg-supply
> +  - right-pos-supply
> +  - right-neg-supply
> +  - left-backlight-supply
> +  - right-backlight-supply
> +  - vdda-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    &mdss_dsi0 {

Please drop the MDSS specifics, there should be one (or two) DSI busses,
driving your panels. The rests are details which are not necessary for
the example.

> +        vdda-supply = <&vreg_l3i_1p2>;
> +        status = "okay";
> +
> +        qcom,dual-dsi-mode;
> +        qcom,master-dsi;
> +
> +        panel: panel@0 {
> +            compatible = "sharp,ls026b3sa06", "synaptics,r63455";
> +            reg = <0>;
> +
> +            reset-gpios = <&pm8550_gpios 3 GPIO_ACTIVE_HIGH>,
> +                          <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
> +
> +            left-pos-supply = <&vpos_left>;
> +            left-neg-supply = <&vneg_left>;
> +            right-pos-supply = <&vpos_right>;
> +            right-neg-supply = <&vneg_right>;
> +            left-backlight-supply = <&backlight_left>;
> +            right-backlight-supply = <&backlight_right>;
> +
> +            vdda-supply = <&vreg_l12b_1p8>;
> +
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +                port@0 {
> +                    reg = <0>;
> +                    panel0_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi0_out>;

What is mdss_dsi0_out?

> +                    };
> +                };
> +
> +                port@1 {
> +                    reg = <1>;
> +                    panel1_in: endpoint {
> +                        remote-endpoint = <&mdss_dsi1_out>;
> +                    };
> +                };
> +            };
> +    };
> +
> +    &mdss_dsi0_out {
> +            remote-endpoint = <&panel0_in>;
> +            data-lanes = <0 1 2>;
> +    };
> +
> +    &mdss_dsi1_out {
> +            remote-endpoint = <&panel1_in>;
> +            data-lanes = <0 1 2>;
> +    };
> +...
> 
> -- 
> 2.43.0
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support
  2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
                     ` (2 preceding siblings ...)
  2026-05-21 20:24   ` Dmitry Baryshkov
@ 2026-05-21 20:46   ` Rob Herring (Arm)
  3 siblings, 0 replies; 14+ messages in thread
From: Rob Herring (Arm) @ 2026-05-21 20:46 UTC (permalink / raw)
  To: Jun Nie
  Cc: Simona Vetter, Thomas Zimmermann, Krzysztof Kozlowski,
	Marijn Suijten, Neil Armstrong, linux-kernel, devicetree,
	linux-arm-msm, Dmitry Baryshkov, Rob Clark, Maxime Ripard,
	dri-devel, Maarten Lankhorst, Jessica Zhang, Conor Dooley,
	David Airlie, freedreno, Dmitry Baryshkov, Abhinav Kumar,
	Sean Paul


On Thu, 21 May 2026 22:46:06 +0800, Jun Nie wrote:
> Add support for the dual-panel system found in the virtual reality device.
> This system consists of two physical 2160x2160 panels, each connected via
> a MIPI DSI interface. The backlight is managed through DSI link.
> 
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
>  .../bindings/display/panel/synaptics,r63455.yaml   | 125 +++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:
./Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml:26:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml:55:14: [error] syntax error: mapping values are not allowed here (syntax)

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml: ignoring, error parsing file
./Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml:55:14: mapping values are not allowed here
make[2]: *** Deleting file 'Documentation/devicetree/bindings/display/panel/synaptics,r63455.example.dts'
Documentation/devicetree/bindings/display/panel/synaptics,r63455.yaml:55:14: mapping values are not allowed here
make[2]: *** [Documentation/devicetree/bindings/Makefile:26: Documentation/devicetree/bindings/display/panel/synaptics,r63455.example.dts] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1659: dt_binding_check] Error 2
make: *** [Makefile:248: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/20260521-sm8650-7-1-bonded-dsi-v4-4-a4dd5e0850f1@linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-05-21 20:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21 14:46 [PATCH v4 0/5] Add support to 2 panels in bonded-DSI mode Jun Nie
2026-05-21 14:46 ` [PATCH v4 1/5] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1 Jun Nie
2026-05-21 15:08   ` sashiko-bot
2026-05-21 14:46 ` [PATCH v4 2/5] drm/mipi-dsi: Add flag to support dual-panel configurations Jun Nie
2026-05-21 15:20   ` sashiko-bot
2026-05-21 14:46 ` [PATCH v4 3/5] drm/msm/dsi: Support dual panel use case with single CRTC Jun Nie
2026-05-21 15:50   ` sashiko-bot
2026-05-21 14:46 ` [PATCH v4 4/5] dt-bindings: display: Add Synaptics R63455 panel support Jun Nie
2026-05-21 16:07   ` sashiko-bot
2026-05-21 19:45   ` Conor Dooley
2026-05-21 20:24   ` Dmitry Baryshkov
2026-05-21 20:46   ` Rob Herring (Arm)
2026-05-21 14:46 ` [PATCH v4 5/5] drm/panel: Add driver for Synaptics R63455 DSI panel Jun Nie
2026-05-21 16:30   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox