From patchwork Fri Oct 3 16:55:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 498 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510613; bh=iCr+DBZ2tP1xOvE2IWjfmASjr7a2H37kVMBoh6ERLcY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=AhrUdP00Ob34i/isuRA/Vnc0qN7VuofvPGO4FViizLSiLoirVM/kZ8o6no27FdSla skkLA64OW0aJKzEWiPEWsuR4Ow78xDVzme7qRN3B42d8xrHJTulA1RLAMirKf7UcYi VpRzeyLPGluAVg+GMCLyiL7f9owtpKOMRRURXQXI3zfOVKS2O5bUk33pUDW/c1Hqqs A883ufwkWNJxX+OSt+jBOelqz7GFLOyMku4IXFpm1kP4ETR8KYzBVEJc1ICGdFe9a1 qTjDcfsUubNds4LK+LDjl7f4xtsoENi6ucugn+2BPgoCgSM+OEl7cpFDCMTshOpPZL /EO0YYIeJvTcw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 63CAE67DC0 for ; Fri, 3 Oct 2025 10:56:53 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id EN7d7yap40mh for ; Fri, 3 Oct 2025 10:56:53 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510612; bh=iCr+DBZ2tP1xOvE2IWjfmASjr7a2H37kVMBoh6ERLcY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Eq6fHNm1/MKeDdTgsGxDqHcL+FHQKwVq46AFP0rBf6+OEGNZfBslXTAGwrd2XtnA/ 9LYbC8wPjNQ/DEVUDQx9TeLCK3h17eUszKef847+Hd7BSbY+rEqZ1Tzl185Oet5Bjj g0etAB9PWgVUSi9Gs8tpQpsDfdQu86hTD6Da0Sna5zMNqw8s30N1uv/zWuWFvkIwoF QWxMVRvWQ761dLn11LXfCw4z4HclaXz8AzjyQf+n3oWlX5E8FiSaaxWPj6HPaYS9O2 +98MVd3ilKmfyi3b/uOuJUSmInfUGLptLFHlrMQAqAn2lCtCsxFBGxZ509vF7/H3GH BatCUxWRY+83w== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id C392F67E82 for ; Fri, 3 Oct 2025 10:56:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510610; bh=7iMhMtzps54AWlTa+KuKAEcnzr36HGHFEyl4/JGDFVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mO/O9mmCpAimUCyNAGYFu+hUspUYvj6aYYa9XC3/pls9RNe62PvH+vhFLkKe0qnKz FZwOq0H+UgObGI9mwO7oM6CuYffqEyzy25Jm5TAz+Lq7Ye/6FofwXWQ4yAQe3L83jC 5CLM9DCsW7+44/XvEYQx4mDRIVdbw10+AMd2xjsvQkHDTykb/1qLkAIRjEQgU+7AQM DT5zXrJYjMvPGFvMFq/FimEMNMOX+Yl38M7OS/XQ5dX3y3p5wGlbPEXchw7eyi/Wqj wEZZ3IDtGOSaqLqVNJL4RI78Ig2Lu4dK1zinb7i3W1WbWgOSMtNfrO86OtiEDbQWQu TODUrVCymF1Mg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AAEE867E82; Fri, 3 Oct 2025 10:56:50 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id f3CTe63PZFo1; Fri, 3 Oct 2025 10:56:50 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510609; bh=VDthGSL0IkgLd1Q9W2q9GzobxdlzeKb4u7kNXy1kWZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iABXDHJ/7REXkCFQX/Sh3xxeD+6kLR1BZR60PLJEZ+oiZ8tNYaVh3zD7b4YzsXKC3 Nv74+EmblVmGG+/7sxMQB0t45miKUcjZtXGhTEs+HIabkqfk0NtytEtU8J/rAsMvyU PfID235n/4GWWTrhPezCxA9h/dSUbsKCnR6lEGr7gnlG9ml8fJm2YUvPVsyZllwpzH UN/ryr0Pxp77u+aGnnPPz/0zohjjYhmBR7JmvWkfoz5VBZOzm7MKKn/beySaYTR5Mm 5fuFIqe7MHjqPgsvzeAgLGBsBtERHWGUF1s4WLnjyvHFR/TiwVEe+0zYM+atBs8Bbb dT2LOYG9y2zdA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id E3E8F67DC0; Fri, 3 Oct 2025 10:56:48 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 3 Oct 2025 10:55:10 -0600 Message-ID: <20251003165525.440173-18-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003165525.440173-1-sjg@u-boot.org> References: <20251003165525.440173-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: NOL3KA6SPOXDXLPJTVSAYKMUVDSZZYEJ X-Message-ID-Hash: NOL3KA6SPOXDXLPJTVSAYKMUVDSZZYEJ X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 17/22] video: Provide a way for expo to control video sync List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass When expo is being used, it should only redraw the display when it has made changes. Add a new 'manual sync' mode which tells the video subsystem to ignore video syncs from other sources. This also disables the idle feature, since it can interfere with tests. Signed-off-by: Simon Glass --- drivers/video/video-uclass.c | 35 ++++++++++++++++++++++++ include/video.h | 10 +++++++ test/dm/video.c | 52 ++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index bf633861ef3..f8ba3abc5f4 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -65,11 +65,13 @@ struct cyclic_info; * gd->video_top and works downwards, running out of space when it hits * gd->video_bottom. * @cyc_active: true if cyclic video sync is currently registered + * @manual_sync: true if manual-sync mode is active (caller controls video sync) * @cyc: handle for cyclic-execution function, or NULL if none */ struct video_uc_priv { ulong video_ptr; bool cyc_active; + bool manual_sync; struct cyclic_info cyc; }; @@ -501,9 +503,14 @@ static void video_flush_copy(struct udevice *vid) int video_sync(struct udevice *vid, bool force) { struct video_priv *priv = dev_get_uclass_priv(vid); + struct video_uc_priv *uc_priv = uclass_get_priv(vid->uclass); struct video_ops *ops = video_get_ops(vid); int ret; + /* Skip sync if manual-sync mode is active */ + if (uc_priv->manual_sync) + return 0; + if (IS_ENABLED(CONFIG_VIDEO_COPY)) video_flush_copy(vid); @@ -622,6 +629,20 @@ int video_default_font_height(struct udevice *dev) static void video_idle(struct cyclic_info *cyc) { + struct video_uc_priv *uc_priv; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_VIDEO, &uc); + if (ret) + return; + + uc_priv = uclass_get_priv(uc); + + /* Skip sync if manual-sync mode is active */ + if (uc_priv->manual_sync) + return; + if (CONFIG_IS_ENABLED(CURSOR)) { struct udevice *cons; struct uclass *uc; @@ -809,6 +830,20 @@ __maybe_unused static int video_destroy(struct uclass *uc) return 0; } +void video_set_manual_sync(bool enable) +{ + struct video_uc_priv *uc_priv; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_VIDEO, &uc); + if (ret) + return; + + uc_priv = uclass_get_priv(uc); + uc_priv->manual_sync = enable; +} + UCLASS_DRIVER(video) = { .id = UCLASS_VIDEO, .name = "video", diff --git a/include/video.h b/include/video.h index 3ce603384dc..3f5c8cbd45a 100644 --- a/include/video.h +++ b/include/video.h @@ -543,4 +543,14 @@ static inline bool video_is_visible(void) #endif } +/** + * video_set_manual_sync() - Set manual-sync mode for video subsystem + * + * When manual-sync mode is enabled, automatic video sync operations are + * suppressed to allow the caller to control rendering timing. + * + * @enable: true to enable manual-sync mode, false to disable + */ +void video_set_manual_sync(bool enable); + #endif diff --git a/test/dm/video.c b/test/dm/video.c index 7ada4c75bf7..cee9e528689 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1293,3 +1293,55 @@ static int dm_test_video_images(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_video_images, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE); + +/* Test manual-sync mode suppresses auto-sync */ +static int dm_test_video_manual_sync(struct unit_test_state *uts) +{ + struct video_priv *priv; + struct udevice *dev, *con; + + ut_assertok(select_vidconsole(uts, "vidconsole0")); + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + priv = dev_get_uclass_priv(dev); + + /* Write some text and verify it appears in the framebuffer */ + vidconsole_put_string(con, "Test"); + ut_asserteq(118, video_compress_fb(uts, dev, false)); + + /* Sync to copy buffer before enabling manual-sync mode */ + ut_assertok(video_sync(dev, true)); + + /* Enable manual-sync mode - sync should be suppressed */ + video_set_manual_sync(true); + + /* Clear and write new text - auto-sync should not happen */ + video_clear(dev); + vidconsole_put_string(con, "Manual Sync"); + + /* should do nothing in manual-sync mode */ + ut_assertok(video_sync(dev, false)); + + /* The copy framebuffer should still show old content */ + if (IS_ENABLED(CONFIG_VIDEO_COPY)) { + ut_assertf(memcmp(priv->fb, priv->copy_fb, priv->fb_size), + "Copy fb should not match fb in manual-sync mode"); + } + + /* + * video_sync() with force=true should still do nothing, except of + * course that without a copy framebuffer the string will be present on + * (only) framebuffer + */ + ut_assertok(video_sync(dev, true)); + if (IS_ENABLED(CONFIG_VIDEO_COPY)) { + ut_asserteq(118, video_compress_fb(uts, dev, true)); + ut_assertf(memcmp(priv->fb, priv->copy_fb, priv->fb_size), + "Copy fb should not match fb in manual-sync mode"); + } else { + ut_asserteq(183, video_compress_fb(uts, dev, true)); + } + + return 0; +} +DM_TEST(dm_test_video_manual_sync, UTF_SCAN_PDATA | UTF_SCAN_FDT);