* [PATCH v4 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels
@ 2026-05-19 8:09 Neil Armstrong
2026-05-19 8:09 ` [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong
2026-05-19 8:09 ` [PATCH v4 2/2] drm: panel: add support for " Neil Armstrong
0 siblings, 2 replies; 7+ messages in thread
From: Neil Armstrong @ 2026-05-19 8:09 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 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 | 97 ++++++
drivers/gpu/drm/panel/Kconfig | 12 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-renesas-r63419.c | 341 +++++++++++++++++++++
4 files changed, 451 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] 7+ messages in thread* [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:09 [PATCH v4 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong @ 2026-05-19 8:09 ` Neil Armstrong 2026-05-19 8:18 ` sashiko-bot 2026-05-19 8:09 ` [PATCH v4 2/2] drm: panel: add support for " Neil Armstrong 1 sibling, 1 reply; 7+ messages in thread From: Neil Armstrong @ 2026-05-19 8:09 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 | 97 ++++++++++++++++++++++ 1 file changed, 97 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..e4db01f88302 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml @@ -0,0 +1,97 @@ +# 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.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 + - 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_pos>; + vsp-supply = <&vdd_5v0_neg>; + 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] 7+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:09 ` [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong @ 2026-05-19 8:18 ` sashiko-bot 2026-05-19 8:27 ` Neil Armstrong 0 siblings, 1 reply; 7+ messages in thread From: sashiko-bot @ 2026-05-19 8:18 UTC (permalink / raw) To: Neil Armstrong; +Cc: wsa+renesas, robh, devicetree, conor+dt Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [Medium] The `reg` property is omitted from the `required` list. - [Medium] Schema validation bypass for dual-DSI ports structure. - [Medium] Flipped positive/negative voltage regulator assignments in the dt-binding example. -- commit b7585613be27a07063e2837b4b237f47e298a1f5 Author: Neil Armstrong <neil.armstrong@linaro.org> dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels This commit documents the Renesas R63419 generic DDIC used to control dual-DSI LCD panels, specifically for the 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..e4db01f88302c > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml [ ... ] > +description: > + The Renesas R63419 is a generic DDIC used to control dual-DSI LCD panels. > + > +allOf: > + - $ref: panel-common.yaml# Since this documents a dual-DSI panel, should this reference panel-common-dual.yaml# instead? Referencing panel-common-dual.yaml# would correctly enforce the dual-DSI topology constraints and validate the ports structure for dual-link DSI panels. [ ... ] > +required: > + - compatible > + - vdd-supply > + - vddio-supply > + - vsp-supply > + - vsn-supply > + - vci-supply > + - backlight > + - reset-gpios > + - ports Should reg be included in this required list? The Renesas R63419 is a DSI peripheral and must be instantiated as a child node under a DSI controller bus, which inherently requires a reg property for its virtual channel. Omitting it from the required list allows incomplete nodes to pass validation. [ ... ] > + reset-gpios = <&gpio 176 GPIO_ACTIVE_LOW>; > + > + vdd-supply = <&vdd_3v0_lcd>; > + vddio-supply = <&vdd_1v8_io>; > + vsn-supply = <&vdd_5v0_pos>; > + vsp-supply = <&vdd_5v0_neg>; Are the voltage regulator assignments flipped in this example? It looks like vsn-supply (Voltage Supply Negative) is mapped to the positive regulator, while vsp-supply (Voltage Supply Positive) is mapped to the negative one. [ ... ] -- Sashiko AI review · https://sashiko.dev/#/patchset/20260519-topic-sm8650-ayaneo-pocket-s2-r63419-v4-0-b8929af5e951@linaro.org?part=1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:18 ` sashiko-bot @ 2026-05-19 8:27 ` Neil Armstrong 0 siblings, 0 replies; 7+ messages in thread From: Neil Armstrong @ 2026-05-19 8:27 UTC (permalink / raw) To: sashiko-reviews; +Cc: wsa+renesas, robh, devicetree, conor+dt On 5/19/26 10:18, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: > - [Medium] The `reg` property is omitted from the `required` list. > - [Medium] Schema validation bypass for dual-DSI ports structure. > - [Medium] Flipped positive/negative voltage regulator assignments in the dt-binding example. > -- > > commit b7585613be27a07063e2837b4b237f47e298a1f5 > Author: Neil Armstrong <neil.armstrong@linaro.org> > > dt-bindings: display: panel: document the Renesas R63419 based dual-DSI video mode Display Panels > > This commit documents the Renesas R63419 generic DDIC used to control > dual-DSI LCD panels, specifically for the 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..e4db01f88302c >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/display/panel/renesas,r63419.yaml > > [ ... ] > >> +description: >> + The Renesas R63419 is a generic DDIC used to control dual-DSI LCD panels. >> + >> +allOf: >> + - $ref: panel-common.yaml# > > Since this documents a dual-DSI panel, should this reference > panel-common-dual.yaml# instead? > > Referencing panel-common-dual.yaml# would correctly enforce the dual-DSI > topology constraints and validate the ports structure for dual-link DSI > panels. Good point > > [ ... ] > >> +required: >> + - compatible >> + - vdd-supply >> + - vddio-supply >> + - vsp-supply >> + - vsn-supply >> + - vci-supply >> + - backlight >> + - reset-gpios >> + - ports > > Should reg be included in this required list? > > The Renesas R63419 is a DSI peripheral and must be instantiated as a child > node under a DSI controller bus, which inherently requires a reg property for > its virtual channel. Omitting it from the required list allows incomplete > nodes to pass validation. Good point > > [ ... ] > >> + reset-gpios = <&gpio 176 GPIO_ACTIVE_LOW>; >> + >> + vdd-supply = <&vdd_3v0_lcd>; >> + vddio-supply = <&vdd_1v8_io>; >> + vsn-supply = <&vdd_5v0_pos>; >> + vsp-supply = <&vdd_5v0_neg>; > > Are the voltage regulator assignments flipped in this example? > > It looks like vsn-supply (Voltage Supply Negative) is mapped to the positive > regulator, while vsp-supply (Voltage Supply Positive) is mapped to the > negative one. Good finding even if it's only an example, will fix > > [ ... ] > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:09 [PATCH v4 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong 2026-05-19 8:09 ` [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong @ 2026-05-19 8:09 ` Neil Armstrong 2026-05-19 8:32 ` sashiko-bot 1 sibling, 1 reply; 7+ messages in thread From: Neil Armstrong @ 2026-05-19 8:09 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 | 341 +++++++++++++++++++++++++++ 3 files changed, 354 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..1643a9c78c3f --- /dev/null +++ b/drivers/gpu/drm/panel/panel-renesas-r63419.c @@ -0,0 +1,341 @@ +// 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); +} + +static int renesas_r63419_on(struct renesas_r63419_panel *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi[0] }; + struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = ctx->dsi[1] }; + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx1); + mipi_dsi_msleep(&dsi_ctx, 150); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx1); + 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 = ctx->dsi[0] }; + struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = ctx->dsi[1] }; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx1); + mipi_dsi_msleep(&dsi_ctx, 50); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx1); + 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) + 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); + 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); + + 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 */ + strscpy(info.type, dsi->name, sizeof(info.type)); + info.channel = dsi->channel; + info.node = dev_of_node(dev); + + /* 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] 7+ messages in thread
* Re: [PATCH v4 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:09 ` [PATCH v4 2/2] drm: panel: add support for " Neil Armstrong @ 2026-05-19 8:32 ` sashiko-bot 2026-05-19 8:48 ` Neil Armstrong 0 siblings, 1 reply; 7+ messages in thread From: sashiko-bot @ 2026-05-19 8:32 UTC (permalink / raw) To: Neil Armstrong; +Cc: wsa+renesas, devicetree, robh, conor+dt Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider: - [High] DCS initialization sequence sends SET_DISPLAY_ON before EXIT_SLEEP_MODE. - [High] Incorrect hardware power sequencing during teardown risks hardware damage. - [High] Resource leak of `vdd_supplies` in the `renesas_r63419_prepare()` error path. - [High] Panel is registered to DRM before DSI devices are attached, causing a race condition. - [High] Secondary DSI device is registered with the primary's `of_node`, causing an unintended re-probe. - [Medium] Silent ignore of errors on the secondary DSI link in multi-context DCS sequences. -- commit 536a4ce2d0cffbeb00543674b725c12c37ef3272 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 > index 0000000000000..1643a9c78c3fd > --- /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 = { .dsi = ctx->dsi[0] }; > + struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = ctx->dsi[1] }; > + > + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); > + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx1); > + mipi_dsi_msleep(&dsi_ctx, 150); > + > + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); > + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx1); > + mipi_dsi_msleep(&dsi_ctx, 50); Are the DCS commands sent in the correct order? Standard MIPI DCS sequences require exiting sleep mode (0x11) and waiting for the hardware to wake up before setting the display on (0x29). Sending a Display On command while the panel is still in sleep mode can prevent the display from turning on. Also, does this silently ignore errors on the secondary DSI link? If a command fails on dsi_ctx1, the error doesn't seem to be captured or checked here. Additionally, mipi_dsi_msleep() only checks the primary context, so if a failure occurs on the primary, the sleep is bypassed, and commands to the secondary are sent without the required delay. > + > + return dsi_ctx.accum_err; Should this return a combination of both dsi_ctx.accum_err and dsi_ctx1.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) > + return ret; If regulator_bulk_enable() for vcc_supplies fails here, does this leak the regulator reference for the already-enabled vdd_supplies? > + > + 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); > + 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); Could this hardware power sequencing risk hardware damage? The power regulators are disabled before the reset GPIO is asserted. Leaving a logic high voltage driven on an IO pin of an unpowered IC can back-power the chip through its ESD protection diodes. The reset GPIO should likely be asserted before disabling the regulators. > + > + return ret; > + } > + > + return 0; > +} > + > +static int renesas_r63419_unprepare(struct drm_panel *panel) > +{ > + struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel); > + > + 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); The same power sequencing issue seems to exist here during teardown. > + > + return 0; > +} [ ... ] > +static int renesas_r63419_probe(struct mipi_dsi_device *dsi) > +{ [ ... ] > + /* Copy current DSI info */ > + strscpy(info.type, dsi->name, sizeof(info.type)); > + info.channel = dsi->channel; > + info.node = dev_of_node(dev); > + > + /* Register the second DSI device */ > + ctx->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi1_host, &info); Could setting info.node to dev_of_node(dev) for the secondary DSI device cause an unintended re-probe loop? Because the secondary device shares the same of_node as the primary device, the MIPI DSI bus driver matching logic will match it against the same renesas_r63419_driver and invoke probe() again for the secondary device. > + 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]); Does registering the panel to DRM before attaching the DSI devices introduce a race condition? Calling devm_drm_panel_add() makes the panel immediately visible to consumers. If a consumer prepares the panel right away, it will attempt to send DCS commands over unattached DSI links. -- Sashiko AI review · https://sashiko.dev/#/patchset/20260519-topic-sm8650-ayaneo-pocket-s2-r63419-v4-0-b8929af5e951@linaro.org?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/2] drm: panel: add support for the Renesas R63419 based dual-DSI video mode Display Panels 2026-05-19 8:32 ` sashiko-bot @ 2026-05-19 8:48 ` Neil Armstrong 0 siblings, 0 replies; 7+ messages in thread From: Neil Armstrong @ 2026-05-19 8:48 UTC (permalink / raw) To: sashiko-reviews; +Cc: wsa+renesas, devicetree, robh, conor+dt On 5/19/26 10:32, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider: > - [High] DCS initialization sequence sends SET_DISPLAY_ON before EXIT_SLEEP_MODE. > - [High] Incorrect hardware power sequencing during teardown risks hardware damage. > - [High] Resource leak of `vdd_supplies` in the `renesas_r63419_prepare()` error path. > - [High] Panel is registered to DRM before DSI devices are attached, causing a race condition. > - [High] Secondary DSI device is registered with the primary's `of_node`, causing an unintended re-probe. > - [Medium] Silent ignore of errors on the secondary DSI link in multi-context DCS sequences. > -- > > commit 536a4ce2d0cffbeb00543674b725c12c37ef3272 > 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 >> index 0000000000000..1643a9c78c3fd >> --- /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 = { .dsi = ctx->dsi[0] }; >> + struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = ctx->dsi[1] }; >> + >> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); >> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx1); >> + mipi_dsi_msleep(&dsi_ctx, 150); >> + >> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); >> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx1); >> + mipi_dsi_msleep(&dsi_ctx, 50); > > Are the DCS commands sent in the correct order? Standard MIPI DCS sequences > require exiting sleep mode (0x11) and waiting for the hardware to wake up > before setting the display on (0x29). Sending a Display On command while > the panel is still in sleep mode can prevent the display from turning on. > > Also, does this silently ignore errors on the secondary DSI link? > If a command fails on dsi_ctx1, the error doesn't seem to be captured or > checked here. Additionally, mipi_dsi_msleep() only checks the primary > context, so if a failure occurs on the primary, the sleep is bypassed, and > commands to the secondary are sent without the required delay. Right indeed, we may need to use a shared dsi_ctx, I overlooked this > >> + >> + return dsi_ctx.accum_err; > > Should this return a combination of both dsi_ctx.accum_err and > dsi_ctx1.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) >> + return ret; > > If regulator_bulk_enable() for vcc_supplies fails here, does this leak the > regulator reference for the already-enabled vdd_supplies? Hmm, indeed > >> + >> + 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); >> + 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); > > Could this hardware power sequencing risk hardware damage? The power > regulators are disabled before the reset GPIO is asserted. Leaving a logic > high voltage driven on an IO pin of an unpowered IC can back-power the > chip through its ESD protection diodes. The reset GPIO should likely be > asserted before disabling the regulators. > This is asked by the spec >> + >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static int renesas_r63419_unprepare(struct drm_panel *panel) >> +{ >> + struct renesas_r63419_panel *ctx = to_renesas_r63419_panel(panel); >> + >> + 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); > > The same power sequencing issue seems to exist here during teardown. This is asked by the spec > >> + >> + return 0; >> +} > [ ... ] >> +static int renesas_r63419_probe(struct mipi_dsi_device *dsi) >> +{ > [ ... ] >> + /* Copy current DSI info */ >> + strscpy(info.type, dsi->name, sizeof(info.type)); >> + info.channel = dsi->channel; >> + info.node = dev_of_node(dev); >> + >> + /* Register the second DSI device */ >> + ctx->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi1_host, &info); > > Could setting info.node to dev_of_node(dev) for the secondary DSI device > cause an unintended re-probe loop? Because the secondary device shares the > same of_node as the primary device, the MIPI DSI bus driver matching logic > will match it against the same renesas_r63419_driver and invoke probe() > again for the secondary device. Hmm, good question > >> + 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]); > > Does registering the panel to DRM before attaching the DSI devices > introduce a race condition? Calling devm_drm_panel_add() makes the panel > immediately visible to consumers. If a consumer prepares the panel right > away, it will attempt to send DCS commands over unattached DSI links. > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-19 8:48 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-19 8:09 [PATCH v4 0/2] drm: panel: support the R63419 based dual-DSI video mode Display Panels Neil Armstrong 2026-05-19 8:09 ` [PATCH v4 1/2] dt-bindings: display: panel: document the Renesas " Neil Armstrong 2026-05-19 8:18 ` sashiko-bot 2026-05-19 8:27 ` Neil Armstrong 2026-05-19 8:09 ` [PATCH v4 2/2] drm: panel: add support for " Neil Armstrong 2026-05-19 8:32 ` sashiko-bot 2026-05-19 8:48 ` Neil Armstrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox