aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch364
1 files changed, 364 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch
new file mode 100644
index 00000000..6b54c351
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2749-drm-amd-display-Add-update-flags-in-to-determine-sur.patch
@@ -0,0 +1,364 @@
+From 855ad09a761f3d1b244358ff1a270be4768f648c Mon Sep 17 00:00:00 2001
+From: Andrew Jiang <Andrew.Jiang@amd.com>
+Date: Mon, 6 Nov 2017 17:00:07 -0500
+Subject: [PATCH 2749/4131] drm/amd/display: Add update flags in to determine
+ surface update type
+
+This way, we can know exactly what triggered the update type we're
+looking at, and we can simplify the logic for determining what exactly
+needs to be updated in the future.
+
+Also allow a dst rect size increase to go through a medium update,
+since that does not require us to increase clock or bandwidth.
+
+Signed-off-by: Andrew Jiang <Andrew.Jiang@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 123 ++++++++++++++++++++-----------
+ drivers/gpu/drm/amd/display/dc/dc.h | 93 +++++++++++++++--------
+ 2 files changed, 140 insertions(+), 76 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index fddca38..b0d4927 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -54,6 +54,13 @@
+ /*******************************************************************************
+ * Private functions
+ ******************************************************************************/
++
++static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
++{
++ if (new > *original)
++ *original = new;
++}
++
+ static void destroy_links(struct dc *dc)
+ {
+ uint32_t i;
+@@ -1122,77 +1129,88 @@ static unsigned int pixel_format_to_bpp(enum surface_pixel_format format)
+
+ static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
+ {
+- struct dc_plane_info temp_plane_info;
+- memset(&temp_plane_info, 0, sizeof(temp_plane_info));
++ union surface_update_flags *update_flags = &u->surface->update_flags;
+
+ if (!u->plane_info)
+ return UPDATE_TYPE_FAST;
+
+- temp_plane_info = *u->plane_info;
++ if (u->plane_info->color_space != u->surface->color_space)
++ update_flags->bits.color_space_change = 1;
+
+- /* 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
+- */
++ if (u->plane_info->input_tf != u->surface->input_tf)
++ update_flags->bits.input_tf_change = 1;
+
+- /* Full update parameters */
+- temp_plane_info.color_space = u->surface->color_space;
+- temp_plane_info.input_tf = u->surface->input_tf;
+- temp_plane_info.horizontal_mirror = u->surface->horizontal_mirror;
+- temp_plane_info.rotation = u->surface->rotation;
+- temp_plane_info.stereo_format = u->surface->stereo_format;
++ if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror)
++ update_flags->bits.horizontal_mirror_change = 1;
+
+- if (memcmp(u->plane_info, &temp_plane_info,
+- sizeof(struct dc_plane_info)) != 0)
+- return UPDATE_TYPE_FULL;
++ if (u->plane_info->rotation != u->surface->rotation)
++ update_flags->bits.rotation_change = 1;
++
++ if (u->plane_info->stereo_format != u->surface->stereo_format)
++ update_flags->bits.stereo_format_change = 1;
++
++ if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha)
++ update_flags->bits.per_pixel_alpha_change = 1;
+
+ if (pixel_format_to_bpp(u->plane_info->format) !=
+- pixel_format_to_bpp(u->surface->format)) {
++ pixel_format_to_bpp(u->surface->format))
+ /* different bytes per element will require full bandwidth
+ * and DML calculation
+ */
+- return UPDATE_TYPE_FULL;
+- }
++ update_flags->bits.bpp_change = 1;
+
+ if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
+ sizeof(union dc_tiling_info)) != 0) {
++ update_flags->bits.swizzle_change = 1;
+ /* todo: below are HW dependent, we should add a hook to
+ * DCE/N resource and validated there.
+ */
+- if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
++ if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR)
+ /* swizzled mode requires RQ to be setup properly,
+ * thus need to run DML to calculate RQ settings
+ */
+- return UPDATE_TYPE_FULL;
+- }
++ update_flags->bits.bandwidth_change = 1;
+ }
+
++ if (update_flags->bits.rotation_change
++ || update_flags->bits.stereo_format_change
++ || update_flags->bits.bpp_change
++ || update_flags->bits.bandwidth_change)
++ return UPDATE_TYPE_FULL;
++
+ return UPDATE_TYPE_MED;
+ }
+
+-static enum surface_update_type get_scaling_info_update_type(
++static enum surface_update_type get_scaling_info_update_type(
+ const struct dc_surface_update *u)
+ {
++ union surface_update_flags *update_flags = &u->surface->update_flags;
++
+ if (!u->scaling_info)
+ return UPDATE_TYPE_FAST;
+
+ if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
+ || u->scaling_info->clip_rect.height != u->surface->clip_rect.height
+ || u->scaling_info->dst_rect.width != u->surface->dst_rect.width
+- || u->scaling_info->dst_rect.height != u->surface->dst_rect.height)
+- return UPDATE_TYPE_FULL;
++ || u->scaling_info->dst_rect.height != u->surface->dst_rect.height) {
++ update_flags->bits.scaling_change = 1;
++
++ if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
++ || u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
++ && (u->scaling_info->dst_rect.width < u->surface->src_rect.width
++ || u->scaling_info->dst_rect.height < u->surface->src_rect.height))
++ /* Making dst rect smaller requires a bandwidth change */
++ update_flags->bits.bandwidth_change = 1;
++ }
+
+ if (u->scaling_info->src_rect.width != u->surface->src_rect.width
+ || u->scaling_info->src_rect.height != u->surface->src_rect.height) {
+
++ update_flags->bits.scaling_change = 1;
+ if (u->scaling_info->src_rect.width > u->surface->src_rect.width
+ && u->scaling_info->src_rect.height > u->surface->src_rect.height)
+- return UPDATE_TYPE_FULL;
+-
+- /* Upscaling does not require a full update */
+- return UPDATE_TYPE_MED;
++ /* Making src rect bigger requires a bandwidth change */
++ update_flags->bits.clock_change = 1;
+ }
+
+ if (u->scaling_info->src_rect.x != u->surface->src_rect.x
+@@ -1201,33 +1219,50 @@ static enum surface_update_type get_scaling_info_update_type(
+ || u->scaling_info->clip_rect.y != u->surface->clip_rect.y
+ || u->scaling_info->dst_rect.x != u->surface->dst_rect.x
+ || u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
++ update_flags->bits.position_change = 1;
++
++ if (update_flags->bits.clock_change
++ || update_flags->bits.bandwidth_change)
++ return UPDATE_TYPE_FULL;
++
++ if (update_flags->bits.scaling_change
++ || update_flags->bits.position_change)
+ return UPDATE_TYPE_MED;
+
+ return UPDATE_TYPE_FAST;
+ }
+
+ static enum surface_update_type det_surface_update(const struct dc *dc,
+- const struct dc_surface_update *u)
++ const struct dc_surface_update *u)
+ {
+ const struct dc_state *context = dc->current_state;
+- enum surface_update_type type = UPDATE_TYPE_FAST;
++ enum surface_update_type type;
+ enum surface_update_type overall_type = UPDATE_TYPE_FAST;
++ union surface_update_flags *update_flags = &u->surface->update_flags;
++
++ update_flags->raw = 0; // Reset all flags
+
+- if (!is_surface_in_context(context, u->surface))
++ if (!is_surface_in_context(context, u->surface)) {
++ update_flags->bits.new_plane = 1;
+ return UPDATE_TYPE_FULL;
++ }
+
+ type = get_plane_info_update_type(u);
+- if (overall_type < type)
+- overall_type = type;
++ elevate_update_type(&overall_type, type);
+
+ type = get_scaling_info_update_type(u);
+- if (overall_type < type)
+- overall_type = type;
++ elevate_update_type(&overall_type, type);
++
++ if (u->in_transfer_func)
++ update_flags->bits.in_transfer_func = 1;
++
++ if (u->input_csc_color_matrix)
++ update_flags->bits.input_csc_change = 1;
+
+- if (u->in_transfer_func ||
+- u->input_csc_color_matrix) {
+- if (overall_type < UPDATE_TYPE_MED)
+- overall_type = UPDATE_TYPE_MED;
++ if (update_flags->bits.in_transfer_func
++ || update_flags->bits.input_csc_change) {
++ type = UPDATE_TYPE_MED;
++ elevate_update_type(&overall_type, type);
+ }
+
+ return overall_type;
+@@ -1253,11 +1288,11 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
+ enum surface_update_type type =
+ det_surface_update(dc, &updates[i]);
+
++ updates[i].surface->update_type = type;
+ if (type == UPDATE_TYPE_FULL)
+ return type;
+
+- if (overall_type < type)
+- overall_type = type;
++ elevate_update_type(&overall_type, type);
+ }
+
+ return overall_type;
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index ae78770..effffda 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -99,6 +99,39 @@ struct dc_static_screen_events {
+ bool overlay_update;
+ };
+
++
++/* Surface update type is used by dc_update_surfaces_and_stream
++ * The update type is determined at the very beginning of the function based
++ * on parameters passed in and decides how much programming (or updating) is
++ * going to be done during the call.
++ *
++ * UPDATE_TYPE_FAST is used for really fast updates that do not require much
++ * logical calculations or hardware register programming. This update MUST be
++ * ISR safe on windows. Currently fast update will only be used to flip surface
++ * address.
++ *
++ * UPDATE_TYPE_MED is used for slower updates which require significant hw
++ * re-programming however do not affect bandwidth consumption or clock
++ * requirements. At present, this is the level at which front end updates
++ * that do not require us to run bw_calcs happen. These are in/out transfer func
++ * updates, viewport offset changes, recout size changes and pixel depth changes.
++ * This update can be done at ISR, but we want to minimize how often this happens.
++ *
++ * UPDATE_TYPE_FULL is slow. Really slow. This requires us to recalculate our
++ * bandwidth and clocks, possibly rearrange some pipes and reprogram anything front
++ * end related. Any time viewport dimensions, recout dimensions, scaling ratios or
++ * gamma need to be adjusted or pipe needs to be turned on (or disconnected) we do
++ * a full update. This cannot be done at ISR level and should be a rare event.
++ * Unless someone is stress testing mpo enter/exit, playing with colour or adjusting
++ * underscan we don't expect to see this call at all.
++ */
++
++enum surface_update_type {
++ UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
++ UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/
++ UPDATE_TYPE_FULL, /* may need to shuffle resources */
++};
++
+ /* Forward declaration*/
+ struct dc;
+ struct dc_plane_state;
+@@ -399,6 +432,32 @@ struct dc_plane_status {
+ bool is_right_eye;
+ };
+
++union surface_update_flags {
++
++ struct {
++ /* Medium updates */
++ uint32_t color_space_change:1;
++ uint32_t input_tf_change:1;
++ uint32_t horizontal_mirror_change:1;
++ uint32_t per_pixel_alpha_change:1;
++ uint32_t rotation_change:1;
++ uint32_t swizzle_change:1;
++ uint32_t scaling_change:1;
++ uint32_t position_change:1;
++ uint32_t in_transfer_func:1;
++ uint32_t input_csc_change:1;
++
++ /* Full updates */
++ uint32_t new_plane:1;
++ uint32_t bpp_change:1;
++ uint32_t bandwidth_change:1;
++ uint32_t clock_change:1;
++ uint32_t stereo_format_change:1;
++ } bits;
++
++ uint32_t raw;
++};
++
+ struct dc_plane_state {
+ struct dc_plane_address address;
+ struct scaling_taps scaling_quality;
+@@ -432,6 +491,8 @@ struct dc_plane_state {
+ bool flip_immediate;
+ bool horizontal_mirror;
+
++ union surface_update_flags update_flags;
++ enum surface_update_type update_type;
+ /* private to DC core */
+ struct dc_plane_status status;
+ struct dc_context *ctx;
+@@ -528,38 +589,6 @@ void dc_flip_plane_addrs(struct dc *dc,
+ bool dc_post_update_surfaces_to_stream(
+ struct dc *dc);
+
+-/* Surface update type is used by dc_update_surfaces_and_stream
+- * The update type is determined at the very beginning of the function based
+- * on parameters passed in and decides how much programming (or updating) is
+- * going to be done during the call.
+- *
+- * UPDATE_TYPE_FAST is used for really fast updates that do not require much
+- * logical calculations or hardware register programming. This update MUST be
+- * ISR safe on windows. Currently fast update will only be used to flip surface
+- * address.
+- *
+- * UPDATE_TYPE_MED is used for slower updates which require significant hw
+- * re-programming however do not affect bandwidth consumption or clock
+- * requirements. At present, this is the level at which front end updates
+- * that do not require us to run bw_calcs happen. These are in/out transfer func
+- * updates, viewport offset changes, recout size changes and pixel depth changes.
+- * This update can be done at ISR, but we want to minimize how often this happens.
+- *
+- * UPDATE_TYPE_FULL is slow. Really slow. This requires us to recalculate our
+- * bandwidth and clocks, possibly rearrange some pipes and reprogram anything front
+- * end related. Any time viewport dimensions, recout dimensions, scaling ratios or
+- * gamma need to be adjusted or pipe needs to be turned on (or disconnected) we do
+- * a full update. This cannot be done at ISR level and should be a rare event.
+- * Unless someone is stress testing mpo enter/exit, playing with colour or adjusting
+- * underscan we don't expect to see this call at all.
+- */
+-
+-enum surface_update_type {
+- UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
+- UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/
+- UPDATE_TYPE_FULL, /* may need to shuffle resources */
+-};
+-
+ /*******************************************************************************
+ * Stream Interfaces
+ ******************************************************************************/
+--
+2.7.4
+