video: Refactor video_sync() to use video_manual_sync()

Extract the core sync logic from video_sync() into a new
video_manual_sync() function that accepts flags directly. This allows
callers to perform sync operations with explicit control over the sync
behavior.

The video_sync() function now:
- Determines the appropriate flags (VIDSYNC_FORCE, VIDSYNC_FLUSH,
  VIDSYNC_COPY) based on the force parameter and timing
- Calls video_manual_sync() with those flags

The video_manual_sync() function:
- Takes explicit flags as a parameter
- Handles VIDSYNC_COPY flag to control copy framebuffer flush
- Performs the actual sync operations

This separation allows manual-sync mode users (and tests) to call
video_manual_sync() directly with custom flags while video_sync()
continues to work as before for normal scenarios.

Add tests for video_manual_sync() to check the behaviour with
different flag combinations.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-10-02 15:40:57 -06:00
parent ad7c596829
commit 69b02023ad
3 changed files with 71 additions and 18 deletions

View File

@@ -499,28 +499,13 @@ static void video_flush_copy(struct udevice *vid)
}
}
/* Flush video activity to the caches */
int video_sync(struct udevice *vid, bool force)
int video_manual_sync(struct udevice *vid, uint flags)
{
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);
uint flags = 0;
int ret;
/* Skip sync if manual-sync mode is active */
if (uc_priv->manual_sync)
return 0;
if (force)
flags |= VIDSYNC_FORCE;
/* Check if sync should do full flush */
if (!CONFIG_IS_ENABLED(CYCLIC) || force ||
get_timer(priv->last_sync) >= CONFIG_VIDEO_SYNC_MS)
flags |= VIDSYNC_FLUSH;
if (IS_ENABLED(CONFIG_VIDEO_COPY))
if (IS_ENABLED(CONFIG_VIDEO_COPY) && (flags & VIDSYNC_COPY))
video_flush_copy(vid);
if (ops && ops->sync) {
@@ -534,7 +519,7 @@ int video_sync(struct udevice *vid, bool force)
video_flush_dcache(vid, false);
if (IS_ENABLED(CONFIG_VIDEO_COPY))
if (IS_ENABLED(CONFIG_VIDEO_COPY) && (flags & VIDSYNC_COPY))
video_flush_dcache(vid, true);
#if defined(CONFIG_VIDEO_SANDBOX_SDL)
@@ -555,6 +540,31 @@ int video_sync(struct udevice *vid, bool force)
return 0;
}
/* Flush video activity to the caches */
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);
uint flags = 0;
/* Skip sync if manual-sync mode is active */
if (uc_priv->manual_sync)
return 0;
if (force)
flags |= VIDSYNC_FORCE;
/* Check if sync should do full flush */
if (!CONFIG_IS_ENABLED(CYCLIC) || force ||
get_timer(priv->last_sync) >= CONFIG_VIDEO_SYNC_MS)
flags |= VIDSYNC_FLUSH;
if (IS_ENABLED(CONFIG_VIDEO_COPY))
flags |= VIDSYNC_COPY;
return video_manual_sync(vid, flags);
}
void video_sync_all(void)
{
struct udevice *dev;

View File

@@ -80,10 +80,12 @@ enum video_format {
*
* @VIDSYNC_FORCE: Force sync even if recently synced or in manual-sync mode
* @VIDSYNC_FLUSH: Flush dcache and perform full sync operations
* @VIDSYNC_COPY: Flush framebuffer to copy buffer
*/
enum video_sync_flags {
VIDSYNC_FORCE = BIT(0),
VIDSYNC_FLUSH = BIT(1),
VIDSYNC_COPY = BIT(2),
};
/**
@@ -341,6 +343,20 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
int width, u32 colour, bool fill);
/**
* video_manual_sync() - Manually sync a device's frame buffer with its hardware
*
* @vid: Device to sync
* @flags: Flags for the sync (enum video_sync_flags)
*
* @return: 0 on success, error code otherwise
*
* Performs the actual sync operation with the provided flags. This is called
* by video_sync() after determining the appropriate flags, but can also be
* called directly when manual-sync mode is enabled.
*/
int video_manual_sync(struct udevice *vid, uint flags);
/**
* video_sync() - Sync a device's frame buffer with its hardware
*

View File

@@ -1343,6 +1343,33 @@ static int dm_test_video_manual_sync(struct unit_test_state *uts)
ut_asserteq(183, video_compress_fb(uts, dev, true));
}
/* Now test video_manual_sync() directly with VIDSYNC_FORCE and COPY */
ut_assertok(video_manual_sync(dev, VIDSYNC_FORCE | VIDSYNC_FLUSH |
VIDSYNC_COPY));
ut_asserteq(183, video_compress_fb(uts, dev, false));
/* The copy framebuffer should now match since we forced the sync */
ut_assertok(video_check_copy_fb(uts, dev));
/* Write new text again */
vidconsole_put_string(con, "Test2");
/* without VIDSYNC_FLUSH or COPY - should do nothing */
ut_assertok(video_manual_sync(dev, 0));
/* Copy fb should not match since neither flush nor copy occurred */
if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
ut_assertf(memcmp(priv->fb, priv->copy_fb, priv->fb_size),
"Copy fb shouldn't match fb w/o VIDSYNC_FLUSH/COPY");
}
/* video_manual_sync() with full flags - should perform full sync */
ut_assertok(video_manual_sync(dev, VIDSYNC_FLUSH | VIDSYNC_COPY));
ut_assertok(video_check_copy_fb(uts, dev));
/* Disable manual-sync mode */
video_set_manual_sync(false);
return 0;
}
DM_TEST(dm_test_video_manual_sync, UTF_SCAN_PDATA | UTF_SCAN_FDT);