summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/Kconfig9
-rw-r--r--common/Makefile2
-rw-r--r--drivers/serial/sandbox.c2
-rw-r--r--drivers/video/Kconfig35
-rw-r--r--drivers/video/video-uclass.c52
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--include/asm-generic/global_data.h2
-rw-r--r--include/cyclic.h5
-rw-r--r--include/video.h2
9 files changed, 96 insertions, 15 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 4bb9f08977a..83c81edac20 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -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
diff --git a/common/Makefile b/common/Makefile
index e9835473420..d871113cbb9 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -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
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index ec0068e33d3..77a1558db68 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -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 */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7808ae7919e..6e79694fd19 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -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
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index ff1382f4a43..a5aa8dd5295 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -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);
- }
+ sandbox_sdl_sync(priv->fb);
#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, ))
};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 8318fd77a32..0c3e9913318 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -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.
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index aa336d63e3a..27aa75e7036 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -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
*/
diff --git a/include/cyclic.h b/include/cyclic.h
index 2c3d383c5ef..cd95b691d48 100644
--- a/include/cyclic.h
+++ b/include/cyclic.h
@@ -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
diff --git a/include/video.h b/include/video.h
index 4d8df9baaad..4013a949983 100644
--- a/include/video.h
+++ b/include/video.h
@@ -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;
};
/**