From 7f6fd3bd9dd20293ddd20d8db50825e1aec49c1b Mon Sep 17 00:00:00 2001 From: Qubot <1445788683@qq.com> Date: Mon, 9 Nov 2026 10:18:46 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=E6=96=B0=E4=B8=83=E5=AF=B8?= =?UTF-8?q?=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uis7885/uis7885-2h10-overlay.dts | 6 +- .../arm/dts/lcd/lcd_jd9365_mipi_wxga.dtsi | 11 +-- .../drivers/video/sprd/dsi/mipi_dsi_api.c | 43 +++++++++--- .../dts/sprd/lcd/lcd_jd9365_mipi_wxga.dtsi | 20 ++++-- .../boot/dts/sprd/uis7885-2h10-overlay.dts | 6 +- .../drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c | 59 +++++++++++++--- .../gpu/drm/sprd/qogirn6pro/global_dpu.c | 68 ------------------- .../kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.c | 12 ---- .../kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.h | 6 -- .../drivers/gpu/drm/sprd/sprd_dsi_panel.c | 26 +++++-- 10 files changed, 131 insertions(+), 126 deletions(-) diff --git a/source_sync_rls_25c/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/uis7885-2h10-overlay.dts b/source_sync_rls_25c/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/uis7885-2h10-overlay.dts index f47f882ac..6b9ae933f 100755 --- a/source_sync_rls_25c/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/uis7885-2h10-overlay.dts +++ b/source_sync_rls_25c/layers/meta-unisoc/recipes-kernel/linux/linux-unisoc-5.4/uis7885/uis7885-2h10-overlay.dts @@ -8,7 +8,7 @@ //#include "lcd/lcd_g40396_truly_mipi_fhd.dtsi" //#include "lcd/lcd_nt36672e_truly_mipi_fhd_nodsc.dtsi" #include "lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi" -#include "lcd/lcd_ili9881c_truly_mipi_wxga.dtsi" +#include "lcd/lcd_jd9365_mipi_wxga.dtsi" #include "tp/ums9620-tp.dtsi" #include #include @@ -594,7 +594,7 @@ sprd,backlight = <&pwm_backlight>; avdd-gpio = <&ap_gpio 153 GPIO_ACTIVE_HIGH>; avee-gpio = <&ap_gpio 178 GPIO_ACTIVE_HIGH>; - iovdd-gpio = <&ap_gpio 187 GPIO_ACTIVE_HIGH>; + /* GPIO187 is kept high by the shared hdmi_5v_en gpio-hog above. */ reset-gpio = <&ap_gpio 152 GPIO_ACTIVE_HIGH>; }; @@ -604,7 +604,7 @@ }; -&lcd_ili9881c_truly_mipi_wxga { +&lcd_jd9365_mipi_wxga { sprd,sr-width = <800>; sprd,sr-height = <1280>; }; diff --git a/source_sync_rls_25c/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_jd9365_mipi_wxga.dtsi b/source_sync_rls_25c/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_jd9365_mipi_wxga.dtsi index ae843fdca..ce953ced2 100644 --- a/source_sync_rls_25c/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_jd9365_mipi_wxga.dtsi +++ b/source_sync_rls_25c/source/bsp/u-boot22/arch/arm/dts/lcd/lcd_jd9365_mipi_wxga.dtsi @@ -11,7 +11,7 @@ sprd,dsi-lane-number = <4>; sprd,dsi-color-format = "rgb888"; - /* Vendor PLL_CLOCK: 407 Mbps per lane. */ + /* Last visually verified clean U-Boot configuration. */ sprd,phy-bit-clock = <407000>; sprd,phy-escape-clock = <20000>; @@ -28,7 +28,7 @@ sprd,reset-on-sequence = <1 5>, <0 10>, <1 120>; sprd,reset-off-sequence = <0 20>; - sprd,use-dcs-write; + /* Vendor table entries are 0x23 generic short writes. */ sprd,initial-command = [ 23 00 00 02 E0 00 23 00 00 02 E1 93 @@ -241,13 +241,14 @@ display-timings { timing0 { - clock-frequency = <67750800>; + clock-frequency = <64000000>; hactive = <800>; vactive = <1280>; hback-porch = <20>; hfront-porch = <20>; - vback-porch = <8>; - vfront-porch = <17>; + /* Keep the U-Boot-only timing that produced a clean logo. */ + vback-porch = <24>; + vfront-porch = <1>; hsync-len = <20>; vsync-len = <8>; }; diff --git a/source_sync_rls_25c/source/bsp/u-boot22/drivers/video/sprd/dsi/mipi_dsi_api.c b/source_sync_rls_25c/source/bsp/u-boot22/drivers/video/sprd/dsi/mipi_dsi_api.c index f25da296a..0d560c062 100644 --- a/source_sync_rls_25c/source/bsp/u-boot22/drivers/video/sprd/dsi/mipi_dsi_api.c +++ b/source_sync_rls_25c/source/bsp/u-boot22/drivers/video/sprd/dsi/mipi_dsi_api.c @@ -18,6 +18,23 @@ #include "mipi_dsi_api.h" #include "mipi_dsi_hal.h" +static bool use_jd9365_rounded_timing(struct sprd_dsi *dsi) +{ + return dsi->panel && dsi->panel->lcd_name && + !strcmp(dsi->panel->lcd_name, "lcd_jd9365_mipi_wxga"); +} + +static u16 calc_dpi_byte_cycles(struct sprd_dsi *dsi, + struct dpi_video_param *param, u32 pixels) +{ + if (use_jd9365_rounded_timing(dsi)) + return DIV_ROUND_CLOSEST_ULL((u64)pixels * param->byte_clk, + param->pixel_clk); + + /* Preserve the vendor calculation for every other panel. */ + return pixels * (param->byte_clk * 1000 / param->pixel_clk) / 1000; +} + static u16 calc_bytes_per_pixel_x100(int coding) { u16 bpp_x100; @@ -207,6 +224,7 @@ int mipi_dsi_dpi_video(struct sprd_dsi *dsi, struct dpi_video_param *param) u32 chunk_overhead = 0; const u8 pkt_header = 6; u32 div = 0; + u16 hline_time; video_size = round_video_size(param->coding, param->hact); bpp_x100 = calc_bytes_per_pixel_x100(param->coding); @@ -215,15 +233,18 @@ int mipi_dsi_dpi_video(struct sprd_dsi *dsi, struct dpi_video_param *param) return -1; ratio_x1000 = param->byte_clk * 1000 / param->pixel_clk; + hline_time = calc_dpi_byte_cycles(dsi, param, param->hline); dsi_hal_power_en(dsi, 0); dsi_hal_dpi_frame_ack_en(dsi, param->frame_ack_en); dsi_hal_dpi_color_coding(dsi, param->coding); dsi_hal_dpi_video_burst_mode(dsi, param->burst_mode); - dsi_hal_dpi_sig_delay(dsi, 95 * param->hline * ratio_x1000 / 100000); - dsi_hal_dpi_hline_time(dsi, param->hline * ratio_x1000 / 1000); - dsi_hal_dpi_hsync_time(dsi, param->hsync * ratio_x1000 / 1000); - dsi_hal_dpi_hbp_time(dsi, param->hbp * ratio_x1000 / 1000); + dsi_hal_dpi_sig_delay(dsi, 95 * hline_time / 100); + dsi_hal_dpi_hline_time(dsi, hline_time); + dsi_hal_dpi_hsync_time(dsi, + calc_dpi_byte_cycles(dsi, param, param->hsync)); + dsi_hal_dpi_hbp_time(dsi, + calc_dpi_byte_cycles(dsi, param, param->hbp)); dsi_hal_dpi_vact(dsi, param->vact); dsi_hal_dpi_vfp(dsi, param->vfp); dsi_hal_dpi_vbp(dsi, param->vbp); @@ -360,15 +381,17 @@ int mipi_dsi_edpi_video(struct sprd_dsi *dsi, struct edpi_video_param *param) int mipi_dsi_htime_update(struct sprd_dsi *dsi, struct dpi_video_param *param) { - u32 ratio_x1000 = 0; + u16 hline_time; - ratio_x1000 = param->byte_clk * 1000 / param->pixel_clk; + hline_time = calc_dpi_byte_cycles(dsi, param, param->hline); dsi_hal_power_en(dsi, 0); - dsi_hal_dpi_sig_delay(dsi, 95 * param->hline * ratio_x1000 / 100000); - dsi_hal_dpi_hline_time(dsi, param->hline * ratio_x1000 / 1000); - dsi_hal_dpi_hsync_time(dsi, param->hsync * ratio_x1000 / 1000); - dsi_hal_dpi_hbp_time(dsi, param->hbp * ratio_x1000 / 1000); + dsi_hal_dpi_sig_delay(dsi, 95 * hline_time / 100); + dsi_hal_dpi_hline_time(dsi, hline_time); + dsi_hal_dpi_hsync_time(dsi, + calc_dpi_byte_cycles(dsi, param, param->hsync)); + dsi_hal_dpi_hbp_time(dsi, + calc_dpi_byte_cycles(dsi, param, param->hbp)); dsi_hal_power_en(dsi, 1); return 0; diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_jd9365_mipi_wxga.dtsi b/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_jd9365_mipi_wxga.dtsi index 70902e362..dfba29c1b 100644 --- a/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_jd9365_mipi_wxga.dtsi +++ b/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/lcd/lcd_jd9365_mipi_wxga.dtsi @@ -10,6 +10,7 @@ __overlay__ { lcds { lcd_jd9365_mipi_wxga: lcd_jd9365_mipi_wxga { + /* Match the U-Boot handoff and the stable Unisoc burst path. */ sprd,dsi-work-mode = <1>; sprd,dsi-lane-number = <4>; sprd,dsi-color-format = "rgb888"; @@ -26,7 +27,13 @@ sprd,reset-on-sequence = <1 5>, <0 10>, <1 120>; sprd,reset-off-sequence = <0 20>; - sprd,use-dcs-write; + /* + * The vendor register table uses packet type 0x23 + * (generic short write, two parameters). Do not set + * sprd,use-dcs-write here: that makes the panel driver + * recode every entry as a DCS packet and the JD9365 + * vendor-page registers are then not programmed. + */ sprd,initial-command = [ 23 00 00 02 E0 00 23 00 00 02 E1 93 @@ -241,13 +248,18 @@ native-mode = <&jd9365_timing0>; jd9365_timing0: timing0 { - clock-frequency = <67750800>; + clock-frequency = <64000000>; hactive = <800>; vactive = <1280>; hback-porch = <20>; hfront-porch = <20>; - vback-porch = <8>; - vfront-porch = <17>; + /* + * DPU r6p0 requires vsync + vback-porch >= 32. + * Keep the 25-line total blanking unchanged while + * matching the visually clean U-Boot handoff. + */ + vback-porch = <24>; + vfront-porch = <1>; hsync-len = <20>; vsync-len = <8>; }; diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/uis7885-2h10-overlay.dts b/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/uis7885-2h10-overlay.dts index f47f882ac..6b9ae933f 100755 --- a/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/uis7885-2h10-overlay.dts +++ b/source_sync_rls_25c/source/kernel/kernel5.4/arch/arm64/boot/dts/sprd/uis7885-2h10-overlay.dts @@ -8,7 +8,7 @@ //#include "lcd/lcd_g40396_truly_mipi_fhd.dtsi" //#include "lcd/lcd_nt36672e_truly_mipi_fhd_nodsc.dtsi" #include "lcd/lcd_lt8912b_mipi_hdmi_1080p.dtsi" -#include "lcd/lcd_ili9881c_truly_mipi_wxga.dtsi" +#include "lcd/lcd_jd9365_mipi_wxga.dtsi" #include "tp/ums9620-tp.dtsi" #include #include @@ -594,7 +594,7 @@ sprd,backlight = <&pwm_backlight>; avdd-gpio = <&ap_gpio 153 GPIO_ACTIVE_HIGH>; avee-gpio = <&ap_gpio 178 GPIO_ACTIVE_HIGH>; - iovdd-gpio = <&ap_gpio 187 GPIO_ACTIVE_HIGH>; + /* GPIO187 is kept high by the shared hdmi_5v_en gpio-hog above. */ reset-gpio = <&ap_gpio 152 GPIO_ACTIVE_HIGH>; }; @@ -604,7 +604,7 @@ }; -&lcd_ili9881c_truly_mipi_wxga { +&lcd_jd9365_mipi_wxga { sprd,sr-width = <800>; sprd,sr-height = <1280>; }; diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c index aa63f5a01..fdaddae3d 100644 --- a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c +++ b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c @@ -7,6 +7,39 @@ #include "sprd_dsi_hal.h" +static bool use_jd9365_rounded_timing(struct dsi_context *ctx) +{ + return ctx->lcd_name && + !strcmp(ctx->lcd_name, "lcd_jd9365_mipi_wxga"); +} + +static u16 calc_dpi_byte_cycles(struct dsi_context *ctx, + struct videomode *vm, u32 pixels) +{ + u32 pixel_clk = vm->pixelclock / 1000; + u32 ratio_x1000; + + if (use_jd9365_rounded_timing(ctx)) + return DIV_ROUND_CLOSEST_ULL((u64)pixels * ctx->byte_clk, + pixel_clk); + + /* Preserve the original calculation for every other DSI panel. */ + ratio_x1000 = ctx->byte_clk * 1000 / pixel_clk; + return pixels * ratio_x1000 / 1000; +} + +static u16 calc_dpi_sig_delay(struct dsi_context *ctx, + struct videomode *vm, u32 pixels) +{ + u32 ratio_x1000; + + if (use_jd9365_rounded_timing(ctx)) + return 95 * calc_dpi_byte_cycles(ctx, vm, pixels) / 100; + + ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000); + return 95 * pixels * ratio_x1000 / 100000; +} + static int dsi_wait_tx_payload_fifo_empty(struct sprd_dsi *dsi) { int timeout; @@ -219,8 +252,8 @@ void sprd_dsi_fini(struct sprd_dsi *dsi) int sprd_dsi_vrr_timing(struct sprd_dsi *dsi) { u16 Bpp_x100; - u32 ratio_x1000; u16 hline; + u16 hline_time; u8 coding; struct dsi_context *ctx = &dsi->ctx; struct videomode *vm = &dsi->ctx.vm; @@ -232,13 +265,15 @@ int sprd_dsi_vrr_timing(struct sprd_dsi *dsi) coding = fmt_to_coding(ctx->format); Bpp_x100 = calc_bytes_per_pixel_x100(coding); - ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000); hline = vm->hactive + vm->hsync_len + vm->hfront_porch + vm->hback_porch; - dsi_hal_dpi_sig_delay(dsi, 95 * hline * ratio_x1000 / 100000); - dsi_hal_dpi_hline_time(dsi, hline * ratio_x1000 / 1000); - dsi_hal_dpi_hsync_time(dsi, vm->hsync_len * ratio_x1000 / 1000); - dsi_hal_dpi_hbp_time(dsi, vm->hback_porch * ratio_x1000 / 1000); + hline_time = calc_dpi_byte_cycles(ctx, vm, hline); + dsi_hal_dpi_sig_delay(dsi, calc_dpi_sig_delay(ctx, vm, hline)); + dsi_hal_dpi_hline_time(dsi, hline_time); + dsi_hal_dpi_hsync_time(dsi, + calc_dpi_byte_cycles(ctx, vm, vm->hsync_len)); + dsi_hal_dpi_hbp_time(dsi, + calc_dpi_byte_cycles(ctx, vm, vm->hback_porch)); dsi_hal_dpi_vact(dsi, vm->vactive); dsi_hal_dpi_vfp(dsi, vm->vfront_porch); dsi_hal_dpi_vbp(dsi, vm->vback_porch); @@ -274,6 +309,7 @@ int sprd_dsi_dpi_video(struct sprd_dsi *dsi) u8 coding; int div; u16 hline; + u16 hline_time; struct dsi_context *ctx = &dsi->ctx; struct videomode *vm = &dsi->ctx.vm; @@ -284,15 +320,18 @@ int sprd_dsi_dpi_video(struct sprd_dsi *dsi) ratio_x1000 = ctx->byte_clk * 1000 / (vm->pixelclock / 1000); hline = vm->hactive + vm->hsync_len + vm->hfront_porch + vm->hback_porch; + hline_time = calc_dpi_byte_cycles(ctx, vm, hline); dsi_hal_power_en(dsi, 0); dsi_hal_dpi_frame_ack_en(dsi, ctx->frame_ack_en); dsi_hal_dpi_color_coding(dsi, coding); dsi_hal_dpi_video_burst_mode(dsi, ctx->burst_mode); - dsi_hal_dpi_sig_delay(dsi, 95 * hline * ratio_x1000 / 100000); - dsi_hal_dpi_hline_time(dsi, hline * ratio_x1000 / 1000); - dsi_hal_dpi_hsync_time(dsi, vm->hsync_len * ratio_x1000 / 1000); - dsi_hal_dpi_hbp_time(dsi, vm->hback_porch * ratio_x1000 / 1000); + dsi_hal_dpi_sig_delay(dsi, calc_dpi_sig_delay(ctx, vm, hline)); + dsi_hal_dpi_hline_time(dsi, hline_time); + dsi_hal_dpi_hsync_time(dsi, + calc_dpi_byte_cycles(ctx, vm, vm->hsync_len)); + dsi_hal_dpi_hbp_time(dsi, + calc_dpi_byte_cycles(ctx, vm, vm->hback_porch)); dsi_hal_dpi_vact(dsi, vm->vactive); dsi_hal_dpi_vfp(dsi, vm->vfront_porch); dsi_hal_dpi_vbp(dsi, vm->vback_porch); diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c index d5e109485..90c9a2aba 100755 --- a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c +++ b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c @@ -8,19 +8,9 @@ #include #include #include -#include -#include #include "sprd_dpu.h" -/* DPU_VSP clock-controller (ums9620 dpu_vsp_clk) register block @ 0x30110000. */ -#define DPU_VSP_CLK_BASE 0x30110000UL -#define DPU_VSP_CLK_SIZE 0x3000 -/* dispc0_dpi pixel-clock divider: offset 0x78, bits[3:0] (value 3 = div-by-4). */ -#define REG_DISPC0_DPI_DIV 0x78 -#define REG_DISPC0_DPI_DIV_MASK 0xf -static void __iomem *dpu_vsp_clk_base; - static struct clk *clk_dpuvsp_eb; static struct clk *clk_dpuvsp_disp_eb; static struct clk *clk_master_div6_eb; @@ -163,20 +153,6 @@ static int dpu_clk_parse_dt(struct dpu_context *ctx, clk_ctx->clk_dpu_dpi = NULL; } - /* Map the DPU_VSP clock-controller MMIO so the DPI-divider workaround - * can write register 0x30110078 directly. pr_err on failure - the ioremap - * must succeed or the workaround cannot fire at all. - */ - if (!dpu_vsp_clk_base) { - dpu_vsp_clk_base = ioremap_nocache(DPU_VSP_CLK_BASE, - DPU_VSP_CLK_SIZE); - if (!dpu_vsp_clk_base) - pr_err("ioremap dpu_vsp_clk (0x%lx) failed\n", - DPU_VSP_CLK_BASE); - else - pr_info("dpu_vsp_clk base mapped for dpi-div workaround\n"); - } - return 0; } @@ -211,40 +187,6 @@ static struct clk *div_to_clk(struct dpu_clk_context *clk_ctx, u32 clk_div) } } -/* - * Most direct path to force the dispc0_dpi pixel-clock divider to 3 - * (divide-by-4): write bits[3:0] of register 0x30110078 (= DPU_VSP clock - * controller base 0x30110000 + offset 0x78). This bypasses the CCF and writes - * the MMIO register directly; the value is read back to confirm it latched. - * Returns the final divider value (should be 3 on success) or a negative errno. - */ -static int dpu_force_dpi_div3(void) -{ - void __iomem *reg; - u32 val; - - if (!dpu_vsp_clk_base) { - pr_err("force dpi div=3: clk mmio not mapped\n"); - return -ENXIO; - } - - reg = dpu_vsp_clk_base + REG_DISPC0_DPI_DIV; - - val = readl_relaxed(reg); - val = (val & ~REG_DISPC0_DPI_DIV_MASK) | 3; - writel_relaxed(val, reg); - - /* read-back flush, then re-read to confirm */ - val = readl_relaxed(reg); - if ((val & REG_DISPC0_DPI_DIV_MASK) != 3) { - pr_err("force dpi div=3 (0x30110078) failed, readback=0x%x\n", val); - return -EIO; - } - - pr_info("force dpi div=3 (0x30110078) ok, reg=0x%x\n", val); - return 0; -} - static int dpu_clk_init(struct dpu_context *ctx) { int ret; @@ -287,16 +229,6 @@ static int dpu_clk_init(struct dpu_context *ctx) if (ret) pr_err("dpu update dpi clk rate failed\n"); - /* Workaround: on resume (suspend->on), the DPI pixel-clock divider - * at 0x30110078 (dispc0_dpi div, bits[3:0]) is not re-applied and - * the panel lights up black. Force divider value 3 (div-by-4) by - * writing the MMIO register directly (most-direct path). Only acted - * upon when flagged from the resume path. - */ - if (ctx->dpi_div_force3) { - ctx->dpi_div_force3 = false; - dpu_force_dpi_div3(); - } } return ret; diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.c b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.c index e739eaa7a..c2d0f0c4c 100755 --- a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.c +++ b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.c @@ -378,18 +378,6 @@ static void sprd_dpu_enable(struct sprd_dpu *dpu) void sprd_dpu_resume(struct sprd_dpu *dpu) { - struct dpu_context *ctx = &dpu->ctx; - u32 mipi_port = 0; - /* Flag the DPI-divider workaround: force value 3 at 0x30110078 on the - * next dpu_clk_init() to avoid black screen on wake. - */ - if (dpu->dsi && dpu->dsi->panel) { - struct sprd_panel *panel = (struct sprd_panel *)container_of(dpu->dsi->panel, struct sprd_panel, base); - mipi_port = panel->info.mipi_port; - } - if(mipi_port == 1){ - ctx->dpi_div_force3 = true; - } sprd_dpu_enable(dpu); enable_irq(dpu->ctx.irq); sprd_iommu_restore(&dpu->dev); diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.h b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.h index 7ffc88973..0ed0a62c9 100755 --- a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.h +++ b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dpu.h @@ -220,12 +220,6 @@ struct dpu_context { /* spi frame refresh parameters */ unsigned int flag_mask_refresh; - /* DPI pixel-clock divider force workaround. - * Set true from the resume path so dpu_clk_init() re-applies divider - * value 3 to register 0x30110078 (dispc0_dpi div, bits[3:0]) which is - * lost/missing on resume and causes a black screen on wake. - */ - bool dpi_div_force3; }; struct sprd_dpu_ops { diff --git a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dsi_panel.c b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dsi_panel.c index 701962fe8..168a9a53a 100644 --- a/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dsi_panel.c +++ b/source_sync_rls_25c/source/kernel/kernel5.4/drivers/gpu/drm/sprd/sprd_dsi_panel.c @@ -278,7 +278,15 @@ static int sprd_panel_get_modes(struct drm_panel *p) /* parse and create sr mode config */ of_property_read_u32(panel->info.of_node, "sprd,sr-width", &sr_width); of_property_read_u32(panel->info.of_node, "sprd,sr-height", &sr_height); - if (sr_width && sr_height) { + /* + * Do not advertise an SR mode when it is identical to the native + * panel mode. drm_display_mode_from_videomode() would otherwise + * create a duplicate with a synthetic pixel clock and zero porches, + * which userspace may select instead of the valid native timing. + */ + if (sr_width && sr_height && + (sr_width != panel->info.mode.hdisplay || + sr_height != panel->info.mode.vdisplay)) { for (i = 0; i < panel->info.num_buildin_modes; i++) { struct videomode vm = {}; vm.hactive = sr_width; @@ -488,27 +496,35 @@ static int sprd_panel_gpio_request(struct device *dev, { panel->info.iovdd_gpio = devm_gpiod_get_optional(dev, "iovdd", GPIOD_ASIS); - if (IS_ERR_OR_NULL(panel->info.iovdd_gpio)) + if (IS_ERR(panel->info.iovdd_gpio)) { DRM_WARN("can't get panel iovdd gpio: %ld\n", PTR_ERR(panel->info.iovdd_gpio)); + panel->info.iovdd_gpio = NULL; + } panel->info.avdd_gpio = devm_gpiod_get_optional(dev, "avdd", GPIOD_ASIS); - if (IS_ERR_OR_NULL(panel->info.avdd_gpio)) + if (IS_ERR(panel->info.avdd_gpio)) { DRM_WARN("can't get panel avdd gpio: %ld\n", PTR_ERR(panel->info.avdd_gpio)); + panel->info.avdd_gpio = NULL; + } panel->info.avee_gpio = devm_gpiod_get_optional(dev, "avee", GPIOD_ASIS); - if (IS_ERR_OR_NULL(panel->info.avee_gpio)) + if (IS_ERR(panel->info.avee_gpio)) { DRM_WARN("can't get panel avee gpio: %ld\n", PTR_ERR(panel->info.avee_gpio)); + panel->info.avee_gpio = NULL; + } panel->info.reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); - if (IS_ERR_OR_NULL(panel->info.reset_gpio)) + if (IS_ERR(panel->info.reset_gpio)) { DRM_WARN("can't get panel reset gpio: %ld\n", PTR_ERR(panel->info.reset_gpio)); + panel->info.reset_gpio = NULL; + } return 0; }