0003-Add-video-damage-tracking.patch 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382
  1. From c3ae7d7f7af47e747f85f06662e26f434c25c891 Mon Sep 17 00:00:00 2001
  2. From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  3. Date: Fri, 18 Aug 2023 13:31:36 +0300
  4. Subject: [PATCH 01/13] video: test: Split copy frame buffer check into a
  5. function
  6. While checking frame buffer contents, the video tests also check if the
  7. copy frame buffer contents match the main frame buffer. To test if only
  8. the modified regions are updated after a sync, we will need to create
  9. situations where the two are mismatched. Split this check into another
  10. function that we can skip calling, since we won't want it to error on
  11. those mismatched cases.
  12. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  13. Reviewed-by: Simon Glass <sjg@chromium.org>
  14. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-2-alpernebiyasak@gmail.com/
  15. ---
  16. test/dm/video.c | 69 +++++++++++++++++++++++++++++++++++++++++--------
  17. 1 file changed, 58 insertions(+), 11 deletions(-)
  18. diff --git a/test/dm/video.c b/test/dm/video.c
  19. index 7dfbeb9555d1..14e6af5181f1 100644
  20. --- a/test/dm/video.c
  21. +++ b/test/dm/video.c
  22. @@ -54,9 +54,6 @@ DM_TEST(dm_test_video_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  23. * size of the compressed data. This provides a pretty good level of
  24. * certainty and the resulting tests need only check a single value.
  25. *
  26. - * If the copy framebuffer is enabled, this compares it to the main framebuffer
  27. - * too.
  28. - *
  29. * @uts: Test state
  30. * @dev: Video device
  31. * Return: compressed size of the frame buffer, or -ve on error
  32. @@ -65,7 +62,6 @@ static int compress_frame_buffer(struct unit_test_state *uts,
  33. struct udevice *dev)
  34. {
  35. struct video_priv *priv = dev_get_uclass_priv(dev);
  36. - struct video_priv *uc_priv = dev_get_uclass_priv(dev);
  37. uint destlen;
  38. void *dest;
  39. int ret;
  40. @@ -81,16 +77,34 @@ static int compress_frame_buffer(struct unit_test_state *uts,
  41. if (ret)
  42. return ret;
  43. - /* Check here that the copy frame buffer is working correctly */
  44. - if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
  45. - ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb,
  46. - uc_priv->fb_size),
  47. - "Copy framebuffer does not match fb");
  48. - }
  49. -
  50. return destlen;
  51. }
  52. +/**
  53. + * check_copy_frame_buffer() - Compare main frame buffer to copy
  54. + *
  55. + * If the copy frame buffer is enabled, this compares it to the main
  56. + * frame buffer. Normally they should have the same contents after a
  57. + * sync.
  58. + *
  59. + * @uts: Test state
  60. + * @dev: Video device
  61. + * Return: 0, or -ve on error
  62. + */
  63. +static int check_copy_frame_buffer(struct unit_test_state *uts,
  64. + struct udevice *dev)
  65. +{
  66. + struct video_priv *priv = dev_get_uclass_priv(dev);
  67. +
  68. + if (!IS_ENABLED(CONFIG_VIDEO_COPY))
  69. + return 0;
  70. +
  71. + ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
  72. + "Copy framebuffer does not match fb");
  73. +
  74. + return 0;
  75. +}
  76. +
  77. /*
  78. * Call this function at any point to halt and show the current display. Be
  79. * sure to run the test with the -l flag.
  80. @@ -154,24 +168,30 @@ static int dm_test_video_text(struct unit_test_state *uts)
  81. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  82. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  83. ut_asserteq(46, compress_frame_buffer(uts, dev));
  84. + ut_assertok(check_copy_frame_buffer(uts, dev));
  85. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  86. vidconsole_putc_xy(con, 0, 0, 'a');
  87. ut_asserteq(79, compress_frame_buffer(uts, dev));
  88. + ut_assertok(check_copy_frame_buffer(uts, dev));
  89. vidconsole_putc_xy(con, 0, 0, ' ');
  90. ut_asserteq(46, compress_frame_buffer(uts, dev));
  91. + ut_assertok(check_copy_frame_buffer(uts, dev));
  92. for (i = 0; i < 20; i++)
  93. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  94. ut_asserteq(273, compress_frame_buffer(uts, dev));
  95. + ut_assertok(check_copy_frame_buffer(uts, dev));
  96. vidconsole_set_row(con, 0, WHITE);
  97. ut_asserteq(46, compress_frame_buffer(uts, dev));
  98. + ut_assertok(check_copy_frame_buffer(uts, dev));
  99. for (i = 0; i < 20; i++)
  100. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  101. ut_asserteq(273, compress_frame_buffer(uts, dev));
  102. + ut_assertok(check_copy_frame_buffer(uts, dev));
  103. return 0;
  104. }
  105. @@ -190,24 +210,30 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts)
  106. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  107. ut_assertok(vidconsole_select_font(con, "12x22", 0));
  108. ut_asserteq(46, compress_frame_buffer(uts, dev));
  109. + ut_assertok(check_copy_frame_buffer(uts, dev));
  110. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  111. vidconsole_putc_xy(con, 0, 0, 'a');
  112. ut_asserteq(89, compress_frame_buffer(uts, dev));
  113. + ut_assertok(check_copy_frame_buffer(uts, dev));
  114. vidconsole_putc_xy(con, 0, 0, ' ');
  115. ut_asserteq(46, compress_frame_buffer(uts, dev));
  116. + ut_assertok(check_copy_frame_buffer(uts, dev));
  117. for (i = 0; i < 20; i++)
  118. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  119. ut_asserteq(363, compress_frame_buffer(uts, dev));
  120. + ut_assertok(check_copy_frame_buffer(uts, dev));
  121. vidconsole_set_row(con, 0, WHITE);
  122. ut_asserteq(46, compress_frame_buffer(uts, dev));
  123. + ut_assertok(check_copy_frame_buffer(uts, dev));
  124. for (i = 0; i < 20; i++)
  125. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  126. ut_asserteq(363, compress_frame_buffer(uts, dev));
  127. + ut_assertok(check_copy_frame_buffer(uts, dev));
  128. return 0;
  129. }
  130. @@ -225,6 +251,7 @@ static int dm_test_video_chars(struct unit_test_state *uts)
  131. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  132. vidconsole_put_string(con, test_string);
  133. ut_asserteq(466, compress_frame_buffer(uts, dev));
  134. + ut_assertok(check_copy_frame_buffer(uts, dev));
  135. return 0;
  136. }
  137. @@ -246,19 +273,23 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
  138. video_clear(con->parent);
  139. video_sync(con->parent, false);
  140. ut_asserteq(46, compress_frame_buffer(uts, dev));
  141. + ut_assertok(check_copy_frame_buffer(uts, dev));
  142. /* test clear escape sequence: [2J */
  143. vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
  144. ut_asserteq(46, compress_frame_buffer(uts, dev));
  145. + ut_assertok(check_copy_frame_buffer(uts, dev));
  146. /* test set-cursor: [%d;%df */
  147. vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
  148. ut_asserteq(143, compress_frame_buffer(uts, dev));
  149. + ut_assertok(check_copy_frame_buffer(uts, dev));
  150. /* test colors (30-37 fg color, 40-47 bg color) */
  151. vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
  152. vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
  153. ut_asserteq(272, compress_frame_buffer(uts, dev));
  154. + ut_assertok(check_copy_frame_buffer(uts, dev));
  155. return 0;
  156. }
  157. @@ -291,11 +322,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
  158. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  159. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  160. ut_asserteq(46, compress_frame_buffer(uts, dev));
  161. + ut_assertok(check_copy_frame_buffer(uts, dev));
  162. /* Check display wrap */
  163. for (i = 0; i < 120; i++)
  164. vidconsole_put_char(con, 'A' + i % 50);
  165. ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
  166. + ut_assertok(check_copy_frame_buffer(uts, dev));
  167. /* Check display scrolling */
  168. for (i = 0; i < SCROLL_LINES; i++) {
  169. @@ -303,11 +336,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
  170. vidconsole_put_char(con, '\n');
  171. }
  172. ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
  173. + ut_assertok(check_copy_frame_buffer(uts, dev));
  174. /* If we scroll enough, the screen becomes blank again */
  175. for (i = 0; i < SCROLL_LINES; i++)
  176. vidconsole_put_char(con, '\n');
  177. ut_asserteq(46, compress_frame_buffer(uts, dev));
  178. + ut_assertok(check_copy_frame_buffer(uts, dev));
  179. return 0;
  180. }
  181. @@ -382,6 +417,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
  182. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  183. ut_asserteq(1368, compress_frame_buffer(uts, dev));
  184. + ut_assertok(check_copy_frame_buffer(uts, dev));
  185. return 0;
  186. }
  187. @@ -401,6 +437,7 @@ static int dm_test_video_bmp8(struct unit_test_state *uts)
  188. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  189. ut_asserteq(1247, compress_frame_buffer(uts, dev));
  190. + ut_assertok(check_copy_frame_buffer(uts, dev));
  191. return 0;
  192. }
  193. @@ -424,6 +461,7 @@ static int dm_test_video_bmp16(struct unit_test_state *uts)
  194. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  195. ut_asserteq(3700, compress_frame_buffer(uts, dev));
  196. + ut_assertok(check_copy_frame_buffer(uts, dev));
  197. return 0;
  198. }
  199. @@ -447,6 +485,7 @@ static int dm_test_video_bmp24(struct unit_test_state *uts)
  200. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  201. ut_asserteq(3656, compress_frame_buffer(uts, dev));
  202. + ut_assertok(check_copy_frame_buffer(uts, dev));
  203. return 0;
  204. }
  205. @@ -470,6 +509,7 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts)
  206. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  207. ut_asserteq(6827, compress_frame_buffer(uts, dev));
  208. + ut_assertok(check_copy_frame_buffer(uts, dev));
  209. return 0;
  210. }
  211. @@ -488,6 +528,7 @@ static int dm_test_video_bmp32(struct unit_test_state *uts)
  212. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  213. ut_asserteq(2024, compress_frame_buffer(uts, dev));
  214. + ut_assertok(check_copy_frame_buffer(uts, dev));
  215. return 0;
  216. }
  217. @@ -504,6 +545,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
  218. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  219. ut_asserteq(1368, compress_frame_buffer(uts, dev));
  220. + ut_assertok(check_copy_frame_buffer(uts, dev));
  221. return 0;
  222. }
  223. @@ -523,6 +565,7 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
  224. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  225. ut_asserteq(2024, compress_frame_buffer(uts, dev));
  226. + ut_assertok(check_copy_frame_buffer(uts, dev));
  227. return 0;
  228. }
  229. @@ -542,6 +585,7 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
  230. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  231. ut_asserteq(1247, compress_frame_buffer(uts, dev));
  232. + ut_assertok(check_copy_frame_buffer(uts, dev));
  233. return 0;
  234. }
  235. @@ -557,6 +601,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
  236. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  237. vidconsole_put_string(con, test_string);
  238. ut_asserteq(12174, compress_frame_buffer(uts, dev));
  239. + ut_assertok(check_copy_frame_buffer(uts, dev));
  240. return 0;
  241. }
  242. @@ -578,6 +623,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
  243. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  244. vidconsole_put_string(con, test_string);
  245. ut_asserteq(34287, compress_frame_buffer(uts, dev));
  246. + ut_assertok(check_copy_frame_buffer(uts, dev));
  247. return 0;
  248. }
  249. @@ -599,6 +645,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
  250. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  251. vidconsole_put_string(con, test_string);
  252. ut_asserteq(29471, compress_frame_buffer(uts, dev));
  253. + ut_assertok(check_copy_frame_buffer(uts, dev));
  254. return 0;
  255. }
  256. --
  257. 2.45.2
  258. From 575ebe8b5d9ae9c9818b4deb708f8a69f9f9a9b1 Mon Sep 17 00:00:00 2001
  259. From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  260. Date: Sun, 20 Aug 2023 17:46:46 +0300
  261. Subject: [PATCH 02/13] video: test: Support checking copy frame buffer
  262. contents
  263. The video tests have a helper function to generate a pseudo-digest of
  264. frame buffer contents, but it only does so for the main one. There is
  265. another check that the copy frame buffer is the same as that. But
  266. neither is enough to test if only the modified regions are copied to the
  267. copy frame buffer, since we will want the two to be different in very
  268. specific ways.
  269. Add a boolean argument to the existing helper function to indicate which
  270. frame buffer we want to inspect, and update the existing callers.
  271. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  272. Reviewed-by: Simon Glass <sjg@chromium.org>
  273. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-3-alpernebiyasak@gmail.com/
  274. ---
  275. test/dm/video.c | 76 ++++++++++++++++++++++++++-----------------------
  276. 1 file changed, 41 insertions(+), 35 deletions(-)
  277. diff --git a/test/dm/video.c b/test/dm/video.c
  278. index 14e6af5181f1..50374cafc009 100644
  279. --- a/test/dm/video.c
  280. +++ b/test/dm/video.c
  281. @@ -56,22 +56,28 @@ DM_TEST(dm_test_video_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  282. *
  283. * @uts: Test state
  284. * @dev: Video device
  285. + * @use_copy: Use copy frame buffer if available
  286. * Return: compressed size of the frame buffer, or -ve on error
  287. */
  288. static int compress_frame_buffer(struct unit_test_state *uts,
  289. - struct udevice *dev)
  290. + struct udevice *dev,
  291. + bool use_copy)
  292. {
  293. struct video_priv *priv = dev_get_uclass_priv(dev);
  294. uint destlen;
  295. void *dest;
  296. int ret;
  297. + if (!IS_ENABLED(CONFIG_VIDEO_COPY))
  298. + use_copy = false;
  299. +
  300. destlen = priv->fb_size;
  301. dest = malloc(priv->fb_size);
  302. if (!dest)
  303. return -ENOMEM;
  304. ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
  305. - priv->fb, priv->fb_size,
  306. + use_copy ? priv->copy_fb : priv->fb,
  307. + priv->fb_size,
  308. 3, 0, 0);
  309. free(dest);
  310. if (ret)
  311. @@ -167,30 +173,30 @@ static int dm_test_video_text(struct unit_test_state *uts)
  312. ut_assertok(video_get_nologo(uts, &dev));
  313. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  314. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  315. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  316. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  317. ut_assertok(check_copy_frame_buffer(uts, dev));
  318. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  319. vidconsole_putc_xy(con, 0, 0, 'a');
  320. - ut_asserteq(79, compress_frame_buffer(uts, dev));
  321. + ut_asserteq(79, compress_frame_buffer(uts, dev, false));
  322. ut_assertok(check_copy_frame_buffer(uts, dev));
  323. vidconsole_putc_xy(con, 0, 0, ' ');
  324. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  325. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  326. ut_assertok(check_copy_frame_buffer(uts, dev));
  327. for (i = 0; i < 20; i++)
  328. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  329. - ut_asserteq(273, compress_frame_buffer(uts, dev));
  330. + ut_asserteq(273, compress_frame_buffer(uts, dev, false));
  331. ut_assertok(check_copy_frame_buffer(uts, dev));
  332. vidconsole_set_row(con, 0, WHITE);
  333. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  334. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  335. ut_assertok(check_copy_frame_buffer(uts, dev));
  336. for (i = 0; i < 20; i++)
  337. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  338. - ut_asserteq(273, compress_frame_buffer(uts, dev));
  339. + ut_asserteq(273, compress_frame_buffer(uts, dev, false));
  340. ut_assertok(check_copy_frame_buffer(uts, dev));
  341. return 0;
  342. @@ -209,30 +215,30 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts)
  343. ut_assertok(video_get_nologo(uts, &dev));
  344. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  345. ut_assertok(vidconsole_select_font(con, "12x22", 0));
  346. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  347. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  348. ut_assertok(check_copy_frame_buffer(uts, dev));
  349. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  350. vidconsole_putc_xy(con, 0, 0, 'a');
  351. - ut_asserteq(89, compress_frame_buffer(uts, dev));
  352. + ut_asserteq(89, compress_frame_buffer(uts, dev, false));
  353. ut_assertok(check_copy_frame_buffer(uts, dev));
  354. vidconsole_putc_xy(con, 0, 0, ' ');
  355. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  356. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  357. ut_assertok(check_copy_frame_buffer(uts, dev));
  358. for (i = 0; i < 20; i++)
  359. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  360. - ut_asserteq(363, compress_frame_buffer(uts, dev));
  361. + ut_asserteq(363, compress_frame_buffer(uts, dev, false));
  362. ut_assertok(check_copy_frame_buffer(uts, dev));
  363. vidconsole_set_row(con, 0, WHITE);
  364. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  365. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  366. ut_assertok(check_copy_frame_buffer(uts, dev));
  367. for (i = 0; i < 20; i++)
  368. vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
  369. - ut_asserteq(363, compress_frame_buffer(uts, dev));
  370. + ut_asserteq(363, compress_frame_buffer(uts, dev, false));
  371. ut_assertok(check_copy_frame_buffer(uts, dev));
  372. return 0;
  373. @@ -250,7 +256,7 @@ static int dm_test_video_chars(struct unit_test_state *uts)
  374. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  375. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  376. vidconsole_put_string(con, test_string);
  377. - ut_asserteq(466, compress_frame_buffer(uts, dev));
  378. + ut_asserteq(466, compress_frame_buffer(uts, dev, false));
  379. ut_assertok(check_copy_frame_buffer(uts, dev));
  380. return 0;
  381. @@ -272,23 +278,23 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
  382. /* reference clear: */
  383. video_clear(con->parent);
  384. video_sync(con->parent, false);
  385. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  386. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  387. ut_assertok(check_copy_frame_buffer(uts, dev));
  388. /* test clear escape sequence: [2J */
  389. vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
  390. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  391. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  392. ut_assertok(check_copy_frame_buffer(uts, dev));
  393. /* test set-cursor: [%d;%df */
  394. vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
  395. - ut_asserteq(143, compress_frame_buffer(uts, dev));
  396. + ut_asserteq(143, compress_frame_buffer(uts, dev, false));
  397. ut_assertok(check_copy_frame_buffer(uts, dev));
  398. /* test colors (30-37 fg color, 40-47 bg color) */
  399. vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
  400. vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
  401. - ut_asserteq(272, compress_frame_buffer(uts, dev));
  402. + ut_asserteq(272, compress_frame_buffer(uts, dev, false));
  403. ut_assertok(check_copy_frame_buffer(uts, dev));
  404. return 0;
  405. @@ -321,13 +327,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
  406. ut_assertok(video_get_nologo(uts, &dev));
  407. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  408. ut_assertok(vidconsole_select_font(con, "8x16", 0));
  409. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  410. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  411. ut_assertok(check_copy_frame_buffer(uts, dev));
  412. /* Check display wrap */
  413. for (i = 0; i < 120; i++)
  414. vidconsole_put_char(con, 'A' + i % 50);
  415. - ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
  416. + ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false));
  417. ut_assertok(check_copy_frame_buffer(uts, dev));
  418. /* Check display scrolling */
  419. @@ -335,13 +341,13 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
  420. vidconsole_put_char(con, 'A' + i % 50);
  421. vidconsole_put_char(con, '\n');
  422. }
  423. - ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
  424. + ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false));
  425. ut_assertok(check_copy_frame_buffer(uts, dev));
  426. /* If we scroll enough, the screen becomes blank again */
  427. for (i = 0; i < SCROLL_LINES; i++)
  428. vidconsole_put_char(con, '\n');
  429. - ut_asserteq(46, compress_frame_buffer(uts, dev));
  430. + ut_asserteq(46, compress_frame_buffer(uts, dev, false));
  431. ut_assertok(check_copy_frame_buffer(uts, dev));
  432. return 0;
  433. @@ -416,7 +422,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
  434. ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  435. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  436. - ut_asserteq(1368, compress_frame_buffer(uts, dev));
  437. + ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
  438. ut_assertok(check_copy_frame_buffer(uts, dev));
  439. return 0;
  440. @@ -436,7 +442,7 @@ static int dm_test_video_bmp8(struct unit_test_state *uts)
  441. ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  442. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  443. - ut_asserteq(1247, compress_frame_buffer(uts, dev));
  444. + ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
  445. ut_assertok(check_copy_frame_buffer(uts, dev));
  446. return 0;
  447. @@ -460,7 +466,7 @@ static int dm_test_video_bmp16(struct unit_test_state *uts)
  448. &src_len));
  449. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  450. - ut_asserteq(3700, compress_frame_buffer(uts, dev));
  451. + ut_asserteq(3700, compress_frame_buffer(uts, dev, false));
  452. ut_assertok(check_copy_frame_buffer(uts, dev));
  453. return 0;
  454. @@ -484,7 +490,7 @@ static int dm_test_video_bmp24(struct unit_test_state *uts)
  455. &src_len));
  456. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  457. - ut_asserteq(3656, compress_frame_buffer(uts, dev));
  458. + ut_asserteq(3656, compress_frame_buffer(uts, dev, false));
  459. ut_assertok(check_copy_frame_buffer(uts, dev));
  460. return 0;
  461. @@ -508,7 +514,7 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts)
  462. &src_len));
  463. ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
  464. - ut_asserteq(6827, compress_frame_buffer(uts, dev));
  465. + ut_asserteq(6827, compress_frame_buffer(uts, dev, false));
  466. ut_assertok(check_copy_frame_buffer(uts, dev));
  467. return 0;
  468. @@ -527,7 +533,7 @@ static int dm_test_video_bmp32(struct unit_test_state *uts)
  469. ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  470. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  471. - ut_asserteq(2024, compress_frame_buffer(uts, dev));
  472. + ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
  473. ut_assertok(check_copy_frame_buffer(uts, dev));
  474. return 0;
  475. @@ -544,7 +550,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
  476. ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
  477. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  478. - ut_asserteq(1368, compress_frame_buffer(uts, dev));
  479. + ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
  480. ut_assertok(check_copy_frame_buffer(uts, dev));
  481. return 0;
  482. @@ -564,7 +570,7 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
  483. ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  484. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  485. - ut_asserteq(2024, compress_frame_buffer(uts, dev));
  486. + ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
  487. ut_assertok(check_copy_frame_buffer(uts, dev));
  488. return 0;
  489. @@ -584,7 +590,7 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
  490. ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  491. ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  492. - ut_asserteq(1247, compress_frame_buffer(uts, dev));
  493. + ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
  494. ut_assertok(check_copy_frame_buffer(uts, dev));
  495. return 0;
  496. @@ -600,7 +606,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
  497. ut_assertok(video_get_nologo(uts, &dev));
  498. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  499. vidconsole_put_string(con, test_string);
  500. - ut_asserteq(12174, compress_frame_buffer(uts, dev));
  501. + ut_asserteq(12174, compress_frame_buffer(uts, dev, false));
  502. ut_assertok(check_copy_frame_buffer(uts, dev));
  503. return 0;
  504. @@ -622,7 +628,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
  505. ut_assertok(video_get_nologo(uts, &dev));
  506. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  507. vidconsole_put_string(con, test_string);
  508. - ut_asserteq(34287, compress_frame_buffer(uts, dev));
  509. + ut_asserteq(34287, compress_frame_buffer(uts, dev, false));
  510. ut_assertok(check_copy_frame_buffer(uts, dev));
  511. return 0;
  512. @@ -644,7 +650,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
  513. ut_assertok(video_get_nologo(uts, &dev));
  514. ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  515. vidconsole_put_string(con, test_string);
  516. - ut_asserteq(29471, compress_frame_buffer(uts, dev));
  517. + ut_asserteq(29471, compress_frame_buffer(uts, dev, false));
  518. ut_assertok(check_copy_frame_buffer(uts, dev));
  519. return 0;
  520. --
  521. 2.45.2
  522. From d1fddc8cbe64a5532ddc43d0b1413ff7cc1bf618 Mon Sep 17 00:00:00 2001
  523. From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  524. Date: Fri, 18 Aug 2023 17:31:27 +0300
  525. Subject: [PATCH 03/13] video: test: Test partial updates of hardware frame
  526. buffer
  527. With VIDEO_COPY enabled, only the modified parts of the frame buffer are
  528. intended to be copied to the hardware. Add a test that checks this, by
  529. overwriting contents we prepared without telling the video uclass and
  530. then checking if the overwritten contents have been redrawn on the next
  531. sync.
  532. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  533. Reviewed-by: Simon Glass <sjg@chromium.org>
  534. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-4-alpernebiyasak@gmail.com/
  535. ---
  536. test/dm/video.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
  537. 1 file changed, 54 insertions(+)
  538. diff --git a/test/dm/video.c b/test/dm/video.c
  539. index 50374cafc009..4798f2205a99 100644
  540. --- a/test/dm/video.c
  541. +++ b/test/dm/video.c
  542. @@ -656,3 +656,57 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
  543. return 0;
  544. }
  545. DM_TEST(dm_test_video_truetype_bs, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  546. +
  547. +/* Test partial rendering onto hardware frame buffer */
  548. +static int dm_test_video_copy(struct unit_test_state *uts)
  549. +{
  550. + struct sandbox_sdl_plat *plat;
  551. + struct video_uc_plat *uc_plat;
  552. + struct udevice *dev, *con;
  553. + struct video_priv *priv;
  554. + const char *test_string = "\n\tCriticism may not be agreeable, but it is necessary.\t";
  555. + ulong addr;
  556. +
  557. + if (!IS_ENABLED(CONFIG_VIDEO_COPY))
  558. + return -EAGAIN;
  559. +
  560. + ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
  561. + ut_assertnonnull(dev);
  562. + uc_plat = dev_get_uclass_plat(dev);
  563. + uc_plat->hide_logo = true;
  564. + plat = dev_get_plat(dev);
  565. + plat->font_size = 32;
  566. + ut_assert(!device_active(dev));
  567. + ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
  568. + ut_assertnonnull(dev);
  569. + priv = dev_get_uclass_priv(dev);
  570. +
  571. + ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
  572. + ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
  573. +
  574. + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  575. + vidconsole_put_string(con, "\n\n\n\n\n");
  576. + vidconsole_put_string(con, test_string);
  577. + vidconsole_put_string(con, test_string);
  578. +
  579. + ut_asserteq(6678, compress_frame_buffer(uts, dev, false));
  580. + ut_assertok(check_copy_frame_buffer(uts, dev));
  581. +
  582. + /*
  583. + * Secretly clear the hardware frame buffer, but in a different
  584. + * color (black) to see which parts will be overwritten.
  585. + */
  586. + memset(priv->copy_fb, 0, priv->fb_size);
  587. +
  588. + /*
  589. + * We should have the full content on the main buffer, but only
  590. + * the new content should have been copied to the copy buffer.
  591. + */
  592. + vidconsole_put_string(con, test_string);
  593. + vidconsole_put_string(con, test_string);
  594. + ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
  595. + ut_asserteq(5278, compress_frame_buffer(uts, dev, true));
  596. +
  597. + return 0;
  598. +}
  599. +DM_TEST(dm_test_video_copy, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  600. --
  601. 2.45.2
  602. From 700a7cdc62fa08f425c05db2061f06c56d96d5b6 Mon Sep 17 00:00:00 2001
  603. From: Alexander Graf <agraf@csgraf.de>
  604. Date: Fri, 10 Jun 2022 00:59:15 +0200
  605. Subject: [PATCH 04/13] dm: video: Add damage tracking API
  606. We are going to introduce image damage tracking to fasten up screen
  607. refresh on large displays. This patch adds damage tracking for up to
  608. one rectangle of the screen which is typically enough to hold blt or
  609. text print updates. Callers into this API and a reduced dcache flush
  610. code path will follow in later patches.
  611. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  612. Reported-by: Da Xue <da@libre.computer>
  613. [Alper: Use xstart/yend, document new fields, return void from
  614. video_damage(), declare priv, drop headers, use IS_ENABLED()]
  615. Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  616. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  617. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-5-alpernebiyasak@gmail.com/
  618. Reviewed-by: Simon Glass <sjg@chromium.org>
  619. ---
  620. drivers/video/Kconfig | 13 ++++++++++++
  621. drivers/video/video-uclass.c | 35 +++++++++++++++++++++++++++++++
  622. include/video.h | 40 ++++++++++++++++++++++++++++++++++--
  623. 3 files changed, 86 insertions(+), 2 deletions(-)
  624. diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
  625. index 6e79694fd192..d7da655cea62 100644
  626. --- a/drivers/video/Kconfig
  627. +++ b/drivers/video/Kconfig
  628. @@ -98,6 +98,19 @@ config VIDEO_COPY
  629. To use this, your video driver must set @copy_base in
  630. struct video_uc_plat.
  631. +config VIDEO_DAMAGE
  632. + bool "Enable damage tracking of frame buffer regions"
  633. + help
  634. + On some machines (most ARM), the display frame buffer resides in
  635. + RAM. To make the display controller pick up screen updates, we
  636. + have to flush frame buffer contents from CPU caches into RAM which
  637. + can be a slow operation.
  638. +
  639. + This feature adds damage tracking to collect information about regions
  640. + that received updates. When we want to sync, we then only flush
  641. + regions of the frame buffer that were modified before, speeding up
  642. + screen refreshes significantly.
  643. +
  644. config BACKLIGHT_PWM
  645. bool "Generic PWM based Backlight Driver"
  646. depends on BACKLIGHT && DM_PWM
  647. diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
  648. index a5aa8dd52954..b95f2dbc7703 100644
  649. --- a/drivers/video/video-uclass.c
  650. +++ b/drivers/video/video-uclass.c
  651. @@ -352,6 +352,34 @@ void video_set_default_colors(struct udevice *dev, bool invert)
  652. priv->colour_bg = video_index_to_colour(priv, back);
  653. }
  654. +/* Notify about changes in the frame buffer */
  655. +#ifdef CONFIG_VIDEO_DAMAGE
  656. +void video_damage(struct udevice *vid, int x, int y, int width, int height)
  657. +{
  658. + struct video_priv *priv = dev_get_uclass_priv(vid);
  659. + int xend = x + width;
  660. + int yend = y + height;
  661. +
  662. + if (x > priv->xsize)
  663. + return;
  664. +
  665. + if (y > priv->ysize)
  666. + return;
  667. +
  668. + if (xend > priv->xsize)
  669. + xend = priv->xsize;
  670. +
  671. + if (yend > priv->ysize)
  672. + yend = priv->ysize;
  673. +
  674. + /* Span a rectangle across all old and new damage */
  675. + priv->damage.xstart = min(x, priv->damage.xstart);
  676. + priv->damage.ystart = min(y, priv->damage.ystart);
  677. + priv->damage.xend = max(xend, priv->damage.xend);
  678. + priv->damage.yend = max(yend, priv->damage.yend);
  679. +}
  680. +#endif
  681. +
  682. /* Flush video activity to the caches */
  683. int video_sync(struct udevice *vid, bool force)
  684. {
  685. @@ -385,6 +413,13 @@ int video_sync(struct udevice *vid, bool force)
  686. #endif
  687. priv->last_sync = get_timer(0);
  688. + if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) {
  689. + priv->damage.xstart = priv->xsize;
  690. + priv->damage.ystart = priv->ysize;
  691. + priv->damage.xend = 0;
  692. + priv->damage.yend = 0;
  693. + }
  694. +
  695. return 0;
  696. }
  697. diff --git a/include/video.h b/include/video.h
  698. index 4013a949983f..835d7734cb75 100644
  699. --- a/include/video.h
  700. +++ b/include/video.h
  701. @@ -88,6 +88,11 @@ enum video_format {
  702. * @fb_size: Frame buffer size
  703. * @copy_fb: Copy of the frame buffer to keep up to date; see struct
  704. * video_uc_plat
  705. + * @damage: A bounding box of framebuffer regions updated since last sync
  706. + * @damage.xstart: X start position in pixels from the left
  707. + * @damage.ystart: Y start position in pixels from the top
  708. + * @damage.xend: X end position in pixels from the left
  709. + * @damage.xend: Y end position in pixels from the top
  710. * @line_length: Length of each frame buffer line, in bytes. This can be
  711. * set by the driver, but if not, the uclass will set it after
  712. * probing
  713. @@ -116,6 +121,12 @@ struct video_priv {
  714. void *fb;
  715. int fb_size;
  716. void *copy_fb;
  717. + struct {
  718. + int xstart;
  719. + int ystart;
  720. + int xend;
  721. + int yend;
  722. + } damage;
  723. int line_length;
  724. u32 colour_fg;
  725. u32 colour_bg;
  726. @@ -259,8 +270,9 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
  727. * @return: 0 on success, error code otherwise
  728. *
  729. * Some frame buffers are cached or have a secondary frame buffer. This
  730. - * function syncs these up so that the current contents of the U-Boot frame
  731. - * buffer are displayed to the user.
  732. + * function syncs the damaged parts of them up so that the current contents
  733. + * of the U-Boot frame buffer are displayed to the user. It clears the damage
  734. + * buffer.
  735. */
  736. int video_sync(struct udevice *vid, bool force);
  737. @@ -380,6 +392,30 @@ static inline int video_sync_copy_all(struct udevice *dev)
  738. #endif
  739. +#ifdef CONFIG_VIDEO_DAMAGE
  740. +/**
  741. + * video_damage() - Notify the video subsystem about screen updates.
  742. + *
  743. + * @vid: Device to sync
  744. + * @x: Upper left X coordinate of the damaged rectangle
  745. + * @y: Upper left Y coordinate of the damaged rectangle
  746. + * @width: Width of the damaged rectangle
  747. + * @height: Height of the damaged rectangle
  748. + *
  749. + * Some frame buffers are cached or have a secondary frame buffer. This
  750. + * function notifies the video subsystem about rectangles that were updated
  751. + * within the frame buffer. They may only get written to the screen on the
  752. + * next call to video_sync().
  753. + */
  754. +void video_damage(struct udevice *vid, int x, int y, int width, int height);
  755. +#else
  756. +static inline void video_damage(struct udevice *vid, int x, int y, int width,
  757. + int height)
  758. +{
  759. + return;
  760. +}
  761. +#endif /* CONFIG_VIDEO_DAMAGE */
  762. +
  763. /**
  764. * video_is_active() - Test if one video device it active
  765. *
  766. --
  767. 2.45.2
  768. From b84ee524454fbfebd71532532bf2e28ad97ef676 Mon Sep 17 00:00:00 2001
  769. From: Alexander Graf <agraf@csgraf.de>
  770. Date: Fri, 10 Jun 2022 00:59:16 +0200
  771. Subject: [PATCH 05/13] dm: video: Add damage notification on display fills
  772. Let's report the video damage when we fill parts of the screen. This
  773. way we can later lazily flush only relevant regions to hardware.
  774. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  775. Reported-by: Da Xue <da@libre.computer>
  776. [Alper: Move from video_clear() to video_fill(), video_fill_part()]
  777. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  778. Reviewed-by: Simon Glass <sjg@chromium.org>
  779. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-6-alpernebiyasak@gmail.com/
  780. ---
  781. drivers/video/video-uclass.c | 4 ++++
  782. 1 file changed, 4 insertions(+)
  783. diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
  784. index b95f2dbc7703..6906b2b83623 100644
  785. --- a/drivers/video/video-uclass.c
  786. +++ b/drivers/video/video-uclass.c
  787. @@ -201,6 +201,8 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
  788. if (ret)
  789. return ret;
  790. + video_damage(dev, xstart, ystart, xend - xstart, yend - ystart);
  791. +
  792. return 0;
  793. }
  794. @@ -250,6 +252,8 @@ int video_fill(struct udevice *dev, u32 colour)
  795. if (ret)
  796. return ret;
  797. + video_damage(dev, 0, 0, priv->xsize, priv->ysize);
  798. +
  799. return video_sync(dev, false);
  800. }
  801. --
  802. 2.45.2
  803. From b18a1ef92e2a003771a4a846c592302c1e92bd83 Mon Sep 17 00:00:00 2001
  804. From: Alexander Graf <agraf@csgraf.de>
  805. Date: Fri, 10 Jun 2022 00:59:17 +0200
  806. Subject: [PATCH 06/13] vidconsole: Add damage notifications to all vidconsole
  807. drivers
  808. Now that we have a damage tracking API, let's populate damage done by
  809. vidconsole drivers. We try to declare as little memory as damaged as
  810. possible.
  811. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  812. Reported-by: Da Xue <da@libre.computer>
  813. [Alper: Rebase for met->baseline, fontdata->height/width, make rotated
  814. console_putc_xy() damages pass tests, edit patch message]
  815. Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  816. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  817. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-7-alpernebiyasak@gmail.com/
  818. ---
  819. drivers/video/console_normal.c | 18 +++++++++++
  820. drivers/video/console_rotate.c | 54 ++++++++++++++++++++++++++++++++
  821. drivers/video/console_truetype.c | 21 +++++++++++++
  822. 3 files changed, 93 insertions(+)
  823. diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
  824. index 6f4194a18147..51ac8cc78e9d 100644
  825. --- a/drivers/video/console_normal.c
  826. +++ b/drivers/video/console_normal.c
  827. @@ -39,6 +39,12 @@ static int console_set_row(struct udevice *dev, uint row, int clr)
  828. if (ret)
  829. return ret;
  830. + video_damage(dev->parent,
  831. + 0,
  832. + fontdata->height * row,
  833. + vid_priv->xsize,
  834. + fontdata->height);
  835. +
  836. return 0;
  837. }
  838. @@ -60,6 +66,12 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
  839. if (ret)
  840. return ret;
  841. + video_damage(dev->parent,
  842. + 0,
  843. + fontdata->height * rowdst,
  844. + vid_priv->xsize,
  845. + fontdata->height * count);
  846. +
  847. return 0;
  848. }
  849. @@ -91,6 +103,12 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
  850. if (ret)
  851. return ret;
  852. + video_damage(dev->parent,
  853. + x,
  854. + y,
  855. + fontdata->width,
  856. + fontdata->height);
  857. +
  858. ret = vidconsole_sync_copy(dev, start, line);
  859. if (ret)
  860. return ret;
  861. diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
  862. index a3f8c6352f83..f11dc3a0b075 100644
  863. --- a/drivers/video/console_rotate.c
  864. +++ b/drivers/video/console_rotate.c
  865. @@ -36,6 +36,12 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
  866. if (ret)
  867. return ret;
  868. + video_damage(dev->parent,
  869. + vid_priv->xsize - ((row + 1) * fontdata->height),
  870. + 0,
  871. + fontdata->height,
  872. + vid_priv->ysize);
  873. +
  874. return 0;
  875. }
  876. @@ -64,6 +70,12 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
  877. dst += vid_priv->line_length;
  878. }
  879. + video_damage(dev->parent,
  880. + vid_priv->xsize - ((rowdst + count) * fontdata->height),
  881. + 0,
  882. + count * fontdata->height,
  883. + vid_priv->ysize);
  884. +
  885. return 0;
  886. }
  887. @@ -97,6 +109,12 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
  888. if (ret)
  889. return ret;
  890. + video_damage(dev->parent,
  891. + vid_priv->xsize - y - fontdata->height,
  892. + linenum - 1,
  893. + fontdata->height,
  894. + fontdata->width);
  895. +
  896. return VID_TO_POS(fontdata->width);
  897. }
  898. @@ -121,6 +139,12 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
  899. if (ret)
  900. return ret;
  901. + video_damage(dev->parent,
  902. + 0,
  903. + vid_priv->ysize - (row + 1) * fontdata->height,
  904. + vid_priv->xsize,
  905. + fontdata->height);
  906. +
  907. return 0;
  908. }
  909. @@ -142,6 +166,12 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
  910. vidconsole_memmove(dev, dst, src,
  911. fontdata->height * vid_priv->line_length * count);
  912. + video_damage(dev->parent,
  913. + 0,
  914. + vid_priv->ysize - (rowdst + count) * fontdata->height,
  915. + vid_priv->xsize,
  916. + count * fontdata->height);
  917. +
  918. return 0;
  919. }
  920. @@ -175,6 +205,12 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
  921. if (ret)
  922. return ret;
  923. + video_damage(dev->parent,
  924. + x - fontdata->width + 1,
  925. + linenum - fontdata->height + 1,
  926. + fontdata->width,
  927. + fontdata->height);
  928. +
  929. return VID_TO_POS(fontdata->width);
  930. }
  931. @@ -199,6 +235,12 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
  932. if (ret)
  933. return ret;
  934. + video_damage(dev->parent,
  935. + row * fontdata->height,
  936. + 0,
  937. + fontdata->height,
  938. + vid_priv->ysize);
  939. +
  940. return 0;
  941. }
  942. @@ -225,6 +267,12 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
  943. dst += vid_priv->line_length;
  944. }
  945. + video_damage(dev->parent,
  946. + rowdst * fontdata->height,
  947. + 0,
  948. + count * fontdata->height,
  949. + vid_priv->ysize);
  950. +
  951. return 0;
  952. }
  953. @@ -257,6 +305,12 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
  954. if (ret)
  955. return ret;
  956. + video_damage(dev->parent,
  957. + y,
  958. + linenum - fontdata->width + 1,
  959. + fontdata->height,
  960. + fontdata->width);
  961. +
  962. return VID_TO_POS(fontdata->width);
  963. }
  964. diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
  965. index c435162d3f94..6a17f732fc26 100644
  966. --- a/drivers/video/console_truetype.c
  967. +++ b/drivers/video/console_truetype.c
  968. @@ -190,6 +190,7 @@ struct console_tt_store {
  969. static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
  970. {
  971. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  972. + struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  973. struct console_tt_priv *priv = dev_get_priv(dev);
  974. struct console_tt_metrics *met = priv->cur_met;
  975. void *end, *line;
  976. @@ -233,6 +234,12 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
  977. if (ret)
  978. return ret;
  979. + video_damage(dev->parent,
  980. + 0,
  981. + vc_priv->y_charsize * row,
  982. + vid_priv->xsize,
  983. + vc_priv->y_charsize);
  984. +
  985. return 0;
  986. }
  987. @@ -240,6 +247,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
  988. uint rowsrc, uint count)
  989. {
  990. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  991. + struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  992. struct console_tt_priv *priv = dev_get_priv(dev);
  993. struct console_tt_metrics *met = priv->cur_met;
  994. void *dst;
  995. @@ -258,6 +266,12 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
  996. for (i = 0; i < priv->pos_ptr; i++)
  997. priv->pos[i].ypos -= diff;
  998. + video_damage(dev->parent,
  999. + 0,
  1000. + vc_priv->y_charsize * rowdst,
  1001. + vid_priv->xsize,
  1002. + vc_priv->y_charsize * count);
  1003. +
  1004. return 0;
  1005. }
  1006. @@ -418,6 +432,13 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
  1007. line += vid_priv->line_length;
  1008. }
  1009. +
  1010. + video_damage(dev->parent,
  1011. + VID_TO_PIXEL(x) + xoff,
  1012. + y + met->baseline + yoff,
  1013. + width,
  1014. + height);
  1015. +
  1016. ret = vidconsole_sync_copy(dev, start, line);
  1017. if (ret)
  1018. return ret;
  1019. --
  1020. 2.45.2
  1021. From 991d7e646de88fd019059679f659761072412e15 Mon Sep 17 00:00:00 2001
  1022. From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1023. Date: Fri, 18 Aug 2023 17:55:08 +0300
  1024. Subject: [PATCH 07/13] video: test: Test video damage tracking via vidconsole
  1025. With VIDEO_DAMAGE, the video uclass tracks updated regions of the frame
  1026. buffer in order to avoid unnecessary work during a video sync. Enable
  1027. the config in sandbox and add a test for it, by printing strings at a
  1028. few locations and checking the tracked region.
  1029. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1030. Reviewed-by: Simon Glass <sjg@chromium.org>
  1031. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-8-alpernebiyasak@gmail.com/
  1032. ---
  1033. configs/sandbox_defconfig | 1 +
  1034. test/dm/video.c | 56 +++++++++++++++++++++++++++++++++++++++
  1035. 2 files changed, 57 insertions(+)
  1036. diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
  1037. index dc5fcdbd1c9e..5e5ad60ee057 100644
  1038. --- a/configs/sandbox_defconfig
  1039. +++ b/configs/sandbox_defconfig
  1040. @@ -319,6 +319,7 @@ CONFIG_USB_ETH_CDC=y
  1041. CONFIG_VIDEO=y
  1042. CONFIG_VIDEO_FONT_SUN12X22=y
  1043. CONFIG_VIDEO_COPY=y
  1044. +CONFIG_VIDEO_DAMAGE=y
  1045. CONFIG_CONSOLE_ROTATION=y
  1046. CONFIG_CONSOLE_TRUETYPE=y
  1047. CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
  1048. diff --git a/test/dm/video.c b/test/dm/video.c
  1049. index 4798f2205a99..119c43153165 100644
  1050. --- a/test/dm/video.c
  1051. +++ b/test/dm/video.c
  1052. @@ -710,3 +710,59 @@ static int dm_test_video_copy(struct unit_test_state *uts)
  1053. return 0;
  1054. }
  1055. DM_TEST(dm_test_video_copy, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  1056. +
  1057. +/* Test video damage tracking */
  1058. +static int dm_test_video_damage(struct unit_test_state *uts)
  1059. +{
  1060. + struct sandbox_sdl_plat *plat;
  1061. + struct udevice *dev, *con;
  1062. + struct video_priv *priv;
  1063. + const char *test_string_1 = "Criticism may not be agreeable, ";
  1064. + const char *test_string_2 = "but it is necessary.";
  1065. + const char *test_string_3 = "It fulfils the same function as pain in the human body.";
  1066. +
  1067. + if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE))
  1068. + return -EAGAIN;
  1069. +
  1070. + ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
  1071. + ut_assert(!device_active(dev));
  1072. + plat = dev_get_plat(dev);
  1073. + plat->font_size = 32;
  1074. +
  1075. + ut_assertok(video_get_nologo(uts, &dev));
  1076. + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
  1077. + priv = dev_get_uclass_priv(dev);
  1078. +
  1079. + vidconsole_position_cursor(con, 14, 10);
  1080. + vidconsole_put_string(con, test_string_2);
  1081. + ut_asserteq(449, priv->damage.xstart);
  1082. + ut_asserteq(325, priv->damage.ystart);
  1083. + ut_asserteq(661, priv->damage.xend);
  1084. + ut_asserteq(350, priv->damage.yend);
  1085. +
  1086. + vidconsole_position_cursor(con, 7, 5);
  1087. + vidconsole_put_string(con, test_string_1);
  1088. + ut_asserteq(225, priv->damage.xstart);
  1089. + ut_asserteq(164, priv->damage.ystart);
  1090. + ut_asserteq(661, priv->damage.xend);
  1091. + ut_asserteq(350, priv->damage.yend);
  1092. +
  1093. + vidconsole_position_cursor(con, 21, 15);
  1094. + vidconsole_put_string(con, test_string_3);
  1095. + ut_asserteq(225, priv->damage.xstart);
  1096. + ut_asserteq(164, priv->damage.ystart);
  1097. + ut_asserteq(1280, priv->damage.xend);
  1098. + ut_asserteq(510, priv->damage.yend);
  1099. +
  1100. + video_sync(dev, false);
  1101. + ut_asserteq(priv->xsize, priv->damage.xstart);
  1102. + ut_asserteq(priv->ysize, priv->damage.ystart);
  1103. + ut_asserteq(0, priv->damage.xend);
  1104. + ut_asserteq(0, priv->damage.yend);
  1105. +
  1106. + ut_asserteq(7339, compress_frame_buffer(uts, dev, false));
  1107. + ut_assertok(check_copy_frame_buffer(uts, dev));
  1108. +
  1109. + return 0;
  1110. +}
  1111. +DM_TEST(dm_test_video_damage, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  1112. --
  1113. 2.45.2
  1114. From f74688b9828f83306dea8553eafe61b5d81fbbe0 Mon Sep 17 00:00:00 2001
  1115. From: Alexander Graf <agraf@csgraf.de>
  1116. Date: Fri, 10 Jun 2022 00:59:18 +0200
  1117. Subject: [PATCH 08/13] video: Add damage notification on bmp display
  1118. Let's report the video damage when we draw a bitmap on the screen. This
  1119. way we can later lazily flush only relevant regions to hardware.
  1120. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1121. Reported-by: Da Xue <da@libre.computer>
  1122. Reviewed-by: Simon Glass <sjg@chromium.org>
  1123. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-9-alpernebiyasak@gmail.com/
  1124. ---
  1125. drivers/video/video_bmp.c | 2 ++
  1126. 1 file changed, 2 insertions(+)
  1127. diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
  1128. index ad512d99a1b9..78de95607924 100644
  1129. --- a/drivers/video/video_bmp.c
  1130. +++ b/drivers/video/video_bmp.c
  1131. @@ -459,6 +459,8 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
  1132. break;
  1133. };
  1134. + video_damage(dev, x, y, width, height);
  1135. +
  1136. /* Find the position of the top left of the image in the framebuffer */
  1137. fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
  1138. ret = video_sync_copy(dev, start, fb);
  1139. --
  1140. 2.45.2
  1141. From 791b0accde45ada93fdf61773f8c7e69b934e55e Mon Sep 17 00:00:00 2001
  1142. From: Alexander Graf <agraf@csgraf.de>
  1143. Date: Fri, 10 Jun 2022 00:59:19 +0200
  1144. Subject: [PATCH 09/13] efi_loader: GOP: Add damage notification on BLT
  1145. Now that we have a damage tracking API, let's populate damage done by
  1146. UEFI payloads when they BLT data onto the screen.
  1147. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1148. Reported-by: Da Xue <da@libre.computer>
  1149. Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
  1150. [Alper: Add struct comment for new member]
  1151. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1152. Reviewed-by: Simon Glass <sjg@chromium.org>
  1153. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-10-alpernebiyasak@gmail.com/
  1154. ---
  1155. lib/efi_loader/efi_gop.c | 7 +++++++
  1156. 1 file changed, 7 insertions(+)
  1157. diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
  1158. index 41e12fa72460..1694e23dcc62 100644
  1159. --- a/lib/efi_loader/efi_gop.c
  1160. +++ b/lib/efi_loader/efi_gop.c
  1161. @@ -24,6 +24,7 @@ static const efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  1162. * @ops: graphical output protocol interface
  1163. * @info: graphical output mode information
  1164. * @mode: graphical output mode
  1165. + * @vdev: backing video device
  1166. * @bpix: bits per pixel
  1167. * @fb: frame buffer
  1168. */
  1169. @@ -32,6 +33,7 @@ struct efi_gop_obj {
  1170. struct efi_gop ops;
  1171. struct efi_gop_mode_info info;
  1172. struct efi_gop_mode mode;
  1173. + struct udevice *vdev;
  1174. /* Fields we only have access to during init */
  1175. u32 bpix;
  1176. void *fb;
  1177. @@ -120,6 +122,7 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this,
  1178. u32 *fb32 = gopobj->fb;
  1179. u16 *fb16 = gopobj->fb;
  1180. struct efi_gop_pixel *buffer = __builtin_assume_aligned(bufferp, 4);
  1181. + bool blt_to_video = (operation != EFI_BLT_VIDEO_TO_BLT_BUFFER);
  1182. if (delta) {
  1183. /* Check for 4 byte alignment */
  1184. @@ -243,6 +246,9 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this,
  1185. dlineoff += dwidth;
  1186. }
  1187. + if (blt_to_video)
  1188. + video_damage(gopobj->vdev, dx, dy, width, height);
  1189. +
  1190. return EFI_SUCCESS;
  1191. }
  1192. @@ -549,6 +555,7 @@ efi_status_t efi_gop_register(void)
  1193. gopobj->info.pixels_per_scanline = col;
  1194. gopobj->bpix = bpix;
  1195. gopobj->fb = map_sysmem(fb_base, fb_size);
  1196. + gopobj->vdev = vdev;
  1197. return EFI_SUCCESS;
  1198. }
  1199. --
  1200. 2.45.2
  1201. From 1b0905d54711c6c170de575a36e66006b8a6583a Mon Sep 17 00:00:00 2001
  1202. From: Alexander Graf <agraf@csgraf.de>
  1203. Date: Fri, 10 Jun 2022 00:59:20 +0200
  1204. Subject: [PATCH 10/13] video: Only dcache flush damaged lines
  1205. Now that we have a damage area tells us which parts of the frame buffer
  1206. actually need updating, let's only dcache flush those on video_sync()
  1207. calls. With this optimization in place, frame buffer updates - especially
  1208. on large screen such as 4k displays - speed up significantly.
  1209. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1210. Reported-by: Da Xue <da@libre.computer>
  1211. [Alper: Use damage.xstart/yend, IS_ENABLED()]
  1212. Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1213. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1214. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-11-alpernebiyasak@gmail.com/
  1215. ---
  1216. drivers/video/video-uclass.c | 43 +++++++++++++++++++++++++++++++-----
  1217. 1 file changed, 38 insertions(+), 5 deletions(-)
  1218. diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
  1219. index 6906b2b83623..3f6572a124ea 100644
  1220. --- a/drivers/video/video-uclass.c
  1221. +++ b/drivers/video/video-uclass.c
  1222. @@ -384,6 +384,40 @@ void video_damage(struct udevice *vid, int x, int y, int width, int height)
  1223. }
  1224. #endif
  1225. +#if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  1226. +static void video_flush_dcache(struct udevice *vid, bool use_copy)
  1227. +{
  1228. + struct video_priv *priv = dev_get_uclass_priv(vid);
  1229. + ulong fb = use_copy ? (ulong)priv->copy_fb : (ulong)priv->fb;
  1230. +
  1231. + if (!priv->flush_dcache)
  1232. + return;
  1233. +
  1234. + if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) {
  1235. + flush_dcache_range(fb, ALIGN(fb + priv->fb_size,
  1236. + CONFIG_SYS_CACHELINE_SIZE));
  1237. +
  1238. + return;
  1239. + }
  1240. +
  1241. + if (priv->damage.xend && priv->damage.yend) {
  1242. + int lstart = priv->damage.xstart * VNBYTES(priv->bpix);
  1243. + int lend = priv->damage.xend * VNBYTES(priv->bpix);
  1244. + int y;
  1245. +
  1246. + for (y = priv->damage.ystart; y < priv->damage.yend; y++) {
  1247. + ulong start = fb + (y * priv->line_length) + lstart;
  1248. + ulong end = start + lend - lstart;
  1249. +
  1250. + start = ALIGN_DOWN(start, CONFIG_SYS_CACHELINE_SIZE);
  1251. + end = ALIGN(end, CONFIG_SYS_CACHELINE_SIZE);
  1252. +
  1253. + flush_dcache_range(start, end);
  1254. + }
  1255. + }
  1256. +}
  1257. +#endif
  1258. +
  1259. /* Flush video activity to the caches */
  1260. int video_sync(struct udevice *vid, bool force)
  1261. {
  1262. @@ -407,11 +441,10 @@ int video_sync(struct udevice *vid, bool force)
  1263. * out whether it exists? For now, ARM is safe.
  1264. */
  1265. #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  1266. - if (priv->flush_dcache) {
  1267. - flush_dcache_range((ulong)priv->fb,
  1268. - ALIGN((ulong)priv->fb + priv->fb_size,
  1269. - CONFIG_SYS_CACHELINE_SIZE));
  1270. - }
  1271. + video_flush_dcache(vid, false);
  1272. +
  1273. + if (IS_ENABLED(CONFIG_VIDEO_COPY))
  1274. + video_flush_dcache(vid, true);
  1275. #elif defined(CONFIG_VIDEO_SANDBOX_SDL)
  1276. sandbox_sdl_sync(priv->fb);
  1277. #endif
  1278. --
  1279. 2.45.2
  1280. From 4c02e522cb00b84cfa61004c32b4e5ae28457c58 Mon Sep 17 00:00:00 2001
  1281. From: Alexander Graf <agraf@csgraf.de>
  1282. Date: Fri, 10 Jun 2022 00:59:21 +0200
  1283. Subject: [PATCH 11/13] video: Use VIDEO_DAMAGE for VIDEO_COPY
  1284. CONFIG_VIDEO_COPY implemented a range-based copying mechanism: If we
  1285. print a single character, it will always copy the full range of bytes
  1286. from the top left corner of the character to the lower right onto the
  1287. uncached frame buffer. This includes pretty much the full line contents
  1288. of the printed character.
  1289. Since we now have proper damage tracking, let's make use of that to reduce
  1290. the amount of data we need to copy. With this patch applied, we will only
  1291. copy the tiny rectangle surrounding characters when we print them,
  1292. speeding up the video console.
  1293. After this, changes to the main frame buffer are not immediately copied
  1294. to the copy frame buffer, but postponed until the next video device
  1295. sync. So issue an explicit sync before inspecting the copy frame buffer
  1296. contents for the video tests.
  1297. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1298. [Alper: Rebase for fontdata->height/w, fill_part(), fix memmove(dev),
  1299. drop from defconfig, use damage.xstart/yend, use IS_ENABLED(),
  1300. call video_sync() before copy_fb check, update video_copy test]
  1301. Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1302. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1303. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-12-alpernebiyasak@gmail.com/
  1304. ---
  1305. configs/sandbox_defconfig | 1 -
  1306. drivers/video/Kconfig | 5 ++
  1307. drivers/video/console_normal.c | 13 +----
  1308. drivers/video/console_rotate.c | 44 +++-----------
  1309. drivers/video/console_truetype.c | 16 +-----
  1310. drivers/video/vidconsole-uclass.c | 16 ------
  1311. drivers/video/video-uclass.c | 96 ++++++++-----------------------
  1312. drivers/video/video_bmp.c | 7 ---
  1313. include/video.h | 37 ------------
  1314. include/video_console.h | 52 -----------------
  1315. test/dm/video.c | 3 +-
  1316. 11 files changed, 43 insertions(+), 247 deletions(-)
  1317. diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
  1318. index 5e5ad60ee057..dc5fcdbd1c9e 100644
  1319. --- a/configs/sandbox_defconfig
  1320. +++ b/configs/sandbox_defconfig
  1321. @@ -319,7 +319,6 @@ CONFIG_USB_ETH_CDC=y
  1322. CONFIG_VIDEO=y
  1323. CONFIG_VIDEO_FONT_SUN12X22=y
  1324. CONFIG_VIDEO_COPY=y
  1325. -CONFIG_VIDEO_DAMAGE=y
  1326. CONFIG_CONSOLE_ROTATION=y
  1327. CONFIG_CONSOLE_TRUETYPE=y
  1328. CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
  1329. diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
  1330. index d7da655cea62..d6497819ea73 100644
  1331. --- a/drivers/video/Kconfig
  1332. +++ b/drivers/video/Kconfig
  1333. @@ -89,11 +89,14 @@ config VIDEO_PCI_DEFAULT_FB_SIZE
  1334. config VIDEO_COPY
  1335. bool "Enable copying the frame buffer to a hardware copy"
  1336. + select VIDEO_DAMAGE
  1337. help
  1338. On some machines (e.g. x86), reading from the frame buffer is very
  1339. slow because it is uncached. To improve performance, this feature
  1340. allows the frame buffer to be kept in cached memory (allocated by
  1341. U-Boot) and then copied to the hardware frame-buffer as needed.
  1342. + It uses the VIDEO_DAMAGE feature to keep track of regions to copy
  1343. + and will only copy actually touched regions.
  1344. To use this, your video driver must set @copy_base in
  1345. struct video_uc_plat.
  1346. @@ -111,6 +114,8 @@ config VIDEO_DAMAGE
  1347. regions of the frame buffer that were modified before, speeding up
  1348. screen refreshes significantly.
  1349. + It is also used by VIDEO_COPY to identify which regions changed.
  1350. +
  1351. config BACKLIGHT_PWM
  1352. bool "Generic PWM based Backlight Driver"
  1353. depends on BACKLIGHT && DM_PWM
  1354. diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
  1355. index 51ac8cc78e9d..07db613ac53c 100644
  1356. --- a/drivers/video/console_normal.c
  1357. +++ b/drivers/video/console_normal.c
  1358. @@ -35,10 +35,6 @@ static int console_set_row(struct udevice *dev, uint row, int clr)
  1359. fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
  1360. end = dst;
  1361. - ret = vidconsole_sync_copy(dev, line, end);
  1362. - if (ret)
  1363. - return ret;
  1364. -
  1365. video_damage(dev->parent,
  1366. 0,
  1367. fontdata->height * row,
  1368. @@ -57,14 +53,11 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
  1369. void *dst;
  1370. void *src;
  1371. int size;
  1372. - int ret;
  1373. dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length;
  1374. src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length;
  1375. size = fontdata->height * vid_priv->line_length * count;
  1376. - ret = vidconsole_memmove(dev, dst, src, size);
  1377. - if (ret)
  1378. - return ret;
  1379. + memmove(dst, src, size);
  1380. video_damage(dev->parent,
  1381. 0,
  1382. @@ -109,10 +102,6 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
  1383. fontdata->width,
  1384. fontdata->height);
  1385. - ret = vidconsole_sync_copy(dev, start, line);
  1386. - if (ret)
  1387. - return ret;
  1388. -
  1389. return VID_TO_POS(fontdata->width);
  1390. }
  1391. diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
  1392. index f11dc3a0b075..886b25dcfafc 100644
  1393. --- a/drivers/video/console_rotate.c
  1394. +++ b/drivers/video/console_rotate.c
  1395. @@ -21,7 +21,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
  1396. int pbytes = VNBYTES(vid_priv->bpix);
  1397. void *start, *dst, *line;
  1398. int i, j;
  1399. - int ret;
  1400. start = vid_priv->fb + vid_priv->line_length -
  1401. (row + 1) * fontdata->height * pbytes;
  1402. @@ -32,9 +31,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
  1403. fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
  1404. line += vid_priv->line_length;
  1405. }
  1406. - ret = vidconsole_sync_copy(dev, start, line);
  1407. - if (ret)
  1408. - return ret;
  1409. video_damage(dev->parent,
  1410. vid_priv->xsize - ((row + 1) * fontdata->height),
  1411. @@ -54,7 +50,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
  1412. int pbytes = VNBYTES(vid_priv->bpix);
  1413. void *dst;
  1414. void *src;
  1415. - int j, ret;
  1416. + int j;
  1417. dst = vid_priv->fb + vid_priv->line_length -
  1418. (rowdst + count) * fontdata->height * pbytes;
  1419. @@ -62,10 +58,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
  1420. (rowsrc + count) * fontdata->height * pbytes;
  1421. for (j = 0; j < vid_priv->ysize; j++) {
  1422. - ret = vidconsole_memmove(dev, dst, src,
  1423. - fontdata->height * pbytes * count);
  1424. - if (ret)
  1425. - return ret;
  1426. + memmove(dst, src, fontdata->height * pbytes * count);
  1427. src += vid_priv->line_length;
  1428. dst += vid_priv->line_length;
  1429. }
  1430. @@ -105,10 +98,6 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
  1431. return ret;
  1432. /* We draw backwards from 'start, so account for the first line */
  1433. - ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
  1434. - if (ret)
  1435. - return ret;
  1436. -
  1437. video_damage(dev->parent,
  1438. vid_priv->xsize - y - fontdata->height,
  1439. linenum - 1,
  1440. @@ -125,7 +114,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
  1441. struct video_fontdata *fontdata = priv->fontdata;
  1442. void *start, *line, *dst, *end;
  1443. int pixels = fontdata->height * vid_priv->xsize;
  1444. - int i, ret;
  1445. + int i;
  1446. int pbytes = VNBYTES(vid_priv->bpix);
  1447. start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
  1448. @@ -135,9 +124,6 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
  1449. for (i = 0; i < pixels; i++)
  1450. fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
  1451. end = dst;
  1452. - ret = vidconsole_sync_copy(dev, start, end);
  1453. - if (ret)
  1454. - return ret;
  1455. video_damage(dev->parent,
  1456. 0,
  1457. @@ -163,8 +149,7 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
  1458. vid_priv->line_length;
  1459. src = end - (rowsrc + count) * fontdata->height *
  1460. vid_priv->line_length;
  1461. - vidconsole_memmove(dev, dst, src,
  1462. - fontdata->height * vid_priv->line_length * count);
  1463. + memmove(dst, src, fontdata->height * vid_priv->line_length * count);
  1464. video_damage(dev->parent,
  1465. 0,
  1466. @@ -200,11 +185,6 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
  1467. if (ret)
  1468. return ret;
  1469. - /* Add 4 bytes to allow for the first pixel writen */
  1470. - ret = vidconsole_sync_copy(dev, start + 4, line);
  1471. - if (ret)
  1472. - return ret;
  1473. -
  1474. video_damage(dev->parent,
  1475. x - fontdata->width + 1,
  1476. linenum - fontdata->height + 1,
  1477. @@ -221,7 +201,7 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
  1478. struct video_fontdata *fontdata = priv->fontdata;
  1479. int pbytes = VNBYTES(vid_priv->bpix);
  1480. void *start, *dst, *line;
  1481. - int i, j, ret;
  1482. + int i, j;
  1483. start = vid_priv->fb + row * fontdata->height * pbytes;
  1484. line = start;
  1485. @@ -231,9 +211,6 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
  1486. fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
  1487. line += vid_priv->line_length;
  1488. }
  1489. - ret = vidconsole_sync_copy(dev, start, line);
  1490. - if (ret)
  1491. - return ret;
  1492. video_damage(dev->parent,
  1493. row * fontdata->height,
  1494. @@ -253,16 +230,13 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
  1495. int pbytes = VNBYTES(vid_priv->bpix);
  1496. void *dst;
  1497. void *src;
  1498. - int j, ret;
  1499. + int j;
  1500. dst = vid_priv->fb + rowdst * fontdata->height * pbytes;
  1501. src = vid_priv->fb + rowsrc * fontdata->height * pbytes;
  1502. for (j = 0; j < vid_priv->ysize; j++) {
  1503. - ret = vidconsole_memmove(dev, dst, src,
  1504. - fontdata->height * pbytes * count);
  1505. - if (ret)
  1506. - return ret;
  1507. + memmove(dst, src, fontdata->height * pbytes * count);
  1508. src += vid_priv->line_length;
  1509. dst += vid_priv->line_length;
  1510. }
  1511. @@ -298,10 +272,6 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
  1512. line = start;
  1513. ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
  1514. - if (ret)
  1515. - return ret;
  1516. - /* Add a line to allow for the first pixels writen */
  1517. - ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
  1518. if (ret)
  1519. return ret;
  1520. diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
  1521. index 6a17f732fc26..58dcd8e050c3 100644
  1522. --- a/drivers/video/console_truetype.c
  1523. +++ b/drivers/video/console_truetype.c
  1524. @@ -194,7 +194,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
  1525. struct console_tt_priv *priv = dev_get_priv(dev);
  1526. struct console_tt_metrics *met = priv->cur_met;
  1527. void *end, *line;
  1528. - int ret;
  1529. line = vid_priv->fb + row * met->font_size * vid_priv->line_length;
  1530. end = line + met->font_size * vid_priv->line_length;
  1531. @@ -230,9 +229,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
  1532. default:
  1533. return -ENOSYS;
  1534. }
  1535. - ret = vidconsole_sync_copy(dev, line, end);
  1536. - if (ret)
  1537. - return ret;
  1538. video_damage(dev->parent,
  1539. 0,
  1540. @@ -252,14 +248,11 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
  1541. struct console_tt_metrics *met = priv->cur_met;
  1542. void *dst;
  1543. void *src;
  1544. - int i, diff, ret;
  1545. + int i, diff;
  1546. dst = vid_priv->fb + rowdst * met->font_size * vid_priv->line_length;
  1547. src = vid_priv->fb + rowsrc * met->font_size * vid_priv->line_length;
  1548. - ret = vidconsole_memmove(dev, dst, src, met->font_size *
  1549. - vid_priv->line_length * count);
  1550. - if (ret)
  1551. - return ret;
  1552. + memmove(dst, src, met->font_size * vid_priv->line_length * count);
  1553. /* Scroll up our position history */
  1554. diff = (rowsrc - rowdst) * met->font_size;
  1555. @@ -292,7 +285,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
  1556. u8 *bits, *data;
  1557. int advance;
  1558. void *start, *end, *line;
  1559. - int row, ret;
  1560. + int row;
  1561. /* First get some basic metrics about this character */
  1562. stbtt_GetCodepointHMetrics(font, cp, &advance, &lsb);
  1563. @@ -439,9 +432,6 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
  1564. width,
  1565. height);
  1566. - ret = vidconsole_sync_copy(dev, start, line);
  1567. - if (ret)
  1568. - return ret;
  1569. free(data);
  1570. return width_frac;
  1571. diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
  1572. index 8b2ef51f1b3b..bcc46a08cbbd 100644
  1573. --- a/drivers/video/vidconsole-uclass.c
  1574. +++ b/drivers/video/vidconsole-uclass.c
  1575. @@ -801,22 +801,6 @@ UCLASS_DRIVER(vidconsole) = {
  1576. .per_device_auto = sizeof(struct vidconsole_priv),
  1577. };
  1578. -#ifdef CONFIG_VIDEO_COPY
  1579. -int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
  1580. -{
  1581. - struct udevice *vid = dev_get_parent(dev);
  1582. -
  1583. - return video_sync_copy(vid, from, to);
  1584. -}
  1585. -
  1586. -int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
  1587. - int size)
  1588. -{
  1589. - memmove(dst, src, size);
  1590. - return vidconsole_sync_copy(dev, dst, dst + size);
  1591. -}
  1592. -#endif
  1593. -
  1594. int vidconsole_clear_and_reset(struct udevice *dev)
  1595. {
  1596. int ret;
  1597. diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
  1598. index 3f6572a124ea..845db1c9b6d3 100644
  1599. --- a/drivers/video/video-uclass.c
  1600. +++ b/drivers/video/video-uclass.c
  1601. @@ -158,7 +158,7 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
  1602. struct video_priv *priv = dev_get_uclass_priv(dev);
  1603. void *start, *line;
  1604. int pixels = xend - xstart;
  1605. - int row, i, ret;
  1606. + int row, i;
  1607. start = priv->fb + ystart * priv->line_length;
  1608. start += xstart * VNBYTES(priv->bpix);
  1609. @@ -197,9 +197,6 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
  1610. }
  1611. line += priv->line_length;
  1612. }
  1613. - ret = video_sync_copy(dev, start, line);
  1614. - if (ret)
  1615. - return ret;
  1616. video_damage(dev, xstart, ystart, xend - xstart, yend - ystart);
  1617. @@ -223,7 +220,6 @@ int video_reserve_from_bloblist(struct video_handoff *ho)
  1618. int video_fill(struct udevice *dev, u32 colour)
  1619. {
  1620. struct video_priv *priv = dev_get_uclass_priv(dev);
  1621. - int ret;
  1622. switch (priv->bpix) {
  1623. case VIDEO_BPP16:
  1624. @@ -248,9 +244,6 @@ int video_fill(struct udevice *dev, u32 colour)
  1625. memset(priv->fb, colour, priv->fb_size);
  1626. break;
  1627. }
  1628. - ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
  1629. - if (ret)
  1630. - return ret;
  1631. video_damage(dev, 0, 0, priv->xsize, priv->ysize);
  1632. @@ -418,6 +411,27 @@ static void video_flush_dcache(struct udevice *vid, bool use_copy)
  1633. }
  1634. #endif
  1635. +static void video_flush_copy(struct udevice *vid)
  1636. +{
  1637. + struct video_priv *priv = dev_get_uclass_priv(vid);
  1638. +
  1639. + if (!priv->copy_fb)
  1640. + return;
  1641. +
  1642. + if (priv->damage.xend && priv->damage.yend) {
  1643. + int lstart = priv->damage.xstart * VNBYTES(priv->bpix);
  1644. + int lend = priv->damage.xend * VNBYTES(priv->bpix);
  1645. + int y;
  1646. +
  1647. + for (y = priv->damage.ystart; y < priv->damage.yend; y++) {
  1648. + ulong offset = (y * priv->line_length) + lstart;
  1649. + ulong len = lend - lstart;
  1650. +
  1651. + memcpy(priv->copy_fb + offset, priv->fb + offset, len);
  1652. + }
  1653. + }
  1654. +}
  1655. +
  1656. /* Flush video activity to the caches */
  1657. int video_sync(struct udevice *vid, bool force)
  1658. {
  1659. @@ -425,6 +439,9 @@ int video_sync(struct udevice *vid, bool force)
  1660. struct video_ops *ops = video_get_ops(vid);
  1661. int ret;
  1662. + if (IS_ENABLED(CONFIG_VIDEO_COPY))
  1663. + video_flush_copy(vid);
  1664. +
  1665. if (ops && ops->video_sync) {
  1666. ret = ops->video_sync(vid);
  1667. if (ret)
  1668. @@ -508,69 +525,6 @@ int video_get_ysize(struct udevice *dev)
  1669. return priv->ysize;
  1670. }
  1671. -#ifdef CONFIG_VIDEO_COPY
  1672. -int video_sync_copy(struct udevice *dev, void *from, void *to)
  1673. -{
  1674. - struct video_priv *priv = dev_get_uclass_priv(dev);
  1675. -
  1676. - if (priv->copy_fb) {
  1677. - long offset, size;
  1678. -
  1679. - /* Find the offset of the first byte to copy */
  1680. - if ((ulong)to > (ulong)from) {
  1681. - size = to - from;
  1682. - offset = from - priv->fb;
  1683. - } else {
  1684. - size = from - to;
  1685. - offset = to - priv->fb;
  1686. - }
  1687. -
  1688. - /*
  1689. - * Allow a bit of leeway for valid requests somewhere near the
  1690. - * frame buffer
  1691. - */
  1692. - if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
  1693. -#ifdef DEBUG
  1694. - char str[120];
  1695. -
  1696. - snprintf(str, sizeof(str),
  1697. - "[** FAULT sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
  1698. - priv->fb, from, to, offset);
  1699. - console_puts_select_stderr(true, str);
  1700. -#endif
  1701. - return -EFAULT;
  1702. - }
  1703. -
  1704. - /*
  1705. - * Silently crop the memcpy. This allows callers to avoid doing
  1706. - * this themselves. It is common for the end pointer to go a
  1707. - * few lines after the end of the frame buffer, since most of
  1708. - * the update algorithms terminate a line after their last write
  1709. - */
  1710. - if (offset + size > priv->fb_size) {
  1711. - size = priv->fb_size - offset;
  1712. - } else if (offset < 0) {
  1713. - size += offset;
  1714. - offset = 0;
  1715. - }
  1716. -
  1717. - memcpy(priv->copy_fb + offset, priv->fb + offset, size);
  1718. - }
  1719. -
  1720. - return 0;
  1721. -}
  1722. -
  1723. -int video_sync_copy_all(struct udevice *dev)
  1724. -{
  1725. - struct video_priv *priv = dev_get_uclass_priv(dev);
  1726. -
  1727. - video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
  1728. -
  1729. - return 0;
  1730. -}
  1731. -
  1732. -#endif
  1733. -
  1734. #define SPLASH_DECL(_name) \
  1735. extern u8 __splash_ ## _name ## _begin[]; \
  1736. extern u8 __splash_ ## _name ## _end[]
  1737. diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
  1738. index 78de95607924..1f267d45812c 100644
  1739. --- a/drivers/video/video_bmp.c
  1740. +++ b/drivers/video/video_bmp.c
  1741. @@ -267,7 +267,6 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
  1742. enum video_format eformat;
  1743. struct bmp_color_table_entry *palette;
  1744. int hdr_size;
  1745. - int ret;
  1746. if (!bmp || !(bmp->header.signature[0] == 'B' &&
  1747. bmp->header.signature[1] == 'M')) {
  1748. @@ -461,11 +460,5 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
  1749. video_damage(dev, x, y, width, height);
  1750. - /* Find the position of the top left of the image in the framebuffer */
  1751. - fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
  1752. - ret = video_sync_copy(dev, start, fb);
  1753. - if (ret)
  1754. - return log_ret(ret);
  1755. -
  1756. return video_sync(dev, false);
  1757. }
  1758. diff --git a/include/video.h b/include/video.h
  1759. index 835d7734cb75..705076facfb5 100644
  1760. --- a/include/video.h
  1761. +++ b/include/video.h
  1762. @@ -355,43 +355,6 @@ void video_set_default_colors(struct udevice *dev, bool invert);
  1763. */
  1764. int video_default_font_height(struct udevice *dev);
  1765. -#ifdef CONFIG_VIDEO_COPY
  1766. -/**
  1767. - * vidconsole_sync_copy() - Sync back to the copy framebuffer
  1768. - *
  1769. - * This ensures that the copy framebuffer has the same data as the framebuffer
  1770. - * for a particular region. It should be called after the framebuffer is updated
  1771. - *
  1772. - * @from and @to can be in either order. The region between them is synced.
  1773. - *
  1774. - * @dev: Vidconsole device being updated
  1775. - * @from: Start/end address within the framebuffer (->fb)
  1776. - * @to: Other address within the frame buffer
  1777. - * Return: 0 if OK, -EFAULT if the start address is before the start of the
  1778. - * frame buffer start
  1779. - */
  1780. -int video_sync_copy(struct udevice *dev, void *from, void *to);
  1781. -
  1782. -/**
  1783. - * video_sync_copy_all() - Sync the entire framebuffer to the copy
  1784. - *
  1785. - * @dev: Vidconsole device being updated
  1786. - * Return: 0 (always)
  1787. - */
  1788. -int video_sync_copy_all(struct udevice *dev);
  1789. -#else
  1790. -static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
  1791. -{
  1792. - return 0;
  1793. -}
  1794. -
  1795. -static inline int video_sync_copy_all(struct udevice *dev)
  1796. -{
  1797. - return 0;
  1798. -}
  1799. -
  1800. -#endif
  1801. -
  1802. #ifdef CONFIG_VIDEO_DAMAGE
  1803. /**
  1804. * video_damage() - Notify the video subsystem about screen updates.
  1805. diff --git a/include/video_console.h b/include/video_console.h
  1806. index 00c5ecb664b9..ead0e05e4003 100644
  1807. --- a/include/video_console.h
  1808. +++ b/include/video_console.h
  1809. @@ -530,56 +530,4 @@ void vidconsole_list_fonts(struct udevice *dev);
  1810. */
  1811. int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
  1812. -#ifdef CONFIG_VIDEO_COPY
  1813. -/**
  1814. - * vidconsole_sync_copy() - Sync back to the copy framebuffer
  1815. - *
  1816. - * This ensures that the copy framebuffer has the same data as the framebuffer
  1817. - * for a particular region. It should be called after the framebuffer is updated
  1818. - *
  1819. - * @from and @to can be in either order. The region between them is synced.
  1820. - *
  1821. - * @dev: Vidconsole device being updated
  1822. - * @from: Start/end address within the framebuffer (->fb)
  1823. - * @to: Other address within the frame buffer
  1824. - * Return: 0 if OK, -EFAULT if the start address is before the start of the
  1825. - * frame buffer start
  1826. - */
  1827. -int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
  1828. -
  1829. -/**
  1830. - * vidconsole_memmove() - Perform a memmove() within the frame buffer
  1831. - *
  1832. - * This handles a memmove(), e.g. for scrolling. It also updates the copy
  1833. - * framebuffer.
  1834. - *
  1835. - * @dev: Vidconsole device being updated
  1836. - * @dst: Destination address within the framebuffer (->fb)
  1837. - * @src: Source address within the framebuffer (->fb)
  1838. - * @size: Number of bytes to transfer
  1839. - * Return: 0 if OK, -EFAULT if the start address is before the start of the
  1840. - * frame buffer start
  1841. - */
  1842. -int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
  1843. - int size);
  1844. -#else
  1845. -
  1846. -#include <string.h>
  1847. -
  1848. -static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
  1849. - void *to)
  1850. -{
  1851. - return 0;
  1852. -}
  1853. -
  1854. -static inline int vidconsole_memmove(struct udevice *dev, void *dst,
  1855. - const void *src, int size)
  1856. -{
  1857. - memmove(dst, src, size);
  1858. -
  1859. - return 0;
  1860. -}
  1861. -
  1862. -#endif
  1863. -
  1864. #endif
  1865. diff --git a/test/dm/video.c b/test/dm/video.c
  1866. index 119c43153165..9b7bb51a3dd9 100644
  1867. --- a/test/dm/video.c
  1868. +++ b/test/dm/video.c
  1869. @@ -105,6 +105,7 @@ static int check_copy_frame_buffer(struct unit_test_state *uts,
  1870. if (!IS_ENABLED(CONFIG_VIDEO_COPY))
  1871. return 0;
  1872. + video_sync(dev, false);
  1873. ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
  1874. "Copy framebuffer does not match fb");
  1875. @@ -705,7 +706,7 @@ static int dm_test_video_copy(struct unit_test_state *uts)
  1876. vidconsole_put_string(con, test_string);
  1877. vidconsole_put_string(con, test_string);
  1878. ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
  1879. - ut_asserteq(5278, compress_frame_buffer(uts, dev, true));
  1880. + ut_asserteq(4127, compress_frame_buffer(uts, dev, true));
  1881. return 0;
  1882. }
  1883. --
  1884. 2.45.2
  1885. From 174b8b118c02e7cadf9ad56462b481c91f4a3343 Mon Sep 17 00:00:00 2001
  1886. From: Alexander Graf <agraf@csgraf.de>
  1887. Date: Tue, 3 Jan 2023 22:50:03 +0100
  1888. Subject: [PATCH 12/13] video: Always compile cache flushing code
  1889. The dcache flushing code path was conditional on ARM && !DCACHE config
  1890. options. However, dcaches exist on other platforms as well and may need
  1891. clearing if their driver requires it.
  1892. Simplify the compile logic and always enable the dcache flush logic in
  1893. the video core. That way, drivers can always rely on it to call the arch
  1894. specific callbacks.
  1895. This will increase code size for non-ARM platforms with CONFIG_VIDEO=y
  1896. slightly.
  1897. Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
  1898. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1899. Reviewed-by: Simon Glass <sjg@chromium.org>
  1900. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-13-alpernebiyasak@gmail.com/
  1901. ---
  1902. drivers/video/video-uclass.c | 12 +++++-------
  1903. 1 file changed, 5 insertions(+), 7 deletions(-)
  1904. diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
  1905. index 845db1c9b6d3..5416e0d9030b 100644
  1906. --- a/drivers/video/video-uclass.c
  1907. +++ b/drivers/video/video-uclass.c
  1908. @@ -383,6 +383,9 @@ static void video_flush_dcache(struct udevice *vid, bool use_copy)
  1909. struct video_priv *priv = dev_get_uclass_priv(vid);
  1910. ulong fb = use_copy ? (ulong)priv->copy_fb : (ulong)priv->fb;
  1911. + if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
  1912. + return;
  1913. +
  1914. if (!priv->flush_dcache)
  1915. return;
  1916. @@ -452,17 +455,12 @@ int video_sync(struct udevice *vid, bool force)
  1917. get_timer(priv->last_sync) < CONFIG_VIDEO_SYNC_MS)
  1918. return 0;
  1919. - /*
  1920. - * flush_dcache_range() is declared in common.h but it seems that some
  1921. - * architectures do not actually implement it. Is there a way to find
  1922. - * out whether it exists? For now, ARM is safe.
  1923. - */
  1924. -#if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  1925. video_flush_dcache(vid, false);
  1926. if (IS_ENABLED(CONFIG_VIDEO_COPY))
  1927. video_flush_dcache(vid, true);
  1928. -#elif defined(CONFIG_VIDEO_SANDBOX_SDL)
  1929. +
  1930. +#if defined(CONFIG_VIDEO_SANDBOX_SDL)
  1931. sandbox_sdl_sync(priv->fb);
  1932. #endif
  1933. priv->last_sync = get_timer(0);
  1934. --
  1935. 2.45.2
  1936. From 2a1af00665464023c38903eeb75a0c89099892fb Mon Sep 17 00:00:00 2001
  1937. From: Alexander Graf <agraf@csgraf.de>
  1938. Date: Tue, 3 Jan 2023 22:50:04 +0100
  1939. Subject: [PATCH 13/13] video: Enable VIDEO_DAMAGE for drivers that need it
  1940. Some drivers call video_set_flush_dcache() to indicate that they want to
  1941. have the dcache flushed for the frame buffer. These drivers benefit from
  1942. our new video damage control, because we can reduce the amount of memory
  1943. that gets flushed significantly.
  1944. This patch enables video damage control for all device drivers that call
  1945. video_set_flush_dcache() to make sure they benefit from it.
  1946. Signed-off-by: Alexander Graf <agraf@csgraf.de>
  1947. [Alper: Add to VIDEO_TIDSS, imply instead of select]
  1948. Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1949. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
  1950. Reviewed-by: Simon Glass <sjg@chromium.org>
  1951. Link: https://lore.kernel.org/u-boot/20230821135111.3558478-14-alpernebiyasak@gmail.com/
  1952. ---
  1953. arch/arm/mach-sunxi/Kconfig | 1 +
  1954. drivers/video/Kconfig | 8 ++++++++
  1955. drivers/video/exynos/Kconfig | 1 +
  1956. drivers/video/imx/Kconfig | 1 +
  1957. drivers/video/meson/Kconfig | 1 +
  1958. drivers/video/rockchip/Kconfig | 1 +
  1959. drivers/video/stm32/Kconfig | 1 +
  1960. drivers/video/tegra20/Kconfig | 1 +
  1961. drivers/video/tidss/Kconfig | 1 +
  1962. 9 files changed, 16 insertions(+)
  1963. diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
  1964. index 17666814c52e..1ba0d2c1c8d7 100644
  1965. --- a/arch/arm/mach-sunxi/Kconfig
  1966. +++ b/arch/arm/mach-sunxi/Kconfig
  1967. @@ -863,6 +863,7 @@ config VIDEO_SUNXI
  1968. depends on !SUNXI_GEN_NCAT2
  1969. select VIDEO
  1970. select DISPLAY
  1971. + imply VIDEO_DAMAGE
  1972. imply VIDEO_DT_SIMPLEFB
  1973. default y
  1974. ---help---
  1975. diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
  1976. index d6497819ea73..8fb69e0b16c2 100644
  1977. --- a/drivers/video/Kconfig
  1978. +++ b/drivers/video/Kconfig
  1979. @@ -534,6 +534,7 @@ config VIDEO_LCD_ANX9804
  1980. config ATMEL_LCD
  1981. bool "Atmel LCD panel support"
  1982. + imply VIDEO_DAMAGE
  1983. depends on ARCH_AT91
  1984. config ATMEL_LCD_BGR555
  1985. @@ -543,6 +544,7 @@ config ATMEL_LCD_BGR555
  1986. config VIDEO_BCM2835
  1987. bool "Display support for BCM2835"
  1988. + imply VIDEO_DAMAGE
  1989. help
  1990. The graphics processor already sets up the display so this driver
  1991. simply checks the resolution and then sets up the frame buffer with
  1992. @@ -706,6 +708,7 @@ source "drivers/video/meson/Kconfig"
  1993. config VIDEO_MVEBU
  1994. bool "Armada XP LCD controller"
  1995. + imply VIDEO_DAMAGE
  1996. ---help---
  1997. Support for the LCD controller integrated in the Marvell
  1998. Armada XP SoC.
  1999. @@ -740,6 +743,7 @@ config NXP_TDA19988
  2000. config ATMEL_HLCD
  2001. bool "Enable ATMEL video support using HLCDC"
  2002. + imply VIDEO_DAMAGE
  2003. help
  2004. HLCDC supports video output to an attached LCD panel.
  2005. @@ -816,6 +820,7 @@ source "drivers/video/tidss/Kconfig"
  2006. config VIDEO_TEGRA124
  2007. bool "Enable video support on Tegra124"
  2008. + imply VIDEO_DAMAGE
  2009. help
  2010. Tegra124 supports many video output options including eDP and
  2011. HDMI. At present only eDP is supported by U-Boot. This option
  2012. @@ -830,6 +835,7 @@ source "drivers/video/imx/Kconfig"
  2013. config VIDEO_MXS
  2014. bool "Enable video support on i.MX28/i.MX6UL/i.MX7 SoCs"
  2015. + imply VIDEO_DAMAGE
  2016. help
  2017. Enable framebuffer driver for i.MX28/i.MX6UL/i.MX7 processors
  2018. @@ -892,6 +898,7 @@ config VIDEO_DW_MIPI_DSI
  2019. config VIDEO_SIMPLE
  2020. bool "Simple display driver for preconfigured display"
  2021. + imply VIDEO_DAMAGE
  2022. help
  2023. Enables a simple generic display driver which utilizes the
  2024. simple-framebuffer devicetree bindings.
  2025. @@ -910,6 +917,7 @@ config VIDEO_DT_SIMPLEFB
  2026. config VIDEO_MCDE_SIMPLE
  2027. bool "Simple driver for ST-Ericsson MCDE with preconfigured display"
  2028. + imply VIDEO_DAMAGE
  2029. help
  2030. Enables a simple display driver for ST-Ericsson MCDE
  2031. (Multichannel Display Engine), which reads the configuration from
  2032. diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
  2033. index 599d19d5ecc2..a2cf752aac03 100644
  2034. --- a/drivers/video/exynos/Kconfig
  2035. +++ b/drivers/video/exynos/Kconfig
  2036. @@ -12,6 +12,7 @@ config EXYNOS_DP
  2037. config EXYNOS_FB
  2038. bool "Exynos FIMD support"
  2039. + imply VIDEO_DAMAGE
  2040. config EXYNOS_MIPI_DSIM
  2041. bool "Exynos MIPI DSI support"
  2042. diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig
  2043. index 34e8b640595b..5db3e5c0499e 100644
  2044. --- a/drivers/video/imx/Kconfig
  2045. +++ b/drivers/video/imx/Kconfig
  2046. @@ -2,6 +2,7 @@
  2047. config VIDEO_IPUV3
  2048. bool "i.MX IPUv3 Core video support"
  2049. depends on VIDEO && (MX5 || MX6)
  2050. + imply VIDEO_DAMAGE
  2051. help
  2052. This enables framebuffer driver for i.MX processors working
  2053. on the IPUv3(Image Processing Unit) internal graphic processor.
  2054. diff --git a/drivers/video/meson/Kconfig b/drivers/video/meson/Kconfig
  2055. index 3c2d72d019b8..fcf486ca0a3a 100644
  2056. --- a/drivers/video/meson/Kconfig
  2057. +++ b/drivers/video/meson/Kconfig
  2058. @@ -8,5 +8,6 @@ config VIDEO_MESON
  2059. bool "Enable Amlogic Meson video support"
  2060. depends on VIDEO
  2061. select DISPLAY
  2062. + imply VIDEO_DAMAGE
  2063. help
  2064. Enable Amlogic Meson Video Processing Unit video support.
  2065. diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig
  2066. index 01804dcb1cc8..0f4550a29e38 100644
  2067. --- a/drivers/video/rockchip/Kconfig
  2068. +++ b/drivers/video/rockchip/Kconfig
  2069. @@ -11,6 +11,7 @@
  2070. menuconfig VIDEO_ROCKCHIP
  2071. bool "Enable Rockchip Video Support"
  2072. depends on VIDEO
  2073. + imply VIDEO_DAMAGE
  2074. help
  2075. Rockchip SoCs provide video output capabilities for High-Definition
  2076. Multimedia Interface (HDMI), Low-voltage Differential Signalling
  2077. diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig
  2078. index 48066063e4c5..c354c402c288 100644
  2079. --- a/drivers/video/stm32/Kconfig
  2080. +++ b/drivers/video/stm32/Kconfig
  2081. @@ -8,6 +8,7 @@
  2082. menuconfig VIDEO_STM32
  2083. bool "Enable STM32 video support"
  2084. depends on VIDEO
  2085. + imply VIDEO_DAMAGE
  2086. help
  2087. STM32 supports many video output options including RGB and
  2088. DSI. This option enables these supports which can be used on
  2089. diff --git a/drivers/video/tegra20/Kconfig b/drivers/video/tegra20/Kconfig
  2090. index f5c4843e1191..2232b0b3ff53 100644
  2091. --- a/drivers/video/tegra20/Kconfig
  2092. +++ b/drivers/video/tegra20/Kconfig
  2093. @@ -1,6 +1,7 @@
  2094. config VIDEO_TEGRA20
  2095. bool "Enable Display Controller support on Tegra20 and Tegra 30"
  2096. depends on OF_CONTROL
  2097. + imply VIDEO_DAMAGE
  2098. help
  2099. T20/T30 support video output to an attached LCD panel as well as
  2100. other options such as HDMI. Only the LCD is supported in U-Boot.
  2101. diff --git a/drivers/video/tidss/Kconfig b/drivers/video/tidss/Kconfig
  2102. index 95086f3a5d66..3291b3ceb8d5 100644
  2103. --- a/drivers/video/tidss/Kconfig
  2104. +++ b/drivers/video/tidss/Kconfig
  2105. @@ -11,6 +11,7 @@
  2106. menuconfig VIDEO_TIDSS
  2107. bool "Enable TIDSS video support"
  2108. depends on VIDEO
  2109. + imply VIDEO_DAMAGE
  2110. help
  2111. TIDSS supports video output options LVDS and
  2112. DPI . This option enables these supports which can be used on
  2113. --
  2114. 2.45.2