<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:#0000FF;margin:5pt;" align="Left">
[AMD Official Use Only - General]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Chandan,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
The dirty rectangle combination is implemented in DMUB firmware instead of DC/DM layer in kernel. The "max # of dirty RECTs of 3" is the limitation in DMUB FW.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
regards</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
David</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> VURDIGERENATARAJ, CHANDAN <CHANDAN.VURDIGERENATARAJ@amd.com><br>
<b>Sent:</b> Monday, May 9, 2022 4:12 AM<br>
<b>To:</b> Zhang, Dingchen (David) <Dingchen.Zhang@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Wang, Chao-kai (Stylon) <Stylon.Wang@amd.com>; Li, Sun peng (Leo) <Sunpeng.Li@amd.com>; Wentland, Harry <Harry.Wentland@amd.com>; Zhuo, Qingqing (Lillian) <Qingqing.Zhuo@amd.com>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; Li, Roman <Roman.Li@amd.com>;
 Chiu, Solomon <Solomon.Chiu@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>; Pillai, Aurabindo <Aurabindo.Pillai@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Lakha, Bhawanpreet <Bhawanpreet.Lakha@amd.com>; Gutierrez, Agustin <Agustin.Gutierrez@amd.com>; Kotarac, Pavle
 <Pavle.Kotarac@amd.com><br>
<b>Subject:</b> RE: [PATCH 03/17] drm/amd/display: combine dirty rectangles in DMUB FW</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi,<br>
<br>
<br>
Why is the DC_MAX_DIRTY_RECTS set to 3? What causes this limitation?<br>
 <br>
