Devicetree
 help / color / mirror / Atom feed
* [PATCH v5 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels
@ 2026-05-21  8:14 Neil Armstrong
  2026-05-21  8:14 ` [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
  2026-05-21  8:14 ` [PATCH v5 2/2] drm: panel: add support for " Neil Armstrong
  0 siblings, 2 replies; 8+ messages in thread
From: Neil Armstrong @ 2026-05-21  8:14 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm
  Cc: dri-devel, devicetree, linux-kernel, linux-renesas-soc,
	Dmitry Baryshkov, Neil Armstrong, KancyJoe

Add support for the Renesas 63419 based dual-DSI video mode
Display Panels found in the Ayaneo gaming handled devices.

Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
Changes in v5:
- Import panel-common-dual.yaml in bindings
- Set reg as required
- fix bindings example typo
- Add helper to switch link in order to use single dsi_ctx to properly handle errors
- Disable vdd supplies if vcc supplied fail to enable
- Precise the power off sequence is recommended by the vendor spec
- Drop passing of node to second dsi to avoid re-probing the driver twice
- Link to v4: https://patch.msgid.link/20260519-topic-sm8650-ayaneo-pocket-s2-r63419-v4-0-b8929af5e951@linaro.org

Changes in v4:
- Moved height/width in the drm_mode, duplicated modes to use drm_connector_helper_get_modes_fixed
- Create dsi_info on the stack with proper OF node and name passed
- Switched to devm_drm_panel_add/devm_mipi_dsi_attach & dropped remove
- Link to v3: https://patch.msgid.link/20260504-topic-sm8650-ayaneo-pocket-s2-r63419-v3-0-9f61cf24aebf@linaro.org

Changes in v3:
- Added DDIC compatible as fallback
- Added rotation in bindings example
- Fixed bindings subject
- Added second MODULE_AUTHOR entry and re-ordered signed-off-by order
- Link to v2: https://patch.msgid.link/20260430-topic-sm8650-ayaneo-pocket-s2-r63419-v2-0-91ac10453d0c@linaro.org

Changes in v2:
- Add missing rotation property into bindings
- Fix commit message & subject typos
- Link to v1: https://patch.msgid.link/20260428-topic-sm8650-ayaneo-pocket-s2-r63419-v1-0-981eb5ab5a51@linaro.org

---
KancyJoe (1):
      drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels

Neil Armstrong (1):
      dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels

 .../bindings/display/panel/renesas,r63419.yaml     |  98 ++++++
 drivers/gpu/drm/panel/Kconfig                      |  12 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-renesas-r63419.c       | 364 +++++++++++++++++++++
 4 files changed, 475 insertions(+)
---
base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83
change-id: 20260428-topic-sm8650-ayaneo-pocket-s2-r63419-e72467e2db0f

Best regards,
--  
Neil Armstrong <neil.armstrong@linaro.org>


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

* [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:14 [PATCH v5 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong
@ 2026-05-21  8:14 ` Neil Armstrong
  2026-05-21  8:22   ` sashiko-bot
  2026-05-21 19:55   ` Conor Dooley
  2026-05-21  8:14 ` [PATCH v5 2/2] drm: panel: add support for " Neil Armstrong
  1 sibling, 2 replies; 8+ messages in thread
From: Neil Armstrong @ 2026-05-21  8:14 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm
  Cc: dri-devel, devicetree, linux-kernel, linux-renesas-soc,
	Dmitry Baryshkov, Neil Armstrong

Document the Renesas R63419 based dual-DSI video mode Display Panels found
in the Ayaneo gaming handled devices.

Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 .../bindings/display/panel/renesas,r63419.yaml     | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
new file mode 100644
index 000000000000..adfdd2c300a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/renesas,r63419.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R63419 based dual-DSI video mode Display Panel
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+  The Renesas R63419 is a generic DDIC used to control dual-DSI LCD panels.
+
+allOf:
+  - $ref: panel-common-dual.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ayaneo,wt0600-2k
+          - ayaneo,wt0630-2k
+      - const: renesas,r63419
+
+  reg:
+    maxItems: 1
+
+  vdd-supply: true
+  vddio-supply: true
+  vsp-supply: true
+  vsn-supply: true
+  vci-supply: true
+
+  backlight: true
+  reset-gpios: true
+  rotation: true
+  ports: true
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - vddio-supply
+  - vsp-supply
+  - vsn-supply
+  - vci-supply
+  - backlight
+  - reset-gpios
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "ayaneo,wt0600-2k", "renesas,r63419";
+            reg = <0>;
+
+            reset-gpios = <&gpio 176 GPIO_ACTIVE_LOW>;
+
+            vdd-supply = <&vdd_3v0_lcd>;
+            vddio-supply = <&vdd_1v8_io>;
+            vsn-supply = <&vdd_5v0_neg>;
+            vsp-supply = <&vdd_5v0_pos>;
+            vci-supply = <&vdd_3v0_vci>;
+
+            backlight = <&backlight>;
+
+            rotation = <90>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+                    panel_in0: endpoint {
+                        remote-endpoint = <&dsi0_out>;
+                    };
+                };
+
+                port@1 {
+                    reg = <1>;
+                    panel_in1: endpoint {
+                        remote-endpoint = <&dsi1_out>;
+                    };
+                };
+            };
+        };
+    };
+...

