[PATCH 13/27] drm/amd/display: Adding FastUpdate functionality
Harry Wentland
harry.wentland at amd.com
Wed Mar 8 21:54:53 UTC 2017
From: Leon Elazar <leon.elazar at amd.com>
Exposing DC Api dc_check_update_surfaces_for_stream
validation will return the answer which type of update is required,
so upper layers can is it safe to call the update API fro high IRQ yes/no.
Change-Id: I094592c5df4227ed2fea2ceb5de5b2604173fa20
Signed-off-by: Leon Elazar <leon.elazar at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 149 ++++++++++++++++++++++++++-----
drivers/gpu/drm/amd/display/dc/dc.h | 12 +++
2 files changed, 140 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c34232c8c322..27e31bd665ce 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1110,42 +1110,149 @@ static bool is_surface_in_context(
return false;
}
-enum surface_update_type {
- UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
- UPDATE_TYPE_MED, /* a lot of programming needed. may need to alloc */
- UPDATE_TYPE_FULL, /* may need to shuffle resources */
-};
+static unsigned int pixel_format_to_bpp(enum surface_pixel_format format)
+{
+ switch (format) {
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+ case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+ return 16;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
+ return 32;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
+ return 64;
+ default:
+ ASSERT_CRITICAL(false);
+ return -1;
+ }
+}
+
+static enum surface_update_type get_plane_info_update_type(
+ const struct dc_surface_update *u)
+{
+ struct dc_plane_info temp_plane_info = { { { { 0 } } } };
+
+ if (!u->plane_info)
+ return UPDATE_TYPE_FAST;
+
+ /* Copy all parameters that will cause a full update
+ * from current surface, the rest of the parameters
+ * from provided plane configuration.
+ * Perform memory compare and special validation
+ * for those that can cause fast/medium updates
+ */
+
+ /* Full update parameters */
+ temp_plane_info.color_space = u->surface->color_space;
+ temp_plane_info.dcc = u->surface->dcc;
+ temp_plane_info.horizontal_mirror = u->surface->horizontal_mirror;
+ temp_plane_info.plane_size = u->surface->plane_size;
+ temp_plane_info.rotation = u->surface->rotation;
+ temp_plane_info.stereo_format = u->surface->stereo_format;
+ temp_plane_info.tiling_info = u->surface->tiling_info;
+ temp_plane_info.visible = u->surface->visible;
+
+ /* Special Validation parameters */
+ temp_plane_info.format = u->plane_info->format;
+
+ if (memcmp(u->plane_info, &temp_plane_info,
+ sizeof(struct dc_plane_info)) != 0)
+ return UPDATE_TYPE_FULL;
+
+ if (pixel_format_to_bpp(u->plane_info->format) !=
+ pixel_format_to_bpp(u->surface->format)) {
+ return UPDATE_TYPE_FULL;
+ } else {
+ return UPDATE_TYPE_MED;
+ }
+}
+
+static enum surface_update_type get_scaling_info_update_type(
+ const struct dc_surface_update *u)
+{
+ struct dc_scaling_info temp_scaling_info = { { 0 } };
+
+ if (!u->scaling_info)
+ return UPDATE_TYPE_FAST;
+
+ /* Copy all parameters that will cause a full update
+ * from current surface, the rest of the parameters
+ * from provided plane configuration.
+ * Perform memory compare and special validation
+ * for those that can cause fast/medium updates
+ */
+
+ /* Full Update Parameters */
+ temp_scaling_info.dst_rect = u->surface->dst_rect;
+ temp_scaling_info.src_rect = u->surface->src_rect;
+ temp_scaling_info.scaling_quality = u->surface->scaling_quality;
+
+ /* Special validation required */
+ temp_scaling_info.clip_rect = u->scaling_info->clip_rect;
+
+ if (memcmp(u->scaling_info, &temp_scaling_info,
+ sizeof(struct dc_scaling_info)) != 0)
+ return UPDATE_TYPE_FULL;
+
+ /* Check Clip rectangles if not equal
+ * difference is in offsets == > UPDATE_TYPE_FAST
+ * difference is in dimensions == > UPDATE_TYPE_FULL
+ */
+ if (memcmp(&u->scaling_info->clip_rect,
+ &u->surface->clip_rect, sizeof(struct rect)) != 0) {
+ if ((u->scaling_info->clip_rect.height ==
+ u->surface->clip_rect.height) &&
+ (u->scaling_info->clip_rect.width ==
+ u->surface->clip_rect.width)) {
+ return UPDATE_TYPE_FAST;
+ } else {
+ return UPDATE_TYPE_FULL;
+ }
+ }
+
+ return UPDATE_TYPE_FAST;
+}
static enum surface_update_type det_surface_update(
const struct core_dc *dc,
const struct dc_surface_update *u)
{
const struct validate_context *context = dc->current_context;
-
- if (u->scaling_info || u->plane_info)
- /* todo: not all scale and plane_info update need full update
- * ie. check if following is the same
- * scale ratio, view port, surface bpp etc
- */
- return UPDATE_TYPE_FULL; /* may need bandwidth update */
+ enum surface_update_type type = UPDATE_TYPE_FAST;
+ enum surface_update_type overall_type = UPDATE_TYPE_FAST;
if (!is_surface_in_context(context, u->surface))
return UPDATE_TYPE_FULL;
+ type = get_plane_info_update_type(u);
+ if (overall_type < type)
+ overall_type = type;
+
+ type = get_scaling_info_update_type(u);
+ if (overall_type < type)
+ overall_type = type;
+
if (u->in_transfer_func ||
u->out_transfer_func ||
- u->hdr_static_metadata)
- return UPDATE_TYPE_MED;
+ u->hdr_static_metadata) {
+ if (overall_type < UPDATE_TYPE_MED)
+ overall_type = UPDATE_TYPE_MED;
+ }
- return UPDATE_TYPE_FAST;
+ return overall_type;
}
-static enum surface_update_type check_update_surfaces_for_stream(
- struct core_dc *dc,
+enum surface_update_type dc_check_update_surfaces_for_stream(
+ struct dc *dc,
struct dc_surface_update *updates,
int surface_count,
const struct dc_stream_status *stream_status)
{
+ struct core_dc *core_dc = DC_TO_CORE(dc);
int i;
enum surface_update_type overall_type = UPDATE_TYPE_FAST;
@@ -1154,7 +1261,7 @@ static enum surface_update_type check_update_surfaces_for_stream(
for (i = 0 ; i < surface_count; i++) {
enum surface_update_type type =
- det_surface_update(dc, &updates[i]);
+ det_surface_update(core_dc, &updates[i]);
if (type == UPDATE_TYPE_FULL)
return type;
@@ -1184,8 +1291,8 @@ void dc_update_surfaces_for_stream(struct dc *dc,
if (!stream_status)
return; /* Cannot commit surface to stream that is not committed */
- update_type = check_update_surfaces_for_stream(
- core_dc, updates, surface_count, stream_status);
+ update_type = dc_check_update_surfaces_for_stream(
+ dc, updates, surface_count, stream_status);
if (update_type >= update_surface_trace_level)
update_surface_trace(dc, updates, surface_count);
@@ -1321,7 +1428,7 @@ void dc_update_surfaces_for_stream(struct dc *dc,
if (pipe_ctx->surface != surface)
continue;
- if (update_type == UPDATE_TYPE_FULL) {
+ if (update_type >= UPDATE_TYPE_MED) {
/* only apply for top pipe */
if (!pipe_ctx->top_pipe) {
core_dc->hwss.apply_ctx_for_surface(core_dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 2d84b18f48b0..69ae94bb209f 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -379,6 +379,12 @@ bool dc_post_update_surfaces_to_stream(
void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *updates,
int surface_count, const struct dc_stream *stream);
+enum surface_update_type {
+ UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
+ UPDATE_TYPE_MED, /* a lot of programming needed. may need to alloc */
+ UPDATE_TYPE_FULL, /* may need to shuffle resources */
+};
+
/*******************************************************************************
* Stream Interfaces
******************************************************************************/
@@ -498,6 +504,12 @@ struct dc_stream_status {
const struct dc_stream_status *dc_stream_get_status(
const struct dc_stream *dc_stream);
+enum surface_update_type dc_check_update_surfaces_for_stream(
+ struct dc *dc,
+ struct dc_surface_update *updates,
+ int surface_count,
+ const struct dc_stream_status *stream_status);
+
/*******************************************************************************
* Link Interfaces
******************************************************************************/
--
2.10.2
More information about the amd-gfx
mailing list