>[why]<br>
>In PSR-SU design, the DMUB FW handles the combination of multiple dirty rectangles.<br>
><br>
>[how]<br>
>- create DC dmub update dirty rectangle helper which sends the<br>
>  dirty rectangles per pipe from DC to DMUB, and DMUB FW will<br>
>  handle to combine the dirty RECTs<br>
>- call the helper from DC commit plane update function.<br>
><br>
>Signed-off-by: David Zhang <dingchen.zhang@amd.com><br>
>---<br>
> drivers/gpu/drm/amd/display/dc/core/dc.c   | 54 ++++++++++++++++++++++<br>
> drivers/gpu/drm/amd/display/dc/dc.h        |  3 ++<br>
> drivers/gpu/drm/amd/display/dc/dc_stream.h |  5 ++<br>
> 3 files changed, 62 insertions(+)<br>
><br>
>diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c<br>
>index c2fcd67bcc4d..0649d84b71b6 100644<br>
>--- a/drivers/gpu/drm/amd/display/dc/core/dc.c<br>
>+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c<br>
>@@ -72,6 +72,9 @@<br>
> #include "dmub/dmub_srv.h"<br>
> <br>
> #include "i2caux_interface.h"<br>
>+<br>
>+#include "dce/dmub_psr.h"<br>
>+<br>
> #include "dce/dmub_hw_lock_mgr.h"<br>
> <br>
> #include "dc_trace.h"<br>
>@@ -2842,6 +2845,55 @@ static void commit_planes_do_stream_update(struct dc *dc,<br>
>        }<br>
> }<br>
> <br>
>+void dc_dmub_update_dirty_rect(struct dc *dc,<br>
>+                             int surface_count,<br>
>+                             struct dc_stream_state *stream,<br>
>+                             struct dc_surface_update *srf_updates,<br>
>+                             struct dc_state *context)<br>
>+{<br>
>+      union dmub_rb_cmd cmd;<br>
>+      struct dc_context *dc_ctx = dc->ctx;<br>
>+      struct dmub_cmd_update_dirty_rect_data *update_dirty_rect;<br>
>+      unsigned int i, j;<br>
>+<br>
>+      if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_SU_1)<br>
>+              return;<br>
>+<br>
>+      memset(&cmd, 0x0, sizeof(cmd));<br>
>+      cmd.update_dirty_rect.header.type = DMUB_CMD__UPDATE_DIRTY_RECT;<br>
>+      cmd.update_dirty_rect.header.sub_type = 0;<br>
>+      cmd.update_dirty_rect.header.payload_bytes =<br>
>+              sizeof(cmd.update_dirty_rect) -<br>
>+              sizeof(cmd.update_dirty_rect.header);<br>
>+      update_dirty_rect = &cmd.update_dirty_rect.update_dirty_rect_data;<br>
>+      for (i = 0; i < surface_count; i++) {<br>
>+              struct dc_plane_state *plane_state = srf_updates[i].surface;<br>
>+              const struct dc_flip_addrs *flip_addr = srf_updates[i].flip_addr;<br>
>+<br>
>+              if (!srf_updates[i].surface || !flip_addr)<br>
>+                      continue;<br>
>+              /* Do not send in immediate flip mode */<br>
>+              if (srf_updates[i].surface->flip_immediate)<br>
>+                      continue;<br>
>+<br>
>+              update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count;<br>
>+              memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects,<br>
>+                              sizeof(flip_addr->dirty_rects));<br>
>+              for (j = 0; j < dc->res_pool->pipe_count; j++) {<br>
>+                      struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];<br>
>+<br>
>+                      if (pipe_ctx->stream != stream)<br>
>+                              continue;<br>
>+                      if (pipe_ctx->plane_state != plane_state)<br>
>+                              continue;<br>
>+<br>
>+                      update_dirty_rect->pipe_idx = j;<br>
>+                      dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd);<br>
>+                      dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv);<br>
>+              }<br>
>+      }<br>
>+}<br>
>+<br>
> static void commit_planes_for_stream(struct dc *dc,<br>
>                struct dc_surface_update *srf_updates,<br>
>                int surface_count,<br>
>@@ -2934,6 +2986,8 @@ static void commit_planes_for_stream(struct dc *dc,<br>
>                 */<br>
>               dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);<br>
> <br>
>+      dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, <br>
>+context);<br>
>+<br>
>        // Stream updates<br>
>        if (stream_update)<br>
>                commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); diff --git >a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h<br>
>index 942bfb8fd851..85f3303e7843 100644<br>
>--- a/drivers/gpu/drm/amd/display/dc/dc.h<br>
>+++ b/drivers/gpu/drm/amd/display/dc/dc.h<br>
>@@ -1134,12 +1134,15 @@ void dc_3dlut_func_retain(struct dc_3dlut *lut);<br>
>  * in cases such as Stereo 3D, Planar YUV, etc.  Other per-flip attributes such<br>
>  * as frame durations and DCC format can also be set.<br>
>  */<br>
>+#define DC_MAX_DIRTY_RECTS 3<br>
> struct dc_flip_addrs {<br>
>        struct dc_plane_address address;<br>
>        unsigned int flip_timestamp_in_us;<br>
>        bool flip_immediate;<br>
>        /* TODO: add flip duration for FreeSync */<br>
>        bool triplebuffer_flips;<br>
>+      unsigned int dirty_rect_count;<br>
>+      struct rect dirty_rects[DC_MAX_DIRTY_RECTS];<br>
> };<br>
> <br>
> void dc_post_update_surfaces_to_stream(<br>
>diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h<br>
>index 58941f4defb3..58036469c62a 100644<br>
>--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h<br>
>+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h<br>
>@@ -529,4 +529,9 @@ bool dc_stream_get_crtc_position(struct dc *dc,<br>
> <br>
> struct pipe_ctx *dc_stream_get_pipe_ctx(struct dc_stream_state *stream);<br>
> <br>
>+void dc_dmub_update_dirty_rect(struct dc *dc,<br>
>+                             int surface_count,<br>
>+                             struct dc_stream_state *stream,<br>
>+                             struct dc_surface_update *srf_updates,<br>
>+                             struct dc_state *context);<br>
> #endif /* DC_STREAM_H_ */<br>
>--<br>
>2.25.1<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>