From c9fea7ca54a868c8916479e270d2c60d0d5ba695 Mon Sep 17 00:00:00 2001 From: Yu Dukai <646689853@qq.com> Date: Wed, 30 Sep 2026 10:19:10 +0800 Subject: [PATCH 1/4] Revert "ARM: dts: overlays: waveshare-dsi: Add auto_detect panel option" This reverts commit fd7924c3ab70ec7ac2a7bfd808d505c118e7e3b4. Signed-off-by: Yu Dukai <646689853@qq.com> --- arch/arm/boot/dts/overlays/README | 2 -- .../boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts | 3 --- 2 files changed, 5 deletions(-) diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index dae2f9a3efdb42..6072f009a7a82f 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -6261,8 +6261,6 @@ Params: 2_8_inch 2.8" 480x640 11_9_inch 11.9" 320x1480 13_3_inch_4lane 13.3" 1920x1080 4lane 13_3_inch_2lane 13.3" 1920x1080 2lane - auto_detect Automatic panel detection (1200x1920 or - 1920x1200 at 30fps/60fps) i2c1 Use i2c-1 with jumper wires from GPIOs 2&3 disable_touch Disable the touch controller rotation Set the panel orientation property diff --git a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts index d41c9dfe810f4e..7af0f3763fc404 100644 --- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts +++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts @@ -136,9 +136,6 @@ 7_0_inchH = <&panel>, "compatible=waveshare,7.0inch-h-panel", <&touch>, "touchscreen-swapped-x-y?", <&touch>, "touchscreen-inverted-x?"; - auto_detect = <&panel>, "compatible=waveshare,automatic-detection-panel", - <&touch>, "touchscreen-swapped-x-y?", - <&touch>, "touchscreen-inverted-x?"; i2c1 = <&i2c_frag>, "target:0=",<&i2c1>, <0>, "-3-4+5"; disable_touch = <&touch>, "status=disabled"; From b9fab6ff9cf54caf4e1e002f707431b034b35815 Mon Sep 17 00:00:00 2001 From: Yu Dukai <646689853@qq.com> Date: Wed, 30 Sep 2026 10:19:14 +0800 Subject: [PATCH 2/4] Revert "drm/panel: waveshare: Add automatic panel detection support" This reverts commit 5d31114d5994a1254c0ac673b8a1050df88e6def. Signed-off-by: Yu Dukai <646689853@qq.com> --- drivers/gpu/drm/panel/panel-waveshare-dsi.c | 154 +------------------- 1 file changed, 6 insertions(+), 148 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-waveshare-dsi.c b/drivers/gpu/drm/panel/panel-waveshare-dsi.c index 6ef696f0aa6320..02e1bd9fa15a2e 100644 --- a/drivers/gpu/drm/panel/panel-waveshare-dsi.c +++ b/drivers/gpu/drm/panel/panel-waveshare-dsi.c @@ -30,7 +30,6 @@ struct ws_panel { struct i2c_client *i2c; const struct drm_display_mode *mode; enum drm_panel_orientation orientation; - int lanes; }; struct ws_panel_data { @@ -346,63 +345,6 @@ static const struct ws_panel_data ws_panel_7_0_h_data = { .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, }; -/* 10.1inch DSI LCD (E) - * https://www.waveshare.com/10.1inch-dsi-lcd-e.htm - */ -static const struct drm_display_mode ws_panel_1200x1920_60fps_mode = { - .clock = 166666, - .hdisplay = 1200, - .hsync_start = 1200 + 28, - .hsync_end = 1200 + 28 + 10, - .htotal = 1200 + 28 + 10 + 30, - .vdisplay = 1920, - .vsync_start = 1920 + 238, - .vsync_end = 1920 + 238 + 4, - .vtotal = 1920 + 238 + 4 + 28, -}; - -static const struct drm_display_mode ws_panel_1200x1920_30fps_mode = { - .clock = 83333, - .hdisplay = 1200, - .hsync_start = 1200 + 28, - .hsync_end = 1200 + 28 + 10, - .htotal = 1200 + 28 + 10 + 30, - .vdisplay = 1920, - .vsync_start = 1920 + 238, - .vsync_end = 1920 + 238 + 4, - .vtotal = 1920 + 238 + 4 + 28, -}; - -static const struct drm_display_mode ws_panel_1920x1200_60fps_mode = { - .clock = 166666, - .hdisplay = 1920, - .hsync_start = 1920 + 238, - .hsync_end = 1920 + 238 + 4, - .htotal = 1920 + 238 + 4 + 28, - .vdisplay = 1200, - .vsync_start = 1200 + 28, - .vsync_end = 1200 + 28 + 10, - .vtotal = 1200 + 28 + 10 + 30, -}; - -static const struct drm_display_mode ws_panel_1920x1200_30fps_mode = { - .clock = 83333, - .hdisplay = 1920, - .hsync_start = 1920 + 238, - .hsync_end = 1920 + 238 + 4, - .htotal = 1920 + 238 + 4 + 28, - .vdisplay = 1200, - .vsync_start = 1200 + 28, - .vsync_end = 1200 + 28 + 10, - .vtotal = 1200 + 28 + 10 + 30, -}; - -static const struct ws_panel_data ws_panel_automatic_data = { - .mode = NULL, - .lanes = 0, - .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, -}; - static struct ws_panel *panel_to_ts(struct drm_panel *panel) { return container_of(panel, struct ws_panel, base); @@ -417,68 +359,6 @@ static void ws_panel_i2c_write(struct ws_panel *ts, u8 reg, u8 val) dev_err(&ts->i2c->dev, "I2C write failed: %d\n", ret); } -static int ws_panel_i2c_read(struct ws_panel *ts, u8 reg) -{ - int ret; - - ret = i2c_smbus_read_byte_data(ts->i2c, reg); - if (ret < 0) - dev_err(&ts->i2c->dev, "read reg 0x%02x failed %d\n", reg, ret); - return ret; -} - -static int ws_panel_auto_detect(struct ws_panel *ts) -{ - int screen_type; - int rotate; - int fps; - - fps = ws_panel_i2c_read(ts, 0xd0); - if (fps < 0) - return fps; - - rotate = ws_panel_i2c_read(ts, 0xd1); - if (rotate < 0) - return rotate; - - screen_type = ws_panel_i2c_read(ts, 0xd3); - if (screen_type < 0) - return screen_type; - - dev_info(&ts->i2c->dev, - "automatic panel detect screen_type=0x%x rotate=0x%x fps=0x%x\n", - screen_type, rotate, fps); - - if (screen_type == 0x01) { - switch (rotate) { - case 0: - case 2: - dev_info(&ts->i2c->dev, "select 1200x1920 panel\n"); - ts->mode = fps == 60 ? - &ws_panel_1200x1920_60fps_mode : - &ws_panel_1200x1920_30fps_mode; - break; - case 1: - case 3: - dev_info(&ts->i2c->dev, "select 1920x1200 panel\n"); - ts->mode = fps == 60 ? - &ws_panel_1920x1200_60fps_mode : - &ws_panel_1920x1200_30fps_mode; - break; - default: - dev_err(&ts->i2c->dev, "unknown rotate value %d\n", rotate); - return -EINVAL; - } - if (fps == 60) - ts->lanes = 4; - else - ts->lanes = 2; - return 0; - } - dev_err(&ts->i2c->dev, "unsupported panel D3=0x%x\n", screen_type); - return -EINVAL; -} - static int ws_panel_disable(struct drm_panel *panel) { struct ws_panel *ts = panel_to_ts(panel); @@ -612,24 +492,14 @@ static int ws_panel_probe(struct i2c_client *i2c) if (!_ws_panel_data) return -EINVAL; - ts->i2c = i2c; - i2c_set_clientdata(i2c, ts); - ts->lanes = _ws_panel_data->lanes; - - /* For automatic detection panels, mode is NULL - detect via I2C */ - if (!_ws_panel_data->mode) { - ret = ws_panel_auto_detect(ts); - if (ret) { - dev_err(dev, "panel auto detect failed\n"); - return ret; - } - } else { - ts->mode = _ws_panel_data->mode; - } - + ts->mode = _ws_panel_data->mode; if (!ts->mode) return -EINVAL; + i2c_set_clientdata(i2c, ts); + + ts->i2c = i2c; + ws_panel_i2c_write(ts, 0xc0, 0x01); ws_panel_i2c_write(ts, 0xc2, 0x01); ws_panel_i2c_write(ts, 0xac, 0x01); @@ -686,7 +556,7 @@ static int ws_panel_probe(struct i2c_client *i2c) ts->dsi->mode_flags = _ws_panel_data->mode_flags; ts->dsi->format = MIPI_DSI_FMT_RGB888; - ts->dsi->lanes = ts->lanes; + ts->dsi->lanes = _ws_panel_data->lanes; ret = devm_mipi_dsi_attach(dev, ts->dsi); @@ -700,18 +570,10 @@ static int ws_panel_probe(struct i2c_client *i2c) return -ENODEV; } -static void ws_panel_reset(struct drm_panel *panel) -{ - struct ws_panel *ts = panel_to_ts(panel); - - ws_panel_i2c_write(ts, 0xd2, 0x5a); -} - static void ws_panel_remove(struct i2c_client *i2c) { struct ws_panel *ts = i2c_get_clientdata(i2c); - ws_panel_reset(&ts->base); ws_panel_disable(&ts->base); drm_panel_remove(&ts->base); @@ -721,7 +583,6 @@ static void ws_panel_shutdown(struct i2c_client *i2c) { struct ws_panel *ts = i2c_get_clientdata(i2c); - ws_panel_reset(&ts->base); ws_panel_disable(&ts->base); } @@ -774,9 +635,6 @@ static const struct of_device_id ws_panel_of_ids[] = { }, { .compatible = "waveshare,7.0inch-h-panel", .data = &ws_panel_7_0_h_data, - }, { - .compatible = "waveshare,automatic-detection-panel", - .data = &ws_panel_automatic_data, }, { /* sentinel */ } From 94dcafc321caf777f6d42d95a18bb7409e5542ea Mon Sep 17 00:00:00 2001 From: Yu Dukai <646689853@qq.com> Date: Wed, 30 Sep 2026 10:19:46 +0800 Subject: [PATCH 3/4] drm/panel: panel-waveshare-dsi: Add 10.1inch DSI LCD (E) variants The 10.1inch DSI LCD (E) panel (1920x1200) is wired either with 4 DSI lanes running at 60fps or with 2 DSI lanes running at 30fps. Expose these as two explicit variants selected via the overlay parameter instead of runtime I2C auto-detection, keeping only the default landscape orientation. Write the corresponding refresh rate to register 0xd0 so the panel controller runs in the expected mode. Signed-off-by: Yu Dukai <646689853@qq.com> --- drivers/gpu/drm/panel/panel-waveshare-dsi.c | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-waveshare-dsi.c b/drivers/gpu/drm/panel/panel-waveshare-dsi.c index 02e1bd9fa15a2e..f243f560e08186 100644 --- a/drivers/gpu/drm/panel/panel-waveshare-dsi.c +++ b/drivers/gpu/drm/panel/panel-waveshare-dsi.c @@ -345,6 +345,45 @@ static const struct ws_panel_data ws_panel_7_0_h_data = { .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, }; +/* 10.1inch DSI LCD (E) + * https://www.waveshare.com/10.1inch-dsi-lcd-e.htm + */ +static const struct drm_display_mode ws_panel_1920x1200_60fps_mode = { + .clock = 166666, + .hdisplay = 1920, + .hsync_start = 1920 + 238, + .hsync_end = 1920 + 238 + 4, + .htotal = 1920 + 238 + 4 + 28, + .vdisplay = 1200, + .vsync_start = 1200 + 28, + .vsync_end = 1200 + 28 + 10, + .vtotal = 1200 + 28 + 10 + 30, +}; + +static const struct drm_display_mode ws_panel_1920x1200_30fps_mode = { + .clock = 83333, + .hdisplay = 1920, + .hsync_start = 1920 + 238, + .hsync_end = 1920 + 238 + 4, + .htotal = 1920 + 238 + 4 + 28, + .vdisplay = 1200, + .vsync_start = 1200 + 28, + .vsync_end = 1200 + 28 + 10, + .vtotal = 1200 + 28 + 10 + 30, +}; + +static const struct ws_panel_data ws_panel_10_1_e_4lane_data = { + .mode = &ws_panel_1920x1200_60fps_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, +}; + +static const struct ws_panel_data ws_panel_10_1_e_2lane_data = { + .mode = &ws_panel_1920x1200_30fps_mode, + .lanes = 2, + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, +}; + static struct ws_panel *panel_to_ts(struct drm_panel *panel) { return container_of(panel, struct ws_panel, base); @@ -493,12 +532,17 @@ static int ws_panel_probe(struct i2c_client *i2c) return -EINVAL; ts->mode = _ws_panel_data->mode; + if (!ts->mode) return -EINVAL; i2c_set_clientdata(i2c, ts); ts->i2c = i2c; + if (of_device_is_compatible(dev->of_node, "waveshare,10.1inch-e-4lane-panel")) + ws_panel_i2c_write(ts, 0xd0, 60); + else if (of_device_is_compatible(dev->of_node, "waveshare,10.1inch-e-2lane-panel")) + ws_panel_i2c_write(ts, 0xd0, 30); ws_panel_i2c_write(ts, 0xc0, 0x01); ws_panel_i2c_write(ts, 0xc2, 0x01); @@ -570,10 +614,18 @@ static int ws_panel_probe(struct i2c_client *i2c) return -ENODEV; } +static void ws_panel_reset(struct drm_panel *panel) +{ + struct ws_panel *ts = panel_to_ts(panel); + + ws_panel_i2c_write(ts, 0xd2, 0x5a); +} + static void ws_panel_remove(struct i2c_client *i2c) { struct ws_panel *ts = i2c_get_clientdata(i2c); + ws_panel_reset(&ts->base); ws_panel_disable(&ts->base); drm_panel_remove(&ts->base); @@ -583,6 +635,7 @@ static void ws_panel_shutdown(struct i2c_client *i2c) { struct ws_panel *ts = i2c_get_clientdata(i2c); + ws_panel_reset(&ts->base); ws_panel_disable(&ts->base); } @@ -635,6 +688,12 @@ static const struct of_device_id ws_panel_of_ids[] = { }, { .compatible = "waveshare,7.0inch-h-panel", .data = &ws_panel_7_0_h_data, + }, { + .compatible = "waveshare,10.1inch-e-4lane-panel", + .data = &ws_panel_10_1_e_4lane_data, + }, { + .compatible = "waveshare,10.1inch-e-2lane-panel", + .data = &ws_panel_10_1_e_2lane_data, }, { /* sentinel */ } From 4355a7af90260be3016650be5e8299e9e003cefc Mon Sep 17 00:00:00 2001 From: Yu Dukai <646689853@qq.com> Date: Wed, 30 Sep 2026 10:20:27 +0800 Subject: [PATCH 4/4] dts: overlays: vc4-kms-dsi-waveshare-panel: Add 10.1inch E variants Add the 10_1_inchE_4lane and 10_1_inchE_2lane overlay parameters matching the new panel driver compatible strings (waveshare,10.1inch-e-4lane-panel / waveshare,10.1inch-e-2lane-panel) for the 10.1inch DSI LCD (E): 1920x1200 at 60fps over 4 DSI lanes or at 30fps over 2 DSI lanes, keeping only the default landscape orientation. Signed-off-by: Yu Dukai <646689853@qq.com> --- arch/arm/boot/dts/overlays/README | 2 ++ .../dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 6072f009a7a82f..35738c33d2f744 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -6261,6 +6261,8 @@ Params: 2_8_inch 2.8" 480x640 11_9_inch 11.9" 320x1480 13_3_inch_4lane 13.3" 1920x1080 4lane 13_3_inch_2lane 13.3" 1920x1080 2lane + 10_1_inchE_4lane 10.1" E 1920x1200 60fps 4lane + 10_1_inchE_2lane 10.1" E 1920x1200 30fps 2lane i2c1 Use i2c-1 with jumper wires from GPIOs 2&3 disable_touch Disable the touch controller rotation Set the panel orientation property diff --git a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts index 7af0f3763fc404..5c1cce1dddcebe 100644 --- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts +++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts @@ -136,6 +136,12 @@ 7_0_inchH = <&panel>, "compatible=waveshare,7.0inch-h-panel", <&touch>, "touchscreen-swapped-x-y?", <&touch>, "touchscreen-inverted-x?"; + 10_1_inchE_4lane = <&panel>, "compatible=waveshare,10.1inch-e-4lane-panel", + <&touch>, "touchscreen-swapped-x-y?", + <&touch>, "touchscreen-inverted-x?"; + 10_1_inchE_2lane = <&panel>, "compatible=waveshare,10.1inch-e-2lane-panel", + <&touch>, "touchscreen-swapped-x-y?", + <&touch>, "touchscreen-inverted-x?"; i2c1 = <&i2c_frag>, "target:0=",<&i2c1>, <0>, "-3-4+5"; disable_touch = <&touch>, "status=disabled";