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: David Zhang <dingchen.zhang@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
b3d0c0f2df
commit
1da5dab029
@ -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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user