-- 
2.34.1


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

* [PATCH v5 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:14 [PATCH v5 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong
  2026-05-21  8:14 ` [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
@ 2026-05-21  8:14 ` Neil Armstrong
  2026-05-21  8:38   ` sashiko-bot
  1 sibling, 1 reply; 8+ messages in thread
From: Neil Armstrong @ 2026-05-21  8:14 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm
  Cc: dri-devel, devicetree, linux-kernel, linux-renesas-soc,
	Dmitry Baryshkov, Neil Armstrong, KancyJoe

From: KancyJoe <kancy2333@outlook.com>

Implement support for the Renesas 63419 based dual-DSI video mode
Display Panels found in the Ayaneo gaming handled devices.

Signed-off-by: KancyJoe <kancy2333@outlook.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 drivers/gpu/drm/panel/Kconfig                |  12 +
 drivers/gpu/drm/panel/Makefile               |   1 +
 drivers/gpu/drm/panel/panel-renesas-r63419.c | 364 +++++++++++++++++++++++++++
 3 files changed, 377 insertions(+)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 7450b27622a2..7295246cfa58 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -796,6 +796,18 @@ config DRM_PANEL_RENESAS_R61307
 	  This panel controller can be found in LG Optimus Vu P895 smartphone
 	  in combination with LCD panel.
 
+config DRM_PANEL_RENESAS_R63419
+	tristate "Renesas R63419 dual-DSI video mode panels"
+	depends on OF && GPIOLIB
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y here if you want to enable support for Ayaneo WT0600 and WT0630
+	  1440x2560 60Hz dual-DSI video mode display panels with Renesas
+	  R63419 IC.
+
+	  These panels are used in Ayaneo handheld gaming devices.
+
 config DRM_PANEL_RENESAS_R69328
 	tristate "Renesas R69328 720x1280 DSI video mode panel"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index c2c5cf817116..be9a6f3c9743 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o
 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o
 obj-$(CONFIG_DRM_PANEL_RENESAS_R61307) += panel-renesas-r61307.o
+obj-$(CONFIG_DRM_PANEL_RENESAS_R63419) += panel-renesas-r63419.o
 obj-$(CONFIG_DRM_PANEL_RENESAS_R69328) += panel-renesas-r69328.o
 obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01) += panel-samsung-ams581vf01.o
diff --git a/drivers/gpu/drm/panel/panel-renesas-r63419.c b/drivers/gpu/drm/panel/panel-renesas-r63419.c
new file mode 100644
index 000000000000..fe62b3bfba63
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-renesas-r63419.c
@@ -0,0 +1,364 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * DRM driver for Renesas R63419 based dual-DSI video mode panels
+ *
+ * Copyright (c) 2025, Kancy Joe <kancy2333@outlook.com>
+ * Copyright (C) 2026 Linaro Limited
+ * Author: Neil Armstrong <neil.armstrong@linaro.org>
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+
+struct renesas_r63419_panel {
+	struct drm_panel panel;
+	struct mipi_dsi_device *dsi[2];
+	const struct panel_desc *desc;
+
+	struct gpio_desc *reset_gpio;
+	struct regulator_bulk_data *vdd_supplies;
+	struct regulator_bulk_data *vcc_supplies;
+	enum drm_panel_orientation orientation;
+};
+
+/* VDDIO/VDD Supplies */
+static const struct regulator_bulk_data renesas_r63419_vdd_supplies[] = {
+	{ .supply = "vddio" },
+	{ .supply = "vdd" },
+};
+
+/* VSP/VSN/VCI Supplies */
+static const struct regulator_bulk_data renesas_r63419_vcc_supplies[] = {
+	{ .supply = "vsp" },
+	{ .supply = "vsn" },
+	{ .supply = "vci" },
+};
+
+struct panel_desc {
+	const struct drm_display_mode *mode;
+	unsigned int lanes;
+	unsigned long mode_flags;
+	enum mipi_dsi_pixel_format format;
+	const struct mipi_dsi_device_info dsi_info;
+};
+
+static const struct drm_display_mode wt0600_mode = {
+	/* Dual dsi */
+	.clock = 2 * (720 + 100 + 8 + 40) * (2560 + 15 + 2 + 8) * 60 / 1000,
+	.hdisplay = 2 * 720,
+	.hsync_start = 2 * (720 + 100),
+	.hsync_end = 2 * (720 + 100 + 8),
+	.htotal = 2 * (720 + 100 + 8 + 40),
+	.vdisplay = 2560,
+	.vsync_start = 2560 + 15,
+	.vsync_end = 2560 + 15 + 2,
+	.vtotal = 2560 + 15 + 2 + 8,
+	.type = DRM_MODE_TYPE_DRIVER,
+	.width_mm = 74,
+	.height_mm = 131,
+};
+
+static const struct drm_display_mode wt0630_mode = {
+	/* Dual dsi */
+	.clock = 2 * (720 + 100 + 8 + 40) * (2560 + 15 + 2 + 8) * 60 / 1000,
+	.hdisplay = 2 * 720,
+	.hsync_start = 2 * (720 + 100),
+	.hsync_end = 2 * (720 + 100 + 8),
+	.htotal = 2 * (720 + 100 + 8 + 40),
+	.vdisplay = 2560,
+	.vsync_start = 2560 + 15,
+	.vsync_end = 2560 + 15 + 2,
+	.vtotal = 2560 + 15 + 2 + 8,
+	.type = DRM_MODE_TYPE_DRIVER,
+	.width_mm = 78,
+	.height_mm = 140,
+};
+
+static struct panel_desc wt0600_desc = {
+	.lanes = 4,
+	.mode = &wt0600_mode,
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+		      MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM,
+	.format = MIPI_DSI_FMT_RGB888,
+};
+
+static struct panel_desc wt0630_desc = {
+	.lanes = 4,
+	.mode = &wt0630_mode,  /* wt0600 only has different screen size */
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+		      MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM,
+	.format = MIPI_DSI_FMT_RGB888,
+};
+
+static inline struct renesas_r63419_panel *
+to_renesas_r63419_panel(struct drm_panel *panel)
+{
+	return container_of(panel, struct renesas_r63419_panel, panel);
+}
+
+/*
+ * Helper to switch between DSI links, so we share a single dsi_ctx
+ * for both links, so in case of an error all writes & sleep for
+ * both links are ignored.
+ */
+static inline void dsi_link_switch(struct renesas_r63419_panel *ctx,
+				   struct mipi_dsi_multi_context *dsi_ctx,
+				   unsigned int link)
+{
+	dsi_ctx->dsi = ctx->dsi[link];
+}
+
+static int renesas_r63419_on(struct renesas_r63419_panel *ctx)
+{
+	struct mipi_dsi_multi_context dsi_ctx;
+
+	dsi_link_switch(ctx, &dsi_ctx, 0);
+	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+	dsi_link_switch(ctx, &dsi_ctx, 1);
+	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+	mipi_dsi_msleep(&dsi_ctx, 150);
+
+	dsi_link_switch(ctx, &dsi_ctx, 0);
+	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+	dsi_link_switch(ctx, &dsi_ctx, 1);
+	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+	mipi_dsi_msleep(&dsi_ctx, 50);
+
+	return dsi_ctx.accum_err;
+}
+
+static int renesas_r63419_disable(struct drm_panel *panel)
+{
+	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
+	struct mipi_dsi_multi_context dsi_ctx;
+
+	dsi_link_switch(ctx, &dsi_ctx, 0);
+	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+	dsi_link_switch(ctx, &dsi_ctx, 1);
+	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+	mipi_dsi_msleep(&dsi_ctx, 50);
+
+	dsi_link_switch(ctx, &dsi_ctx, 0);
+	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+	dsi_link_switch(ctx, &dsi_ctx, 1);
+	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+	mipi_dsi_msleep(&dsi_ctx, 120);
+
+	return dsi_ctx.accum_err;
+}
+
+static int renesas_r63419_prepare(struct drm_panel *panel)
+{
+	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(renesas_r63419_vdd_supplies),
+				    ctx->vdd_supplies);
+	if (ret < 0)
+		return ret;
+
+	usleep_range(1000, 2000);
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(renesas_r63419_vcc_supplies),
+				    ctx->vcc_supplies);
+	if (ret < 0) {
+		regulator_bulk_disable(ARRAY_SIZE(renesas_r63419_vdd_supplies),
+				       ctx->vdd_supplies);
+		return ret;
+	}
+
+	usleep_range(1000, 2000);
+
+	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+
+	usleep_range(3000, 4000);
+
+	ret = renesas_r63419_on(ctx);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to initialize panel: %d\n", ret);
+
+		/* Power off sequence from the r63419 datasheet */
+		regulator_bulk_disable(ARRAY_SIZE(renesas_r63419_vcc_supplies),
+				       ctx->vcc_supplies);
+		regulator_bulk_disable(ARRAY_SIZE(renesas_r63419_vdd_supplies),
+				       ctx->vdd_supplies);
+
+		gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+static int renesas_r63419_unprepare(struct drm_panel *panel)
+{
+	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
+
+	/* Power off sequence from the r63419 datasheet */
+	regulator_bulk_disable(ARRAY_SIZE(renesas_r63419_vcc_supplies), ctx->vcc_supplies);
+	regulator_bulk_disable(ARRAY_SIZE(renesas_r63419_vdd_supplies), ctx->vdd_supplies);
+
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+	return 0;
+}
+
+static int renesas_r63419_get_modes(struct drm_panel *panel,
+				    struct drm_connector *connector)
+{
+	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
+	const struct drm_display_mode *mode = ctx->desc->mode;
+
+	drm_connector_set_panel_orientation(connector, ctx->orientation);
+
+	return drm_connector_helper_get_modes_fixed(connector, mode);
+}
+
+static enum drm_panel_orientation
+renesas_r63419_get_orientation(struct drm_panel *panel)
+{
+	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
+
+	return ctx->orientation;
+}
+
+static const struct drm_panel_funcs renesas_r63419_panel_funcs = {
+	.disable = renesas_r63419_disable,
+	.prepare = renesas_r63419_prepare,
+	.unprepare = renesas_r63419_unprepare,
+	.get_modes = renesas_r63419_get_modes,
+	.get_orientation = renesas_r63419_get_orientation,
+};
+
+static int renesas_r63419_probe(struct mipi_dsi_device *dsi)
+{
+	struct mipi_dsi_device_info info = { };
+	struct device *dev = &dsi->dev;
+	struct renesas_r63419_panel *ctx;
+	struct device_node *dsi1_node;
+	struct mipi_dsi_host *dsi1_host;
+	int ret, i;
+
+	ctx = devm_drm_panel_alloc(dev, struct renesas_r63419_panel, panel,
+				   &renesas_r63419_panel_funcs, DRM_MODE_CONNECTOR_DSI);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	ctx->desc = of_device_get_match_data(dev);
+	if (!ctx->desc)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to get panel description\n");
+
+	ret = devm_regulator_bulk_get_const(&dsi->dev,
+					    ARRAY_SIZE(renesas_r63419_vdd_supplies),
+					    renesas_r63419_vdd_supplies, &ctx->vdd_supplies);
+	if (ret < 0)
+		return ret;
+
+	ret = devm_regulator_bulk_get_const(&dsi->dev,
+					    ARRAY_SIZE(renesas_r63419_vcc_supplies),
+					    renesas_r63419_vcc_supplies, &ctx->vcc_supplies);
+	if (ret < 0)
+		return ret;
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+				     "Failed to get reset gpio\n");
+
+	/* Get second DSI host */
+	dsi1_node = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
+	if (!dsi1_node)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to get remote node for second DSI\n");
+
+	dsi1_host = of_find_mipi_dsi_host_by_node(dsi1_node);
+	of_node_put(dsi1_node);
+	if (!dsi1_host)
+		return dev_err_probe(dev, -EPROBE_DEFER,
+				     "Failed to find second DSI host\n");
+
+	/* Copy current DSI info, do not provide OF node since no driver needs to be attached */
+	strscpy(info.type, dsi->name, sizeof(info.type));
+	info.channel = dsi->channel;
+
+	/* Register the second DSI device */
+	ctx->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi1_host, &info);
+	if (IS_ERR(ctx->dsi[1]))
+		return dev_err_probe(dev, PTR_ERR(ctx->dsi[1]),
+				     "Failed to register second DSI device\n");
+
+	ctx->dsi[0] = dsi;
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	/* Get panel orientation */
+	ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
+	if (ret < 0 && ret != -ENODEV)
+		return dev_err_probe(dev, ret,
+				     "Failed to get panel orientation\n");
+
+	ctx->panel.prepare_prev_first = true;
+
+	ret = drm_panel_of_backlight(&ctx->panel);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get backlight\n");
+
+	ret = devm_drm_panel_add(dev, &ctx->panel);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add panel\n");
+
+	/* Configure and attach both DSI devices */
+	for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
+		ctx->dsi[i]->lanes = ctx->desc->lanes;
+		ctx->dsi[i]->format = ctx->desc->format;
+		ctx->dsi[i]->mode_flags = ctx->desc->mode_flags;
+
+		ret = devm_mipi_dsi_attach(dev, ctx->dsi[i]);
+		if (ret < 0)
+			return dev_err_probe(dev, ret,
+					     "Failed to attach DSI device %d\n", i);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id renesas_r63419_of_match[] = {
+	{
+		.compatible = "ayaneo,wt0600-2k",
+		.data = &wt0600_desc,
+	},
+	{
+		.compatible = "ayaneo,wt0630-2k",
+		.data = &wt0630_desc,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, renesas_r63419_of_match);
+
+static struct mipi_dsi_driver renesas_r63419_driver = {
+	.probe = renesas_r63419_probe,
+	.driver = {
+		.name = "panel-renesas-r63419",
+		.of_match_table = renesas_r63419_of_match,
+	},
+};
+module_mipi_dsi_driver(renesas_r63419_driver);
+
+MODULE_AUTHOR("Kancy Joe <kancy2333@outlook.com>");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+MODULE_DESCRIPTION("DRM driver for Renesas R63419 based dual-DSI video mode panels");
+MODULE_LICENSE("GPL");

-- 
2.34.1


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

* Re: [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:14 ` [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
@ 2026-05-21  8:22   ` sashiko-bot
  2026-05-21  8:33     ` Neil Armstrong
  2026-05-21 19:55   ` Conor Dooley
  1 sibling, 1 reply; 8+ messages in thread
From: sashiko-bot @ 2026-05-21  8:22 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: robh, devicetree, wsa+renesas, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The schema incorrectly uses `additionalProperties: false` instead of `unevaluatedProperties: false` when inheriting from a common schema.
--

commit 06ab207971a6f54327d9bb05b5e8355cbba81b0c
Author: Neil Armstrong <neil.armstrong@linaro.org>

dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels

This commit adds a new device tree binding document for the Renesas
R63419 generic DDIC. The DDIC is used to control dual-DSI LCD panels,
such as those found in Ayaneo gaming handheld devices.

> diff --git a/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
> new file mode 100644
> index 0000000000000..adfdd2c300a35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
[ ... ]
> +allOf:
> +  - $ref: panel-common-dual.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - ayaneo,wt0600-2k
> +          - ayaneo,wt0630-2k
> +      - const: renesas,r63419
[ ... ]
> +  backlight: true
> +  reset-gpios: true
> +  rotation: true
> +  ports: true
> +
> +required:
> +  - compatible
> +  - reg
[ ... ]
> +  - reset-gpios
> +  - ports
> +
> +additionalProperties: false

[Severity: Low]
Since this schema inherits from panel-common-dual.yaml in the allOf block
above, should this be unevaluatedProperties: false instead?

In JSON schema, additionalProperties: false only considers the properties
explicitly listed in the local properties block. This means any standard
panel properties (like width-mm, height-mm, or enable-gpios) not explicitly
listed here will be incorrectly rejected during validation.

Using unevaluatedProperties: false would allow properties defined in the
inherited schemas. It would also eliminate the need to redundantly define
properties like backlight or ports in the local properties block.

> +
> +examples:
> +  - |
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-topic-sm8650-ayaneo-pocket-s2-r63419-v5-0-dd5700299390@linaro.org?part=1

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

* Re: [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:22   ` sashiko-bot
@ 2026-05-21  8:33     ` Neil Armstrong
  0 siblings, 0 replies; 8+ messages in thread
From: Neil Armstrong @ 2026-05-21  8:33 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: robh, devicetree, wsa+renesas, conor+dt

On 5/21/26 10:22, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] The schema incorrectly uses `additionalProperties: false` instead of `unevaluatedProperties: false` when inheriting from a common schema.
> --
> 
> commit 06ab207971a6f54327d9bb05b5e8355cbba81b0c
> Author: Neil Armstrong <neil.armstrong@linaro.org>
> 
> dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels
> 
> This commit adds a new device tree binding document for the Renesas
> R63419 generic DDIC. The DDIC is used to control dual-DSI LCD panels,
> such as those found in Ayaneo gaming handheld devices.
> 
>> diff --git a/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
>> new file mode 100644
>> index 0000000000000..adfdd2c300a35
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml
> [ ... ]
>> +allOf:
>> +  - $ref: panel-common-dual.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    items:
>> +      - enum:
>> +          - ayaneo,wt0600-2k
>> +          - ayaneo,wt0630-2k
>> +      - const: renesas,r63419
> [ ... ]
>> +  backlight: true
>> +  reset-gpios: true
>> +  rotation: true
>> +  ports: true
>> +
>> +required:
>> +  - compatible
>> +  - reg
> [ ... ]
>> +  - reset-gpios
>> +  - ports
>> +
>> +additionalProperties: false
> 
> [Severity: Low]
> Since this schema inherits from panel-common-dual.yaml in the allOf block
> above, should this be unevaluatedProperties: false instead?

No, it's deliberate to control the properties we allow

> 
> In JSON schema, additionalProperties: false only considers the properties
> explicitly listed in the local properties block. This means any standard
> panel properties (like width-mm, height-mm, or enable-gpios) not explicitly
> listed here will be incorrectly rejected during validation.
> 
> Using unevaluatedProperties: false would allow properties defined in the
> inherited schemas. It would also eliminate the need to redundantly define
> properties like backlight or ports in the local properties block.
> 
>> +
>> +examples:
>> +  - |
> [ ... ]
> 


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

* Re: [PATCH v5 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:14 ` [PATCH v5 2/2] drm: panel: add support for " Neil Armstrong
@ 2026-05-21  8:38   ` sashiko-bot
  2026-05-21 13:05     ` Neil Armstrong
  0 siblings, 1 reply; 8+ messages in thread
From: sashiko-bot @ 2026-05-21  8:38 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: wsa+renesas, devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Uninitialized stack variable `dsi_ctx` causes undefined behavior in DSI initialization
- [High] Incorrect MIPI DCS initialization sequence (Set Display On before Exit Sleep Mode)
- [High] Race condition due to panel registration before DSI hardware is attached
--

commit 1aa27fde3d1fe4c1d08cfa9a63d3e7e28912831f
Author: KancyJoe <kancy2333@outlook.com>

drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels

Implement support for the Renesas 63419 based dual-DSI video mode
Display Panels found in the Ayaneo gaming handled devices.

> diff --git a/drivers/gpu/drm/panel/panel-renesas-r63419.c b/drivers/gpu/drm/panel/panel-renesas-r63419.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-renesas-r63419.c

[ ... ]

> +static int renesas_r63419_on(struct renesas_r63419_panel *ctx)
> +{
> +	struct mipi_dsi_multi_context dsi_ctx;

[Severity: High]
Does leaving dsi_ctx uninitialized here leave dsi_ctx.accum_err with
random stack garbage?

The helper dsi_link_switch() only assigns the dsi pointer, so subsequent
multi-context calls like mipi_dsi_dcs_set_display_on_multi() might immediately
return if accum_err is non-zero, silently skipping the initialization.

> +
> +	dsi_link_switch(ctx, &dsi_ctx, 0);
> +	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> +	dsi_link_switch(ctx, &dsi_ctx, 1);
> +	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> +	mipi_dsi_msleep(&dsi_ctx, 150);
> +
> +	dsi_link_switch(ctx, &dsi_ctx, 0);
> +	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> +	dsi_link_switch(ctx, &dsi_ctx, 1);
> +	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> +	mipi_dsi_msleep(&dsi_ctx, 50);

[Severity: High]
Is it intentional to send the Set Display On command before Exit Sleep Mode?

According to the MIPI DCS specification, the display must exit sleep mode and
stabilize before it can process the Set Display On command. Sending these
commands in this order will likely result in the panel ignoring Set Display On,
causing it to remain blank.

> +
> +	return dsi_ctx.accum_err;
> +}
> +
> +static int renesas_r63419_disable(struct drm_panel *panel)
> +{
> +	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
> +	struct mipi_dsi_multi_context dsi_ctx;

[Severity: High]
Like in renesas_r63419_on(), can this uninitialized struct leave
dsi_ctx.accum_err with stack garbage? This might cause the panel disable
commands to be silently skipped.

> +
> +	dsi_link_switch(ctx, &dsi_ctx, 0);
> +	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);

[ ... ]

> +static int renesas_r63419_probe(struct mipi_dsi_device *dsi)
> +{

[ ... ]

> +	ret = devm_drm_panel_add(dev, &ctx->panel);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to add panel\n");
> +
> +	/* Configure and attach both DSI devices */
> +	for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
> +		ctx->dsi[i]->lanes = ctx->desc->lanes;
> +		ctx->dsi[i]->format = ctx->desc->format;
> +		ctx->dsi[i]->mode_flags = ctx->desc->mode_flags;
> +
> +		ret = devm_mipi_dsi_attach(dev, ctx->dsi[i]);

[Severity: High]
Could registering the panel before the DSI hardware is attached cause a race
condition?

If a bridge driver concurrently finds the panel and triggers a display enable
sequence, it might invoke the panel's callbacks before the DSI endpoints are
actually attached, leading to DCS command timeouts or crashes.

Additionally, because devm actions are executed in reverse order on cleanup,
the DSI devices would be detached before the panel is unregistered, exposing
an unattached panel during driver unload. Should devm_drm_panel_add() be
called only after all hardware setup and DSI attachments are complete?

> +		if (ret < 0)
> +			return dev_err_probe(dev, ret,
> +					     "Failed to attach DSI device %d\n", i);
> +	}
> +
> +	return 0;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-topic-sm8650-ayaneo-pocket-s2-r63419-v5-0-dd5700299390@linaro.org?part=2

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

* Re: [PATCH v5 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:38   ` sashiko-bot
@ 2026-05-21 13:05     ` Neil Armstrong
  0 siblings, 0 replies; 8+ messages in thread
From: Neil Armstrong @ 2026-05-21 13:05 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: wsa+renesas, devicetree, robh, conor+dt

On 5/21/26 10:38, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] Uninitialized stack variable `dsi_ctx` causes undefined behavior in DSI initialization
> - [High] Incorrect MIPI DCS initialization sequence (Set Display On before Exit Sleep Mode)
> - [High] Race condition due to panel registration before DSI hardware is attached
> --
> 
> commit 1aa27fde3d1fe4c1d08cfa9a63d3e7e28912831f
> Author: KancyJoe <kancy2333@outlook.com>
> 
> drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels
> 
> Implement support for the Renesas 63419 based dual-DSI video mode
> Display Panels found in the Ayaneo gaming handled devices.
> 
>> diff --git a/drivers/gpu/drm/panel/panel-renesas-r63419.c b/drivers/gpu/drm/panel/panel-renesas-r63419.c
>> new file mode 100644
>> --- /dev/null
>> +++ b/drivers/gpu/drm/panel/panel-renesas-r63419.c
> 
> [ ... ]
> 
>> +static int renesas_r63419_on(struct renesas_r63419_panel *ctx)
>> +{
>> +	struct mipi_dsi_multi_context dsi_ctx;
> 
> [Severity: High]
> Does leaving dsi_ctx uninitialized here leave dsi_ctx.accum_err with
> random stack garbage?
> 
> The helper dsi_link_switch() only assigns the dsi pointer, so subsequent
> multi-context calls like mipi_dsi_dcs_set_display_on_multi() might immediately
> return if accum_err is non-zero, silently skipping the initialization.

Good point

> 
>> +
>> +	dsi_link_switch(ctx, &dsi_ctx, 0);
>> +	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
>> +	dsi_link_switch(ctx, &dsi_ctx, 1);
>> +	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
>> +	mipi_dsi_msleep(&dsi_ctx, 150);
>> +
>> +	dsi_link_switch(ctx, &dsi_ctx, 0);
>> +	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
>> +	dsi_link_switch(ctx, &dsi_ctx, 1);
>> +	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
>> +	mipi_dsi_msleep(&dsi_ctx, 50);
> 
> [Severity: High]
> Is it intentional to send the Set Display On command before Exit Sleep Mode?
> 
> According to the MIPI DCS specification, the display must exit sleep mode and
> stabilize before it can process the Set Display On command. Sending these
> commands in this order will likely result in the panel ignoring Set Display On,
> causing it to remain blank.

It's required by the panel spec

>> +
>> +	return dsi_ctx.accum_err;
>> +}
>> +
>> +static int renesas_r63419_disable(struct drm_panel *panel)
>> +{
>> +	struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel);
>> +	struct mipi_dsi_multi_context dsi_ctx;
> 
> [Severity: High]
> Like in renesas_r63419_on(), can this uninitialized struct leave
> dsi_ctx.accum_err with stack garbage? This might cause the panel disable
> commands to be silently skipped.

Good point

> 
>> +
>> +	dsi_link_switch(ctx, &dsi_ctx, 0);
>> +	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
> 
> [ ... ]
> 
>> +static int renesas_r63419_probe(struct mipi_dsi_device *dsi)
>> +{
> 
> [ ... ]
> 
>> +	ret = devm_drm_panel_add(dev, &ctx->panel);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "Failed to add panel\n");
>> +
>> +	/* Configure and attach both DSI devices */
>> +	for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
>> +		ctx->dsi[i]->lanes = ctx->desc->lanes;
>> +		ctx->dsi[i]->format = ctx->desc->format;
>> +		ctx->dsi[i]->mode_flags = ctx->desc->mode_flags;
>> +
>> +		ret = devm_mipi_dsi_attach(dev, ctx->dsi[i]);
> 
> [Severity: High]
> Could registering the panel before the DSI hardware is attached cause a race
> condition?
> 
> If a bridge driver concurrently finds the panel and triggers a display enable
> sequence, it might invoke the panel's callbacks before the DSI endpoints are
> actually attached, leading to DCS command timeouts or crashes.
> 
> Additionally, because devm actions are executed in reverse order on cleanup,
> the DSI devices would be detached before the panel is unregistered, exposing
> an unattached panel during driver unload. Should devm_drm_panel_add() be
> called only after all hardware setup and DSI attachments are complete?

No

> 
>> +		if (ret < 0)
>> +			return dev_err_probe(dev, ret,
>> +					     "Failed to attach DSI device %d\n", i);
>> +	}
>> +
>> +	return 0;
>> +}
> 


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

* Re: [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels
  2026-05-21  8:14 ` [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
  2026-05-21  8:22   ` sashiko-bot
@ 2026-05-21 19:55   ` Conor Dooley
  1 sibling, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2026-05-21 19:55 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm, dri-devel, devicetree, linux-kernel,
	linux-renesas-soc, Dmitry Baryshkov

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

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

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

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

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

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21  8:14 [PATCH v5 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong
2026-05-21  8:14 ` [PATCH v5 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
2026-05-21  8:22   ` sashiko-bot
2026-05-21  8:33     ` Neil Armstrong
2026-05-21 19:55   ` Conor Dooley
2026-05-21  8:14 ` [PATCH v5 2/2] drm: panel: add support for " Neil Armstrong
2026-05-21  8:38   ` sashiko-bot
2026-05-21 13:05     ` Neil Armstrong

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