Commit 1da5dab0 authored by David Zhang's avatar David Zhang Committed by Alex Deucher

drm/amd/display: combine dirty rectangles in DMUB FW

[why]
In PSR-SU design, the DMUB FW handles the combination of multiple
dirty rectangles.

[how]
- create DC dmub update dirty rectangle helper which sends the
  dirty rectangles per pipe from DC to DMUB, and DMUB FW will
  handle to combine the dirty RECTs
- call the helper from DC commit plane update function.
Signed-off-by: default avatarDavid Zhang <dingchen.zhang@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Reviewed-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b3d0c0f2
......@@ -72,6 +72,9 @@
#include "dmub/dmub_srv.h"
#include "i2caux_interface.h"
#include "dce/dmub_psr.h"
#include "dce/dmub_hw_lock_mgr.h"
#include "dc_trace.h"
......@@ -2824,6 +2827,55 @@ static void commit_planes_do_stream_update(struct dc *dc,
}
}
void dc_dmub_update_dirty_rect(struct dc *dc,
int surface_count,
struct dc_stream_state *stream,
struct dc_surface_update *srf_updates,
struct dc_state *context)
{
union dmub_rb_cmd cmd;
struct dc_context *dc_ctx = dc->ctx;
struct dmub_cmd_update_dirty_rect_data *update_dirty_rect;
unsigned int i, j;
if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_SU_1)
return;
memset(&cmd, 0x0, sizeof(cmd));
cmd.update_dirty_rect.header.type = DMUB_CMD__UPDATE_DIRTY_RECT;
cmd.update_dirty_rect.header.sub_type = 0;
cmd.update_dirty_rect.header.payload_bytes =
sizeof(cmd.update_dirty_rect) -
sizeof(cmd.update_dirty_rect.header);
update_dirty_rect = &cmd.update_dirty_rect.update_dirty_rect_data;
for (i = 0; i < surface_count; i++) {
struct dc_plane_state *plane_state = srf_updates[i].surface;
const struct dc_flip_addrs *flip_addr = srf_updates[i].flip_addr;
if (!srf_updates[i].surface || !flip_addr)
continue;
/* Do not send in immediate flip mode */
if (srf_updates[i].surface->flip_immediate)
continue;
update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count;
memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects,
sizeof(flip_addr->dirty_rects));
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
if (pipe_ctx->stream != stream)
continue;
if (pipe_ctx->plane_state != plane_state)
continue;
update_dirty_rect->pipe_idx = j;
dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd);
dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv);
}
}
}
static void commit_planes_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
......@@ -2911,6 +2963,8 @@ static void commit_planes_for_stream(struct dc *dc,
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
}
dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context);
// Stream updates
if (stream_update)
commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
......
......@@ -550,4 +550,9 @@ bool dc_stream_get_crtc_position(struct dc *dc,
struct pipe_ctx *dc_stream_get_pipe_ctx(struct dc_stream_state *stream);
void dc_dmub_update_dirty_rect(struct dc *dc,
int surface_count,
struct dc_stream_state *stream,
struct dc_surface_update *srf_updates,
struct dc_state *context);
#endif /* DC_STREAM_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment