[PATCH v2 12/21] drm/panel: jadard-jd9365da-h3: support variable DSI configuration

Dmitry Baryshkov
2026-04-11T12:11:18Z

Several panels support attachment either using 4 DSI lanes or just 2. In
some cases, this requires a different panel mode to fulfill clock
requirements. Extend the driver to handle such cases by letting the
panel description to omit lanes specification and parsing number of
lanes from the DT.

Reviewed-by: Linus Walleij <linusw@kernel.org>
Tested-by: Riccardo Mereu <r.mereu@arduino.cc>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 32 +++++++++++++++++-------
1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
index 1884ad2404cd..5d9db2e1f28f 100644
--- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
+++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
@@ -10,6 +10,7 @@

#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
+#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -23,7 +24,8 @@
struct jadard;

struct jadard_panel_desc {
- const struct drm_display_mode mode;
+ const struct drm_display_mode *mode_4ln;
+ const struct drm_display_mode *mode_2ln;
unsigned int lanes;
enum mipi_dsi_pixel_format format;
int (*init)(struct jadard *jadard);
@@ -57,7 +59,10 @@ static void jadard_enable_standard_cmds(struct mipi_dsi_multi_context *dsi_ctx)
mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe1, 0x93);
mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe2, 0x65);
mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe3, 0xf8);
- mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03);
+ if (dsi_ctx->dsi->lanes == 2)
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x01);
+ else
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03);
}

static inline struct jadard *panel_to_jadard(struct drm_panel *panel)
@@ -151,7 +156,10 @@ static int jadard_get_modes(struct drm_panel *panel,
{
struct jadard *jadard = panel_to_jadard(panel);

- return drm_connector_helper_get_modes_fixed(connector, &jadard->desc->mode);
+ if (jadard->dsi->lanes == 2)
+ return drm_connector_helper_get_modes_fixed(connector, jadard->desc->mode_2ln);
+ else
+ return drm_connector_helper_get_modes_fixed(connector, jadard->desc->mode_4ln);
}

static enum drm_panel_orientation jadard_panel_get_orientation(struct drm_panel *panel)
@@ -354,7 +362,7 @@ static int radxa_display_8hd_ad002_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc radxa_display_8hd_ad002_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = 70000,

.hdisplay = 800,
@@ -586,7 +594,7 @@ static int cz101b4001_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc cz101b4001_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = 70000,

.hdisplay = 800,
@@ -819,7 +827,7 @@ static int kingdisplay_kd101ne3_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc kingdisplay_kd101ne3_40ti_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000,

.hdisplay = 800,
@@ -1070,7 +1078,7 @@ static int melfas_lmfbx101117480_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc melfas_lmfbx101117480_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000,

.hdisplay = 800,
@@ -1326,7 +1334,7 @@ static int anbernic_rgds_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc anbernic_rgds_display_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = (640 + 260 + 220 + 260) * (480 + 10 + 2 + 16) * 60 / 1000,

.hdisplay = 640,
@@ -1562,7 +1570,7 @@ static int taiguan_xti05101_01a_init_cmds(struct jadard *jadard)
};

static const struct jadard_panel_desc taiguan_xti05101_01a_desc = {
- .mode = {
+ .mode_4ln = &(const struct drm_display_mode) {
.clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000,

.hdisplay = 800,
@@ -1614,6 +1622,12 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi)

dsi->format = desc->format;
dsi->lanes = desc->lanes;
+ if (!dsi->lanes) {
+ dsi->lanes = drm_of_get_data_lanes_count_remote(dsi->dev.of_node, 0, -1, 2, 4);
+ if (dsi->lanes < 0)
+ return dsi->lanes;
+ }
+ dev_dbg(&dsi->dev, "lanes: %d\n", dsi->lanes);

jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(jadard->reset))

--
2.47.3