- improve video sync performance with background syncing (cyclic)

- fix dropping characters when pasting commands over the UART
  - enable background syncing by default for boards using VIDEO
  - make sandbox video more responsive
 -----BEGIN PGP SIGNATURE-----
 
 iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCZqqD3w4cYWd1c3RAZGVu
 eC5kZQAKCRBM6ATMmsalXBXOAJ4+YXVj/tqYfGzbYgMvmQjdpHs3XQCfX6hJwBWG
 gfdZp+gqv/FnVjeDCVQ=
 =0ThR
 -----END PGP SIGNATURE-----

Merge tag 'video-20240731' of https://source.denx.de/u-boot/custodians/u-boot-video

 - improve video sync performance with background syncing (cyclic)
 - fix dropping characters when pasting commands over the UART
 - enable background syncing by default for boards using VIDEO
 - make sandbox video more responsive
This commit is contained in:
Tom Rini 2024-07-31 13:39:14 -06:00
commit 7010f22eba
9 changed files with 96 additions and 15 deletions

View file

@ -626,8 +626,17 @@ config CYCLIC
if CYCLIC
config SPL_CYCLIC
bool "General-purpose cyclic execution mechanism (SPL)"
help
This enables a general-purpose cyclic execution infrastructure in SPL,
to allow "small" (run-time wise) functions to be executed at
a specified frequency. Things like LED blinking or watchdog
triggering are examples for such tasks.
config CYCLIC_MAX_CPU_TIME_US
int "Sets the max allowed time for a cyclic function in us"
default 100000 if SANDBOX # sandbox video is quite slow
default 5000
help
The max allowed time for a cyclic function in us. If a functions

View file

@ -79,7 +79,7 @@ obj-$(CONFIG_CROS_EC) += cros_ec.o
obj-y += dlmalloc.o
obj-$(CONFIG_$(SPL_TPL_)SYS_MALLOC_F) += malloc_simple.o
obj-$(CONFIG_CYCLIC) += cyclic.o
obj-$(CONFIG_$(SPL_TPL_)CYCLIC) += cyclic.o
obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o
obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o

View file

@ -138,8 +138,6 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
return 0;
os_usleep(100);
if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_SPL_BUILD))
video_sync_all();
avail = membuff_putraw(&priv->buf, 100, false, &data);
if (!avail)
return 1; /* buffer full */

View file

@ -7,6 +7,7 @@ menu "Graphics support"
config VIDEO
bool "Enable driver model support for LCD/video"
depends on DM
imply CYCLIC
help
This enables driver model for LCD and video devices. These support
a bitmap display of various sizes and depths which can be drawn on
@ -14,6 +15,11 @@ config VIDEO
option compiles in the video uclass and routes all LCD/video access
through this.
If CYCLIC is enabled (which it is by default), the cyclic subsystem
is used to flush pending output to the display periodically, rather
than this happening with every chunk of output. This allows for more
efficient operation and faster display output.
if VIDEO
config VIDEO_FONT_4X6
@ -232,6 +238,35 @@ config NO_FB_CLEAR
loads takes over the screen. This, for example, can be used to
keep splash image on screen until grub graphical boot menu starts.
config VIDEO_SYNC_MS
int "Video-sync period in milliseconds for foreground processing"
default 300 if SANDBOX
default 100
help
This sets the requested, maximum time before a video sync will take
place, in milliseconds. Note that the time between video syncs
may be longer than this, since syncs only happen when the video system
is used, e.g. by outputting a character to the console.
It may also be shorter, since the video uclass will automatically
force a sync in certain situations.
Many video-output systems require a sync operation before any output
is visible. This may flush the CPU cache or perhaps copy the
display contents to a hardware framebuffer. Without this, change to
the video may never be displayed.
config VIDEO_SYNC_CYCLIC_MS
int "Video-sync period in milliseconds for cyclic processing"
depends on CYCLIC
default 100 if SANDBOX
default 10
help
This sets the frequency of cyclic video syncs. The cyclic system is
used to ensure that when U-Boot is idle, it syncs the video. This
improves the responsiveness of the command line to new characters
being entered.
config PANEL
bool "Enable panel uclass support"
default y

View file

