diff --git a/Add-video-damage-tracking.patch b/Add-video-damage-tracking.patch deleted file mode 100644 index 72475de..0000000 --- a/Add-video-damage-tracking.patch +++ /dev/null @@ -1,2382 +0,0 @@ -From a05aeec18576ddce60c2fbd797245b5eeaddee25 Mon Sep 17 00:00:00 2001 -From: Alper Nebi Yasak -Date: Mon, 21 Aug 2023 16:50:58 +0300 -Subject: [PATCH 01/13] video: test: Split copy frame buffer check into a - function - -While checking frame buffer contents, the video tests also check if the -copy frame buffer contents match the main frame buffer. To test if only -the modified regions are updated after a sync, we will need to create -situations where the two are mismatched. Split this check into another -function that we can skip calling, since we won't want it to error on -those mismatched cases. - -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - test/dm/video.c | 69 +++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 58 insertions(+), 11 deletions(-) - -diff --git a/test/dm/video.c b/test/dm/video.c -index e347c1403fd..01fa9e1b241 100644 ---- a/test/dm/video.c -+++ b/test/dm/video.c -@@ -54,9 +54,6 @@ DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT); - * size of the compressed data. This provides a pretty good level of - * certainty and the resulting tests need only check a single value. - * -- * If the copy framebuffer is enabled, this compares it to the main framebuffer -- * too. -- * - * @uts: Test state - * @dev: Video device - * Return: compressed size of the frame buffer, or -ve on error -@@ -65,7 +62,6 @@ static int compress_frame_buffer(struct unit_test_state *uts, - struct udevice *dev) - { - struct video_priv *priv = dev_get_uclass_priv(dev); -- struct video_priv *uc_priv = dev_get_uclass_priv(dev); - uint destlen; - void *dest; - int ret; -@@ -81,16 +77,34 @@ static int compress_frame_buffer(struct unit_test_state *uts, - if (ret) - return ret; - -- /* Check here that the copy frame buffer is working correctly */ -- if (IS_ENABLED(CONFIG_VIDEO_COPY)) { -- ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb, -- uc_priv->fb_size), -- "Copy framebuffer does not match fb"); -- } -- - return destlen; - } - -+/** -+ * check_copy_frame_buffer() - Compare main frame buffer to copy -+ * -+ * If the copy frame buffer is enabled, this compares it to the main -+ * frame buffer. Normally they should have the same contents after a -+ * sync. -+ * -+ * @uts: Test state -+ * @dev: Video device -+ * Return: 0, or -ve on error -+ */ -+static int check_copy_frame_buffer(struct unit_test_state *uts, -+ struct udevice *dev) -+{ -+ struct video_priv *priv = dev_get_uclass_priv(dev); -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_COPY)) -+ return 0; -+ -+ ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size), -+ "Copy framebuffer does not match fb"); -+ -+ return 0; -+} -+ - /* - * Call this function at any point to halt and show the current display. Be - * sure to run the test with the -l flag. -@@ -154,24 +168,30 @@ static int dm_test_video_text(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "8x16", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); - ut_asserteq(79, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_putc_xy(con, 0, 0, ' '); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(273, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_set_row(con, 0, WHITE); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(273, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -190,24 +210,30 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "12x22", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); - ut_asserteq(89, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_putc_xy(con, 0, 0, ' '); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(363, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_set_row(con, 0, WHITE); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); - ut_asserteq(363, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -225,6 +251,7 @@ static int dm_test_video_chars(struct unit_test_state *uts) - ut_assertok(vidconsole_select_font(con, "8x16", 0)); - vidconsole_put_string(con, test_string); - ut_asserteq(466, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -246,19 +273,23 @@ static int dm_test_video_ansi(struct unit_test_state *uts) - video_clear(con->parent); - video_sync(con->parent, false); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test clear escape sequence: [2J */ - vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J"); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test set-cursor: [%d;%df */ - vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd"); - ut_asserteq(143, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test colors (30-37 fg color, 40-47 bg color) */ - vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ - vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ - ut_asserteq(272, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -291,11 +322,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "8x16", 0)); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* Check display wrap */ - for (i = 0; i < 120; i++) - vidconsole_put_char(con, 'A' + i % 50); - ut_asserteq(wrap_size, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* Check display scrolling */ - for (i = 0; i < SCROLL_LINES; i++) { -@@ -303,11 +336,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, - vidconsole_put_char(con, '\n'); - } - ut_asserteq(scroll_size, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* If we scroll enough, the screen becomes blank again */ - for (i = 0; i < SCROLL_LINES; i++) - vidconsole_put_char(con, '\n'); - ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -382,6 +417,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1368, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -401,6 +437,7 @@ static int dm_test_video_bmp8(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1247, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -424,6 +461,7 @@ static int dm_test_video_bmp16(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(3700, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -447,6 +485,7 @@ static int dm_test_video_bmp24(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(3656, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -470,6 +509,7 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); - ut_asserteq(6827, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -488,6 +528,7 @@ static int dm_test_video_bmp32(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(2024, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -504,6 +545,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1368, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -523,6 +565,7 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(2024, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -542,6 +585,7 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts) - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); - ut_asserteq(1247, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -557,6 +601,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); - ut_asserteq(12174, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -578,6 +623,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); - ut_asserteq(34287, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } -@@ -599,6 +645,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); - ut_asserteq(29471, compress_frame_buffer(uts, dev)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; - } --- -2.48.1 - -From 37f92f0ac721bc300659d166d8a19f6b18b2bbcb Mon Sep 17 00:00:00 2001 -From: Alper Nebi Yasak -Date: Mon, 21 Aug 2023 16:50:59 +0300 -Subject: [PATCH 02/13] video: test: Support checking copy frame buffer - contents - -The video tests have a helper function to generate a pseudo-digest of -frame buffer contents, but it only does so for the main one. There is -another check that the copy frame buffer is the same as that. But -neither is enough to test if only the modified regions are copied to the -copy frame buffer, since we will want the two to be different in very -specific ways. - -Add a boolean argument to the existing helper function to indicate which -frame buffer we want to inspect, and update the existing callers. - -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - test/dm/video.c | 76 ++++++++++++++++++++++++++----------------------- - 1 file changed, 41 insertions(+), 35 deletions(-) - -diff --git a/test/dm/video.c b/test/dm/video.c -index 01fa9e1b241..edb1b4ede8c 100644 ---- a/test/dm/video.c -+++ b/test/dm/video.c -@@ -56,22 +56,28 @@ DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT); - * - * @uts: Test state - * @dev: Video device -+ * @use_copy: Use copy frame buffer if available - * Return: compressed size of the frame buffer, or -ve on error - */ - static int compress_frame_buffer(struct unit_test_state *uts, -- struct udevice *dev) -+ struct udevice *dev, -+ bool use_copy) - { - struct video_priv *priv = dev_get_uclass_priv(dev); - uint destlen; - void *dest; - int ret; - -+ if (!IS_ENABLED(CONFIG_VIDEO_COPY)) -+ use_copy = false; -+ - destlen = priv->fb_size; - dest = malloc(priv->fb_size); - if (!dest) - return -ENOMEM; - ret = BZ2_bzBuffToBuffCompress(dest, &destlen, -- priv->fb, priv->fb_size, -+ use_copy ? priv->copy_fb : priv->fb, -+ priv->fb_size, - 3, 0, 0); - free(dest); - if (ret) -@@ -167,30 +173,30 @@ static int dm_test_video_text(struct unit_test_state *uts) - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "8x16", 0)); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); -- ut_asserteq(79, compress_frame_buffer(uts, dev)); -+ ut_asserteq(79, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_putc_xy(con, 0, 0, ' '); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); -- ut_asserteq(273, compress_frame_buffer(uts, dev)); -+ ut_asserteq(273, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_set_row(con, 0, WHITE); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); -- ut_asserteq(273, compress_frame_buffer(uts, dev)); -+ ut_asserteq(273, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -209,30 +215,30 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "12x22", 0)); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); -- ut_asserteq(89, compress_frame_buffer(uts, dev)); -+ ut_asserteq(89, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_putc_xy(con, 0, 0, ' '); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); -- ut_asserteq(363, compress_frame_buffer(uts, dev)); -+ ut_asserteq(363, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - vidconsole_set_row(con, 0, WHITE); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); -- ut_asserteq(363, compress_frame_buffer(uts, dev)); -+ ut_asserteq(363, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -250,7 +256,7 @@ static int dm_test_video_chars(struct unit_test_state *uts) - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "8x16", 0)); - vidconsole_put_string(con, test_string); -- ut_asserteq(466, compress_frame_buffer(uts, dev)); -+ ut_asserteq(466, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -272,23 +278,23 @@ static int dm_test_video_ansi(struct unit_test_state *uts) - /* reference clear: */ - video_clear(con->parent); - video_sync(con->parent, false); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test clear escape sequence: [2J */ - vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J"); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test set-cursor: [%d;%df */ - vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd"); -- ut_asserteq(143, compress_frame_buffer(uts, dev)); -+ ut_asserteq(143, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* test colors (30-37 fg color, 40-47 bg color) */ - vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ - vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ -- ut_asserteq(272, compress_frame_buffer(uts, dev)); -+ ut_asserteq(272, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -321,13 +327,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - ut_assertok(vidconsole_select_font(con, "8x16", 0)); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* Check display wrap */ - for (i = 0; i < 120; i++) - vidconsole_put_char(con, 'A' + i % 50); -- ut_asserteq(wrap_size, compress_frame_buffer(uts, dev)); -+ ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* Check display scrolling */ -@@ -335,13 +341,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, - vidconsole_put_char(con, 'A' + i % 50); - vidconsole_put_char(con, '\n'); - } -- ut_asserteq(scroll_size, compress_frame_buffer(uts, dev)); -+ ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - /* If we scroll enough, the screen becomes blank again */ - for (i = 0; i < SCROLL_LINES; i++) - vidconsole_put_char(con, '\n'); -- ut_asserteq(46, compress_frame_buffer(uts, dev)); -+ ut_asserteq(46, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -416,7 +422,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(1368, compress_frame_buffer(uts, dev)); -+ ut_asserteq(1368, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -436,7 +442,7 @@ static int dm_test_video_bmp8(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(1247, compress_frame_buffer(uts, dev)); -+ ut_asserteq(1247, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -460,7 +466,7 @@ static int dm_test_video_bmp16(struct unit_test_state *uts) - &src_len)); - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); -- ut_asserteq(3700, compress_frame_buffer(uts, dev)); -+ ut_asserteq(3700, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -484,7 +490,7 @@ static int dm_test_video_bmp24(struct unit_test_state *uts) - &src_len)); - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); -- ut_asserteq(3656, compress_frame_buffer(uts, dev)); -+ ut_asserteq(3656, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -508,7 +514,7 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts) - &src_len)); - - ut_assertok(video_bmp_display(dev, dst, 0, 0, false)); -- ut_asserteq(6827, compress_frame_buffer(uts, dev)); -+ ut_asserteq(6827, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -527,7 +533,7 @@ static int dm_test_video_bmp32(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(2024, compress_frame_buffer(uts, dev)); -+ ut_asserteq(2024, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -544,7 +550,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(1368, compress_frame_buffer(uts, dev)); -+ ut_asserteq(1368, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -564,7 +570,7 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(2024, compress_frame_buffer(uts, dev)); -+ ut_asserteq(2024, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -584,7 +590,7 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts) - ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); - - ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -- ut_asserteq(1247, compress_frame_buffer(uts, dev)); -+ ut_asserteq(1247, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -600,7 +606,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts) - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); -- ut_asserteq(12174, compress_frame_buffer(uts, dev)); -+ ut_asserteq(12174, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -622,7 +628,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts) - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); -- ut_asserteq(34287, compress_frame_buffer(uts, dev)); -+ ut_asserteq(34287, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; -@@ -644,7 +650,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts) - ut_assertok(video_get_nologo(uts, &dev)); - ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); -- ut_asserteq(29471, compress_frame_buffer(uts, dev)); -+ ut_asserteq(29471, compress_frame_buffer(uts, dev, false)); - ut_assertok(check_copy_frame_buffer(uts, dev)); - - return 0; --- -2.48.1 - -From eb739214f97a59e2d902b965f9990eab9b243658 Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Tue, 18 Feb 2025 21:42:26 +0000 -Subject: [PATCH 03/13] video: test: Test partial updates of hardware frame - buffer - -With VIDEO_COPY enabled, only the modified parts of the frame buffer are -intended to be copied to the hardware. Add a test that checks this, by -overwriting contents we prepared without telling the video uclass and -then checking if the overwritten contents have been redrawn on the next -sync. - -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass -Signed-off-by: Peter Robinson ---- - test/dm/video.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 54 insertions(+) - -diff --git a/test/dm/video.c b/test/dm/video.c -index edb1b4ede8c..d520938d1b2 100644 ---- a/test/dm/video.c -+++ b/test/dm/video.c -@@ -656,3 +656,57 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts) - return 0; - } - DM_TEST(dm_test_video_truetype_bs, UTF_SCAN_PDATA | UTF_SCAN_FDT); -+ -+/* Test partial rendering onto hardware frame buffer */ -+static int dm_test_video_copy(struct unit_test_state *uts) -+{ -+ struct sandbox_sdl_plat *plat; -+ struct video_uc_plat *uc_plat; -+ struct udevice *dev, *con; -+ struct video_priv *priv; -+ const char *test_string = "\n\tCriticism may not be agreeable, but it is necessary.\t"; -+ ulong addr; -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_COPY)) -+ return -EAGAIN; -+ -+ ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev)); -+ ut_assertnonnull(dev); -+ uc_plat = dev_get_uclass_plat(dev); -+ uc_plat->hide_logo = true; -+ plat = dev_get_plat(dev); -+ plat->font_size = 32; -+ ut_assert(!device_active(dev)); -+ ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev)); -+ ut_assertnonnull(dev); -+ priv = dev_get_uclass_priv(dev); -+ -+ ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr)); -+ ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); -+ -+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); -+ vidconsole_put_string(con, "\n\n\n\n\n"); -+ vidconsole_put_string(con, test_string); -+ vidconsole_put_string(con, test_string); -+ -+ ut_asserteq(6678, compress_frame_buffer(uts, dev, false)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); -+ -+ /* -+ * Secretly clear the hardware frame buffer, but in a different -+ * color (black) to see which parts will be overwritten. -+ */ -+ memset(priv->copy_fb, 0, priv->fb_size); -+ -+ /* -+ * We should have the full content on the main buffer, but only -+ * the new content should have been copied to the copy buffer. -+ */ -+ vidconsole_put_string(con, test_string); -+ vidconsole_put_string(con, test_string); -+ ut_asserteq(7589, compress_frame_buffer(uts, dev, false)); -+ ut_asserteq(5278, compress_frame_buffer(uts, dev, true)); -+ -+ return 0; -+} -+DM_TEST(dm_test_video_copy, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); --- -2.48.1 - -From 60e428bb54f2f7ee922f53ec3d3e0976a37bd47d Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Tue, 18 Feb 2025 21:51:29 +0000 -Subject: [PATCH 04/13] dm: video: Add damage tracking API - -We are going to introduce image damage tracking to fasten up screen -refresh on large displays. This patch adds damage tracking for up to -one rectangle of the screen which is typically enough to hold blt or -text print updates. Callers into this API and a reduced dcache flush -code path will follow in later patches. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -[Alper: Use xstart/yend, document new fields, return void from - video_damage(), declare priv, drop headers, use IS_ENABLED()] -Co-developed-by: Alper Nebi Yasak -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass -Signed-off-by: Peter Robinson ---- - drivers/video/Kconfig | 13 +++++++++++++ - drivers/video/video-uclass.c | 37 ++++++++++++++++++++++++++++++++++++ - include/video.h | 32 +++++++++++++++++++++++++++++-- - 3 files changed, 80 insertions(+), 2 deletions(-) - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 3c3cebaacd0..5d67067891b 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -98,6 +98,19 @@ config VIDEO_COPY - To use this, your video driver must set @copy_base in - struct video_uc_plat. - -+config VIDEO_DAMAGE -+ bool "Enable damage tracking of frame buffer regions" -+ help -+ On some machines (most ARM), the display frame buffer resides in -+ RAM. To make the display controller pick up screen updates, we -+ have to flush frame buffer contents from CPU caches into RAM which -+ can be a slow operation. -+ -+ This feature adds damage tracking to collect information about regions -+ that received updates. When we want to sync, we then only flush -+ regions of the frame buffer that were modified before, speeding up -+ screen refreshes significantly. -+ - config BACKLIGHT_PWM - bool "Generic PWM based Backlight Driver" - depends on BACKLIGHT && DM_PWM -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index ff4f2199585..ad20af760b8 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -367,6 +367,35 @@ void video_set_default_colors(struct udevice *dev, bool invert) - priv->colour_bg = video_index_to_colour(priv, back); - } - -+/* Notify about changes in the frame buffer */ -+void video_damage(struct udevice *vid, int x, int y, int width, int height) -+{ -+ struct video_priv *priv = dev_get_uclass_priv(vid); -+ int xend = x + width; -+ int yend = y + height; -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) -+ return; -+ -+ if (x > priv->xsize) -+ return; -+ -+ if (y > priv->ysize) -+ return; -+ -+ if (xend > priv->xsize) -+ xend = priv->xsize; -+ -+ if (yend > priv->ysize) -+ yend = priv->ysize; -+ -+ /* Span a rectangle across all old and new damage */ -+ priv->damage.xstart = min(x, priv->damage.xstart); -+ priv->damage.ystart = min(y, priv->damage.ystart); -+ priv->damage.xend = max(xend, priv->damage.xend); -+ priv->damage.yend = max(yend, priv->damage.yend); -+} -+ - /* Flush video activity to the caches */ - int video_sync(struct udevice *vid, bool force) - { -@@ -398,8 +427,16 @@ int video_sync(struct udevice *vid, bool force) - #elif defined(CONFIG_VIDEO_SANDBOX_SDL) - sandbox_sdl_sync(priv->fb); - #endif -+ - priv->last_sync = get_timer(0); - -+ if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) { -+ priv->damage.xstart = priv->xsize; -+ priv->damage.ystart = priv->ysize; -+ priv->damage.xend = 0; -+ priv->damage.yend = 0; -+ } -+ - return 0; - } - -diff --git a/include/video.h b/include/video.h -index a1f7fd7e839..92aa5da4ff3 100644 ---- a/include/video.h -+++ b/include/video.h -@@ -85,6 +85,11 @@ enum video_format { - * @fb_size: Frame buffer size - * @copy_fb: Copy of the frame buffer to keep up to date; see struct - * video_uc_plat -+ * @damage: A bounding box of framebuffer regions updated since last sync -+ * @damage.xstart: X start position in pixels from the left -+ * @damage.ystart: Y start position in pixels from the top -+ * @damage.xend: X end position in pixels from the left -+ * @damage.xend: Y end position in pixels from the top - * @line_length: Length of each frame buffer line, in bytes. This can be - * set by the driver, but if not, the uclass will set it after - * probing -@@ -113,6 +118,12 @@ struct video_priv { - void *fb; - int fb_size; - void *copy_fb; -+ struct { -+ int xstart; -+ int ystart; -+ int xend; -+ int yend; -+ } damage; - int line_length; - u32 colour_fg; - u32 colour_bg; -@@ -259,8 +270,9 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, - * @return: 0 on success, error code otherwise - * - * Some frame buffers are cached or have a secondary frame buffer. This -- * function syncs these up so that the current contents of the U-Boot frame -- * buffer are displayed to the user. -+ * function syncs the damaged parts of them up so that the current contents -+ * of the U-Boot frame buffer are displayed to the user. It clears the damage -+ * buffer. - */ - int video_sync(struct udevice *vid, bool force); - -@@ -380,6 +392,22 @@ static inline int video_sync_copy_all(struct udevice *dev) - - #endif - -+/** -+ * video_damage() - Notify the video subsystem about screen updates. -+ * -+ * @vid: Device to sync -+ * @x: Upper left X coordinate of the damaged rectangle -+ * @y: Upper left Y coordinate of the damaged rectangle -+ * @width: Width of the damaged rectangle -+ * @height: Height of the damaged rectangle -+ * -+ * Some frame buffers are cached or have a secondary frame buffer. This -+ * function notifies the video subsystem about rectangles that were updated -+ * within the frame buffer. They may only get written to the screen on the -+ * next call to video_sync(). -+ */ -+void video_damage(struct udevice *vid, int x, int y, int width, int height); -+ - /** - * video_is_active() - Test if one video device it active - * --- -2.48.1 - -From 8c180ab43a35b355a4f1612d813ec2e655bc7b37 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 21 Aug 2023 16:51:02 +0300 -Subject: [PATCH 05/13] dm: video: Add damage notification on display fills - -Let's report the video damage when we fill parts of the screen. This -way we can later lazily flush only relevant regions to hardware. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -[Alper: Call video_damage() in video_fill_part(), edit commit message] -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - drivers/video/video-uclass.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index ad20af760b8..43b714085a7 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -214,6 +214,8 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, - if (ret) - return ret; - -+ video_damage(dev, xstart, ystart, xend - xstart, yend - ystart); -+ - return 0; - } - -@@ -262,6 +264,8 @@ int video_fill(struct udevice *dev, u32 colour) - if (ret) - return ret; - -+ video_damage(dev, 0, 0, priv->xsize, priv->ysize); -+ - return video_sync(dev, false); - } - --- -2.48.1 - -From 8047ae54ddde0b5ac6aa7503710e7c3d9c56bc67 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 21 Aug 2023 16:51:03 +0300 -Subject: [PATCH 06/13] vidconsole: Add damage notifications to all vidconsole - drivers - -Now that we have a damage tracking API, let's populate damage done by -vidconsole drivers. We try to declare as little memory as damaged as -possible. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -[Alper: Rebase for met->baseline, fontdata->height/width, make rotated - console_putc_xy() damages pass tests, edit patch message] -Co-developed-by: Alper Nebi Yasak -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - drivers/video/console_normal.c | 18 +++++++++++ - drivers/video/console_rotate.c | 54 ++++++++++++++++++++++++++++++++ - drivers/video/console_truetype.c | 21 +++++++++++++ - drivers/video/video-uclass.c | 1 + - 4 files changed, 94 insertions(+) - -diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c -index 6f4194a1814..51ac8cc78e9 100644 ---- a/drivers/video/console_normal.c -+++ b/drivers/video/console_normal.c -@@ -39,6 +39,12 @@ static int console_set_row(struct udevice *dev, uint row, int clr) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ 0, -+ fontdata->height * row, -+ vid_priv->xsize, -+ fontdata->height); -+ - return 0; - } - -@@ -60,6 +66,12 @@ static int console_move_rows(struct udevice *dev, uint rowdst, - if (ret) - return ret; - -+ video_damage(dev->parent, -+ 0, -+ fontdata->height * rowdst, -+ vid_priv->xsize, -+ fontdata->height * count); -+ - return 0; - } - -@@ -91,6 +103,12 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ x, -+ y, -+ fontdata->width, -+ fontdata->height); -+ - ret = vidconsole_sync_copy(dev, start, line); - if (ret) - return ret; -diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c -index a3f8c6352f8..f11dc3a0b07 100644 ---- a/drivers/video/console_rotate.c -+++ b/drivers/video/console_rotate.c -@@ -36,6 +36,12 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ vid_priv->xsize - ((row + 1) * fontdata->height), -+ 0, -+ fontdata->height, -+ vid_priv->ysize); -+ - return 0; - } - -@@ -64,6 +70,12 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc, - dst += vid_priv->line_length; - } - -+ video_damage(dev->parent, -+ vid_priv->xsize - ((rowdst + count) * fontdata->height), -+ 0, -+ count * fontdata->height, -+ vid_priv->ysize); -+ - return 0; - } - -@@ -97,6 +109,12 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ vid_priv->xsize - y - fontdata->height, -+ linenum - 1, -+ fontdata->height, -+ fontdata->width); -+ - return VID_TO_POS(fontdata->width); - } - -@@ -121,6 +139,12 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ 0, -+ vid_priv->ysize - (row + 1) * fontdata->height, -+ vid_priv->xsize, -+ fontdata->height); -+ - return 0; - } - -@@ -142,6 +166,12 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc, - vidconsole_memmove(dev, dst, src, - fontdata->height * vid_priv->line_length * count); - -+ video_damage(dev->parent, -+ 0, -+ vid_priv->ysize - (rowdst + count) * fontdata->height, -+ vid_priv->xsize, -+ count * fontdata->height); -+ - return 0; - } - -@@ -175,6 +205,12 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ x - fontdata->width + 1, -+ linenum - fontdata->height + 1, -+ fontdata->width, -+ fontdata->height); -+ - return VID_TO_POS(fontdata->width); - } - -@@ -199,6 +235,12 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ row * fontdata->height, -+ 0, -+ fontdata->height, -+ vid_priv->ysize); -+ - return 0; - } - -@@ -225,6 +267,12 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc, - dst += vid_priv->line_length; - } - -+ video_damage(dev->parent, -+ rowdst * fontdata->height, -+ 0, -+ count * fontdata->height, -+ vid_priv->ysize); -+ - return 0; - } - -@@ -257,6 +305,12 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ y, -+ linenum - fontdata->width + 1, -+ fontdata->height, -+ fontdata->width); -+ - return VID_TO_POS(fontdata->width); - } - -diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c -index 17a29817664..073ddcfb695 100644 ---- a/drivers/video/console_truetype.c -+++ b/drivers/video/console_truetype.c -@@ -190,6 +190,7 @@ struct console_tt_store { - static int console_truetype_set_row(struct udevice *dev, uint row, int clr) - { - struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); -+ struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_metrics *met = priv->cur_met; - void *end, *line; -@@ -233,6 +234,12 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) - if (ret) - return ret; - -+ video_damage(dev->parent, -+ 0, -+ vc_priv->y_charsize * row, -+ vid_priv->xsize, -+ vc_priv->y_charsize); -+ - return 0; - } - -@@ -240,6 +247,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, - uint rowsrc, uint count) - { - struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); -+ struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_metrics *met = priv->cur_met; - void *dst; -@@ -258,6 +266,12 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, - for (i = 0; i < priv->pos_ptr; i++) - priv->pos[i].ypos -= diff; - -+ video_damage(dev->parent, -+ 0, -+ vc_priv->y_charsize * rowdst, -+ vid_priv->xsize, -+ vc_priv->y_charsize * count); -+ - return 0; - } - -@@ -418,6 +432,13 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, - - line += vid_priv->line_length; - } -+ -+ video_damage(dev->parent, -+ VID_TO_PIXEL(x) + xoff, -+ y + met->baseline + yoff, -+ width, -+ height); -+ - ret = vidconsole_sync_copy(dev, start, line); - if (ret) - return ret; -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 43b714085a7..d175ed61ac8 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -210,6 +210,7 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, - } - line += priv->line_length; - } -+ - ret = video_sync_copy(dev, start, line); - if (ret) - return ret; --- -2.48.1 - -From f701195fca932fda3b08ddfe6317fb2ca01f0fcf Mon Sep 17 00:00:00 2001 -From: Alper Nebi Yasak -Date: Mon, 21 Aug 2023 16:51:04 +0300 -Subject: [PATCH 07/13] video: test: Test video damage tracking via vidconsole - -With VIDEO_DAMAGE, the video uclass tracks updated regions of the frame -buffer in order to avoid unnecessary work during a video sync. Enable -the config in sandbox and add a test for it, by printing strings at a -few locations and checking the tracked region. - -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - configs/sandbox_defconfig | 1 + - test/dm/video.c | 56 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - -diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig -index 7b35ad8a88f..d9e5ac6af48 100644 ---- a/configs/sandbox_defconfig -+++ b/configs/sandbox_defconfig -@@ -328,6 +328,7 @@ CONFIG_USB_ETH_CDC=y - CONFIG_VIDEO=y - CONFIG_VIDEO_FONT_SUN12X22=y - CONFIG_VIDEO_COPY=y -+CONFIG_VIDEO_DAMAGE=y - CONFIG_CONSOLE_ROTATION=y - CONFIG_CONSOLE_TRUETYPE=y - CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y -diff --git a/test/dm/video.c b/test/dm/video.c -index d520938d1b2..9da00be5479 100644 ---- a/test/dm/video.c -+++ b/test/dm/video.c -@@ -710,3 +710,59 @@ static int dm_test_video_copy(struct unit_test_state *uts) - return 0; - } - DM_TEST(dm_test_video_copy, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -+ -+/* Test video damage tracking */ -+static int dm_test_video_damage(struct unit_test_state *uts) -+{ -+ struct sandbox_sdl_plat *plat; -+ struct udevice *dev, *con; -+ struct video_priv *priv; -+ const char *test_string_1 = "Criticism may not be agreeable, "; -+ const char *test_string_2 = "but it is necessary."; -+ const char *test_string_3 = "It fulfils the same function as pain in the human body."; -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) -+ return -EAGAIN; -+ -+ ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev)); -+ ut_assert(!device_active(dev)); -+ plat = dev_get_plat(dev); -+ plat->font_size = 32; -+ -+ ut_assertok(video_get_nologo(uts, &dev)); -+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); -+ priv = dev_get_uclass_priv(dev); -+ -+ vidconsole_position_cursor(con, 14, 10); -+ vidconsole_put_string(con, test_string_2); -+ ut_asserteq(449, priv->damage.xstart); -+ ut_asserteq(325, priv->damage.ystart); -+ ut_asserteq(661, priv->damage.xend); -+ ut_asserteq(350, priv->damage.yend); -+ -+ vidconsole_position_cursor(con, 7, 5); -+ vidconsole_put_string(con, test_string_1); -+ ut_asserteq(225, priv->damage.xstart); -+ ut_asserteq(164, priv->damage.ystart); -+ ut_asserteq(661, priv->damage.xend); -+ ut_asserteq(350, priv->damage.yend); -+ -+ vidconsole_position_cursor(con, 21, 15); -+ vidconsole_put_string(con, test_string_3); -+ ut_asserteq(225, priv->damage.xstart); -+ ut_asserteq(164, priv->damage.ystart); -+ ut_asserteq(1280, priv->damage.xend); -+ ut_asserteq(510, priv->damage.yend); -+ -+ video_sync(dev, false); -+ ut_asserteq(priv->xsize, priv->damage.xstart); -+ ut_asserteq(priv->ysize, priv->damage.ystart); -+ ut_asserteq(0, priv->damage.xend); -+ ut_asserteq(0, priv->damage.yend); -+ -+ ut_asserteq(7339, compress_frame_buffer(uts, dev, false)); -+ ut_assertok(check_copy_frame_buffer(uts, dev)); -+ -+ return 0; -+} -+DM_TEST(dm_test_video_damage, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); --- -2.48.1 - -From 88bc7e2c640a504bbd7de27b28a3ad2b05d43163 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 21 Aug 2023 16:51:05 +0300 -Subject: [PATCH 08/13] video: Add damage notification on bmp display - -Let's report the video damage when we draw a bitmap on the screen. This -way we can later lazily flush only relevant regions to hardware. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -Reviewed-by: Simon Glass -Signed-off-by: Alper Nebi Yasak ---- - drivers/video/video_bmp.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c -index ad512d99a1b..78de9560792 100644 ---- a/drivers/video/video_bmp.c -+++ b/drivers/video/video_bmp.c -@@ -459,6 +459,8 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, - break; - }; - -+ video_damage(dev, x, y, width, height); -+ - /* Find the position of the top left of the image in the framebuffer */ - fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8); - ret = video_sync_copy(dev, start, fb); --- -2.48.1 - -From a3680479d62d38637fc26750756a8cddac380aaf Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 21 Aug 2023 16:51:06 +0300 -Subject: [PATCH 09/13] efi_loader: GOP: Add damage notification on BLT - -Now that we have a damage tracking API, let's populate damage done by -UEFI payloads when they BLT data onto the screen. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -Reviewed-by: Heinrich Schuchardt -[Alper: Add struct comment for new member] -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - lib/efi_loader/efi_gop.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c -index 4593975be5a..3abb47d610e 100644 ---- a/lib/efi_loader/efi_gop.c -+++ b/lib/efi_loader/efi_gop.c -@@ -26,6 +26,7 @@ static const efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - * @ops: graphical output protocol interface - * @info: graphical output mode information - * @mode: graphical output mode -+ * @vdev: backing video device - * @bpix: bits per pixel - * @fb: frame buffer - */ -@@ -34,6 +35,7 @@ struct efi_gop_obj { - struct efi_gop ops; - struct efi_gop_mode_info info; - struct efi_gop_mode mode; -+ struct udevice *vdev; - /* Fields we only have access to during init */ - u32 bpix; - void *fb; -@@ -122,6 +124,7 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this, - u32 *fb32 = gopobj->fb; - u16 *fb16 = gopobj->fb; - struct efi_gop_pixel *buffer = __builtin_assume_aligned(bufferp, 4); -+ bool blt_to_video = (operation != EFI_BLT_VIDEO_TO_BLT_BUFFER); - - if (delta) { - /* Check for 4 byte alignment */ -@@ -245,6 +248,9 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this, - dlineoff += dwidth; - } - -+ if (blt_to_video) -+ video_damage(gopobj->vdev, dx, dy, width, height); -+ - return EFI_SUCCESS; - } - -@@ -551,6 +557,7 @@ efi_status_t efi_gop_register(void) - gopobj->info.pixels_per_scanline = col; - gopobj->bpix = bpix; - gopobj->fb = map_sysmem(fb_base, fb_size); -+ gopobj->vdev = vdev; - - return EFI_SUCCESS; - } --- -2.48.1 - -From cbbd24764c84943078d07728e3c0f4b55268b0dc Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Tue, 18 Feb 2025 21:53:28 +0000 -Subject: [PATCH 10/13] video: Only dcache flush damaged lines - -Now that we have a damage area tells us which parts of the frame buffer -actually need updating, let's only dcache flush those on video_sync() -calls. With this optimization in place, frame buffer updates - especially -on large screen such as 4k displays - speed up significantly. - -Signed-off-by: Alexander Graf -Reported-by: Da Xue -[Alper: Use damage.xstart/yend, IS_ENABLED()] -Co-developed-by: Alper Nebi Yasak -Signed-off-by: Alper Nebi Yasak -Signed-off-by: Peter Robinson ---- - drivers/video/video-uclass.c | 41 +++++++++++++++++++++++++++++++----- - 1 file changed, 36 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index d175ed61ac8..6452ff5039e 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -401,6 +401,41 @@ void video_damage(struct udevice *vid, int x, int y, int width, int height) - priv->damage.yend = max(yend, priv->damage.yend); - } - -+#if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) -+static void video_flush_dcache(struct udevice *vid) -+{ -+ struct video_priv *priv = dev_get_uclass_priv(vid); -+ -+ if (!priv->flush_dcache) -+ return; -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) { -+ flush_dcache_range((ulong)priv->fb, -+ ALIGN((ulong)priv->fb + priv->fb_size, -+ CONFIG_SYS_CACHELINE_SIZE)); -+ -+ return; -+ } -+ -+ if (priv->damage.xend && priv->damage.yend) { -+ int lstart = priv->damage.xstart * VNBYTES(priv->bpix); -+ int lend = priv->damage.xend * VNBYTES(priv->bpix); -+ int y; -+ -+ for (y = priv->damage.ystart; y < priv->damage.yend; y++) { -+ ulong fb = (ulong)priv->fb; -+ ulong start = fb + (y * priv->line_length) + lstart; -+ ulong end = start + lend - lstart; -+ -+ start = ALIGN_DOWN(start, CONFIG_SYS_CACHELINE_SIZE); -+ end = ALIGN(end, CONFIG_SYS_CACHELINE_SIZE); -+ -+ flush_dcache_range(start, end); -+ } -+ } -+} -+#endif -+ - /* Flush video activity to the caches */ - int video_sync(struct udevice *vid, bool force) - { -@@ -424,11 +459,7 @@ int video_sync(struct udevice *vid, bool force) - * out whether it exists? For now, ARM is safe. - */ - #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) -- if (priv->flush_dcache) { -- flush_dcache_range((ulong)priv->fb, -- ALIGN((ulong)priv->fb + priv->fb_size, -- CONFIG_SYS_CACHELINE_SIZE)); -- } -+ video_flush_dcache(vid); - #elif defined(CONFIG_VIDEO_SANDBOX_SDL) - sandbox_sdl_sync(priv->fb); - #endif --- -2.48.1 - -From d0c47756db0fbd0c50d4cbc377a35af7133493f3 Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Sat, 25 May 2024 12:18:41 +0100 -Subject: [PATCH 11/13] video: Use VIDEO_DAMAGE for VIDEO_COPY - -CONFIG_VIDEO_COPY implemented a range-based copying mechanism: If we -print a single character, it will always copy the full range of bytes -from the top left corner of the character to the lower right onto the -uncached frame buffer. This includes pretty much the full line contents -of the printed character. - -Since we now have proper damage tracking, let's make use of that to reduce -the amount of data we need to copy. With this patch applied, we will only -copy the tiny rectangle surrounding characters when we print them, -speeding up the video console. - -After this, changes to the main frame buffer are not immediately copied -to the copy frame buffer, but postponed until the next video device -sync. So issue an explicit sync before inspecting the copy frame buffer -contents for the video tests. - -Signed-off-by: Alexander Graf -[Alper: Rebase for fontdata->height/w, fill_part(), fix memmove(dev), - drop from defconfig, use damage.xstart/yend, use IS_ENABLED(), - call video_sync() before copy_fb check, update video_copy test] -Co-developed-by: Alper Nebi Yasak -Signed-off-by: Alper Nebi Yasak -Signed-off-by: Peter Robinson ---- - configs/sandbox_defconfig | 1 - - drivers/video/Kconfig | 5 ++ - drivers/video/console_normal.c | 13 +---- - drivers/video/console_rotate.c | 44 +++----------- - drivers/video/console_truetype.c | 16 +---- - drivers/video/vidconsole-uclass.c | 16 ----- - drivers/video/video-uclass.c | 97 ++++++++----------------------- - drivers/video/video_bmp.c | 7 --- - include/video.h | 37 ------------ - include/video_console.h | 52 ----------------- - test/dm/video.c | 3 +- - 11 files changed, 43 insertions(+), 248 deletions(-) - -diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig -index d9e5ac6af48..7b35ad8a88f 100644 ---- a/configs/sandbox_defconfig -+++ b/configs/sandbox_defconfig -@@ -328,7 +328,6 @@ CONFIG_USB_ETH_CDC=y - CONFIG_VIDEO=y - CONFIG_VIDEO_FONT_SUN12X22=y - CONFIG_VIDEO_COPY=y --CONFIG_VIDEO_DAMAGE=y - CONFIG_CONSOLE_ROTATION=y - CONFIG_CONSOLE_TRUETYPE=y - CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 5d67067891b..964174b01ac 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -89,11 +89,14 @@ config VIDEO_PCI_DEFAULT_FB_SIZE - - config VIDEO_COPY - bool "Enable copying the frame buffer to a hardware copy" -+ select VIDEO_DAMAGE - help - On some machines (e.g. x86), reading from the frame buffer is very - slow because it is uncached. To improve performance, this feature - allows the frame buffer to be kept in cached memory (allocated by - U-Boot) and then copied to the hardware frame-buffer as needed. -+ It uses the VIDEO_DAMAGE feature to keep track of regions to copy -+ and will only copy actually touched regions. - - To use this, your video driver must set @copy_base in - struct video_uc_plat. -@@ -111,6 +114,8 @@ config VIDEO_DAMAGE - regions of the frame buffer that were modified before, speeding up - screen refreshes significantly. - -+ It is also used by VIDEO_COPY to identify which regions changed. -+ - config BACKLIGHT_PWM - bool "Generic PWM based Backlight Driver" - depends on BACKLIGHT && DM_PWM -diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c -index 51ac8cc78e9..07db613ac53 100644 ---- a/drivers/video/console_normal.c -+++ b/drivers/video/console_normal.c -@@ -35,10 +35,6 @@ static int console_set_row(struct udevice *dev, uint row, int clr) - fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); - end = dst; - -- ret = vidconsole_sync_copy(dev, line, end); -- if (ret) -- return ret; -- - video_damage(dev->parent, - 0, - fontdata->height * row, -@@ -57,14 +53,11 @@ static int console_move_rows(struct udevice *dev, uint rowdst, - void *dst; - void *src; - int size; -- int ret; - - dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length; - src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length; - size = fontdata->height * vid_priv->line_length * count; -- ret = vidconsole_memmove(dev, dst, src, size); -- if (ret) -- return ret; -+ memmove(dst, src, size); - - video_damage(dev->parent, - 0, -@@ -109,10 +102,6 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) - fontdata->width, - fontdata->height); - -- ret = vidconsole_sync_copy(dev, start, line); -- if (ret) -- return ret; -- - return VID_TO_POS(fontdata->width); - } - -diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c -index f11dc3a0b07..886b25dcfaf 100644 ---- a/drivers/video/console_rotate.c -+++ b/drivers/video/console_rotate.c -@@ -21,7 +21,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr) - int pbytes = VNBYTES(vid_priv->bpix); - void *start, *dst, *line; - int i, j; -- int ret; - - start = vid_priv->fb + vid_priv->line_length - - (row + 1) * fontdata->height * pbytes; -@@ -32,9 +31,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr) - fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); - line += vid_priv->line_length; - } -- ret = vidconsole_sync_copy(dev, start, line); -- if (ret) -- return ret; - - video_damage(dev->parent, - vid_priv->xsize - ((row + 1) * fontdata->height), -@@ -54,7 +50,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc, - int pbytes = VNBYTES(vid_priv->bpix); - void *dst; - void *src; -- int j, ret; -+ int j; - - dst = vid_priv->fb + vid_priv->line_length - - (rowdst + count) * fontdata->height * pbytes; -@@ -62,10 +58,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc, - (rowsrc + count) * fontdata->height * pbytes; - - for (j = 0; j < vid_priv->ysize; j++) { -- ret = vidconsole_memmove(dev, dst, src, -- fontdata->height * pbytes * count); -- if (ret) -- return ret; -+ memmove(dst, src, fontdata->height * pbytes * count); - src += vid_priv->line_length; - dst += vid_priv->line_length; - } -@@ -105,10 +98,6 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp) - return ret; - - /* We draw backwards from 'start, so account for the first line */ -- ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line); -- if (ret) -- return ret; -- - video_damage(dev->parent, - vid_priv->xsize - y - fontdata->height, - linenum - 1, -@@ -125,7 +114,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr) - struct video_fontdata *fontdata = priv->fontdata; - void *start, *line, *dst, *end; - int pixels = fontdata->height * vid_priv->xsize; -- int i, ret; -+ int i; - int pbytes = VNBYTES(vid_priv->bpix); - - start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length - -@@ -135,9 +124,6 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr) - for (i = 0; i < pixels; i++) - fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); - end = dst; -- ret = vidconsole_sync_copy(dev, start, end); -- if (ret) -- return ret; - - video_damage(dev->parent, - 0, -@@ -163,8 +149,7 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc, - vid_priv->line_length; - src = end - (rowsrc + count) * fontdata->height * - vid_priv->line_length; -- vidconsole_memmove(dev, dst, src, -- fontdata->height * vid_priv->line_length * count); -+ memmove(dst, src, fontdata->height * vid_priv->line_length * count); - - video_damage(dev->parent, - 0, -@@ -200,11 +185,6 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp) - if (ret) - return ret; - -- /* Add 4 bytes to allow for the first pixel writen */ -- ret = vidconsole_sync_copy(dev, start + 4, line); -- if (ret) -- return ret; -- - video_damage(dev->parent, - x - fontdata->width + 1, - linenum - fontdata->height + 1, -@@ -221,7 +201,7 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr) - struct video_fontdata *fontdata = priv->fontdata; - int pbytes = VNBYTES(vid_priv->bpix); - void *start, *dst, *line; -- int i, j, ret; -+ int i, j; - - start = vid_priv->fb + row * fontdata->height * pbytes; - line = start; -@@ -231,9 +211,6 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr) - fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); - line += vid_priv->line_length; - } -- ret = vidconsole_sync_copy(dev, start, line); -- if (ret) -- return ret; - - video_damage(dev->parent, - row * fontdata->height, -@@ -253,16 +230,13 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc, - int pbytes = VNBYTES(vid_priv->bpix); - void *dst; - void *src; -- int j, ret; -+ int j; - - dst = vid_priv->fb + rowdst * fontdata->height * pbytes; - src = vid_priv->fb + rowsrc * fontdata->height * pbytes; - - for (j = 0; j < vid_priv->ysize; j++) { -- ret = vidconsole_memmove(dev, dst, src, -- fontdata->height * pbytes * count); -- if (ret) -- return ret; -+ memmove(dst, src, fontdata->height * pbytes * count); - src += vid_priv->line_length; - dst += vid_priv->line_length; - } -@@ -298,10 +272,6 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp) - line = start; - - ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION); -- if (ret) -- return ret; -- /* Add a line to allow for the first pixels writen */ -- ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line); - if (ret) - return ret; - -diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c -index 073ddcfb695..0dfd7914dc1 100644 ---- a/drivers/video/console_truetype.c -+++ b/drivers/video/console_truetype.c -@@ -194,7 +194,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) - struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_metrics *met = priv->cur_met; - void *end, *line; -- int ret; - - line = vid_priv->fb + row * met->font_size * vid_priv->line_length; - end = line + met->font_size * vid_priv->line_length; -@@ -230,9 +229,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) - default: - return -ENOSYS; - } -- ret = vidconsole_sync_copy(dev, line, end); -- if (ret) -- return ret; - - video_damage(dev->parent, - 0, -@@ -252,14 +248,11 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, - struct console_tt_metrics *met = priv->cur_met; - void *dst; - void *src; -- int i, diff, ret; -+ int i, diff; - - dst = vid_priv->fb + rowdst * met->font_size * vid_priv->line_length; - src = vid_priv->fb + rowsrc * met->font_size * vid_priv->line_length; -- ret = vidconsole_memmove(dev, dst, src, met->font_size * -- vid_priv->line_length * count); -- if (ret) -- return ret; -+ memmove(dst, src, met->font_size * vid_priv->line_length * count); - - /* Scroll up our position history */ - diff = (rowsrc - rowdst) * met->font_size; -@@ -292,7 +285,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, - u8 *bits, *data; - int advance; - void *start, *end, *line; -- int row, ret; -+ int row; - - /* First get some basic metrics about this character */ - stbtt_GetCodepointHMetrics(font, cp, &advance, &lsb); -@@ -439,9 +432,6 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, - width, - height); - -- ret = vidconsole_sync_copy(dev, start, line); -- if (ret) -- return ret; - free(data); - - return width_frac; -diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c -index ebe96bf0c2f..a1dfd35b7b8 100644 ---- a/drivers/video/vidconsole-uclass.c -+++ b/drivers/video/vidconsole-uclass.c -@@ -761,22 +761,6 @@ UCLASS_DRIVER(vidconsole) = { - .per_device_auto = sizeof(struct vidconsole_priv), - }; - --#ifdef CONFIG_VIDEO_COPY --int vidconsole_sync_copy(struct udevice *dev, void *from, void *to) --{ -- struct udevice *vid = dev_get_parent(dev); -- -- return video_sync_copy(vid, from, to); --} -- --int vidconsole_memmove(struct udevice *dev, void *dst, const void *src, -- int size) --{ -- memmove(dst, src, size); -- return vidconsole_sync_copy(dev, dst, dst + size); --} --#endif -- - int vidconsole_clear_and_reset(struct udevice *dev) - { - int ret; -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 6452ff5039e..a828e67341b 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -171,7 +171,7 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, - struct video_priv *priv = dev_get_uclass_priv(dev); - void *start, *line; - int pixels = xend - xstart; -- int row, i, ret; -+ int row, i; - - start = priv->fb + ystart * priv->line_length; - start += xstart * VNBYTES(priv->bpix); -@@ -211,10 +211,6 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, - line += priv->line_length; - } - -- ret = video_sync_copy(dev, start, line); -- if (ret) -- return ret; -- - video_damage(dev, xstart, ystart, xend - xstart, yend - ystart); - - return 0; -@@ -236,7 +232,6 @@ int video_reserve_from_bloblist(struct video_handoff *ho) - int video_fill(struct udevice *dev, u32 colour) - { - struct video_priv *priv = dev_get_uclass_priv(dev); -- int ret; - - switch (priv->bpix) { - case VIDEO_BPP16: -@@ -261,9 +256,6 @@ int video_fill(struct udevice *dev, u32 colour) - memset(priv->fb, colour, priv->fb_size); - break; - } -- ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size); -- if (ret) -- return ret; - - video_damage(dev, 0, 0, priv->xsize, priv->ysize); - -@@ -436,6 +428,27 @@ static void video_flush_dcache(struct udevice *vid) - } - #endif - -+static void video_flush_copy(struct udevice *vid) -+{ -+ struct video_priv *priv = dev_get_uclass_priv(vid); -+ -+ if (!priv->copy_fb) -+ return; -+ -+ if (priv->damage.xend && priv->damage.yend) { -+ int lstart = priv->damage.xstart * VNBYTES(priv->bpix); -+ int lend = priv->damage.xend * VNBYTES(priv->bpix); -+ int y; -+ -+ for (y = priv->damage.ystart; y < priv->damage.yend; y++) { -+ ulong offset = (y * priv->line_length) + lstart; -+ ulong len = lend - lstart; -+ -+ memcpy(priv->copy_fb + offset, priv->fb + offset, len); -+ } -+ } -+} -+ - /* Flush video activity to the caches */ - int video_sync(struct udevice *vid, bool force) - { -@@ -443,6 +456,9 @@ int video_sync(struct udevice *vid, bool force) - struct video_ops *ops = video_get_ops(vid); - int ret; - -+ if (IS_ENABLED(CONFIG_VIDEO_COPY)) -+ video_flush_copy(vid); -+ - if (ops && ops->video_sync) { - ret = ops->video_sync(vid); - if (ret) -@@ -524,69 +540,6 @@ int video_get_ysize(struct udevice *dev) - return priv->ysize; - } - --#ifdef CONFIG_VIDEO_COPY --int video_sync_copy(struct udevice *dev, void *from, void *to) --{ -- struct video_priv *priv = dev_get_uclass_priv(dev); -- -- if (priv->copy_fb) { -- long offset, size; -- -- /* Find the offset of the first byte to copy */ -- if ((ulong)to > (ulong)from) { -- size = to - from; -- offset = from - priv->fb; -- } else { -- size = from - to; -- offset = to - priv->fb; -- } -- -- /* -- * Allow a bit of leeway for valid requests somewhere near the -- * frame buffer -- */ -- if (offset < -priv->fb_size || offset > 2 * priv->fb_size) { --#ifdef DEBUG -- char str[120]; -- -- snprintf(str, sizeof(str), -- "[** FAULT sync_copy fb=%p, from=%p, to=%p, offset=%lx]", -- priv->fb, from, to, offset); -- console_puts_select_stderr(true, str); --#endif -- return -EFAULT; -- } -- -- /* -- * Silently crop the memcpy. This allows callers to avoid doing -- * this themselves. It is common for the end pointer to go a -- * few lines after the end of the frame buffer, since most of -- * the update algorithms terminate a line after their last write -- */ -- if (offset + size > priv->fb_size) { -- size = priv->fb_size - offset; -- } else if (offset < 0) { -- size += offset; -- offset = 0; -- } -- -- memcpy(priv->copy_fb + offset, priv->fb + offset, size); -- } -- -- return 0; --} -- --int video_sync_copy_all(struct udevice *dev) --{ -- struct video_priv *priv = dev_get_uclass_priv(dev); -- -- video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size); -- -- return 0; --} -- --#endif -- - #define SPLASH_DECL(_name) \ - extern u8 __splash_ ## _name ## _begin[]; \ - extern u8 __splash_ ## _name ## _end[] -diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c -index 78de9560792..1f267d45812 100644 ---- a/drivers/video/video_bmp.c -+++ b/drivers/video/video_bmp.c -@@ -267,7 +267,6 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, - enum video_format eformat; - struct bmp_color_table_entry *palette; - int hdr_size; -- int ret; - - if (!bmp || !(bmp->header.signature[0] == 'B' && - bmp->header.signature[1] == 'M')) { -@@ -461,11 +460,5 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, - - video_damage(dev, x, y, width, height); - -- /* Find the position of the top left of the image in the framebuffer */ -- fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8); -- ret = video_sync_copy(dev, start, fb); -- if (ret) -- return log_ret(ret); -- - return video_sync(dev, false); - } -diff --git a/include/video.h b/include/video.h -index 92aa5da4ff3..26327473738 100644 ---- a/include/video.h -+++ b/include/video.h -@@ -355,43 +355,6 @@ void video_set_default_colors(struct udevice *dev, bool invert); - */ - int video_default_font_height(struct udevice *dev); - --#ifdef CONFIG_VIDEO_COPY --/** -- * vidconsole_sync_copy() - Sync back to the copy framebuffer -- * -- * This ensures that the copy framebuffer has the same data as the framebuffer -- * for a particular region. It should be called after the framebuffer is updated -- * -- * @from and @to can be in either order. The region between them is synced. -- * -- * @dev: Vidconsole device being updated -- * @from: Start/end address within the framebuffer (->fb) -- * @to: Other address within the frame buffer -- * Return: 0 if OK, -EFAULT if the start address is before the start of the -- * frame buffer start -- */ --int video_sync_copy(struct udevice *dev, void *from, void *to); -- --/** -- * video_sync_copy_all() - Sync the entire framebuffer to the copy -- * -- * @dev: Vidconsole device being updated -- * Return: 0 (always) -- */ --int video_sync_copy_all(struct udevice *dev); --#else --static inline int video_sync_copy(struct udevice *dev, void *from, void *to) --{ -- return 0; --} -- --static inline int video_sync_copy_all(struct udevice *dev) --{ -- return 0; --} -- --#endif -- - /** - * video_damage() - Notify the video subsystem about screen updates. - * -diff --git a/include/video_console.h b/include/video_console.h -index 723d2315606..13197fa4518 100644 ---- a/include/video_console.h -+++ b/include/video_console.h -@@ -537,56 +537,4 @@ void vidconsole_list_fonts(struct udevice *dev); - */ - int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep); - --#ifdef CONFIG_VIDEO_COPY --/** -- * vidconsole_sync_copy() - Sync back to the copy framebuffer -- * -- * This ensures that the copy framebuffer has the same data as the framebuffer -- * for a particular region. It should be called after the framebuffer is updated -- * -- * @from and @to can be in either order. The region between them is synced. -- * -- * @dev: Vidconsole device being updated -- * @from: Start/end address within the framebuffer (->fb) -- * @to: Other address within the frame buffer -- * Return: 0 if OK, -EFAULT if the start address is before the start of the -- * frame buffer start -- */ --int vidconsole_sync_copy(struct udevice *dev, void *from, void *to); -- --/** -- * vidconsole_memmove() - Perform a memmove() within the frame buffer -- * -- * This handles a memmove(), e.g. for scrolling. It also updates the copy -- * framebuffer. -- * -- * @dev: Vidconsole device being updated -- * @dst: Destination address within the framebuffer (->fb) -- * @src: Source address within the framebuffer (->fb) -- * @size: Number of bytes to transfer -- * Return: 0 if OK, -EFAULT if the start address is before the start of the -- * frame buffer start -- */ --int vidconsole_memmove(struct udevice *dev, void *dst, const void *src, -- int size); --#else -- --#include -- --static inline int vidconsole_sync_copy(struct udevice *dev, void *from, -- void *to) --{ -- return 0; --} -- --static inline int vidconsole_memmove(struct udevice *dev, void *dst, -- const void *src, int size) --{ -- memmove(dst, src, size); -- -- return 0; --} -- --#endif -- - #endif -diff --git a/test/dm/video.c b/test/dm/video.c -index 9da00be5479..eda1195d3b9 100644 ---- a/test/dm/video.c -+++ b/test/dm/video.c -@@ -105,6 +105,7 @@ static int check_copy_frame_buffer(struct unit_test_state *uts, - if (!IS_ENABLED(CONFIG_VIDEO_COPY)) - return 0; - -+ video_sync(dev, false); - ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size), - "Copy framebuffer does not match fb"); - -@@ -705,7 +706,7 @@ static int dm_test_video_copy(struct unit_test_state *uts) - vidconsole_put_string(con, test_string); - vidconsole_put_string(con, test_string); - ut_asserteq(7589, compress_frame_buffer(uts, dev, false)); -- ut_asserteq(5278, compress_frame_buffer(uts, dev, true)); -+ ut_asserteq(4127, compress_frame_buffer(uts, dev, true)); - - return 0; - } --- -2.48.1 - -From 3fb044255ec50a026195586ced9e53499d701254 Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Tue, 18 Feb 2025 21:57:38 +0000 -Subject: [PATCH 12/13] video: Always compile cache flushing code - -The dcache flushing code path was conditional on ARM && !DCACHE config -options. However, dcaches exist on other platforms as well and may need -clearing if their driver requires it. - -Simplify the compile logic and always enable the dcache flush logic in -the video core. That way, drivers can always rely on it to call the arch -specific callbacks. - -This will increase code size for non-ARM platforms with CONFIG_VIDEO=y -slightly. - -Reported-by: Heinrich Schuchardt -Signed-off-by: Alexander Graf -Reviewed-by: Simon Glass -Signed-off-by: Alper Nebi Yasak -Signed-off-by: Peter Robinson ---- - drivers/video/video-uclass.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index a828e67341b..c566931a050 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -393,11 +393,13 @@ void video_damage(struct udevice *vid, int x, int y, int width, int height) - priv->damage.yend = max(yend, priv->damage.yend); - } - --#if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) - static void video_flush_dcache(struct udevice *vid) - { - struct video_priv *priv = dev_get_uclass_priv(vid); - -+ if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) -+ return; -+ - if (!priv->flush_dcache) - return; - -@@ -426,7 +428,6 @@ static void video_flush_dcache(struct udevice *vid) - } - } - } --#endif - - static void video_flush_copy(struct udevice *vid) - { -@@ -469,14 +470,9 @@ int video_sync(struct udevice *vid, bool 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) - video_flush_dcache(vid); --#elif defined(CONFIG_VIDEO_SANDBOX_SDL) -+ -+#if defined(CONFIG_VIDEO_SANDBOX_SDL) - sandbox_sdl_sync(priv->fb); - #endif - --- -2.48.1 - -From 7d1ef5a8dafc5e95d5db753010f53880f49e979e Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 21 Aug 2023 16:51:10 +0300 -Subject: [PATCH 13/13] video: Enable VIDEO_DAMAGE for drivers that need it - -Some drivers call video_set_flush_dcache() to indicate that they want to -have the dcache flushed for the frame buffer. These drivers benefit from -our new video damage control, because we can reduce the amount of memory -that gets flushed significantly. - -This patch enables video damage control for all device drivers that call -video_set_flush_dcache() to make sure they benefit from it. - -Signed-off-by: Alexander Graf -[Alper: Add to VIDEO_TIDSS, imply instead of select] -Co-developed-by: Alper Nebi Yasak -Signed-off-by: Alper Nebi Yasak -Reviewed-by: Simon Glass ---- - arch/arm/mach-sunxi/Kconfig | 1 + - drivers/video/Kconfig | 8 ++++++++ - drivers/video/exynos/Kconfig | 1 + - drivers/video/imx/Kconfig | 1 + - drivers/video/meson/Kconfig | 1 + - drivers/video/rockchip/Kconfig | 1 + - drivers/video/stm32/Kconfig | 1 + - drivers/video/tegra20/Kconfig | 1 + - drivers/video/tidss/Kconfig | 1 + - 9 files changed, 16 insertions(+) - -diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig -index ba1b1541437..bb1ea961704 100644 ---- a/arch/arm/mach-sunxi/Kconfig -+++ b/arch/arm/mach-sunxi/Kconfig -@@ -882,6 +882,7 @@ config VIDEO_SUNXI - depends on !SUNXI_GEN_NCAT2 - select VIDEO - select DISPLAY -+ imply VIDEO_DAMAGE - imply VIDEO_DT_SIMPLEFB - default y - ---help--- -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 964174b01ac..6e1577ae687 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -534,6 +534,7 @@ config VIDEO_LCD_ANX9804 - - config ATMEL_LCD - bool "Atmel LCD panel support" -+ imply VIDEO_DAMAGE - depends on ARCH_AT91 - - config ATMEL_LCD_BGR555 -@@ -543,6 +544,7 @@ config ATMEL_LCD_BGR555 - - config VIDEO_BCM2835 - bool "Display support for BCM2835" -+ imply VIDEO_DAMAGE - help - The graphics processor already sets up the display so this driver - simply checks the resolution and then sets up the frame buffer with -@@ -715,6 +717,7 @@ source "drivers/video/meson/Kconfig" - - config VIDEO_MVEBU - bool "Armada XP LCD controller" -+ imply VIDEO_DAMAGE - ---help--- - Support for the LCD controller integrated in the Marvell - Armada XP SoC. -@@ -749,6 +752,7 @@ config NXP_TDA19988 - - config ATMEL_HLCD - bool "Enable ATMEL video support using HLCDC" -+ imply VIDEO_DAMAGE - help - HLCDC supports video output to an attached LCD panel. - -@@ -825,6 +829,7 @@ source "drivers/video/tidss/Kconfig" - - config VIDEO_TEGRA124 - bool "Enable video support on Tegra124" -+ imply VIDEO_DAMAGE - help - Tegra124 supports many video output options including eDP and - HDMI. At present only eDP is supported by U-Boot. This option -@@ -839,6 +844,7 @@ source "drivers/video/imx/Kconfig" - - config VIDEO_MXS - bool "Enable video support on i.MX28/i.MX6UL/i.MX7 SoCs" -+ imply VIDEO_DAMAGE - help - Enable framebuffer driver for i.MX28/i.MX6UL/i.MX7 processors - -@@ -901,6 +907,7 @@ config VIDEO_DW_MIPI_DSI - - config VIDEO_SIMPLE - bool "Simple display driver for preconfigured display" -+ imply VIDEO_DAMAGE - help - Enables a simple generic display driver which utilizes the - simple-framebuffer devicetree bindings. -@@ -919,6 +926,7 @@ config VIDEO_DT_SIMPLEFB - - config VIDEO_MCDE_SIMPLE - bool "Simple driver for ST-Ericsson MCDE with preconfigured display" -+ imply VIDEO_DAMAGE - help - Enables a simple display driver for ST-Ericsson MCDE - (Multichannel Display Engine), which reads the configuration from -diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig -index 599d19d5ecc..a2cf752aac0 100644 ---- a/drivers/video/exynos/Kconfig -+++ b/drivers/video/exynos/Kconfig -@@ -12,6 +12,7 @@ config EXYNOS_DP - - config EXYNOS_FB - bool "Exynos FIMD support" -+ imply VIDEO_DAMAGE - - config EXYNOS_MIPI_DSIM - bool "Exynos MIPI DSI support" -diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig -index 34e8b640595..5db3e5c0499 100644 ---- a/drivers/video/imx/Kconfig -+++ b/drivers/video/imx/Kconfig -@@ -2,6 +2,7 @@ - config VIDEO_IPUV3 - bool "i.MX IPUv3 Core video support" - depends on VIDEO && (MX5 || MX6) -+ imply VIDEO_DAMAGE - help - This enables framebuffer driver for i.MX processors working - on the IPUv3(Image Processing Unit) internal graphic processor. -diff --git a/drivers/video/meson/Kconfig b/drivers/video/meson/Kconfig -index 3c2d72d019b..fcf486ca0a3 100644 ---- a/drivers/video/meson/Kconfig -+++ b/drivers/video/meson/Kconfig -@@ -8,5 +8,6 @@ config VIDEO_MESON - bool "Enable Amlogic Meson video support" - depends on VIDEO - select DISPLAY -+ imply VIDEO_DAMAGE - help - Enable Amlogic Meson Video Processing Unit video support. -diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig -index 01804dcb1cc..0f4550a29e3 100644 ---- a/drivers/video/rockchip/Kconfig -+++ b/drivers/video/rockchip/Kconfig -@@ -11,6 +11,7 @@ - menuconfig VIDEO_ROCKCHIP - bool "Enable Rockchip Video Support" - depends on VIDEO -+ imply VIDEO_DAMAGE - help - Rockchip SoCs provide video output capabilities for High-Definition - Multimedia Interface (HDMI), Low-voltage Differential Signalling -diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig -index 48066063e4c..c354c402c28 100644 ---- a/drivers/video/stm32/Kconfig -+++ b/drivers/video/stm32/Kconfig -@@ -8,6 +8,7 @@ - menuconfig VIDEO_STM32 - bool "Enable STM32 video support" - depends on VIDEO -+ imply VIDEO_DAMAGE - help - STM32 supports many video output options including RGB and - DSI. This option enables these supports which can be used on -diff --git a/drivers/video/tegra20/Kconfig b/drivers/video/tegra20/Kconfig -index f5c4843e119..2232b0b3ff5 100644 ---- a/drivers/video/tegra20/Kconfig -+++ b/drivers/video/tegra20/Kconfig -@@ -1,6 +1,7 @@ - config VIDEO_TEGRA20 - bool "Enable Display Controller support on Tegra20 and Tegra 30" - depends on OF_CONTROL -+ imply VIDEO_DAMAGE - help - T20/T30 support video output to an attached LCD panel as well as - other options such as HDMI. Only the LCD is supported in U-Boot. -diff --git a/drivers/video/tidss/Kconfig b/drivers/video/tidss/Kconfig -index 95086f3a5d6..3291b3ceb8d 100644 ---- a/drivers/video/tidss/Kconfig -+++ b/drivers/video/tidss/Kconfig -@@ -11,6 +11,7 @@ - menuconfig VIDEO_TIDSS - bool "Enable TIDSS video support" - depends on VIDEO -+ imply VIDEO_DAMAGE - help - TIDSS supports video output options LVDS and - DPI . This option enables these supports which can be used on --- -2.48.1 - diff --git a/Initial-MNT-Reform2-support.patch b/Initial-MNT-Reform2-support.patch new file mode 100644 index 0000000..c91d3fe --- /dev/null +++ b/Initial-MNT-Reform2-support.patch @@ -0,0 +1,980 @@ +From bcce96109c2fc3e8ed9e2ba12f1cbff43c0bd3c5 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Fri, 20 Jun 2025 17:45:02 +0100 +Subject: [PATCH 1/2] Initial MNT Reform2 support + +--- + arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi | 20 + + board/rockchip/evb_rk3588/MAINTAINERS | 6 + + configs/mnt-reform2-rk3588_defconfig | 93 ++++ + .../rockchip/rk3588-firefly-icore-3588q.dtsi | 443 ++++++++++++++++++ + .../src/arm64/rockchip/rk3588-mnt-reform2.dts | 336 +++++++++++++ + 5 files changed, 898 insertions(+) + create mode 100644 arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi + create mode 100644 configs/mnt-reform2-rk3588_defconfig + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-firefly-icore-3588q.dtsi + create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts + +diff --git a/arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi b/arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi +new file mode 100644 +index 00000000000..afd33dd3248 +--- /dev/null ++++ b/arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3588-u-boot.dtsi" ++ ++&fspim2_pins { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&sdhci { ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++}; ++ ++&sfc { ++ flash@0 { ++ bootph-pre-ram; ++ bootph-some-ram; ++ }; ++}; +diff --git a/board/rockchip/evb_rk3588/MAINTAINERS b/board/rockchip/evb_rk3588/MAINTAINERS +index 1232f05a387..24cf13c3c48 100644 +--- a/board/rockchip/evb_rk3588/MAINTAINERS ++++ b/board/rockchip/evb_rk3588/MAINTAINERS +@@ -29,6 +29,12 @@ F: configs/generic-rk3588_defconfig + F: arch/arm/dts/rk3588-generic.dts + F: arch/arm/dts/rk3588-generic-u-boot.dtsi + ++MNT-REFORM2-RK3588 ++M: Peter Robinson ++S: Maintained ++F: configs/mnt-reform2-rk3588_defconfig ++F: arch/arm/dts/rk3588-mnt-reform2-u-boot.dtsi ++ + ORANGEPI-5-RK3588 + M: Jonas Karlman + S: Maintained +diff --git a/configs/mnt-reform2-rk3588_defconfig b/configs/mnt-reform2-rk3588_defconfig +new file mode 100644 +index 00000000000..e12c48af70a +--- /dev/null ++++ b/configs/mnt-reform2-rk3588_defconfig +@@ -0,0 +1,93 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SF_DEFAULT_SPEED=24000000 ++CONFIG_SF_DEFAULT_MODE=0x2000 ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588-mnt-reform2" ++CONFIG_ROCKCHIP_RK3588=y ++CONFIG_ROCKCHIP_SPI_IMAGE=y ++CONFIG_SPL_SERIAL=y ++CONFIG_TARGET_EVB_RK3588=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_SF_DEFAULT_BUS=5 ++CONFIG_DEBUG_UART_BASE=0xFEB50000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI=y ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-mnt-reform2" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_MAX_SIZE=0x40000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_SPI_LOAD=y ++CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 ++CONFIG_SPL_ATF=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_SPL_DM_SEQ_ALIAS=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_SPL_CLK=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_HS400_ES_SUPPORT=y ++CONFIG_SPL_MMC_HS400_ES_SUPPORT=y ++CONFIG_MMC_HS400_SUPPORT=y ++CONFIG_SPL_MMC_HS400_SUPPORT=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_SPI_FLASH_SFDP_SUPPORT=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_PHYLIB=y ++CONFIG_RTL8169=y ++CONFIG_NVME_PCI=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_PHY_ROCKCHIP_USBDP=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_ROCKCHIP_SPI=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_ERRNO_STR=y +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-firefly-icore-3588q.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-firefly-icore-3588q.dtsi +new file mode 100644 +index 00000000000..6726eeb4925 +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-firefly-icore-3588q.dtsi +@@ -0,0 +1,443 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include ++#include ++ ++#include "rk3588.dtsi" ++ ++/ { ++ compatible = "firefly,icore-3588q", "rockchip,rk3588"; ++ ++ aliases { ++ mmc0 = &sdhci; ++ }; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_big0_s0>; ++}; ++ ++&cpu_b2 { ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++&cpu_b3 { ++ cpu-supply = <&vdd_cpu_big1_s0>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_lit_s0>; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0m2_xfer>; ++ status = "okay"; ++ ++ vdd_cpu_big0_s0: regulator@42 { ++ compatible = "rockchip,rk8602"; ++ reg = <0x42>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-name = "vdd_cpu_big0_s0"; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_big1_s0: regulator@43 { ++ compatible = "rockchip,rk8603", "rockchip,rk8602"; ++ reg = <0x43>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-name = "vdd_cpu_big1_s0"; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1m2_xfer>; ++ status = "okay"; ++ ++ vdd_npu_s0: vdd_npu_mem_s0: regulator@42 { ++ compatible = "rockchip,rk8602"; ++ reg = <0x42>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-name = "vdd_npu_s0"; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ no-sdio; ++ no-sd; ++ non-removable; ++ max-frequency = <150000000>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ status = "okay"; ++}; ++ ++&spi2 { ++ assigned-clocks = <&cru CLK_SPI2>; ++ assigned-clock-rates = <200000000>; ++ num-cs = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; ++ status = "okay"; ++ ++ pmic@0 { ++ compatible = "rockchip,rk806"; ++ reg = <0x0>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, ++ <&rk806_dvs2_null>, <&rk806_dvs3_null>; ++ spi-max-frequency = <1000000>; ++ system-power-controller; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc5v0_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc_2v0_pldo_s3>; ++ vcc12-supply = <&vcc5v0_sys>; ++ vcc13-supply = <&vcc_1v1_nldo_s3>; ++ vcc14-supply = <&vcc_1v1_nldo_s3>; ++ vcca-supply = <&vcc5v0_sys>; ++ ++ rk806_dvs1_null: dvs1-null-pins { ++ pins = "gpio_pwrctrl1"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs2_null: dvs2-null-pins { ++ pins = "gpio_pwrctrl2"; ++ function = "pin_fun0"; ++ }; ++ ++ rk806_dvs3_null: dvs3-null-pins { ++ pins = "gpio_pwrctrl3"; ++ function = "pin_fun0"; ++ }; ++ ++ regulators { ++ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_gpu_s0"; ++ regulator-enable-ramp-delay = <400>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_cpu_lit_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_log_s0: dcdc-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <750000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_log_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <550000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_vdenc_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_ddr_s0: dcdc-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <675000>; ++ regulator-max-microvolt = <950000>; ++ regulator-ramp-delay = <12500>; ++ regulator-name = "vdd_ddr_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <850000>; ++ }; ++ }; ++ ++ vdd2_ddr_s3: dcdc-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vdd2_ddr_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_2v0_pldo_s3: dcdc-reg7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2000000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-name = "vdd_2v0_pldo_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <2000000>; ++ }; ++ }; ++ ++ vcc_3v3_s3: dcdc-reg8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc_3v3_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vddq_ddr_s0: dcdc-reg9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vddq_ddr_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_s3: dcdc-reg10 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc_1v8_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ avcc_1v8_s0: pldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "avcc_1v8_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8_s0: pldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc_1v8_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ avdd_1v2_s0: pldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-name = "avdd_1v2_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3_s0: pldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc_3v3_s0"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vccio_sd_s0: pldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vccio_sd_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ pldo6_s3: pldo-reg6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "pldo6_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_0v75_s3: nldo-reg1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "vdd_0v75_s3"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_ddr_pll_s0: nldo-reg2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdd_ddr_pll_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <850000>; ++ }; ++ }; ++ ++ avdd_0v75_s0: nldo-reg3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "avdd_0v75_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_0v85_s0: nldo-reg4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <850000>; ++ regulator-max-microvolt = <850000>; ++ regulator-name = "vdd_0v85_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_0v75_s0: nldo-reg5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "vdd_0v75_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&uart2 { ++ pinctrl-0 = <&uart2m0_xfer>; ++ status = "okay"; ++}; +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts b/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts +new file mode 100644 +index 00000000000..78a4e896f66 +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts +@@ -0,0 +1,336 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd. ++ * Copyright (c) 2024 MNT Research GmbH ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "rk3588-firefly-icore-3588q.dtsi" ++ ++/ { ++ model = "MNT Reform 2 with RCORE RK3588 Module"; ++ compatible = "mntre,reform2-rcore", "firefly,icore-3588q", "rockchip,rk3588"; ++ chassis-type = "laptop"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ mmc1 = &sdmmc; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ brightness-levels = <0 8 16 32 64 128 160 200 255>; ++ default-brightness-level = <128>; ++ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; ++ pwms = <&pwm8 0 10000 0>; ++ }; ++ ++ gmac0_clkin: external-gmac0-clock { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac0_clkin"; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "pcie30_avdd1v8"; ++ vin-supply = <&avcc_1v8_s0>; ++ }; ++ ++ pcie30_avdd0v75: regulator-pcie30-avdd0v75 { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <750000>; ++ regulator-name = "pcie30_avdd0v75"; ++ vin-supply = <&avdd_0v75_s0>; ++ }; ++ ++ vcc12v_dcin: regulator-vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ regulator-name = "vcc12v_dcin"; ++ }; ++ ++ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_1v1_nldo_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pcie30: regulator-vcc3v3-pcie30 { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc3v3_pcie30"; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc5v0_host: regulator-vcc5v0-host { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vcc5v0_host"; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vcc5v0_sys"; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc5v0_usb: regulator-vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vcc5v0_usb"; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++}; ++ ++&combphy0_ps { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus ++ &gmac0_clkinout ++ ð_phy_reset>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu_s0>; ++ sram-supply = <&vdd_gpu_mem_s0>; ++ status = "okay"; ++}; ++ ++&hdmi0 { ++ status = "okay"; ++}; ++ ++&hdmi0_in { ++ hdmi0_in_vp2: endpoint { ++ remote-endpoint = <&vp2_out_hdmi0>; ++ }; ++}; ++ ++&hdptxphy0 { ++ status = "okay"; ++}; ++ ++&i2c6 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c6m0_xfer>; ++ status = "okay"; ++ ++ rtc@68 { ++ compatible = "nxp,pcf8523"; ++ reg = <0x68>; ++ }; ++}; ++ ++&mdio0 { ++ rgmii_phy: ethernet-phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x0>; ++ }; ++}; ++ ++&pcie2x1l2 { ++ pinctrl-0 = <&pcie2_0_rst>; ++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ status = "okay"; ++}; ++ ++&pcie3x4 { ++ num-lanes = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie3_reset>; ++ reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pcie30>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ dp { ++ dp1_hpd: dp1-hpd { ++ rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie2 { ++ pcie2_0_rst: pcie2-0-rst { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie3 { ++ pcie3_reset: pcie3-reset { ++ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ eth_phy { ++ eth_phy_reset: eth-phy-reset { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pwm8 { ++ pinctrl-0 = <&pwm8m2_pins>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&avcc_1v8_s0>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ max-frequency = <40000000>; ++ no-1-8-v; ++ no-mmc; ++ no-sdio; ++ vmmc-supply = <&vcc3v3_pcie30>; ++ vqmmc-supply = <&vcc3v3_pcie30>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ status = "okay"; ++}; ++ ++&u2phy2 { ++ status = "okay"; ++}; ++ ++&u2phy2_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&u2phy3 { ++ status = "okay"; ++}; ++ ++&u2phy3_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usbdp_phy0 { ++ status = "okay"; ++}; ++ ++&usbdp_phy1 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp2 { ++ vp2_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi0_in_vp2>; ++ }; ++}; +-- +2.50.0 + +From e4eae92727e9c87b2fc8769666347c4b715dc81a Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Fri, 20 Jun 2025 17:56:32 +0100 +Subject: [PATCH 2/2] mnt: drop hdptxphy0 + +--- + dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts b/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts +index 78a4e896f66..c76dd271d1d 100644 +--- a/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts ++++ b/dts/upstream/src/arm64/rockchip/rk3588-mnt-reform2.dts +@@ -157,10 +157,6 @@ + }; + }; + +-&hdptxphy0 { +- status = "okay"; +-}; +- + &i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m0_xfer>; +-- +2.50.0 + diff --git a/0001-Rebase-to-upstream-6.15.5-rockchip-DTs.patch b/Rebase-to-upstream-6.15.5-rockchip-DTs.patch similarity index 100% rename from 0001-Rebase-to-upstream-6.15.5-rockchip-DTs.patch rename to Rebase-to-upstream-6.15.5-rockchip-DTs.patch diff --git a/p3450-fix-board.patch b/p3450-fix-board.patch new file mode 100644 index 0000000..a4bce81 --- /dev/null +++ b/p3450-fix-board.patch @@ -0,0 +1,139 @@ +From 00937cdf45286364c2acd7250f0900cb2c3dae86 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Tue, 8 Jul 2025 21:48:22 +0100 +Subject: [PATCH] p3450: reduce size of Jetson Nano u-boot.bin + +The Jetson Nano contains all it's firmware on a 4Mb SPI +flash, the allocated size in that flash for U-Boot is +753664 bytes so we need to ensure the u-boot.bin doesn't +exceed that else it will fail. + +Add a BOARD_SIZE_LIMIT and drop a few large, and somewhat +esoteric, options to bring us back under that limit. + +Signed-off-by: Peter Robinson +--- + configs/p3450-0000_defconfig | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig +index a002178b7fb..518ed6b37a2 100644 +--- a/configs/p3450-0000_defconfig ++++ b/configs/p3450-0000_defconfig +@@ -14,6 +14,8 @@ CONFIG_ENV_SECT_SIZE=0x1000 + CONFIG_DEFAULT_DEVICE_TREE="tegra210-p3450-0000" + CONFIG_SYS_BOOTM_LEN=0x800000 + CONFIG_SYS_LOAD_ADDR=0x80080000 ++CONFIG_HAS_BOARD_SIZE_LIMIT=y ++CONFIG_BOARD_SIZE_LIMIT=753664 + CONFIG_TEGRA210=y + CONFIG_TARGET_P3450_0000=y + CONFIG_TEGRA_GPU=y +@@ -24,8 +26,14 @@ CONFIG_SYS_PBSIZE=2089 + CONFIG_CONSOLE_MUX=y + CONFIG_SYS_STDIO_DEREGISTER=y + CONFIG_SYS_PROMPT="Tegra210 (P3450-0000) # " ++# CONFIG_BOOTM_RTEMS is not set ++# CONFIG_BOOTM_VXWORKS is not set ++# CONFIG_BOOTM_PLAN9 is not set + # CONFIG_CMD_IMI is not set ++# CONFIG_CRC32_VERIFY is not set + CONFIG_CMD_DFU=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_GO is not set + CONFIG_CMD_GPIO=y + CONFIG_CMD_I2C=y + CONFIG_CMD_MMC=y +-- +2.50.0 +From 60287cee71a5748d0036c356d16b85938f5bf9c8 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Wed, 9 Jul 2025 22:06:06 +0100 +Subject: [PATCH] p3450: fix Jetson Nano SPI flash + +The Nano's SPI flash stopped working in U-Boot, as the +prior stage loaded U-Boot, the only thing it was used +for was save/loading env vars so update the DT so it +can now initialise it. It also drops enabling the old +TEGRA114_SPI driver, as the flash hangs off the faster +TEGRA210_QSPI interface, nothing on the Nano uses the +old interface by default so it's surplus. + +Signed-off-by: Peter Robinson +--- + arch/arm/dts/tegra210-p3450-0000.dts | 9 ++++++++- + arch/arm/dts/tegra210.dtsi | 6 +++--- + configs/p3450-0000_defconfig | 1 - + include/dt-bindings/clock/tegra210-car.h | 6 +++--- + 4 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/dts/tegra210-p3450-0000.dts b/arch/arm/dts/tegra210-p3450-0000.dts +index 9ef744ac8b0..ddeeb232de2 100644 +--- a/arch/arm/dts/tegra210-p3450-0000.dts ++++ b/arch/arm/dts/tegra210-p3450-0000.dts +@@ -124,7 +124,14 @@ + + spi@70410000 { + status = "okay"; +- spi-max-frequency = <80000000>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <104000000>; ++ spi-tx-bus-width = <2>; ++ spi-rx-bus-width = <2>; ++ }; + }; + + usb@7d000000 { +diff --git a/arch/arm/dts/tegra210.dtsi b/arch/arm/dts/tegra210.dtsi +index 28ecd2b467a..6dd8fe26c38 100644 +--- a/arch/arm/dts/tegra210.dtsi ++++ b/arch/arm/dts/tegra210.dtsi +@@ -762,10 +762,10 @@ + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; +- clocks = <&tegra_car TEGRA210_CLK_QSPI>; +- clock-names = "qspi"; ++ clocks = <&tegra_car TEGRA210_CLK_QSPI>, ++ <&tegra_car TEGRA210_CLK_QSPI_PM>; ++ clock-names = "qspi", "qspi_out"; + resets = <&tegra_car 211>; +- reset-names = "qspi"; + dmas = <&apbdma 5>, <&apbdma 5>; + dma-names = "rx", "tx"; + status = "disabled"; +diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig +index 518ed6b37a2..3b4b863100f 100644 +--- a/configs/p3450-0000_defconfig ++++ b/configs/p3450-0000_defconfig +@@ -61,7 +61,6 @@ CONFIG_RTL8169=y + CONFIG_NVME_PCI=y + CONFIG_PCI_TEGRA=y + CONFIG_SYS_NS16550=y +-CONFIG_TEGRA114_SPI=y + CONFIG_TEGRA210_QSPI=y + CONFIG_USB=y + CONFIG_USB_EHCI_HCD=y +diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h +index eddac16800d..50d19647fb9 100644 +--- a/include/dt-bindings/clock/tegra210-car.h ++++ b/include/dt-bindings/clock/tegra210-car.h +@@ -302,9 +302,9 @@ + #define TEGRA210_CLK_AUDIO3 274 + #define TEGRA210_CLK_AUDIO4 275 + #define TEGRA210_CLK_SPDIF 276 +-#define TEGRA210_CLK_CLK_OUT_1 277 +-#define TEGRA210_CLK_CLK_OUT_2 278 +-#define TEGRA210_CLK_CLK_OUT_3 279 ++/* 277 */ ++#define TEGRA210_CLK_QSPI_PM 278 ++/* 279 */ + #define TEGRA210_CLK_BLINK 280 + /* 281 */ + /* 282 */ +-- +2.50.0 + diff --git a/sources b/sources index adaeddf..88fc3b3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (u-boot-2025.07-rc5.tar.bz2) = f439f2b1c4b892fd28aa1830b31e85188e4d36d611957515491e281befc2a95c99b25d47bd09bfd52307f2d4f008022769d932ff4975f43526463115ddd51d9c +SHA512 (u-boot-2025.07.tar.bz2) = 0d9a4906aaee134c6b6c496aaf7f54c653ede8e878f851e877ec7876e26cd14e356cd29112849295deeb72bee6b4d292151fb4d9db23d23608350c3fe567d955 diff --git a/uboot-tools.spec b/uboot-tools.spec index 15e874a..5d58d66 100644 --- a/uboot-tools.spec +++ b/uboot-tools.spec @@ -1,4 +1,4 @@ -%global candidate rc5 +#global candidate rc0 %if 0%{?rhel} %bcond_with toolsonly %else @@ -10,7 +10,7 @@ Name: uboot-tools Version: 2025.07 -Release: 0.5%{?candidate:.%{candidate}}%{?dist} +Release: 1%{?candidate:.%{candidate}}%{?dist} Epoch: 1 Summary: U-Boot utilities # Automatically converted from old format: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+ - review is highly recommended. @@ -38,21 +38,22 @@ Patch8: uefi-enable-https-boot-by-default.patch Patch9: tools-termios_linux.h-Fix-build-error-on-ppc64.patch # Device improvments -# Rockchips improvements -Patch10: rockchip-Enable-preboot-start-for-pci-usb.patch # USB-PD improvements -Patch11: USB-PD-TCPM-improvements.patch +Patch10: USB-PD-TCPM-improvements.patch +# Rockchips improvements +Patch11: rockchip-Enable-preboot-start-for-pci-usb.patch # Rockchip DT rebase for fixes -Patch12: 0001-Rebase-to-upstream-6.15.5-rockchip-DTs.patch +Patch12: Rebase-to-upstream-6.15.5-rockchip-DTs.patch +Patch13: Initial-MNT-Reform2-support.patch +# Fix Jetson Nano +Patch14: p3450-fix-board.patch # Add EFI_PARTITION_INFO_PROTOCOL support -Patch13: disk-efi-Move-logic-to-get-a-GPT-entry-into-a-helper.patch -Patch14: disk-efi-expose-the-part_get_gpt_pte-helper-function.patch -Patch15: efi_loader-disk-add-EFI_PARTITION_INFO_PROTOCOL-supp.patch -Patch16: efi_selftest-Add-basic-partition-info-check-to-block.patch +Patch20: disk-efi-Move-logic-to-get-a-GPT-entry-into-a-helper.patch +Patch21: disk-efi-expose-the-part_get_gpt_pte-helper-function.patch +Patch22: efi_loader-disk-add-EFI_PARTITION_INFO_PROTOCOL-supp.patch +Patch23: efi_selftest-Add-basic-partition-info-check-to-block.patch -# Should be upstream but it's taking time -#Patch9: Add-video-damage-tracking.patch BuildRequires: bc BuildRequires: bison @@ -279,6 +280,9 @@ install -p -m 0755 builds/tools/env/fw_printenv %{buildroot}%{_bindir} %endif %changelog +* Wed Jul 09 2025 Peter Robinson - 1:2025.07-1 +- Update to 2025.07 GA + * Fri Jun 27 2025 Peter Robinson - 1:2025.07-0.5.rc5 - Update to 2025.07 RC5 - Enable LWIP stack by default