@ -8,6 +8,7 @@
#include <bloblist.h>
#include <console.h>
#include <cpu_func.h>
#include <cyclic.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
@ -52,6 +53,8 @@
*/
DECLARE_GLOBAL_DATA_PTR;
struct cyclic_info;
/**
* struct video_uc_priv - Information for the video uclass
*
@ -60,9 +63,12 @@ DECLARE_GLOBAL_DATA_PTR;
* available address to use for a device's framebuffer. It starts at
* gd->video_top and works downwards, running out of space when it hits
* gd->video_bottom.
* @cyc: handle for cyclic-execution function, or NULL if none
*/
struct video_uc_priv {
ulong video_ptr;
bool cyc_active;
struct cyclic_info cyc;
};
/** struct vid_rgb - Describes a video colour */
@ -349,6 +355,7 @@ void video_set_default_colors(struct udevice *dev, bool invert)
/* 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_ops *ops = video_get_ops(vid);
int ret;
@ -358,28 +365,26 @@ int video_sync(struct udevice *vid, bool force)
return ret;
}
if (CONFIG_IS_ENABLED(CYCLIC) && !force &&
get_timer(priv->last_sync) < CONFIG_VIDEO_SYNC_MS)
return 0;
/*
* flush_dcache_range() is declared in common.h but it seems that some
* architectures do not actually implement it. Is there a way to find
* out whether it exists? For now, ARM is safe.
*/
#if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
struct video_priv *priv = dev_get_uclass_priv(vid);
if (priv->flush_dcache) {
flush_dcache_range((ulong)priv->fb,
ALIGN((ulong)priv->fb + priv->fb_size,
CONFIG_SYS_CACHELINE_SIZE));
}
#elif defined(CONFIG_VIDEO_SANDBOX_SDL)
struct video_priv *priv = dev_get_uclass_priv(vid);
static ulong last_sync;
if (force || get_timer(last_sync) > 100) {
sandbox_sdl_sync(priv->fb);
last_sync = get_timer(0);
}
#endif
priv->last_sync = get_timer(0);
return 0;
}
@ -528,10 +533,16 @@ int video_default_font_height(struct udevice *dev)
return vc_priv->y_charsize;
}
static void video_idle(struct cyclic_info *cyc)
{
video_sync_all();
}
/* Set up the display ready for use */
static int video_post_probe(struct udevice *dev)
{
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
struct video_uc_priv *uc_priv = uclass_get_priv(dev->uclass);
struct video_priv *priv = dev_get_uclass_priv(dev);
char name[30], drv[15], *str;
const char *drv_name = drv;
@ -622,6 +633,16 @@ static int video_post_probe(struct udevice *dev)
}
}
/* register cyclic as soon as the first video device is probed */
if (CONFIG_IS_ENABLED(CYCLIC) && (gd->flags && GD_FLG_RELOC) &&
!uc_priv->cyc_active) {
uint ms = CONFIG_IF_ENABLED_INT(CYCLIC, VIDEO_SYNC_CYCLIC_MS);
cyclic_register(&uc_priv->cyc, video_idle, ms * 1000,
"video_init");
uc_priv->cyc_active = true;
}
return 0;
};
@ -661,6 +682,18 @@ static int video_post_bind(struct udevice *dev)
return 0;
}
__maybe_unused static int video_destroy(struct uclass *uc)
{
struct video_uc_priv *uc_priv = uclass_get_priv(uc);
if (uc_priv->cyc_active) {
cyclic_unregister(&uc_priv->cyc);
uc_priv->cyc_active = false;
}
return 0;
}
UCLASS_DRIVER(video) = {
.id = UCLASS_VIDEO,
.name = "video",
@ -670,4 +703,5 @@ UCLASS_DRIVER(video) = {
.priv_auto = sizeof(struct video_uc_priv),
.per_device_auto = sizeof(struct video_priv),
.per_device_plat_auto = sizeof(struct video_uc_plat),
CONFIG_IS_ENABLED(CYCLIC, (.destroy = video_destroy, ))
};

View file

@ -4,6 +4,7 @@ config WATCHDOG
bool "Enable U-Boot watchdog reset"
depends on !HW_WATCHDOG
select CYCLIC
imply SPL_CYCLIC if SPL
help
This option enables U-Boot watchdog support where U-Boot is using
watchdog_reset function to service watchdog device in U-Boot. Enable
@ -408,6 +409,7 @@ config WDT_ARM_SMC
config SPL_WDT
bool "Enable driver model for watchdog timer drivers in SPL"
depends on SPL_DM
select SPL_CYCLIC if CYCLIC
help
Enable driver model for watchdog timer in SPL.
This is similar to CONFIG_WDT in U-Boot.

View file

@ -481,7 +481,7 @@ struct global_data {
*/
struct event_state event_state;
#endif
#ifdef CONFIG_CYCLIC
#if CONFIG_IS_ENABLED(CYCLIC)
/**
* @cyclic_list: list of registered cyclic functions
*/

View file

@ -46,7 +46,8 @@ struct cyclic_info {
/** Function type for cyclic functions */
typedef void (*cyclic_func_t)(struct cyclic_info *c);
#if defined(CONFIG_CYCLIC)
#if CONFIG_IS_ENABLED(CYCLIC)
/**
* cyclic_register - Register a new cyclic function
*
@ -123,6 +124,6 @@ static inline int cyclic_unregister_all(void)
{
return 0;
}
#endif
#endif /* CYCLIC */
#endif

View file

@ -97,6 +97,7 @@ enum video_format {
* the LCD is updated
* @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color)
* @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color)
* @last_sync: Monotonic time of last video sync
*/
struct video_priv {
/* Things set up by the driver: */
@ -121,6 +122,7 @@ struct video_priv {
bool flush_dcache;
u8 fg_col_idx;
u8 bg_col_idx;
ulong last_sync;
};
/**