All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+
@ 2020-03-26 18:09 Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 01/10] drm/i915: Start passing latency as parameter Stanislav Lisovskiy
                   ` (22 more replies)
  0 siblings, 23 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

For Gen11+ platforms BSpec suggests disabling specific
QGV points separately, depending on bandwidth limitations
and current display configuration. Thus it required adding
a new PCode request for disabling QGV points and some
refactoring of already existing SAGV code.
Also had to refactor intel_can_enable_sagv function,
as current seems to be outdated and using skl specific
workarounds, also not following BSpec for Gen11+.

v17: Had to rebase the whole series.

v19: Added some new patches in between, rebased

v20: Added new patches and rebased the series

Stanislav Lisovskiy (10):
  drm/i915: Start passing latency as parameter
  drm/i915: Eliminate magic numbers "0" and "1" from color plane
  drm/i915: Introduce skl_plane_wm_level accessor.
  drm/i915: Add intel_atomic_get_bw_*_state helpers
  drm/i915: Extract gen specific functions from intel_can_enable_sagv
  drm/i915: Add proper SAGV support for TGL+
  drm/i915: Added required new PCode commands
  drm/i915: Rename bw_state to new_bw_state
  drm/i915: Restrict qgv points which don't have enough bandwidth.
  drm/i915: Enable SAGV support for Gen12

 drivers/gpu/drm/i915/display/intel_bw.c       | 200 +++++--
 drivers/gpu/drm/i915/display/intel_bw.h       |  24 +
 drivers/gpu/drm/i915/display/intel_display.c  |  29 +-
 .../drm/i915/display/intel_display_types.h    |  12 +
 drivers/gpu/drm/i915/i915_reg.h               |   4 +
 drivers/gpu/drm/i915/intel_pm.c               | 555 +++++++++++++++---
 drivers/gpu/drm/i915/intel_pm.h               |   6 +-
 drivers/gpu/drm/i915/intel_sideband.c         |   2 +
 8 files changed, 690 insertions(+), 142 deletions(-)

-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 01/10] drm/i915: Start passing latency as parameter
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
@ 2020-03-26 18:09 ` Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane Stanislav Lisovskiy
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We need to start passing memory latency as a
parameter when calculating plane wm levels,
as latency can get changed in different
circumstances(for example with or without SAGV).
So we need to be more flexible on that matter.

v2: Changed latency type from u32 to unsigned int(Ville Syrjälä)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8375054ba27d..b632b6bb9c3e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4016,6 +4016,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 				 int color_plane);
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
+				 unsigned int latency,
 				 const struct skl_wm_params *wp,
 				 const struct skl_wm_level *result_prev,
 				 struct skl_wm_level *result /* out */);
@@ -4038,7 +4039,9 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 	drm_WARN_ON(&dev_priv->drm, ret);
 
 	for (level = 0; level <= max_level; level++) {
-		skl_compute_plane_wm(crtc_state, level, &wp, &wm, &wm);
+		unsigned int latency = dev_priv->wm.skl_latency[level];
+
+		skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm);
 		if (wm.min_ddb_alloc == U16_MAX)
 			break;
 
@@ -4972,12 +4975,12 @@ static bool skl_wm_has_lines(struct drm_i915_private *dev_priv, int level)
 
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
+				 unsigned int latency,
 				 const struct skl_wm_params *wp,
 				 const struct skl_wm_level *result_prev,
 				 struct skl_wm_level *result /* out */)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
-	u32 latency = dev_priv->wm.skl_latency[level];
 	uint_fixed_16_16_t method1, method2;
 	uint_fixed_16_16_t selected_result;
 	u32 res_blocks, res_lines, min_ddb_alloc = 0;
@@ -5106,9 +5109,10 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 
 	for (level = 0; level <= max_level; level++) {
 		struct skl_wm_level *result = &levels[level];
+		unsigned int latency = dev_priv->wm.skl_latency[level];
 
-		skl_compute_plane_wm(crtc_state, level, wm_params,
-				     result_prev, result);
+		skl_compute_plane_wm(crtc_state, level, latency,
+				     wm_params, result_prev, result);
 
 		result_prev = result;
 	}
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 01/10] drm/i915: Start passing latency as parameter Stanislav Lisovskiy
@ 2020-03-26 18:09 ` Stanislav Lisovskiy
  2020-04-02 16:17   ` Ville Syrjälä
  2020-04-03 15:41   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 03/10] drm/i915: Introduce skl_plane_wm_level accessor Stanislav Lisovskiy
                   ` (20 subsequent siblings)
  22 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to many computer science sources - magic values
in code _are_ _bad_. For many reasons: the reason is that "0"
or "1" or whatever magic values confuses and doesn't give any
info why this parameter is this value and what it's meaning
is.
I renamed "0" to COLOR_PLANE_Y and "1" to COLOR_PLANE_UV,
because we in fact already use this naming in many other places
and function names, when dealing with color planes.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  5 +++
 drivers/gpu/drm/i915/intel_pm.c               | 40 +++++++++----------
 2 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 176ab5f1e867..523e0444b373 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -682,6 +682,11 @@ struct skl_plane_wm {
 	bool is_planar;
 };
 
+enum color_plane {
+	COLOR_PLANE_Y,
+	COLOR_PLANE_UV
+};
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 };
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b632b6bb9c3e..9e9a4612d842 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4013,7 +4013,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 				 int width, const struct drm_format_info *format,
 				 u64 modifier, unsigned int rotation,
 				 u32 plane_pixel_rate, struct skl_wm_params *wp,
-				 int color_plane);
+				 enum color_plane);
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
 				 unsigned int latency,
@@ -4035,7 +4035,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 				    drm_format_info(DRM_FORMAT_ARGB8888),
 				    DRM_FORMAT_MOD_LINEAR,
 				    DRM_MODE_ROTATE_0,
-				    crtc_state->pixel_rate, &wp, 0);
+				    crtc_state->pixel_rate, &wp, COLOR_PLANE_Y);
 	drm_WARN_ON(&dev_priv->drm, ret);
 
 	for (level = 0; level <= max_level; level++) {
@@ -4431,7 +4431,7 @@ static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
 static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 			     const struct intel_plane_state *plane_state,
-			     int color_plane)
+			     enum color_plane color_plane)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	const struct drm_framebuffer *fb = plane_state->hw.fb;
@@ -4446,7 +4446,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 	if (plane->id == PLANE_CURSOR)
 		return 0;
 
-	if (color_plane == 1 &&
+	if (color_plane == COLOR_PLANE_UV &&
 	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
 		return 0;
 
@@ -4459,7 +4459,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 	height = drm_rect_height(&plane_state->uapi.src) >> 16;
 
 	/* UV plane does 1/2 pixel sub-sampling */
-	if (color_plane == 1) {
+	if (color_plane == COLOR_PLANE_UV) {
 		width /= 2;
 		height /= 2;
 	}
@@ -4489,12 +4489,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		u64 rate;
 
 		/* packed/y */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
 		plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 
 		/* uv-plane */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
 		uv_plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 	}
@@ -4516,7 +4516,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		u64 rate;
 
 		if (!plane_state->planar_linked_plane) {
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
 		} else {
@@ -4533,12 +4533,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				continue;
 
 			/* Y plane rate is calculated on the slave */
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
 			y_plane_id = plane_state->planar_linked_plane->id;
 			plane_data_rate[y_plane_id] = rate;
 			total_data_rate += rate;
 
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
 		}
@@ -4854,14 +4854,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 		      int width, const struct drm_format_info *format,
 		      u64 modifier, unsigned int rotation,
 		      u32 plane_pixel_rate, struct skl_wm_params *wp,
-		      int color_plane)
+		      enum color_plane color_plane)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 interm_pbpl;
 
 	/* only planar format has two planes */
-	if (color_plane == 1 &&
+	if (color_plane == COLOR_PLANE_UV &&
 	    !intel_format_info_is_yuv_semiplanar(format, modifier)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "Non planar format have single plane\n");
@@ -4878,7 +4878,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
 
 	wp->width = width;
-	if (color_plane == 1 && wp->is_planar)
+	if (color_plane == COLOR_PLANE_UV && wp->is_planar)
 		wp->width /= 2;
 
 	wp->cpp = format->cpp[color_plane];
@@ -4945,7 +4945,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 static int
 skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
 			    const struct intel_plane_state *plane_state,
-			    struct skl_wm_params *wp, int color_plane)
+			    struct skl_wm_params *wp, enum color_plane color_plane)
 {
 	const struct drm_framebuffer *fb = plane_state->hw.fb;
 	int width;
@@ -5187,7 +5187,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 
 static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 				     const struct intel_plane_state *plane_state,
-				     enum plane_id plane_id, int color_plane)
+				     enum plane_id plane_id, enum color_plane color_plane)
 {
 	struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
 	struct skl_wm_params wm_params;
@@ -5216,7 +5216,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 
 	/* uv plane watermarks must also be validated for NV12/Planar */
 	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
-					  &wm_params, 1);
+					  &wm_params, COLOR_PLANE_UV);
 	if (ret)
 		return ret;
 
@@ -5237,7 +5237,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	ret = skl_build_plane_wm_single(crtc_state, plane_state,
-					plane_id, 0);
+					plane_id, COLOR_PLANE_Y);
 	if (ret)
 		return ret;
 
@@ -5270,17 +5270,17 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 			fb->format->num_planes == 1);
 
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						y_plane_id, 0);
+						y_plane_id, COLOR_PLANE_Y);
 		if (ret)
 			return ret;
 
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 1);
+						plane_id, COLOR_PLANE_UV);
 		if (ret)
 			return ret;
 	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 0);
+						plane_id, COLOR_PLANE_Y);
 		if (ret)
 			return ret;
 	}
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 03/10] drm/i915: Introduce skl_plane_wm_level accessor.
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 01/10] drm/i915: Start passing latency as parameter Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane Stanislav Lisovskiy
@ 2020-03-26 18:09 ` Stanislav Lisovskiy
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

For future Gen12 SAGV implementation we need to
seemlessly alter wm levels calculated, depending
on whether we are allowed to enable SAGV or not.

So this accessor will give additional flexibility
to do that.

Currently this accessor is still simply working
as "pass-through" function. This will be changed
in next coming patches from this series.

v2: - plane_id -> plane->id(Ville Syrjälä)
    - Moved wm_level var to have more local scope
      (Ville Syrjälä)
    - Renamed yuv to color_plane(Ville Syrjälä) in
      skl_plane_wm_level

v3: - plane->id -> plane_id(this time for real, Ville Syrjälä)
    - Changed colorplane id type from boolean to int as index
      (Ville Syrjälä)
    - Moved crtc_state param so that it is first now
      (Ville Syrjälä)
    - Moved wm_level declaration to tigher scope in
      skl_write_plane_wm(Ville Syrjälä)

v4: - Started to use enum values for color plane
    - Do sizeof for a type what we are memset'ing
    - Zero out wm_uv as well(Ville Syrjälä)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 85 ++++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9e9a4612d842..f8d62d1977ac 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4547,6 +4547,18 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 	return total_data_rate;
 }
 
+static const struct skl_wm_level *
+skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
+		   enum plane_id plane_id,
+		   int level,
+		   enum color_plane color_plane)
+{
+	const struct skl_plane_wm *wm =
+		&crtc_state->wm.skl.optimal.planes[plane_id];
+
+	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 {
@@ -4606,22 +4618,28 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 	 */
 	for (level = ilk_wm_max_level(dev_priv); level >= 0; level--) {
 		blocks = 0;
+
 		for_each_plane_id_on_crtc(crtc, plane_id) {
-			const struct skl_plane_wm *wm =
-				&crtc_state->wm.skl.optimal.planes[plane_id];
+			const struct skl_wm_level *wm_level;
+			const struct skl_wm_level *wm_uv_level;
+
+			wm_level = skl_plane_wm_level(crtc_state, plane_id,
+						      level, COLOR_PLANE_Y);
+			wm_uv_level = skl_plane_wm_level(crtc_state, plane_id,
+							 level, COLOR_PLANE_UV);
 
 			if (plane_id == PLANE_CURSOR) {
-				if (wm->wm[level].min_ddb_alloc > total[PLANE_CURSOR]) {
+				if (wm_level->min_ddb_alloc > total[PLANE_CURSOR]) {
 					drm_WARN_ON(&dev_priv->drm,
-						    wm->wm[level].min_ddb_alloc != U16_MAX);
+						    wm_level->min_ddb_alloc != U16_MAX);
 					blocks = U32_MAX;
 					break;
 				}
 				continue;
 			}
 
-			blocks += wm->wm[level].min_ddb_alloc;
-			blocks += wm->uv_wm[level].min_ddb_alloc;
+			blocks += wm_level->min_ddb_alloc;
+			blocks += wm_uv_level->min_ddb_alloc;
 		}
 
 		if (blocks <= alloc_size) {
@@ -4644,11 +4662,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 	 * proportional to its relative data rate.
 	 */
 	for_each_plane_id_on_crtc(crtc, plane_id) {
-		const struct skl_plane_wm *wm =
-			&crtc_state->wm.skl.optimal.planes[plane_id];
+		const struct skl_wm_level *wm_level;
+		const struct skl_wm_level *wm_uv_level;
 		u64 rate;
 		u16 extra;
 
+		wm_level = skl_plane_wm_level(crtc_state, plane_id,
+					      level, COLOR_PLANE_Y);
+		wm_uv_level = skl_plane_wm_level(crtc_state, plane_id,
+						 level, COLOR_PLANE_UV);
+
 		if (plane_id == PLANE_CURSOR)
 			continue;
 
@@ -4663,7 +4686,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 		extra = min_t(u16, alloc_size,
 			      DIV64_U64_ROUND_UP(alloc_size * rate,
 						 total_data_rate));
-		total[plane_id] = wm->wm[level].min_ddb_alloc + extra;
+		total[plane_id] = wm_level->min_ddb_alloc + extra;
 		alloc_size -= extra;
 		total_data_rate -= rate;
 
@@ -4674,7 +4697,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 		extra = min_t(u16, alloc_size,
 			      DIV64_U64_ROUND_UP(alloc_size * rate,
 						 total_data_rate));
-		uv_total[plane_id] = wm->uv_wm[level].min_ddb_alloc + extra;
+		uv_total[plane_id] = wm_uv_level->min_ddb_alloc + extra;
 		alloc_size -= extra;
 		total_data_rate -= rate;
 	}
@@ -4717,9 +4740,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 	 */
 	for (level++; level <= ilk_wm_max_level(dev_priv); level++) {
 		for_each_plane_id_on_crtc(crtc, plane_id) {
+			const struct skl_wm_level *wm_level;
+			const struct skl_wm_level *wm_uv_level;
 			struct skl_plane_wm *wm =
 				&crtc_state->wm.skl.optimal.planes[plane_id];
 
+			wm_level = skl_plane_wm_level(crtc_state, plane_id,
+						      level, COLOR_PLANE_Y);
+			wm_uv_level = skl_plane_wm_level(crtc_state, plane_id,
+							 level, COLOR_PLANE_UV);
+
 			/*
 			 * We only disable the watermarks for each plane if
 			 * they exceed the ddb allocation of said plane. This
@@ -4732,9 +4762,13 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 			 *  planes must be enabled before the level will be used."
 			 * So this is actually safe to do.
 			 */
-			if (wm->wm[level].min_ddb_alloc > total[plane_id] ||
-			    wm->uv_wm[level].min_ddb_alloc > uv_total[plane_id])
-				memset(&wm->wm[level], 0, sizeof(wm->wm[level]));
+			if (wm_level->min_ddb_alloc > total[plane_id] ||
+			    wm_uv_level->min_ddb_alloc > uv_total[plane_id]) {
+				memset(&wm->wm[level], 0,
+				       sizeof(wm->wm[level]));
+				memset(&wm->uv_wm[level], 0,
+				       sizeof(wm->uv_wm[level]));
+			}
 
 			/*
 			 * Wa_1408961008:icl, ehl
@@ -4742,9 +4776,14 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 			 */
 			if (IS_GEN(dev_priv, 11) &&
 			    level == 1 && wm->wm[0].plane_en) {
-				wm->wm[level].plane_res_b = wm->wm[0].plane_res_b;
-				wm->wm[level].plane_res_l = wm->wm[0].plane_res_l;
-				wm->wm[level].ignore_lines = wm->wm[0].ignore_lines;
+				wm_level = skl_plane_wm_level(crtc_state, plane_id,
+							      0, COLOR_PLANE_Y);
+				wm->wm[level].plane_res_b =
+					wm_level->plane_res_b;
+				wm->wm[level].plane_res_l =
+					wm_level->plane_res_l;
+				wm->wm[level].ignore_lines =
+					wm_level->ignore_lines;
 			}
 		}
 	}
@@ -5358,8 +5397,13 @@ void skl_write_plane_wm(struct intel_plane *plane,
 		&crtc_state->wm.skl.plane_ddb_uv[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
+		const struct skl_wm_level *wm_level;
+		int color_plane = 0;
+
+		wm_level = skl_plane_wm_level(crtc_state, plane_id, level, color_plane);
+
 		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level),
-				   &wm->wm[level]);
+				   wm_level);
 	}
 	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
 			   &wm->trans_wm);
@@ -5392,8 +5436,13 @@ void skl_write_cursor_wm(struct intel_plane *plane,
 		&crtc_state->wm.skl.plane_ddb_y[plane_id];
 
 	for (level = 0; level <= max_level; level++) {
+		const struct skl_wm_level *wm_level;
+		int color_plane = 0;
+
+		wm_level = skl_plane_wm_level(crtc_state, plane_id, level, color_plane);
+
 		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
-				   &wm->wm[level]);
+				   wm_level);
 	}
 	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm);
 
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (2 preceding siblings ...)
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 03/10] drm/i915: Introduce skl_plane_wm_level accessor Stanislav Lisovskiy
@ 2020-03-26 18:09 ` Stanislav Lisovskiy
  2020-04-02 16:20   ` Ville Syrjälä
                     ` (2 more replies)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv Stanislav Lisovskiy
                   ` (18 subsequent siblings)
  22 siblings, 3 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:09 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Add correspondent helpers to be able to get old/new bandwidth
global state object.

v2: - Fixed typo in function call
v3: - Changed new functions naming to use convention proposed
      by Jani Nikula, i.e intel_bw_* in intel_bw.c file.
v4: - Change function naming back to intel_atomic* pattern,
      was decided to rename in a separate patch series.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 29 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_bw.h |  9 ++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 58b264bc318d..a8b2038db4d2 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -374,7 +374,34 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
 	return data_rate;
 }
 
-static struct intel_bw_state *
+struct intel_bw_state *
+intel_atomic_get_bw_old_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
+	if (IS_ERR(bw_state))
+		return ERR_CAST(bw_state);
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
+intel_atomic_get_bw_new_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
+
+	if (IS_ERR(bw_state))
+		return ERR_CAST(bw_state);
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
 intel_atomic_get_bw_state(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index a8aa7624c5aa..fe6579c952f5 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,15 @@ struct intel_bw_state {
 
 #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
 
+struct intel_bw_state *
+intel_atomic_get_bw_old_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_bw_new_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_bw_state(struct intel_atomic_state *state);
+
 void intel_bw_init_hw(struct drm_i915_private *dev_priv);
 int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (3 preceding siblings ...)
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-04-02 16:44   ` Ville Syrjälä
  2020-04-03  6:20   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+ Stanislav Lisovskiy
                   ` (17 subsequent siblings)
  22 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Addressing one of the comments, recommending to extract platform
specific code from intel_can_enable_sagv as a preparation, before
we are going to add support for tgl+.

Current code in intel_can_enable_sagv is valid only for skl,
so this patch adds also proper support for icl, subsequent
patches will add support for tgl+, combined with other required
changes.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 89 ++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f8d62d1977ac..64193b098175 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3757,41 +3757,24 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool icl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = state->base.dev;
+	struct drm_device *dev = crtc_state->uapi.crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *crtc;
 	struct intel_plane *plane;
-	struct intel_crtc_state *crtc_state;
-	enum pipe pipe;
+	struct intel_plane_state *plane_state;
 	int level, latency;
 
-	if (!intel_has_sagv(dev_priv))
-		return false;
+	crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
-	/*
-	 * If there are no active CRTCs, no additional checks need be performed
-	 */
-	if (hweight8(state->active_pipes) == 0)
-		return true;
-
-	/*
-	 * SKL+ workaround: bspec recommends we disable SAGV when we have
-	 * more then one pipe enabled
-	 */
-	if (hweight8(state->active_pipes) > 1)
-		return false;
-
-	/* Since we're now guaranteed to only have one active CRTC... */
-	pipe = ffs(state->active_pipes) - 1;
-	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
-	crtc_state = to_intel_crtc_state(crtc->base.state);
-
-	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
+			      pipe_name(crtc->pipe));
 		return false;
+	}
 
-	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
 		struct skl_plane_wm *wm =
 			&crtc_state->wm.skl.optimal.planes[plane->id];
 
@@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
 		latency = dev_priv->wm.skl_latency[level];
 
 		if (skl_needs_memory_bw_wa(dev_priv) &&
-		    plane->base.state->fb->modifier ==
+		    plane_state->uapi.fb->modifier ==
 		    I915_FORMAT_MOD_X_TILED)
 			latency += 15;
 
@@ -3816,8 +3799,58 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
 		 * incur memory latencies higher than sagv_block_time_us we
 		 * can't enable SAGV.
 		 */
-		if (latency < dev_priv->sagv_block_time_us)
+		if (latency < dev_priv->sagv_block_time_us) {
+			DRM_DEBUG_KMS("Latency %d < sagv block time %d, no SAGV for pipe %c\n",
+				      latency, dev_priv->sagv_block_time_us, pipe_name(crtc->pipe));
 			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool skl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+
+	/*
+	 * It has been recommended that for Gen 9 we switch SAGV off when
+	 * multiple pipes are used.
+	 */
+	if (hweight8(state->active_pipes) > 1)
+		return false;
+
+	/*
+	 * Besides active pipe limitation, rest of checks pretty much match ICL
+	 * so no need to duplicate code
+	 */
+	return icl_can_enable_sagv_on_pipe(crtc_state);
+}
+
+bool intel_can_enable_sagv(struct intel_atomic_state *state)
+{
+	struct drm_device *dev = state->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	int i;
+
+	if (!intel_has_sagv(dev_priv))
+		return false;
+
+	/*
+	 * If there are no active CRTCs, no additional checks need be performed
+	 */
+	if (hweight8(state->active_pipes) == 0)
+		return true;
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		if (INTEL_GEN(dev_priv) <= 9) {
+			if (!skl_can_enable_sagv_on_pipe(crtc_state))
+				return false;
+		} else if (!icl_can_enable_sagv_on_pipe(crtc_state)) {
+			return false;
+		}
 	}
 
 	return true;
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (4 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-03-26 18:39   ` Stanislav Lisovskiy
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands Stanislav Lisovskiy
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Let's refactor the whole SAGV logic, moving
the main calculations from intel_can_enable_sagv
to intel_compute_sagv_mask, which also handles
this in a unified way calling gen specific
functions to evaluate if SAGV is allowed for
each crtc. If crtc sagv mask have been changed
we serialize access and modify global state.

intel_can_enable_sagv now uses bw_state which
stores all information related to SAGV and
is now a trivial helper.

v2:
    - Rework watermark calculation algorithm to
      attempt to calculate Level 0 watermark
      with added sagv block time latency and
      check if it fits in DBuf in order to
      determine if SAGV can be enabled already
      at this stage, just as BSpec 49325 states.
      if that fails rollback to usual Level 0
      latency and disable SAGV.
    - Remove unneeded tabs(James Ausmus)

v3: Rebased the patch

v4: - Added back interlaced check for Gen12 and
      added separate function for TGL SAGV check
      (thanks to James Ausmus for spotting)
    - Removed unneeded gen check
    - Extracted Gen12 SAGV decision making code
      to a separate function from skl_compute_wm

v5: - Added SAGV global state to dev_priv, because
      we need to track all pipes, not only those
      in atomic state. Each pipe has now correspondent
      bit mask reflecting, whether it can tolerate
      SAGV or not(thanks to Ville Syrjala for suggestions).
    - Now using active flag instead of enable in crc
      usage check.

v6: - Fixed rebase conflicts

v7: - kms_cursor_legacy seems to get broken because of multiple memcpy
      calls when copying level 0 water marks for enabled SAGV, to
      fix this now simply using that field right away, without copying,
      for that introduced a new wm_level accessor which decides which
      wm_level to return based on SAGV state.

v8: - Protect crtc_sagv_mask same way as we do for other global state
      changes: i.e check if changes are needed, then grab all crtc locks
      to serialize the changes(Ville Syrjälä)
    - Add crtc_sagv_mask caching in order to avoid needless recalculations
      (Matthew Roper)
    - Put back Gen12 SAGV switch in order to get it enabled in separate
      patch(Matthew Roper)
    - Rename *_set_sagv_mask to *_compute_sagv_mask(Matthew Roper)
    - Check if there are no active pipes in intel_can_enable_sagv
      instead of platform specific functions(Matthew Roper), same
      for intel_has_sagv check.

v9  - Switched to u8 for crtc_sagv_mask(Ville Syrjälä)
    - crtc_sagv_mask now is pipe_sagv_mask(Ville Syrjälä)
    - Extracted sagv checking logic from skl/icl/tgl_compute_sagv_mask
    - Extracted skl_plane_wm_level function and passing latency to
      separate patches(Ville Syrjälä)
    - Removed part of unneeded copy-paste from tgl_check_pipe_fits_sagv_wm
      (Ville Syrjälä)
    - Now using simple assignment for sagv_wm0 as it contains only
      pod types and no pointers(Ville Syrjälä)
    - Fixed intel_can_enable_sagv not to do double duty, now it only
      check SAGV bits by ANDing those between local and global state.
      The SAGV masks are now computed after watermarks are available,
      in order to be able to figure out if ddb ranges are fitting nicely.
      (Ville Syrjälä)
    - Now having uv_sagv_wm0 and sagv_wm0, otherwise we have wrong logic
      when using skl_plane_wm_level accessor, as we had previously for
      Gen11+ color plane and regular wm levels, so probably both
      has to be recalculated with additional SAGV block time for Level 0.

v10: - Starting to use new global state for storing pipe_sagv_mask

v11: - Fixed rebase conflict with recent drm-tip
     - Check if we really need to recalculate SAGV mask, otherwise
       bail out without making any changes.
     - Use cached SAGV result, instead of recalculating it everytime,
       if bw_state hasn't changed.

v12: - Removed WARN from intel_can_enable_sagv, in some of the commits
       if we don't recalculated watermarks, bw_state is not recalculated,
       thus leading to SAGV state not recalculated by the commit state,
       which is still calling intel_can_enable_sagv function. Fix that
       by just analyzing the current global bw_state object - because
       we simply have no other objects related to that.

v13: - Rebased, fixed warnings regarding long lines
     - Changed function call sites from intel_atomic_bw* to
       intel_wb_* as was suggested.(Jani Nikula)
     - Taken ddb_state_changed and bw_state_changed into use.

v14: - total_affected_planes is no longer needed to check for ddb changes,
       just as active_pipe_changes.

v15: - Fixed stupid mistake with uninitialized crtc in
       skl_compute_sagv_mask.

v16: - Convert pipe_sagv_mask to pipe_sagv_reject and now using inverted
       flag to indicate SAGV readiness for the pipe(Ville Syrjälä)
     - Added return value to intel_compute_sagv_mask which call
       intel_atomic_serialize_global_state in order to properly
       propagate EDEADLCK to drm.
     - Based on the discussion with Ville, removed active_pipe_changes
       check and also there seems to be no need for checking
       ddb_state_changes as well.
       Instead we just iterate through crtcs in state - having
       crtc in a state already guarantees that it is at least read-locked
       Having additional flag to check if there actually were some plane
       wm/ddb changes would be probably added later as an optimization.
     - We can't get parent atomic state from crtc_state at commit stage
       (nice drm feature), also propagating state through function call
       chain seems to be overkill and not possible(cursor legacy updates)
       Querying for bw_state object from global state is not possible as
       it might get swapped with other global state.
       So... just sticked can_sagv boolean into wm crtc state.

v17: - Skip inactive crtcs, when checking for SAGV-readiness.

v18: - Switch to use intel_atomic_crtc_state_for_each_plane_state
       instead of for_each_intel_plane_on_crtc and fixed previous
       code, which was using old plane state, which caused NULL ptr
       dereference, bacause that code is now called before we swap the
       state.

v19: - Use intel_atomic_bw_* pattern again
     - Optimized sagv checks in verify_wm_state(Ville Syrjälä)
     - Do intel_compute_sagv_mask after ddb is allocated(Ville Syrjälä),
       using it's results
     - Use bw_state in intel_can_enable_sagv
     - Use COLOR_PLANE enum instead of boolean yuv or "0", "1" magic
     - Extracted sagv wm0 calculation into separate skl_compute_sagv_wm
       function(Ville Syrjälä)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.h       |   6 +
 drivers/gpu/drm/i915/display/intel_display.c  |  30 ++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 244 ++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.h               |   4 +-
 5 files changed, 256 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index fe6579c952f5..6ad3ea7cedfe 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -18,6 +18,12 @@ struct intel_crtc_state;
 struct intel_bw_state {
 	struct intel_global_state base;
 
+	/*
+	 * Contains a bit mask, used to determine, whether correspondent
+	 * pipe allows SAGV or not.
+	 */
+	u8 pipe_sagv_reject;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e630429af2c0..e1d259913fe3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14009,7 +14009,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -14064,7 +14066,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -15535,6 +15539,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_bw_new_state(state);
+
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
@@ -15543,8 +15551,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * SKL workaround: bspec recommends we disable the SAGV when we
 		 * have more then one pipe enabled
 		 */
-		if (!intel_can_enable_sagv(state))
-			intel_disable_sagv(dev_priv);
+		if (INTEL_GEN(dev_priv) < 11) {
+			if (!intel_can_enable_sagv(bw_state))
+				intel_disable_sagv(dev_priv);
+		}
 
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
@@ -15644,8 +15654,15 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	if (state->modeset)
 		intel_verify_planes(state);
 
-	if (state->modeset && intel_can_enable_sagv(state))
-		intel_enable_sagv(dev_priv);
+	if (INTEL_GEN(dev_priv) < 11) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_bw_new_state(state);
+
+		if (state->modeset && intel_can_enable_sagv(bw_state)) {
+			intel_enable_sagv(dev_priv);
+		}
+	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
 
@@ -15797,7 +15814,6 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	if (state->global_state_changed) {
 		assert_global_state_locked(dev_priv);
-
 		dev_priv->active_pipes = state->active_pipes;
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 523e0444b373..51fa5a746a5f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -679,6 +679,8 @@ struct skl_plane_wm {
 	struct skl_wm_level wm[8];
 	struct skl_wm_level uv_wm[8];
 	struct skl_wm_level trans_wm;
+	struct skl_wm_level sagv_wm0;
+	struct skl_wm_level uv_sagv_wm0;
 	bool is_planar;
 };
 
@@ -689,6 +691,7 @@ enum color_plane {
 
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
+	bool can_sagv;
 };
 
 enum vlv_wm_level {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 64193b098175..63c46918d1ed 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -43,6 +43,7 @@
 #include "i915_fixed.h"
 #include "i915_irq.h"
 #include "i915_trace.h"
+#include "display/intel_bw.h"
 #include "intel_pm.h"
 #include "intel_sideband.h"
 #include "../../../platform/x86/intel_ips.h"
@@ -3634,7 +3635,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
 	return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv);
 }
 
-static bool
+bool
 intel_has_sagv(struct drm_i915_private *dev_priv)
 {
 	/* HACK! */
@@ -3827,33 +3828,106 @@ static bool skl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
 	return icl_can_enable_sagv_on_pipe(crtc_state);
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool
+tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state);
+
+bool intel_can_enable_sagv(struct intel_bw_state *bw_state)
+{
+	return bw_state->pipe_sagv_reject == 0;
+}
+
+static int intel_compute_sagv_mask(struct intel_atomic_state *state)
 {
+	int ret;
 	struct drm_device *dev = state->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *crtc;
-	struct intel_crtc_state *crtc_state;
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
 	int i;
+	bool can_sagv;
 
+	/*
+	 * If SAGV is not supported we just can't do anything
+	 * not even set or reject SAGV points - just bail out.
+	 * Thus avoid needless calculations.
+	 */
 	if (!intel_has_sagv(dev_priv))
-		return false;
+		return 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		bool pipe_sagv_enable;
+
+		new_bw_state = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state)) {
+			WARN(1, "Could not get bw_state\n");
+			return PTR_ERR(new_bw_state);
+		}
+
+		old_bw_state = intel_atomic_get_bw_old_state(state);
+
+		if (!new_crtc_state->hw.active)
+			continue;
+
+		if (INTEL_GEN(dev_priv) >= 12) {
+			pipe_sagv_enable = tgl_can_enable_sagv_on_pipe(new_crtc_state);
+		} else if (INTEL_GEN(dev_priv) >= 11) {
+			pipe_sagv_enable = icl_can_enable_sagv_on_pipe(new_crtc_state);
+		} else {
+			pipe_sagv_enable = skl_can_enable_sagv_on_pipe(new_crtc_state);
+		}
+
+		if (pipe_sagv_enable)
+			new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
+		else
+			new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
+	}
+
+	if (!new_bw_state || !old_bw_state)
+		return 0;
+
+	can_sagv = new_bw_state->pipe_sagv_reject == 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
+
+		/*
+		 * Due to drm limitation at commit state, when
+		 * changes are written the whole atomic state is
+		 * zeroed away => which prevents from using it,
+		 * so just sticking it into pipe wm state for
+		 * keeping it simple - anyway this is related to wm.
+		 * Proper way in ideal universe would be of course not
+		 * to lose parent atomic state object from child crtc_state,
+		 * and stick to OOP programming principles, which had been
+		 * scientifically proven to work.
+		 */
+		pipe_wm->can_sagv = can_sagv;
+	}
 
 	/*
-	 * If there are no active CRTCs, no additional checks need be performed
+	 * For SAGV we need to account all the pipes,
+	 * not only the ones which are in state currently.
+	 * Grab all locks if we detect that we are actually
+	 * going to do something.
 	 */
-	if (hweight8(state->active_pipes) == 0)
-		return true;
+	if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
+		DRM_DEBUG_KMS("State %p: old sagv mask 0x%x, new sagv mask 0x%x\n",
+			      state,
+			      old_bw_state->pipe_sagv_reject,
+			      new_bw_state->pipe_sagv_reject);
 
-	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		if (INTEL_GEN(dev_priv) <= 9) {
-			if (!skl_can_enable_sagv_on_pipe(crtc_state))
-				return false;
-		} else if (!icl_can_enable_sagv_on_pipe(crtc_state)) {
-			return false;
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret) {
+			DRM_DEBUG_KMS("Could not serialize global state\n");
+			return ret;
 		}
 	}
 
-	return true;
+	return 0;
 }
 
 /*
@@ -4075,6 +4149,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 		unsigned int latency = dev_priv->wm.skl_latency[level];
 
 		skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm);
+
 		if (wm.min_ddb_alloc == U16_MAX)
 			break;
 
@@ -4589,9 +4664,66 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
 	const struct skl_plane_wm *wm =
 		&crtc_state->wm.skl.optimal.planes[plane_id];
 
+	if (!level) {
+		const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+
+		if (pipe_wm->can_sagv)
+			return color_plane == COLOR_PLANE_Y ? &wm->sagv_wm0 : &wm->uv_sagv_wm0;
+	}
+
 	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
 }
 
+static bool
+tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	enum plane_id plane_id;
+
+	/*
+	 * If pipe is not active it can't affect SAGV rejection
+	 * Checking it here is needed to leave only cases when
+	 * alloc_size is 0 for any other reasons, except inactive
+	 * pipe. As inactive pipe is fine, however having no ddb
+	 * space available is already problematic - so need to
+	 * to separate those.
+	 */
+	if (!crtc_state->hw.active)
+		return true;
+
+	/*
+	 * skl_allocate_pipe_ddb already done it's job to allocate
+	 * as much blocks as possible for each plane - let's now
+	 * evaluate if those were enough to enable SAGV.
+	 * Criteria is that we need to have wm0 + sagv_block_time blocks
+	 * for level 0 for each plane.
+	 */
+	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
+		struct skl_ddb_entry *plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_y[plane_id];
+		struct skl_ddb_entry *uv_plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_uv[plane_id];
+		const struct skl_plane_wm *wm =
+			&crtc_state->wm.skl.optimal.planes[plane_id];
+
+		if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc) {
+			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV plane %d pipe %c\n",
+				      plane_alloc->start, plane_alloc->end, plane_id,
+				      pipe_name(intel_crtc->pipe));
+			return false;
+		}
+
+		if (skl_ddb_entry_size(uv_plane_alloc) < wm->uv_sagv_wm0.min_ddb_alloc) {
+			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV uv plane %d pipe %c\n",
+				      plane_alloc->start, plane_alloc->end, plane_id,
+				      pipe_name(intel_crtc->pipe));
+			return false;
+		}
+	}
+
+	return true;
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 {
@@ -5173,10 +5305,17 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 static void
 skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_wm_level *levels)
+		      struct skl_plane_wm *plane_wm,
+		      enum color_plane color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
+	/*
+	 * Check which kind of plane is it and based on that calculate
+	 * correspondent WM levels.
+	 */
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				      plane_wm->uv_wm : plane_wm->wm;
 	struct skl_wm_level *result_prev = &levels[0];
 
 	for (level = 0; level <= max_level; level++) {
@@ -5190,6 +5329,40 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 	}
 }
 
+static void skl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
+				const struct skl_wm_params *wm_params,
+				struct skl_plane_wm *plane_wm,
+				enum color_plane color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct skl_wm_level *sagv_wm = color_plane == COLOR_PLANE_UV ?
+				&plane_wm->uv_sagv_wm0 : &plane_wm->sagv_wm0;
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				plane_wm->uv_wm : plane_wm->wm;
+
+	/*
+	 * For Gen12 if it is an L0 we need to also
+	 * consider sagv_block_time when calculating
+	 * L0 watermark - we will need that when making
+	 * a decision whether enable SAGV or not.
+	 * For older gens we agreed to copy L0 value for
+	 * compatibility.
+	 */
+	if ((INTEL_GEN(dev_priv) >= 12)) {
+		u32 latency = dev_priv->wm.skl_latency[0];
+
+		latency += dev_priv->sagv_block_time_us;
+		skl_compute_plane_wm(crtc_state, 0, latency,
+				     wm_params, &levels[0],
+				     sagv_wm);
+		DRM_DEBUG_KMS("%d L0 blocks required for SAGV vs %d for non-SAGV\n",
+			      sagv_wm->min_ddb_alloc, levels[0].min_ddb_alloc);
+	} else {
+		/* Since all members are POD */
+		*sagv_wm = levels[0];
+	}
+}
+
 static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 				      const struct skl_wm_params *wp,
 				      struct skl_plane_wm *wm)
@@ -5270,7 +5443,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
 	skl_compute_transition_wm(crtc_state, &wm_params, wm);
 
 	return 0;
@@ -5292,7 +5466,8 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
 
 	return 0;
 }
@@ -5631,9 +5806,25 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
 			enum plane_id plane_id = plane->id;
 			const struct skl_plane_wm *old_wm, *new_wm;
+			const struct skl_wm_level *old_wm_level, *new_wm_level;
+			u16 old_plane_res_l, new_plane_res_l;
+			u8  old_plane_res_b, new_plane_res_b;
+			u16 old_min_ddb_alloc, new_min_ddb_alloc;
+			int color_plane = 0;
 
 			old_wm = &old_pipe_wm->planes[plane_id];
 			new_wm = &new_pipe_wm->planes[plane_id];
+			old_wm_level = skl_plane_wm_level(old_crtc_state, plane_id, 0, color_plane);
+			new_wm_level = skl_plane_wm_level(new_crtc_state, plane_id, 0, color_plane);
+
+			old_plane_res_l = old_wm_level->plane_res_l;
+			old_plane_res_b = old_wm_level->plane_res_b;
+
+			new_plane_res_l = new_wm_level->plane_res_l;
+			new_plane_res_b = new_wm_level->plane_res_b;
+
+			old_min_ddb_alloc = old_wm_level->min_ddb_alloc;
+			new_min_ddb_alloc = new_wm_level->min_ddb_alloc;
 
 			if (skl_plane_wm_equals(dev_priv, old_wm, new_wm))
 				continue;
@@ -5657,7 +5848,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s]   lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d"
 				      " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d\n",
 				    plane->base.base.id, plane->base.name,
-				    enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].plane_res_l,
+				    enast(old_wm->wm[0].ignore_lines), old_plane_res_l,
 				    enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].plane_res_l,
 				    enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].plane_res_l,
 				    enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].plane_res_l,
@@ -5667,7 +5858,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].plane_res_l,
 				    enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.plane_res_l,
 
-				    enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].plane_res_l,
+				    enast(new_wm->wm[0].ignore_lines), new_plane_res_l,
 				    enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].plane_res_l,
 				    enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].plane_res_l,
 				    enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].plane_res_l,
@@ -5681,12 +5872,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s]  blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
 				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
 				    plane->base.base.id, plane->base.name,
-				    old_wm->wm[0].plane_res_b, old_wm->wm[1].plane_res_b,
+				    old_plane_res_b, old_wm->wm[1].plane_res_b,
 				    old_wm->wm[2].plane_res_b, old_wm->wm[3].plane_res_b,
 				    old_wm->wm[4].plane_res_b, old_wm->wm[5].plane_res_b,
 				    old_wm->wm[6].plane_res_b, old_wm->wm[7].plane_res_b,
 				    old_wm->trans_wm.plane_res_b,
-				    new_wm->wm[0].plane_res_b, new_wm->wm[1].plane_res_b,
+				    new_plane_res_b, new_wm->wm[1].plane_res_b,
 				    new_wm->wm[2].plane_res_b, new_wm->wm[3].plane_res_b,
 				    new_wm->wm[4].plane_res_b, new_wm->wm[5].plane_res_b,
 				    new_wm->wm[6].plane_res_b, new_wm->wm[7].plane_res_b,
@@ -5696,12 +5887,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
 				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
 				    plane->base.base.id, plane->base.name,
-				    old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
+				    old_min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
 				    old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc,
 				    old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc,
 				    old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc,
 				    old_wm->trans_wm.min_ddb_alloc,
-				    new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
+				    new_min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
 				    new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc,
 				    new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
 				    new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
@@ -5866,6 +6057,10 @@ skl_compute_wm(struct intel_atomic_state *state)
 	if (ret)
 		return ret;
 
+	ret = intel_compute_sagv_mask(state);
+	if (ret)
+		return ret;
+
 	/*
 	 * skl_compute_ddb() will have adjusted the final watermarks
 	 * based on how much ddb is available. Now we can actually
@@ -5993,6 +6188,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 				val = I915_READ(CUR_WM(pipe, level));
 
 			skl_wm_level_from_reg_val(val, &wm->wm[level]);
+			if (level == 0)
+				memcpy(&wm->sagv_wm0, &wm->wm[level],
+				       sizeof(struct skl_wm_level));
 		}
 
 		if (plane_id != PLANE_CURSOR)
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index d60a85421c5a..5fb32db4abc5 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 
 #include "i915_reg.h"
+#include "display/intel_bw.h"
 
 struct drm_device;
 struct drm_i915_private;
@@ -41,7 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
-bool intel_can_enable_sagv(struct intel_atomic_state *state);
+bool intel_has_sagv(struct drm_i915_private *dev_priv);
+bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
 int intel_disable_sagv(struct drm_i915_private *dev_priv);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (5 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+ Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-04-02 17:27   ` Ville Syrjälä
  2020-04-03  6:32   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state Stanislav Lisovskiy
                   ` (15 subsequent siblings)
  22 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We need a new PCode request commands and reply codes
to be added as a prepartion patch for QGV points
restricting for new SAGV support.

v2: - Extracted those changes into separate patch
      (Ville Syrjälä)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h       | 4 ++++
 drivers/gpu/drm/i915/intel_sideband.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9c53fe918be6..1a61db746c7e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8994,6 +8994,7 @@ enum {
 #define     GEN7_PCODE_ILLEGAL_DATA		0x3
 #define     GEN11_PCODE_ILLEGAL_SUBCOMMAND	0x4
 #define     GEN11_PCODE_LOCKED			0x6
+#define     GEN11_PCODE_REJECTED		0x11
 #define     GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10
 #define   GEN6_PCODE_WRITE_RC6VIDS		0x4
 #define   GEN6_PCODE_READ_RC6VIDS		0x5
@@ -9015,6 +9016,7 @@ enum {
 #define   ICL_PCODE_MEM_SUBSYSYSTEM_INFO	0xd
 #define     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO	(0x0 << 8)
 #define     ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point)	(((point) << 16) | (0x1 << 8))
+#define   ICL_PCODE_SAGV_DE_MEM_SS_CONFIG	0xe
 #define   GEN6_PCODE_READ_D_COMP		0x10
 #define   GEN6_PCODE_WRITE_D_COMP		0x11
 #define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
@@ -9027,6 +9029,8 @@ enum {
 #define     GEN9_SAGV_IS_DISABLED		0x1
 #define     GEN9_SAGV_ENABLE			0x3
 #define GEN12_PCODE_READ_SAGV_BLOCK_TIME_US	0x23
+#define GEN11_PCODE_POINTS_RESTRICTED		0x0
+#define GEN11_PCODE_POINTS_RESTRICTED_MASK	0x1
 #define GEN6_PCODE_DATA				_MMIO(0x138128)
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 1447e7516cb7..1e7dd6b6f103 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -370,6 +370,8 @@ static inline int gen7_check_mailbox_status(u32 mbox)
 		return -ENXIO;
 	case GEN11_PCODE_LOCKED:
 		return -EBUSY;
+	case GEN11_PCODE_REJECTED:
+		return -EACCES;
 	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
 		return -EOVERFLOW;
 	default:
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (6 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-04-02 17:30   ` Ville Syrjälä
  2020-04-03  6:34   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth Stanislav Lisovskiy
                   ` (14 subsequent siblings)
  22 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

That is a preparation patch before next one where we
introduce old_bw_state and a bunch of other changes
as well.
In a review comment it was suggested to split out
at least that renaming into a separate patch, what
is done here.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index a8b2038db4d2..d16771dd2b10 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -418,7 +418,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
-	struct intel_bw_state *bw_state = NULL;
+	struct intel_bw_state *new_bw_state = NULL;
 	unsigned int data_rate, max_data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
@@ -447,29 +447,29 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		    old_active_planes == new_active_planes)
 			continue;
 
-		bw_state  = intel_atomic_get_bw_state(state);
-		if (IS_ERR(bw_state))
-			return PTR_ERR(bw_state);
+		new_bw_state  = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state))
+			return PTR_ERR(new_bw_state);
 
-		bw_state->data_rate[crtc->pipe] = new_data_rate;
-		bw_state->num_active_planes[crtc->pipe] = new_active_planes;
+		new_bw_state->data_rate[crtc->pipe] = new_data_rate;
+		new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
 
 		drm_dbg_kms(&dev_priv->drm,
 			    "pipe %c data rate %u num active planes %u\n",
 			    pipe_name(crtc->pipe),
-			    bw_state->data_rate[crtc->pipe],
-			    bw_state->num_active_planes[crtc->pipe]);
+			    new_bw_state->data_rate[crtc->pipe],
+			    new_bw_state->num_active_planes[crtc->pipe]);
 	}
 
-	if (!bw_state)
+	if (!new_bw_state)
 		return 0;
 
-	ret = intel_atomic_lock_global_state(&bw_state->base);
+	ret = intel_atomic_lock_global_state(&new_bw_state->base);
 	if (ret)
 		return ret;
 
-	data_rate = intel_bw_data_rate(dev_priv, bw_state);
-	num_active_planes = intel_bw_num_active_planes(dev_priv, bw_state);
+	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
 	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
 
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth.
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (7 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-03-26 18:36   ` Stanislav Lisovskiy
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 10/10] drm/i915: Enable SAGV support for Gen12 Stanislav Lisovskiy
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.

Currently we are just comparing against all of
those and take minimum(worst case).

v2: Fixed wrong PCode reply mask, removed hardcoded
    values.

v3: Forbid simultaneous legacy SAGV PCode requests and
    restricting qgv points. Put the actual restriction
    to commit function, added serialization(thanks to Ville)
    to prevent commit being applied out of order in case of
    nonblocking and/or nomodeset commits.

v4:
    - Minor code refactoring, fixed few typos(thanks to James Ausmus)
    - Change the naming of qgv point
      masking/unmasking functions(James Ausmus).
    - Simplify the masking/unmasking operation itself,
      as we don't need to mask only single point per request(James Ausmus)
    - Reject and stick to highest bandwidth point if SAGV
      can't be enabled(BSpec)

v5:
    - Add new mailbox reply codes, which seems to happen during boot
      time for TGL and indicate that QGV setting is not yet available.

v6:
    - Increase number of supported QGV points to be in sync with BSpec.

v7: - Rebased and resolved conflict to fix build failure.
    - Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)

v8: - Don't report an error if we can't restrict qgv points, as SAGV
      can be disabled by BIOS, which is completely legal. So don't
      make CI panic. Instead if we detect that there is only 1 QGV
      point accessible just analyze if we can fit the required bandwidth
      requirements, but no need in restricting.

v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
      simultaneously.

v10: - Fix CDCLK corruption, because of global state getting serialized
       without modeset, which caused copying of non-calculated cdclk
       to be copied to dev_priv(thanks to Ville for the hint).

v11: - Remove unneeded headers and spaces(Matthew Roper)
     - Remove unneeded intel_qgv_info qi struct from bw check and zero
       out the needed one(Matthew Roper)
     - Changed QGV error message to have more clear meaning(Matthew Roper)
     - Use state->modeset_set instead of any_ms(Matthew Roper)
     - Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
     - Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
     - Moved unrelated changes to other patch(using latency as parameter
       for plane wm calculation, moved to SAGV refactoring patch)

v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
     - Remove unnecessary mask being zero check when unmasking
       qgv points as this is completely legal(Matt Roper)
     - Check if we are setting the same mask as already being set
       in hardware to prevent error from PCode.
     - Fix error message when restricting/unrestricting qgv points
       to "mask/unmask" which sounds more accurate(Matt Roper)
     - Move sagv status setting to icl_get_bw_info from atomic check
       as this should be calculated only once.(Matt Roper)
     - Edited comments for the case when we can't enable SAGV and
       use only 1 QGV point with highest bandwidth to be more
       understandable.(Matt Roper)

v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
     - Changed comment for zero new_mask in qgv points masking function
       to better reflect reality(Ville Syrjälä)
     - Simplified bit mask operation in qgv points masking function
       (Ville Syrjälä)
     - Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
       however this still can't be under modeset condition(Ville Syrjälä)
     - Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
       (Ville Syrjälä)
     - Extracted PCode changes to separate patch.(Ville Syrjälä)
     - Now treat num_planes 0 same as 1 to avoid confusion and
       returning max_bw as 0, which would prevent choosing QGV
       point having max bandwidth in case if SAGV is not allowed,
       as per BSpec(Ville Syrjälä)
     - Do the actual qgv_points_mask swap in the same place as
       all other global state parts like cdclk are swapped.
       In the next patch, this all will be moved to bw state as
       global state, once new global state patch series from Ville
       lands

v14: - Now using global state to serialize access to qgv points
     - Added global state locking back, otherwise we seem to read
       bw state in a wrong way.

v15: - Added TODO comment for near atomic global state locking in
       bw code.

v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
       with Jani Nikula.
     - Take bw_state_changed flag into use.

v17: - Moved qgv point related manipulations next to SAGV code, as
       those are semantically related(Ville Syrjälä)
     - Renamed those into intel_sagv_(pre)|(post)_plane_update
       (Ville Syrjälä)

v18: - Move sagv related calls from commit tail into
       intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c       | 147 +++++++++++++-----
 drivers/gpu/drm/i915/display/intel_bw.h       |   9 ++
 drivers/gpu/drm/i915/display/intel_display.c  |  29 +---
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 119 ++++++++++++++
 drivers/gpu/drm/i915/intel_pm.h               |   2 +
 6 files changed, 251 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index d16771dd2b10..d5a93e8f7134 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -8,6 +8,9 @@
 #include "intel_bw.h"
 #include "intel_display_types.h"
 #include "intel_sideband.h"
+#include "intel_atomic.h"
+#include "intel_pm.h"
+
 
 /* Parameters for Qclk Geyserville (QGV) */
 struct intel_qgv_point {
@@ -113,6 +116,26 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask)
+{
+	int ret;
+
+	/* bspec says to keep retrying for at least 1 ms */
+	ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
+				points_mask,
+				GEN11_PCODE_POINTS_RESTRICTED_MASK,
+				GEN11_PCODE_POINTS_RESTRICTED,
+				1);
+
+	if (ret < 0) {
+		DRM_ERROR("Failed to disable qgv points (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 			      struct intel_qgv_info *qi)
 {
@@ -240,6 +263,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
 			break;
 	}
 
+	/*
+	 * In case if SAGV is disabled in BIOS, we always get 1
+	 * SAGV point, but we can't send PCode commands to restrict it
+	 * as it will fail and pointless anyway.
+	 */
+	if (qi.num_points == 1)
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+	else
+		dev_priv->sagv_status = I915_SAGV_ENABLED;
+
 	return 0;
 }
 
@@ -259,7 +292,7 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
 		if (qgv_point >= bi->num_qgv_points)
 			return UINT_MAX;
 
-		if (num_planes >= bi->num_planes)
+		if (num_planes >= bi->num_planes || !num_planes)
 			return bi->deratedbw[qgv_point];
 	}
 
@@ -277,34 +310,6 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 		icl_get_bw_info(dev_priv, &icl_sa_info);
 }
 
-static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
-					int num_planes)
-{
-	if (INTEL_GEN(dev_priv) >= 11) {
-		/*
-		 * Any bw group has same amount of QGV points
-		 */
-		const struct intel_bw_info *bi =
-			&dev_priv->max_bw[0];
-		unsigned int min_bw = UINT_MAX;
-		int i;
-
-		/*
-		 * FIXME with SAGV disabled maybe we can assume
-		 * point 1 will always be used? Seems to match
-		 * the behaviour observed in the wild.
-		 */
-		for (i = 0; i < bi->num_qgv_points; i++) {
-			unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
-
-			min_bw = min(bw, min_bw);
-		}
-		return min_bw;
-	} else {
-		return UINT_MAX;
-	}
-}
-
 static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
 {
 	/*
@@ -419,10 +424,15 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_bw_state *new_bw_state = NULL;
-	unsigned int data_rate, max_data_rate;
+	struct intel_bw_state *old_bw_state = NULL;
+	unsigned int data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
 	int i, ret;
+	u32 allowed_points = 0;
+	unsigned int max_bw_point = 0, max_bw = 0;
+	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
+	u32 mask = (1 << num_qgv_points) - 1;
 
 	/* FIXME earlier gens need some checks too */
 	if (INTEL_GEN(dev_priv) < 11)
@@ -465,23 +475,86 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		return 0;
 
 	ret = intel_atomic_lock_global_state(&new_bw_state->base);
-	if (ret)
+	if (ret) {
+		DRM_DEBUG_KMS("Could not lock global state\n");
 		return ret;
+	}
 
 	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	data_rate = DIV_ROUND_UP(data_rate, 1000);
+
 	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
-	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
+	for (i = 0; i < num_qgv_points; i++) {
+		unsigned int max_data_rate;
 
-	data_rate = DIV_ROUND_UP(data_rate, 1000);
+		max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
+		/*
+		 * We need to know which qgv point gives us
+		 * maximum bandwidth in order to disable SAGV
+		 * if we find that we exceed SAGV block time
+		 * with watermarks. By that moment we already
+		 * have those, as it is calculated earlier in
+		 * intel_atomic_check,
+		 */
+		if (max_data_rate > max_bw) {
+			max_bw_point = i;
+			max_bw = max_data_rate;
+		}
+		if (max_data_rate >= data_rate)
+			allowed_points |= BIT(i);
+		DRM_DEBUG_KMS("QGV point %d: max bw %d required %d\n",
+			      i, max_data_rate, data_rate);
+	}
 
-	if (data_rate > max_data_rate) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
-			    data_rate, max_data_rate, num_active_planes);
+	/*
+	 * BSpec states that we always should have at least one allowed point
+	 * left, so if we couldn't - simply reject the configuration for obvious
+	 * reasons.
+	 */
+	if (allowed_points == 0) {
+		DRM_DEBUG_KMS("No QGV points provide sufficient memory"
+			      " bandwidth for display configuration.\n");
 		return -EINVAL;
 	}
 
+	/*
+	 * Leave only single point with highest bandwidth, if
+	 * we can't enable SAGV due to the increased memory latency it may
+	 * cause.
+	 */
+	if (!intel_can_enable_sagv(new_bw_state)) {
+		allowed_points = 1 << max_bw_point;
+		DRM_DEBUG_KMS("No SAGV, using single QGV point %d\n",
+			      max_bw_point);
+	}
+	/*
+	 * We store the ones which need to be masked as that is what PCode
+	 * actually accepts as a parameter.
+	 */
+	new_bw_state->qgv_points_mask = (~allowed_points) & mask;
+
+	DRM_DEBUG_KMS("New state %p qgv mask %x\n",
+		      state, new_bw_state->qgv_points_mask);
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (IS_ERR(old_bw_state)) {
+		DRM_DEBUG_KMS("Could not get old bw state!\n");
+		return PTR_ERR(old_bw_state);
+	}
+
+	/*
+	 * If the actual mask had changed we need to make sure that
+	 * the commits are serialized(in case this is a nomodeset, nonblocking)
+	 */
+	if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret) {
+			DRM_DEBUG_KMS("Could not serialize global state\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index 6ad3ea7cedfe..5cb0717c2df8 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,13 @@ struct intel_bw_state {
 	 */
 	u8 pipe_sagv_reject;
 
+	/*
+	 * Current QGV points mask, which restricts
+	 * some particular SAGV states, not to confuse
+	 * with pipe_sagv_mask.
+	 */
+	u8 qgv_points_mask;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
@@ -44,5 +51,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state);
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask);
 
 #endif /* __INTEL_BW_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e1d259913fe3..ab3d94e3e97e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -15539,23 +15539,17 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_bw_new_state(state);
+		/*
+		 * Now we need to check if SAGV needs to be disabled(i.e QGV points
+		 * modified even, when no modeset is done(for example plane updates
+		 * can now trigger that).
+		 */
+		intel_sagv_pre_plane_update(state);
 
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
 
-		/*
-		 * SKL workaround: bspec recommends we disable the SAGV when we
-		 * have more then one pipe enabled
-		 */
-		if (INTEL_GEN(dev_priv) < 11) {
-			if (!intel_can_enable_sagv(bw_state))
-				intel_disable_sagv(dev_priv);
-		}
-
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
 
@@ -15651,17 +15645,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	intel_check_cpu_fifo_underruns(dev_priv);
 	intel_check_pch_fifo_underruns(dev_priv);
 
-	if (state->modeset)
+	if (state->modeset) {
 		intel_verify_planes(state);
 
-	if (INTEL_GEN(dev_priv) < 11) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_bw_new_state(state);
-
-		if (state->modeset && intel_can_enable_sagv(bw_state)) {
-			intel_enable_sagv(dev_priv);
-		}
+		intel_sagv_post_plane_update(state);
 	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 51fa5a746a5f..8655038bafe7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -689,6 +689,9 @@ enum color_plane {
 	COLOR_PLANE_UV
 };
 
+/* BSpec precisely defines this */
+#define NUM_SAGV_POINTS 8
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 	bool can_sagv;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 63c46918d1ed..6e4d64b626f8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3758,6 +3758,125 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_device *dev = state->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_bw_state(state);
+	if (!new_bw_state) {
+		WARN(1, "Could not get new bw_state\n");
+		return;
+	}
+
+	if ((INTEL_GEN(dev_priv) < 11) && !intel_can_enable_sagv(new_bw_state)) {
+		intel_disable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (!old_bw_state) {
+		WARN(1, "Could not get old bw_state\n");
+		return;
+	}
+
+	/*
+	 * Nothing to mask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
+
+	/*
+	 * If new mask is zero - means there is nothing to mask,
+	 * we can only unmask, which should be done in unmask.
+	 */
+	if (!new_mask)
+		return;
+
+	/*
+	 * Restrict required qgv points before updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Could not mask required qgv points(%d)\n",
+			      ret);
+}
+
+void intel_sagv_post_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_device *dev = state->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_bw_state(state);
+	if (!new_bw_state) {
+		WARN(1, "Could not get new bw_state\n");
+		return;
+	}
+
+	if ((INTEL_GEN(dev_priv) < 11) && intel_can_enable_sagv(new_bw_state)) {
+		intel_enable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (!old_bw_state) {
+		WARN(1, "Could not get old bw_state\n");
+		return;
+	}
+
+	/*
+	 * Nothing to unmask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = new_bw_state->qgv_points_mask;
+
+	/*
+	 * Allow required qgv points after updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Could not unmask required qgv points(%d)\n",
+			      ret);
+}
+
 static bool icl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
 {
 	struct drm_device *dev = crtc_state->uapi.crtc->dev;
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index 5fb32db4abc5..793a4add9831 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -42,6 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
+void intel_sagv_post_plane_update(struct intel_atomic_state *state);
 bool intel_has_sagv(struct drm_i915_private *dev_priv);
 bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 10/10] drm/i915: Enable SAGV support for Gen12
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (8 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth Stanislav Lisovskiy
@ 2020-03-26 18:10 ` Stanislav Lisovskiy
  2020-03-26 20:59 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev3) Patchwork
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Flip the switch and enable SAGV support
for Gen12 also.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6e4d64b626f8..4c278493559a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3638,10 +3638,6 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
 bool
 intel_has_sagv(struct drm_i915_private *dev_priv)
 {
-	/* HACK! */
-	if (IS_GEN(dev_priv, 12))
-		return false;
-
 	return (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) &&
 		dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED;
 }
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth.
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth Stanislav Lisovskiy
@ 2020-03-26 18:36   ` Stanislav Lisovskiy
  2020-04-02 17:50     ` Ville Syrjälä
  2020-04-03  6:37     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  0 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.

Currently we are just comparing against all of
those and take minimum(worst case).

v2: Fixed wrong PCode reply mask, removed hardcoded
    values.

v3: Forbid simultaneous legacy SAGV PCode requests and
    restricting qgv points. Put the actual restriction
    to commit function, added serialization(thanks to Ville)
    to prevent commit being applied out of order in case of
    nonblocking and/or nomodeset commits.

v4:
    - Minor code refactoring, fixed few typos(thanks to James Ausmus)
    - Change the naming of qgv point
      masking/unmasking functions(James Ausmus).
    - Simplify the masking/unmasking operation itself,
      as we don't need to mask only single point per request(James Ausmus)
    - Reject and stick to highest bandwidth point if SAGV
      can't be enabled(BSpec)

v5:
    - Add new mailbox reply codes, which seems to happen during boot
      time for TGL and indicate that QGV setting is not yet available.

v6:
    - Increase number of supported QGV points to be in sync with BSpec.

v7: - Rebased and resolved conflict to fix build failure.
    - Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)

v8: - Don't report an error if we can't restrict qgv points, as SAGV
      can be disabled by BIOS, which is completely legal. So don't
      make CI panic. Instead if we detect that there is only 1 QGV
      point accessible just analyze if we can fit the required bandwidth
      requirements, but no need in restricting.

v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
      simultaneously.

v10: - Fix CDCLK corruption, because of global state getting serialized
       without modeset, which caused copying of non-calculated cdclk
       to be copied to dev_priv(thanks to Ville for the hint).

v11: - Remove unneeded headers and spaces(Matthew Roper)
     - Remove unneeded intel_qgv_info qi struct from bw check and zero
       out the needed one(Matthew Roper)
     - Changed QGV error message to have more clear meaning(Matthew Roper)
     - Use state->modeset_set instead of any_ms(Matthew Roper)
     - Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
     - Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
     - Moved unrelated changes to other patch(using latency as parameter
       for plane wm calculation, moved to SAGV refactoring patch)

v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
     - Remove unnecessary mask being zero check when unmasking
       qgv points as this is completely legal(Matt Roper)
     - Check if we are setting the same mask as already being set
       in hardware to prevent error from PCode.
     - Fix error message when restricting/unrestricting qgv points
       to "mask/unmask" which sounds more accurate(Matt Roper)
     - Move sagv status setting to icl_get_bw_info from atomic check
       as this should be calculated only once.(Matt Roper)
     - Edited comments for the case when we can't enable SAGV and
       use only 1 QGV point with highest bandwidth to be more
       understandable.(Matt Roper)

v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
     - Changed comment for zero new_mask in qgv points masking function
       to better reflect reality(Ville Syrjälä)
     - Simplified bit mask operation in qgv points masking function
       (Ville Syrjälä)
     - Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
       however this still can't be under modeset condition(Ville Syrjälä)
     - Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
       (Ville Syrjälä)
     - Extracted PCode changes to separate patch.(Ville Syrjälä)
     - Now treat num_planes 0 same as 1 to avoid confusion and
       returning max_bw as 0, which would prevent choosing QGV
       point having max bandwidth in case if SAGV is not allowed,
       as per BSpec(Ville Syrjälä)
     - Do the actual qgv_points_mask swap in the same place as
       all other global state parts like cdclk are swapped.
       In the next patch, this all will be moved to bw state as
       global state, once new global state patch series from Ville
       lands

v14: - Now using global state to serialize access to qgv points
     - Added global state locking back, otherwise we seem to read
       bw state in a wrong way.

v15: - Added TODO comment for near atomic global state locking in
       bw code.

v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
       with Jani Nikula.
     - Take bw_state_changed flag into use.

v17: - Moved qgv point related manipulations next to SAGV code, as
       those are semantically related(Ville Syrjälä)
     - Renamed those into intel_sagv_(pre)|(post)_plane_update
       (Ville Syrjälä)

v18: - Move sagv related calls from commit tail into
       intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)

v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
       for commit tail stage.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c       | 147 +++++++++++++-----
 drivers/gpu/drm/i915/display/intel_bw.h       |   9 ++
 drivers/gpu/drm/i915/display/intel_display.c  |  29 +---
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 119 ++++++++++++++
 drivers/gpu/drm/i915/intel_pm.h               |   2 +
 6 files changed, 251 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index d16771dd2b10..d5a93e8f7134 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -8,6 +8,9 @@
 #include "intel_bw.h"
 #include "intel_display_types.h"
 #include "intel_sideband.h"
+#include "intel_atomic.h"
+#include "intel_pm.h"
+
 
 /* Parameters for Qclk Geyserville (QGV) */
 struct intel_qgv_point {
@@ -113,6 +116,26 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask)
+{
+	int ret;
+
+	/* bspec says to keep retrying for at least 1 ms */
+	ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
+				points_mask,
+				GEN11_PCODE_POINTS_RESTRICTED_MASK,
+				GEN11_PCODE_POINTS_RESTRICTED,
+				1);
+
+	if (ret < 0) {
+		DRM_ERROR("Failed to disable qgv points (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 			      struct intel_qgv_info *qi)
 {
@@ -240,6 +263,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
 			break;
 	}
 
+	/*
+	 * In case if SAGV is disabled in BIOS, we always get 1
+	 * SAGV point, but we can't send PCode commands to restrict it
+	 * as it will fail and pointless anyway.
+	 */
+	if (qi.num_points == 1)
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+	else
+		dev_priv->sagv_status = I915_SAGV_ENABLED;
+
 	return 0;
 }
 
@@ -259,7 +292,7 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
 		if (qgv_point >= bi->num_qgv_points)
 			return UINT_MAX;
 
-		if (num_planes >= bi->num_planes)
+		if (num_planes >= bi->num_planes || !num_planes)
 			return bi->deratedbw[qgv_point];
 	}
 
@@ -277,34 +310,6 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 		icl_get_bw_info(dev_priv, &icl_sa_info);
 }
 
-static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
-					int num_planes)
-{
-	if (INTEL_GEN(dev_priv) >= 11) {
-		/*
-		 * Any bw group has same amount of QGV points
-		 */
-		const struct intel_bw_info *bi =
-			&dev_priv->max_bw[0];
-		unsigned int min_bw = UINT_MAX;
-		int i;
-
-		/*
-		 * FIXME with SAGV disabled maybe we can assume
-		 * point 1 will always be used? Seems to match
-		 * the behaviour observed in the wild.
-		 */
-		for (i = 0; i < bi->num_qgv_points; i++) {
-			unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
-
-			min_bw = min(bw, min_bw);
-		}
-		return min_bw;
-	} else {
-		return UINT_MAX;
-	}
-}
-
 static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
 {
 	/*
@@ -419,10 +424,15 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_bw_state *new_bw_state = NULL;
-	unsigned int data_rate, max_data_rate;
+	struct intel_bw_state *old_bw_state = NULL;
+	unsigned int data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
 	int i, ret;
+	u32 allowed_points = 0;
+	unsigned int max_bw_point = 0, max_bw = 0;
+	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
+	u32 mask = (1 << num_qgv_points) - 1;
 
 	/* FIXME earlier gens need some checks too */
 	if (INTEL_GEN(dev_priv) < 11)
@@ -465,23 +475,86 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		return 0;
 
 	ret = intel_atomic_lock_global_state(&new_bw_state->base);
-	if (ret)
+	if (ret) {
+		DRM_DEBUG_KMS("Could not lock global state\n");
 		return ret;
+	}
 
 	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	data_rate = DIV_ROUND_UP(data_rate, 1000);
+
 	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
-	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
+	for (i = 0; i < num_qgv_points; i++) {
+		unsigned int max_data_rate;
 
-	data_rate = DIV_ROUND_UP(data_rate, 1000);
+		max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
+		/*
+		 * We need to know which qgv point gives us
+		 * maximum bandwidth in order to disable SAGV
+		 * if we find that we exceed SAGV block time
+		 * with watermarks. By that moment we already
+		 * have those, as it is calculated earlier in
+		 * intel_atomic_check,
+		 */
+		if (max_data_rate > max_bw) {
+			max_bw_point = i;
+			max_bw = max_data_rate;
+		}
+		if (max_data_rate >= data_rate)
+			allowed_points |= BIT(i);
+		DRM_DEBUG_KMS("QGV point %d: max bw %d required %d\n",
+			      i, max_data_rate, data_rate);
+	}
 
-	if (data_rate > max_data_rate) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
-			    data_rate, max_data_rate, num_active_planes);
+	/*
+	 * BSpec states that we always should have at least one allowed point
+	 * left, so if we couldn't - simply reject the configuration for obvious
+	 * reasons.
+	 */
+	if (allowed_points == 0) {
+		DRM_DEBUG_KMS("No QGV points provide sufficient memory"
+			      " bandwidth for display configuration.\n");
 		return -EINVAL;
 	}
 
+	/*
+	 * Leave only single point with highest bandwidth, if
+	 * we can't enable SAGV due to the increased memory latency it may
+	 * cause.
+	 */
+	if (!intel_can_enable_sagv(new_bw_state)) {
+		allowed_points = 1 << max_bw_point;
+		DRM_DEBUG_KMS("No SAGV, using single QGV point %d\n",
+			      max_bw_point);
+	}
+	/*
+	 * We store the ones which need to be masked as that is what PCode
+	 * actually accepts as a parameter.
+	 */
+	new_bw_state->qgv_points_mask = (~allowed_points) & mask;
+
+	DRM_DEBUG_KMS("New state %p qgv mask %x\n",
+		      state, new_bw_state->qgv_points_mask);
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (IS_ERR(old_bw_state)) {
+		DRM_DEBUG_KMS("Could not get old bw state!\n");
+		return PTR_ERR(old_bw_state);
+	}
+
+	/*
+	 * If the actual mask had changed we need to make sure that
+	 * the commits are serialized(in case this is a nomodeset, nonblocking)
+	 */
+	if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret) {
+			DRM_DEBUG_KMS("Could not serialize global state\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index 6ad3ea7cedfe..5cb0717c2df8 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,13 @@ struct intel_bw_state {
 	 */
 	u8 pipe_sagv_reject;
 
+	/*
+	 * Current QGV points mask, which restricts
+	 * some particular SAGV states, not to confuse
+	 * with pipe_sagv_mask.
+	 */
+	u8 qgv_points_mask;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
@@ -44,5 +51,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state);
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask);
 
 #endif /* __INTEL_BW_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8a0d952c67bf..ab3d94e3e97e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -15539,23 +15539,17 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_bw_new_state(state);
+		/*
+		 * Now we need to check if SAGV needs to be disabled(i.e QGV points
+		 * modified even, when no modeset is done(for example plane updates
+		 * can now trigger that).
+		 */
+		intel_sagv_pre_plane_update(state);
 
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
 
-		/*
-		 * SKL workaround: bspec recommends we disable the SAGV when we
-		 * have more then one pipe enabled
-		 */
-		if (INTEL_GEN(dev_priv) < 11) {
-			if (bw_state && !intel_can_enable_sagv(bw_state))
-				intel_disable_sagv(dev_priv);
-		}
-
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
 
@@ -15651,17 +15645,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	intel_check_cpu_fifo_underruns(dev_priv);
 	intel_check_pch_fifo_underruns(dev_priv);
 
-	if (state->modeset)
+	if (state->modeset) {
 		intel_verify_planes(state);
 
-	if (INTEL_GEN(dev_priv) < 11) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_bw_new_state(state);
-
-		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state)) {
-			intel_enable_sagv(dev_priv);
-		}
+		intel_sagv_post_plane_update(state);
 	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 51fa5a746a5f..8655038bafe7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -689,6 +689,9 @@ enum color_plane {
 	COLOR_PLANE_UV
 };
 
+/* BSpec precisely defines this */
+#define NUM_SAGV_POINTS 8
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 	bool can_sagv;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 63c46918d1ed..4b96c14f9361 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3758,6 +3758,125 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_device *dev = state->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_bw_new_state(state);
+	if (!new_bw_state) {
+		WARN(1, "Could not get new bw_state\n");
+		return;
+	}
+
+	if ((INTEL_GEN(dev_priv) < 11) && !intel_can_enable_sagv(new_bw_state)) {
+		intel_disable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (!old_bw_state) {
+		WARN(1, "Could not get old bw_state\n");
+		return;
+	}
+
+	/*
+	 * Nothing to mask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
+
+	/*
+	 * If new mask is zero - means there is nothing to mask,
+	 * we can only unmask, which should be done in unmask.
+	 */
+	if (!new_mask)
+		return;
+
+	/*
+	 * Restrict required qgv points before updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Could not mask required qgv points(%d)\n",
+			      ret);
+}
+
+void intel_sagv_post_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_device *dev = state->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_bw_new_state(state);
+	if (!new_bw_state) {
+		WARN(1, "Could not get new bw_state\n");
+		return;
+	}
+
+	if ((INTEL_GEN(dev_priv) < 11) && intel_can_enable_sagv(new_bw_state)) {
+		intel_enable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_bw_old_state(state);
+	if (!old_bw_state) {
+		WARN(1, "Could not get old bw_state\n");
+		return;
+	}
+
+	/*
+	 * Nothing to unmask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = new_bw_state->qgv_points_mask;
+
+	/*
+	 * Allow required qgv points after updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Could not unmask required qgv points(%d)\n",
+			      ret);
+}
+
 static bool icl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
 {
 	struct drm_device *dev = crtc_state->uapi.crtc->dev;
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index 5fb32db4abc5..793a4add9831 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -42,6 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
+void intel_sagv_post_plane_update(struct intel_atomic_state *state);
 bool intel_has_sagv(struct drm_i915_private *dev_priv);
 bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+ Stanislav Lisovskiy
@ 2020-03-26 18:39   ` Stanislav Lisovskiy
  2020-04-02 17:22     ` Ville Syrjälä
  2020-04-03  6:29     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  0 siblings, 2 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-03-26 18:39 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Let's refactor the whole SAGV logic, moving
the main calculations from intel_can_enable_sagv
to intel_compute_sagv_mask, which also handles
this in a unified way calling gen specific
functions to evaluate if SAGV is allowed for
each crtc. If crtc sagv mask have been changed
we serialize access and modify global state.

intel_can_enable_sagv now uses bw_state which
stores all information related to SAGV and
is now a trivial helper.

v2:
    - Rework watermark calculation algorithm to
      attempt to calculate Level 0 watermark
      with added sagv block time latency and
      check if it fits in DBuf in order to
      determine if SAGV can be enabled already
      at this stage, just as BSpec 49325 states.
      if that fails rollback to usual Level 0
      latency and disable SAGV.
    - Remove unneeded tabs(James Ausmus)

v3: Rebased the patch

v4: - Added back interlaced check for Gen12 and
      added separate function for TGL SAGV check
      (thanks to James Ausmus for spotting)
    - Removed unneeded gen check
    - Extracted Gen12 SAGV decision making code
      to a separate function from skl_compute_wm

v5: - Added SAGV global state to dev_priv, because
      we need to track all pipes, not only those
      in atomic state. Each pipe has now correspondent
      bit mask reflecting, whether it can tolerate
      SAGV or not(thanks to Ville Syrjala for suggestions).
    - Now using active flag instead of enable in crc
      usage check.

v6: - Fixed rebase conflicts

v7: - kms_cursor_legacy seems to get broken because of multiple memcpy
      calls when copying level 0 water marks for enabled SAGV, to
      fix this now simply using that field right away, without copying,
      for that introduced a new wm_level accessor which decides which
      wm_level to return based on SAGV state.

v8: - Protect crtc_sagv_mask same way as we do for other global state
      changes: i.e check if changes are needed, then grab all crtc locks
      to serialize the changes(Ville Syrjälä)
    - Add crtc_sagv_mask caching in order to avoid needless recalculations
      (Matthew Roper)
    - Put back Gen12 SAGV switch in order to get it enabled in separate
      patch(Matthew Roper)
    - Rename *_set_sagv_mask to *_compute_sagv_mask(Matthew Roper)
    - Check if there are no active pipes in intel_can_enable_sagv
      instead of platform specific functions(Matthew Roper), same
      for intel_has_sagv check.

v9  - Switched to u8 for crtc_sagv_mask(Ville Syrjälä)
    - crtc_sagv_mask now is pipe_sagv_mask(Ville Syrjälä)
    - Extracted sagv checking logic from skl/icl/tgl_compute_sagv_mask
    - Extracted skl_plane_wm_level function and passing latency to
      separate patches(Ville Syrjälä)
    - Removed part of unneeded copy-paste from tgl_check_pipe_fits_sagv_wm
      (Ville Syrjälä)
    - Now using simple assignment for sagv_wm0 as it contains only
      pod types and no pointers(Ville Syrjälä)
    - Fixed intel_can_enable_sagv not to do double duty, now it only
      check SAGV bits by ANDing those between local and global state.
      The SAGV masks are now computed after watermarks are available,
      in order to be able to figure out if ddb ranges are fitting nicely.
      (Ville Syrjälä)
    - Now having uv_sagv_wm0 and sagv_wm0, otherwise we have wrong logic
      when using skl_plane_wm_level accessor, as we had previously for
      Gen11+ color plane and regular wm levels, so probably both
      has to be recalculated with additional SAGV block time for Level 0.

v10: - Starting to use new global state for storing pipe_sagv_mask

v11: - Fixed rebase conflict with recent drm-tip
     - Check if we really need to recalculate SAGV mask, otherwise
       bail out without making any changes.
     - Use cached SAGV result, instead of recalculating it everytime,
       if bw_state hasn't changed.

v12: - Removed WARN from intel_can_enable_sagv, in some of the commits
       if we don't recalculated watermarks, bw_state is not recalculated,
       thus leading to SAGV state not recalculated by the commit state,
       which is still calling intel_can_enable_sagv function. Fix that
       by just analyzing the current global bw_state object - because
       we simply have no other objects related to that.

v13: - Rebased, fixed warnings regarding long lines
     - Changed function call sites from intel_atomic_bw* to
       intel_wb_* as was suggested.(Jani Nikula)
     - Taken ddb_state_changed and bw_state_changed into use.

v14: - total_affected_planes is no longer needed to check for ddb changes,
       just as active_pipe_changes.

v15: - Fixed stupid mistake with uninitialized crtc in
       skl_compute_sagv_mask.

v16: - Convert pipe_sagv_mask to pipe_sagv_reject and now using inverted
       flag to indicate SAGV readiness for the pipe(Ville Syrjälä)
     - Added return value to intel_compute_sagv_mask which call
       intel_atomic_serialize_global_state in order to properly
       propagate EDEADLCK to drm.
     - Based on the discussion with Ville, removed active_pipe_changes
       check and also there seems to be no need for checking
       ddb_state_changes as well.
       Instead we just iterate through crtcs in state - having
       crtc in a state already guarantees that it is at least read-locked
       Having additional flag to check if there actually were some plane
       wm/ddb changes would be probably added later as an optimization.
     - We can't get parent atomic state from crtc_state at commit stage
       (nice drm feature), also propagating state through function call
       chain seems to be overkill and not possible(cursor legacy updates)
       Querying for bw_state object from global state is not possible as
       it might get swapped with other global state.
       So... just sticked can_sagv boolean into wm crtc state.

v17: - Skip inactive crtcs, when checking for SAGV-readiness.

v18: - Switch to use intel_atomic_crtc_state_for_each_plane_state
       instead of for_each_intel_plane_on_crtc and fixed previous
       code, which was using old plane state, which caused NULL ptr
       dereference, bacause that code is now called before we swap the
       state.

v19: - Use intel_atomic_bw_* pattern again
     - Optimized sagv checks in verify_wm_state(Ville Syrjälä)
     - Do intel_compute_sagv_mask after ddb is allocated(Ville Syrjälä),
       using it's results
     - Use bw_state in intel_can_enable_sagv
     - Use COLOR_PLANE enum instead of boolean yuv or "0", "1" magic
     - Extracted sagv wm0 calculation into separate skl_compute_sagv_wm
       function(Ville Syrjälä)

v20: - Added check for NULL for bw_state in commit_tail

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.h       |   6 +
 drivers/gpu/drm/i915/display/intel_display.c  |  30 ++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 244 ++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.h               |   4 +-
 5 files changed, 256 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index fe6579c952f5..6ad3ea7cedfe 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -18,6 +18,12 @@ struct intel_crtc_state;
 struct intel_bw_state {
 	struct intel_global_state base;
 
+	/*
+	 * Contains a bit mask, used to determine, whether correspondent
+	 * pipe allows SAGV or not.
+	 */
+	u8 pipe_sagv_reject;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e630429af2c0..8a0d952c67bf 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14009,7 +14009,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -14064,7 +14066,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -15535,6 +15539,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_bw_new_state(state);
+
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
@@ -15543,8 +15551,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * SKL workaround: bspec recommends we disable the SAGV when we
 		 * have more then one pipe enabled
 		 */
-		if (!intel_can_enable_sagv(state))
-			intel_disable_sagv(dev_priv);
+		if (INTEL_GEN(dev_priv) < 11) {
+			if (bw_state && !intel_can_enable_sagv(bw_state))
+				intel_disable_sagv(dev_priv);
+		}
 
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
@@ -15644,8 +15654,15 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	if (state->modeset)
 		intel_verify_planes(state);
 
-	if (state->modeset && intel_can_enable_sagv(state))
-		intel_enable_sagv(dev_priv);
+	if (INTEL_GEN(dev_priv) < 11) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_bw_new_state(state);
+
+		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state)) {
+			intel_enable_sagv(dev_priv);
+		}
+	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
 
@@ -15797,7 +15814,6 @@ static int intel_atomic_commit(struct drm_device *dev,
 
 	if (state->global_state_changed) {
 		assert_global_state_locked(dev_priv);
-
 		dev_priv->active_pipes = state->active_pipes;
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 523e0444b373..51fa5a746a5f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -679,6 +679,8 @@ struct skl_plane_wm {
 	struct skl_wm_level wm[8];
 	struct skl_wm_level uv_wm[8];
 	struct skl_wm_level trans_wm;
+	struct skl_wm_level sagv_wm0;
+	struct skl_wm_level uv_sagv_wm0;
 	bool is_planar;
 };
 
@@ -689,6 +691,7 @@ enum color_plane {
 
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
+	bool can_sagv;
 };
 
 enum vlv_wm_level {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 64193b098175..63c46918d1ed 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -43,6 +43,7 @@
 #include "i915_fixed.h"
 #include "i915_irq.h"
 #include "i915_trace.h"
+#include "display/intel_bw.h"
 #include "intel_pm.h"
 #include "intel_sideband.h"
 #include "../../../platform/x86/intel_ips.h"
@@ -3634,7 +3635,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
 	return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv);
 }
 
-static bool
+bool
 intel_has_sagv(struct drm_i915_private *dev_priv)
 {
 	/* HACK! */
@@ -3827,33 +3828,106 @@ static bool skl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
 	return icl_can_enable_sagv_on_pipe(crtc_state);
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool
+tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state);
+
+bool intel_can_enable_sagv(struct intel_bw_state *bw_state)
+{
+	return bw_state->pipe_sagv_reject == 0;
+}
+
+static int intel_compute_sagv_mask(struct intel_atomic_state *state)
 {
+	int ret;
 	struct drm_device *dev = state->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *crtc;
-	struct intel_crtc_state *crtc_state;
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
 	int i;
+	bool can_sagv;
 
+	/*
+	 * If SAGV is not supported we just can't do anything
+	 * not even set or reject SAGV points - just bail out.
+	 * Thus avoid needless calculations.
+	 */
 	if (!intel_has_sagv(dev_priv))
-		return false;
+		return 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		bool pipe_sagv_enable;
+
+		new_bw_state = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state)) {
+			WARN(1, "Could not get bw_state\n");
+			return PTR_ERR(new_bw_state);
+		}
+
+		old_bw_state = intel_atomic_get_bw_old_state(state);
+
+		if (!new_crtc_state->hw.active)
+			continue;
+
+		if (INTEL_GEN(dev_priv) >= 12) {
+			pipe_sagv_enable = tgl_can_enable_sagv_on_pipe(new_crtc_state);
+		} else if (INTEL_GEN(dev_priv) >= 11) {
+			pipe_sagv_enable = icl_can_enable_sagv_on_pipe(new_crtc_state);
+		} else {
+			pipe_sagv_enable = skl_can_enable_sagv_on_pipe(new_crtc_state);
+		}
+
+		if (pipe_sagv_enable)
+			new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
+		else
+			new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
+	}
+
+	if (!new_bw_state || !old_bw_state)
+		return 0;
+
+	can_sagv = new_bw_state->pipe_sagv_reject == 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
+
+		/*
+		 * Due to drm limitation at commit state, when
+		 * changes are written the whole atomic state is
+		 * zeroed away => which prevents from using it,
+		 * so just sticking it into pipe wm state for
+		 * keeping it simple - anyway this is related to wm.
+		 * Proper way in ideal universe would be of course not
+		 * to lose parent atomic state object from child crtc_state,
+		 * and stick to OOP programming principles, which had been
+		 * scientifically proven to work.
+		 */
+		pipe_wm->can_sagv = can_sagv;
+	}
 
 	/*
-	 * If there are no active CRTCs, no additional checks need be performed
+	 * For SAGV we need to account all the pipes,
+	 * not only the ones which are in state currently.
+	 * Grab all locks if we detect that we are actually
+	 * going to do something.
 	 */
-	if (hweight8(state->active_pipes) == 0)
-		return true;
+	if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
+		DRM_DEBUG_KMS("State %p: old sagv mask 0x%x, new sagv mask 0x%x\n",
+			      state,
+			      old_bw_state->pipe_sagv_reject,
+			      new_bw_state->pipe_sagv_reject);
 
-	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		if (INTEL_GEN(dev_priv) <= 9) {
-			if (!skl_can_enable_sagv_on_pipe(crtc_state))
-				return false;
-		} else if (!icl_can_enable_sagv_on_pipe(crtc_state)) {
-			return false;
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret) {
+			DRM_DEBUG_KMS("Could not serialize global state\n");
+			return ret;
 		}
 	}
 
-	return true;
+	return 0;
 }
 
 /*
@@ -4075,6 +4149,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 		unsigned int latency = dev_priv->wm.skl_latency[level];
 
 		skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm);
+
 		if (wm.min_ddb_alloc == U16_MAX)
 			break;
 
@@ -4589,9 +4664,66 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
 	const struct skl_plane_wm *wm =
 		&crtc_state->wm.skl.optimal.planes[plane_id];
 
+	if (!level) {
+		const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+
+		if (pipe_wm->can_sagv)
+			return color_plane == COLOR_PLANE_Y ? &wm->sagv_wm0 : &wm->uv_sagv_wm0;
+	}
+
 	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
 }
 
+static bool
+tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	enum plane_id plane_id;
+
+	/*
+	 * If pipe is not active it can't affect SAGV rejection
+	 * Checking it here is needed to leave only cases when
+	 * alloc_size is 0 for any other reasons, except inactive
+	 * pipe. As inactive pipe is fine, however having no ddb
+	 * space available is already problematic - so need to
+	 * to separate those.
+	 */
+	if (!crtc_state->hw.active)
+		return true;
+
+	/*
+	 * skl_allocate_pipe_ddb already done it's job to allocate
+	 * as much blocks as possible for each plane - let's now
+	 * evaluate if those were enough to enable SAGV.
+	 * Criteria is that we need to have wm0 + sagv_block_time blocks
+	 * for level 0 for each plane.
+	 */
+	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
+		struct skl_ddb_entry *plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_y[plane_id];
+		struct skl_ddb_entry *uv_plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_uv[plane_id];
+		const struct skl_plane_wm *wm =
+			&crtc_state->wm.skl.optimal.planes[plane_id];
+
+		if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc) {
+			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV plane %d pipe %c\n",
+				      plane_alloc->start, plane_alloc->end, plane_id,
+				      pipe_name(intel_crtc->pipe));
+			return false;
+		}
+
+		if (skl_ddb_entry_size(uv_plane_alloc) < wm->uv_sagv_wm0.min_ddb_alloc) {
+			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV uv plane %d pipe %c\n",
+				      plane_alloc->start, plane_alloc->end, plane_id,
+				      pipe_name(intel_crtc->pipe));
+			return false;
+		}
+	}
+
+	return true;
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 {
@@ -5173,10 +5305,17 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 static void
 skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_wm_level *levels)
+		      struct skl_plane_wm *plane_wm,
+		      enum color_plane color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
+	/*
+	 * Check which kind of plane is it and based on that calculate
+	 * correspondent WM levels.
+	 */
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				      plane_wm->uv_wm : plane_wm->wm;
 	struct skl_wm_level *result_prev = &levels[0];
 
 	for (level = 0; level <= max_level; level++) {
@@ -5190,6 +5329,40 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 	}
 }
 
+static void skl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
+				const struct skl_wm_params *wm_params,
+				struct skl_plane_wm *plane_wm,
+				enum color_plane color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct skl_wm_level *sagv_wm = color_plane == COLOR_PLANE_UV ?
+				&plane_wm->uv_sagv_wm0 : &plane_wm->sagv_wm0;
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				plane_wm->uv_wm : plane_wm->wm;
+
+	/*
+	 * For Gen12 if it is an L0 we need to also
+	 * consider sagv_block_time when calculating
+	 * L0 watermark - we will need that when making
+	 * a decision whether enable SAGV or not.
+	 * For older gens we agreed to copy L0 value for
+	 * compatibility.
+	 */
+	if ((INTEL_GEN(dev_priv) >= 12)) {
+		u32 latency = dev_priv->wm.skl_latency[0];
+
+		latency += dev_priv->sagv_block_time_us;
+		skl_compute_plane_wm(crtc_state, 0, latency,
+				     wm_params, &levels[0],
+				     sagv_wm);
+		DRM_DEBUG_KMS("%d L0 blocks required for SAGV vs %d for non-SAGV\n",
+			      sagv_wm->min_ddb_alloc, levels[0].min_ddb_alloc);
+	} else {
+		/* Since all members are POD */
+		*sagv_wm = levels[0];
+	}
+}
+
 static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 				      const struct skl_wm_params *wp,
 				      struct skl_plane_wm *wm)
@@ -5270,7 +5443,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
 	skl_compute_transition_wm(crtc_state, &wm_params, wm);
 
 	return 0;
@@ -5292,7 +5466,8 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
 
 	return 0;
 }
@@ -5631,9 +5806,25 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
 			enum plane_id plane_id = plane->id;
 			const struct skl_plane_wm *old_wm, *new_wm;
+			const struct skl_wm_level *old_wm_level, *new_wm_level;
+			u16 old_plane_res_l, new_plane_res_l;
+			u8  old_plane_res_b, new_plane_res_b;
+			u16 old_min_ddb_alloc, new_min_ddb_alloc;
+			int color_plane = 0;
 
 			old_wm = &old_pipe_wm->planes[plane_id];
 			new_wm = &new_pipe_wm->planes[plane_id];
+			old_wm_level = skl_plane_wm_level(old_crtc_state, plane_id, 0, color_plane);
+			new_wm_level = skl_plane_wm_level(new_crtc_state, plane_id, 0, color_plane);
+
+			old_plane_res_l = old_wm_level->plane_res_l;
+			old_plane_res_b = old_wm_level->plane_res_b;
+
+			new_plane_res_l = new_wm_level->plane_res_l;
+			new_plane_res_b = new_wm_level->plane_res_b;
+
+			old_min_ddb_alloc = old_wm_level->min_ddb_alloc;
+			new_min_ddb_alloc = new_wm_level->min_ddb_alloc;
 
 			if (skl_plane_wm_equals(dev_priv, old_wm, new_wm))
 				continue;
@@ -5657,7 +5848,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s]   lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d"
 				      " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d\n",
 				    plane->base.base.id, plane->base.name,
-				    enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].plane_res_l,
+				    enast(old_wm->wm[0].ignore_lines), old_plane_res_l,
 				    enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].plane_res_l,
 				    enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].plane_res_l,
 				    enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].plane_res_l,
@@ -5667,7 +5858,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].plane_res_l,
 				    enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.plane_res_l,
 
-				    enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].plane_res_l,
+				    enast(new_wm->wm[0].ignore_lines), new_plane_res_l,
 				    enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].plane_res_l,
 				    enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].plane_res_l,
 				    enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].plane_res_l,
@@ -5681,12 +5872,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s]  blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
 				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
 				    plane->base.base.id, plane->base.name,
-				    old_wm->wm[0].plane_res_b, old_wm->wm[1].plane_res_b,
+				    old_plane_res_b, old_wm->wm[1].plane_res_b,
 				    old_wm->wm[2].plane_res_b, old_wm->wm[3].plane_res_b,
 				    old_wm->wm[4].plane_res_b, old_wm->wm[5].plane_res_b,
 				    old_wm->wm[6].plane_res_b, old_wm->wm[7].plane_res_b,
 				    old_wm->trans_wm.plane_res_b,
-				    new_wm->wm[0].plane_res_b, new_wm->wm[1].plane_res_b,
+				    new_plane_res_b, new_wm->wm[1].plane_res_b,
 				    new_wm->wm[2].plane_res_b, new_wm->wm[3].plane_res_b,
 				    new_wm->wm[4].plane_res_b, new_wm->wm[5].plane_res_b,
 				    new_wm->wm[6].plane_res_b, new_wm->wm[7].plane_res_b,
@@ -5696,12 +5887,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
 				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
 				    plane->base.base.id, plane->base.name,
-				    old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
+				    old_min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
 				    old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc,
 				    old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc,
 				    old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc,
 				    old_wm->trans_wm.min_ddb_alloc,
-				    new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
+				    new_min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
 				    new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc,
 				    new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
 				    new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
@@ -5866,6 +6057,10 @@ skl_compute_wm(struct intel_atomic_state *state)
 	if (ret)
 		return ret;
 
+	ret = intel_compute_sagv_mask(state);
+	if (ret)
+		return ret;
+
 	/*
 	 * skl_compute_ddb() will have adjusted the final watermarks
 	 * based on how much ddb is available. Now we can actually
@@ -5993,6 +6188,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 				val = I915_READ(CUR_WM(pipe, level));
 
 			skl_wm_level_from_reg_val(val, &wm->wm[level]);
+			if (level == 0)
+				memcpy(&wm->sagv_wm0, &wm->wm[level],
+				       sizeof(struct skl_wm_level));
 		}
 
 		if (plane_id != PLANE_CURSOR)
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index d60a85421c5a..5fb32db4abc5 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 
 #include "i915_reg.h"
+#include "display/intel_bw.h"
 
 struct drm_device;
 struct drm_i915_private;
@@ -41,7 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
-bool intel_can_enable_sagv(struct intel_atomic_state *state);
+bool intel_has_sagv(struct drm_i915_private *dev_priv);
+bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
 int intel_disable_sagv(struct drm_i915_private *dev_priv);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev3)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (9 preceding siblings ...)
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 10/10] drm/i915: Enable SAGV support for Gen12 Stanislav Lisovskiy
@ 2020-03-26 20:59 ` Patchwork
  2020-03-26 21:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-03-26 20:59 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev3)
URL   : https://patchwork.freedesktop.org/series/75129/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
ad8810ff373a drm/i915: Start passing latency as parameter
930754956920 drm/i915: Eliminate magic numbers "0" and "1" from color plane
-:118: WARNING:LONG_LINE: line over 100 characters
#118: FILE: drivers/gpu/drm/i915/intel_pm.c:4541:
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);

total: 0 errors, 1 warnings, 0 checks, 163 lines checked
b76321aa6824 drm/i915: Introduce skl_plane_wm_level accessor.
9cd6396bdbd9 drm/i915: Add intel_atomic_get_bw_*_state helpers
345239c1e284 drm/i915: Extract gen specific functions from intel_can_enable_sagv
37f392cf14b8 drm/i915: Add proper SAGV support for TGL+
-:234: WARNING:BRACES: braces {} are not necessary for single statement blocks
#234: FILE: drivers/gpu/drm/i915/display/intel_display.c:15662:
+		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state)) {
+			intel_enable_sagv(dev_priv);
+		}

-:341: WARNING:BRACES: braces {} are not necessary for any arm of this statement
#341: FILE: drivers/gpu/drm/i915/intel_pm.c:3874:
+		if (INTEL_GEN(dev_priv) >= 12) {
[...]
+		} else if (INTEL_GEN(dev_priv) >= 11) {
[...]
+		} else {
[...]

total: 0 errors, 2 warnings, 0 checks, 480 lines checked
5ac95b3960a7 drm/i915: Added required new PCode commands
7ddef9fc5a42 drm/i915: Rename bw_state to new_bw_state
9ab9d139acd7 drm/i915: Restrict qgv points which don't have enough bandwidth.
17b1ab4ef65f drm/i915: Enable SAGV support for Gen12

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for SAGV support for Gen12+ (rev3)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (10 preceding siblings ...)
  2020-03-26 20:59 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev3) Patchwork
@ 2020-03-26 21:26 ` Patchwork
  2020-03-27 11:58 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-03-26 21:26 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev3)
URL   : https://patchwork.freedesktop.org/series/75129/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8195 -> Patchwork_17103
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/index.html

Known issues
------------

  Here are the changes found in Patchwork_17103 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@hangcheck:
    - fi-apl-guc:         [PASS][1] -> [INCOMPLETE][2] ([fdo#103927])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/fi-apl-guc/igt@i915_selftest@live@hangcheck.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/fi-apl-guc/igt@i915_selftest@live@hangcheck.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@execlists:
    - fi-icl-dsi:         [DMESG-FAIL][3] ([fdo#108569]) -> [PASS][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/fi-icl-dsi/igt@i915_selftest@live@execlists.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/fi-icl-dsi/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@hangcheck:
    - fi-icl-u2:          [INCOMPLETE][5] ([fdo#108569]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/fi-icl-u2/igt@i915_selftest@live@hangcheck.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/fi-icl-u2/igt@i915_selftest@live@hangcheck.html

  
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569


Participating hosts (49 -> 37)
------------------------------

  Missing    (12): fi-ilk-m540 fi-bdw-samus fi-hsw-4200u fi-hsw-peppy fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-gdg-551 fi-bsw-kefka fi-kbl-7560u fi-byt-clapper fi-skl-6600u 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8195 -> Patchwork_17103

  CI-20190529: 20190529
  CI_DRM_8195: bcb3db890b651ee74ca510bbc4dacebdaa65d311 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5539: e7aae12e37771a8b7796ba252574eb832a5839c3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17103: 17b1ab4ef65f19f4159f1dcf8939b989d1cf83b9 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

17b1ab4ef65f drm/i915: Enable SAGV support for Gen12
9ab9d139acd7 drm/i915: Restrict qgv points which don't have enough bandwidth.
7ddef9fc5a42 drm/i915: Rename bw_state to new_bw_state
5ac95b3960a7 drm/i915: Added required new PCode commands
37f392cf14b8 drm/i915: Add proper SAGV support for TGL+
345239c1e284 drm/i915: Extract gen specific functions from intel_can_enable_sagv
9cd6396bdbd9 drm/i915: Add intel_atomic_get_bw_*_state helpers
b76321aa6824 drm/i915: Introduce skl_plane_wm_level accessor.
930754956920 drm/i915: Eliminate magic numbers "0" and "1" from color plane
ad8810ff373a drm/i915: Start passing latency as parameter

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for SAGV support for Gen12+ (rev3)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (11 preceding siblings ...)
  2020-03-26 21:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-03-27 11:58 ` Patchwork
  2020-04-03  6:19 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev4) Patchwork
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-03-27 11:58 UTC (permalink / raw)
  To: Lisovskiy, Stanislav; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev3)
URL   : https://patchwork.freedesktop.org/series/75129/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8195_full -> Patchwork_17103_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

New tests
---------

  New tests have been introduced between CI_DRM_8195_full and Patchwork_17103_full:

### New IGT tests (1) ###

  * igt@gem_ctx_isolation@dirty-switch:
    - Statuses :
    - Exec time: [None] s

  

Known issues
------------

  Here are the changes found in Patchwork_17103_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_schedule@pi-ringfull-bsd2:
    - shard-iclb:         [PASS][1] -> [SKIP][2] ([fdo#109276]) +7 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb2/igt@gem_exec_schedule@pi-ringfull-bsd2.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb3/igt@gem_exec_schedule@pi-ringfull-bsd2.html

  * igt@gem_exec_schedule@pi-userfault-bsd:
    - shard-iclb:         [PASS][3] -> [SKIP][4] ([i915#677])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb6/igt@gem_exec_schedule@pi-userfault-bsd.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@gem_exec_schedule@pi-userfault-bsd.html

  * igt@gem_exec_schedule@reorder-wide-bsd:
    - shard-iclb:         [PASS][5] -> [SKIP][6] ([fdo#112146]) +3 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb6/igt@gem_exec_schedule@reorder-wide-bsd.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-snb:          [PASS][7] -> [TIMEOUT][8] ([i915#1526])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-snb6/igt@i915_pm_rc6_residency@rc6-idle.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-snb2/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-kbl:          [PASS][9] -> [DMESG-WARN][10] ([i915#180]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-kbl2/igt@i915_suspend@fence-restore-untiled.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-kbl7/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen:
    - shard-kbl:          [PASS][11] -> [FAIL][12] ([i915#54] / [i915#93] / [i915#95])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-kbl2/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html

  * igt@kms_draw_crc@draw-method-rgb565-blt-untiled:
    - shard-glk:          [PASS][13] -> [FAIL][14] ([i915#52] / [i915#54])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-glk2/igt@kms_draw_crc@draw-method-rgb565-blt-untiled.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-glk3/igt@kms_draw_crc@draw-method-rgb565-blt-untiled.html

  * igt@kms_draw_crc@draw-method-rgb565-mmap-wc-xtiled:
    - shard-skl:          [PASS][15] -> [FAIL][16] ([i915#52] / [i915#54])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-skl1/igt@kms_draw_crc@draw-method-rgb565-mmap-wc-xtiled.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-skl9/igt@kms_draw_crc@draw-method-rgb565-mmap-wc-xtiled.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [PASS][17] -> [DMESG-WARN][18] ([i915#180] / [i915#95])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-apl8/igt@kms_fbcon_fbt@fbc-suspend.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-apl6/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@2x-flip-vs-expired-vblank:
    - shard-glk:          [PASS][19] -> [FAIL][20] ([i915#79])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-glk8/igt@kms_flip@2x-flip-vs-expired-vblank.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank.html

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-skl:          [PASS][21] -> [FAIL][22] ([fdo#108145])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-skl1/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-skl9/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [PASS][23] -> [FAIL][24] ([i915#173])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb4/igt@kms_psr@no_drrs.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb1/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         [PASS][25] -> [SKIP][26] ([fdo#109441]) +1 similar issue
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb2/igt@kms_psr@psr2_cursor_blt.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb1/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_setmode@basic:
    - shard-apl:          [PASS][27] -> [FAIL][28] ([i915#31])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-apl3/igt@kms_setmode@basic.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-apl1/igt@kms_setmode@basic.html

  * igt@perf_pmu@busy-no-semaphores-vcs1:
    - shard-iclb:         [PASS][29] -> [SKIP][30] ([fdo#112080]) +2 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb1/igt@perf_pmu@busy-no-semaphores-vcs1.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb5/igt@perf_pmu@busy-no-semaphores-vcs1.html

  
#### Possible fixes ####

  * igt@gem_ctx_persistence@processes:
    - shard-tglb:         [FAIL][31] -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-tglb2/igt@gem_ctx_persistence@processes.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-tglb8/igt@gem_ctx_persistence@processes.html

  * igt@gem_exec_schedule@implicit-write-read-bsd:
    - shard-iclb:         [SKIP][33] ([i915#677]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb1/igt@gem_exec_schedule@implicit-write-read-bsd.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb5/igt@gem_exec_schedule@implicit-write-read-bsd.html

  * igt@gem_exec_schedule@implicit-write-read-bsd1:
    - shard-iclb:         [SKIP][35] ([fdo#109276] / [i915#677]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb6/igt@gem_exec_schedule@implicit-write-read-bsd1.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@gem_exec_schedule@implicit-write-read-bsd1.html

  * igt@gem_exec_schedule@preempt-queue-bsd:
    - shard-iclb:         [SKIP][37] ([fdo#112146]) -> [PASS][38] +1 similar issue
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb2/igt@gem_exec_schedule@preempt-queue-bsd.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb3/igt@gem_exec_schedule@preempt-queue-bsd.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [DMESG-WARN][39] ([i915#180]) -> [PASS][40] +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-kbl2/igt@gem_workarounds@suspend-resume-fd.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-kbl7/igt@gem_workarounds@suspend-resume-fd.html

  * igt@i915_selftest@live@hangcheck:
    - shard-iclb:         [DMESG-FAIL][41] ([i915#419]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb6/igt@i915_selftest@live@hangcheck.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb6/igt@i915_selftest@live@hangcheck.html

  * igt@i915_suspend@sysfs-reader:
    - shard-apl:          [DMESG-WARN][43] ([i915#180]) -> [PASS][44] +3 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-apl6/igt@i915_suspend@sysfs-reader.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-apl4/igt@i915_suspend@sysfs-reader.html

  * igt@kms_flip@plain-flip-fb-recreate:
    - shard-skl:          [FAIL][45] ([i915#34]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-skl1/igt@kms_flip@plain-flip-fb-recreate.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-skl9/igt@kms_flip@plain-flip-fb-recreate.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [DMESG-WARN][47] ([i915#180] / [i915#93] / [i915#95]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-kbl3/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-skl:          [INCOMPLETE][49] ([i915#648] / [i915#69]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-skl10/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-skl6/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min:
    - shard-skl:          [FAIL][51] ([fdo#108145]) -> [PASS][52] +1 similar issue
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-skl4/igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-constant-alpha-min.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [SKIP][53] ([fdo#109441]) -> [PASS][54] +1 similar issue
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb4/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * igt@kms_vblank@pipe-b-accuracy-idle:
    - shard-snb:          [SKIP][55] ([fdo#109271]) -> [PASS][56]
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-snb1/igt@kms_vblank@pipe-b-accuracy-idle.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-snb2/igt@kms_vblank@pipe-b-accuracy-idle.html

  * igt@perf_pmu@busy-accuracy-98-vcs1:
    - shard-iclb:         [SKIP][57] ([fdo#112080]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb5/igt@perf_pmu@busy-accuracy-98-vcs1.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb4/igt@perf_pmu@busy-accuracy-98-vcs1.html

  * igt@prime_busy@hang-bsd2:
    - shard-iclb:         [SKIP][59] ([fdo#109276]) -> [PASS][60] +7 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb6/igt@prime_busy@hang-bsd2.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@prime_busy@hang-bsd2.html

  
#### Warnings ####

  * igt@i915_pm_dc@dc6-psr:
    - shard-tglb:         [FAIL][61] ([i915#454]) -> [SKIP][62] ([i915#468])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-tglb3/igt@i915_pm_dc@dc6-psr.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-tglb2/igt@i915_pm_dc@dc6-psr.html

  * igt@i915_pm_rpm@system-suspend:
    - shard-snb:          [SKIP][63] ([fdo#109271]) -> [INCOMPLETE][64] ([i915#82]) +1 similar issue
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-snb1/igt@i915_pm_rpm@system-suspend.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-snb6/igt@i915_pm_rpm@system-suspend.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [SKIP][65] ([fdo#109642] / [fdo#111068]) -> [FAIL][66] ([i915#608])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8195/shard-iclb1/igt@kms_psr2_su@page_flip.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/shard-iclb2/igt@kms_psr2_su@page_flip.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#112080]: https://bugs.freedesktop.org/show_bug.cgi?id=112080
  [fdo#112146]: https://bugs.freedesktop.org/show_bug.cgi?id=112146
  [i915#1526]: https://gitlab.freedesktop.org/drm/intel/issues/1526
  [i915#173]: https://gitlab.freedesktop.org/drm/intel/issues/173
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
  [i915#34]: https://gitlab.freedesktop.org/drm/intel/issues/34
  [i915#419]: https://gitlab.freedesktop.org/drm/intel/issues/419
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#468]: https://gitlab.freedesktop.org/drm/intel/issues/468
  [i915#52]: https://gitlab.freedesktop.org/drm/intel/issues/52
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#608]: https://gitlab.freedesktop.org/drm/intel/issues/608
  [i915#648]: https://gitlab.freedesktop.org/drm/intel/issues/648
  [i915#677]: https://gitlab.freedesktop.org/drm/intel/issues/677
  [i915#69]: https://gitlab.freedesktop.org/drm/intel/issues/69
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#82]: https://gitlab.freedesktop.org/drm/intel/issues/82
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (9 -> 10)
------------------------------

  Additional (1): pig-skl-6260u 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8195 -> Patchwork_17103

  CI-20190529: 20190529
  CI_DRM_8195: bcb3db890b651ee74ca510bbc4dacebdaa65d311 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5539: e7aae12e37771a8b7796ba252574eb832a5839c3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17103: 17b1ab4ef65f19f4159f1dcf8939b989d1cf83b9 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17103/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane Stanislav Lisovskiy
@ 2020-04-02 16:17   ` Ville Syrjälä
  2020-04-02 16:28     ` Lisovskiy, Stanislav
  2020-04-03 15:41   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 1 reply; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 16:17 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:09:57PM +0200, Stanislav Lisovskiy wrote:
> According to many computer science sources - magic values
> in code _are_ _bad_. For many reasons: the reason is that "0"
> or "1" or whatever magic values confuses and doesn't give any
> info why this parameter is this value and what it's meaning
> is.
> I renamed "0" to COLOR_PLANE_Y and "1" to COLOR_PLANE_UV,
> because we in fact already use this naming in many other places
> and function names, when dealing with color planes.

And now it's incosistent with all the rest of the codebase :(

> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  .../drm/i915/display/intel_display_types.h    |  5 +++
>  drivers/gpu/drm/i915/intel_pm.c               | 40 +++++++++----------
>  2 files changed, 25 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 176ab5f1e867..523e0444b373 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -682,6 +682,11 @@ struct skl_plane_wm {
>  	bool is_planar;
>  };
>  
> +enum color_plane {
> +	COLOR_PLANE_Y,
> +	COLOR_PLANE_UV
> +};
> +
>  struct skl_pipe_wm {
>  	struct skl_plane_wm planes[I915_MAX_PLANES];
>  };
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index b632b6bb9c3e..9e9a4612d842 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4013,7 +4013,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>  				 int width, const struct drm_format_info *format,
>  				 u64 modifier, unsigned int rotation,
>  				 u32 plane_pixel_rate, struct skl_wm_params *wp,
> -				 int color_plane);
> +				 enum color_plane);
>  static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>  				 int level,
>  				 unsigned int latency,
> @@ -4035,7 +4035,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
>  				    drm_format_info(DRM_FORMAT_ARGB8888),
>  				    DRM_FORMAT_MOD_LINEAR,
>  				    DRM_MODE_ROTATE_0,
> -				    crtc_state->pixel_rate, &wp, 0);
> +				    crtc_state->pixel_rate, &wp, COLOR_PLANE_Y);
>  	drm_WARN_ON(&dev_priv->drm, ret);
>  
>  	for (level = 0; level <= max_level; level++) {
> @@ -4431,7 +4431,7 @@ static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
>  static u64
>  skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
>  			     const struct intel_plane_state *plane_state,
> -			     int color_plane)
> +			     enum color_plane color_plane)
>  {
>  	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
>  	const struct drm_framebuffer *fb = plane_state->hw.fb;
> @@ -4446,7 +4446,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
>  	if (plane->id == PLANE_CURSOR)
>  		return 0;
>  
> -	if (color_plane == 1 &&
> +	if (color_plane == COLOR_PLANE_UV &&
>  	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
>  		return 0;
>  
> @@ -4459,7 +4459,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
>  	height = drm_rect_height(&plane_state->uapi.src) >> 16;
>  
>  	/* UV plane does 1/2 pixel sub-sampling */
> -	if (color_plane == 1) {
> +	if (color_plane == COLOR_PLANE_UV) {
>  		width /= 2;
>  		height /= 2;
>  	}
> @@ -4489,12 +4489,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  		u64 rate;
>  
>  		/* packed/y */
> -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
>  		plane_data_rate[plane_id] = rate;
>  		total_data_rate += rate;
>  
>  		/* uv-plane */
> -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
>  		uv_plane_data_rate[plane_id] = rate;
>  		total_data_rate += rate;
>  	}
> @@ -4516,7 +4516,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  		u64 rate;
>  
>  		if (!plane_state->planar_linked_plane) {
> -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
>  			plane_data_rate[plane_id] = rate;
>  			total_data_rate += rate;
>  		} else {
> @@ -4533,12 +4533,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  				continue;
>  
>  			/* Y plane rate is calculated on the slave */
> -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
>  			y_plane_id = plane_state->planar_linked_plane->id;
>  			plane_data_rate[y_plane_id] = rate;
>  			total_data_rate += rate;
>  
> -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
>  			plane_data_rate[plane_id] = rate;
>  			total_data_rate += rate;
>  		}
> @@ -4854,14 +4854,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>  		      int width, const struct drm_format_info *format,
>  		      u64 modifier, unsigned int rotation,
>  		      u32 plane_pixel_rate, struct skl_wm_params *wp,
> -		      int color_plane)
> +		      enum color_plane color_plane)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 interm_pbpl;
>  
>  	/* only planar format has two planes */
> -	if (color_plane == 1 &&
> +	if (color_plane == COLOR_PLANE_UV &&
>  	    !intel_format_info_is_yuv_semiplanar(format, modifier)) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "Non planar format have single plane\n");
> @@ -4878,7 +4878,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>  	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
>  
>  	wp->width = width;
> -	if (color_plane == 1 && wp->is_planar)
> +	if (color_plane == COLOR_PLANE_UV && wp->is_planar)
>  		wp->width /= 2;
>  
>  	wp->cpp = format->cpp[color_plane];
> @@ -4945,7 +4945,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>  static int
>  skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
>  			    const struct intel_plane_state *plane_state,
> -			    struct skl_wm_params *wp, int color_plane)
> +			    struct skl_wm_params *wp, enum color_plane color_plane)
>  {
>  	const struct drm_framebuffer *fb = plane_state->hw.fb;
>  	int width;
> @@ -5187,7 +5187,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
>  
>  static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
>  				     const struct intel_plane_state *plane_state,
> -				     enum plane_id plane_id, int color_plane)
> +				     enum plane_id plane_id, enum color_plane color_plane)
>  {
>  	struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
>  	struct skl_wm_params wm_params;
> @@ -5216,7 +5216,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
>  
>  	/* uv plane watermarks must also be validated for NV12/Planar */
>  	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
> -					  &wm_params, 1);
> +					  &wm_params, COLOR_PLANE_UV);
>  	if (ret)
>  		return ret;
>  
> @@ -5237,7 +5237,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
>  		return 0;
>  
>  	ret = skl_build_plane_wm_single(crtc_state, plane_state,
> -					plane_id, 0);
> +					plane_id, COLOR_PLANE_Y);
>  	if (ret)
>  		return ret;
>  
> @@ -5270,17 +5270,17 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
>  			fb->format->num_planes == 1);
>  
>  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> -						y_plane_id, 0);
> +						y_plane_id, COLOR_PLANE_Y);
>  		if (ret)
>  			return ret;
>  
>  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> -						plane_id, 1);
> +						plane_id, COLOR_PLANE_UV);
>  		if (ret)
>  			return ret;
>  	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
>  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> -						plane_id, 0);
> +						plane_id, COLOR_PLANE_Y);
>  		if (ret)
>  			return ret;
>  	}
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
@ 2020-04-02 16:20   ` Ville Syrjälä
  2020-04-02 16:49     ` Ville Syrjälä
  2020-04-03  6:11   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  2020-04-03  6:15   ` Stanislav Lisovskiy
  2 siblings, 1 reply; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 16:20 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:09:59PM +0200, Stanislav Lisovskiy wrote:
> Add correspondent helpers to be able to get old/new bandwidth
> global state object.
> 
> v2: - Fixed typo in function call
> v3: - Changed new functions naming to use convention proposed
>       by Jani Nikula, i.e intel_bw_* in intel_bw.c file.
> v4: - Change function naming back to intel_atomic* pattern,
>       was decided to rename in a separate patch series.
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 29 ++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_bw.h |  9 ++++++++
>  2 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index 58b264bc318d..a8b2038db4d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -374,7 +374,34 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
>  	return data_rate;
>  }
>  
> -static struct intel_bw_state *
> +struct intel_bw_state *
> +intel_atomic_get_bw_old_state(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_global_state *bw_state;
> +
> +	bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
> +	if (IS_ERR(bw_state))
> +		return ERR_CAST(bw_state);

These can't return an error.

> +
> +	return to_intel_bw_state(bw_state);
> +}
> +
> +struct intel_bw_state *
> +intel_atomic_get_bw_new_state(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_global_state *bw_state;
> +
> +	bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
> +
> +	if (IS_ERR(bw_state))
> +		return ERR_CAST(bw_state);
> +
> +	return to_intel_bw_state(bw_state);
> +}
> +
> +struct intel_bw_state *
>  intel_atomic_get_bw_state(struct intel_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
> index a8aa7624c5aa..fe6579c952f5 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -24,6 +24,15 @@ struct intel_bw_state {
>  
>  #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
>  
> +struct intel_bw_state *
> +intel_atomic_get_bw_old_state(struct intel_atomic_state *state);
> +
> +struct intel_bw_state *
> +intel_atomic_get_bw_new_state(struct intel_atomic_state *state);
> +
> +struct intel_bw_state *
> +intel_atomic_get_bw_state(struct intel_atomic_state *state);
> +
>  void intel_bw_init_hw(struct drm_i915_private *dev_priv);
>  int intel_bw_init(struct drm_i915_private *dev_priv);
>  int intel_bw_atomic_check(struct intel_atomic_state *state);
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane
  2020-04-02 16:17   ` Ville Syrjälä
@ 2020-04-02 16:28     ` Lisovskiy, Stanislav
  2020-04-02 16:41       ` Ville Syrjälä
  0 siblings, 1 reply; 52+ messages in thread
From: Lisovskiy, Stanislav @ 2020-04-02 16:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: jani.nikula, intel-gfx

On Thu, Apr 02, 2020 at 07:17:52PM +0300, Ville Syrjälä wrote:
> On Thu, Mar 26, 2020 at 08:09:57PM +0200, Stanislav Lisovskiy wrote:
> > According to many computer science sources - magic values
> > in code _are_ _bad_. For many reasons: the reason is that "0"
> > or "1" or whatever magic values confuses and doesn't give any
> > info why this parameter is this value and what it's meaning
> > is.
> > I renamed "0" to COLOR_PLANE_Y and "1" to COLOR_PLANE_UV,
> > because we in fact already use this naming in many other places
> > and function names, when dealing with color planes.
> 
> And now it's incosistent with all the rest of the codebase :(

]I think functions like func(0,1,2) is more than ugly.

I can find dozens of sources from credible people stating why it's
wrong.

If the existing code base is inspiring people to do it that way
 - then it's wrong.

And I honestly don't even know what is more stupid here:
passing magic numbers into functions, making it look non-obvious
or arguing about that. Kind of competition.

I think we have also enum values passed into functions in our
code and that seems fine(may be because that code wasn't written by me?). 

For instance you do use PIPE_A, PIPE_B instead of 0,1,2 right?

Or sure I can find another examples.


> 
> > 
> > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > ---
> >  .../drm/i915/display/intel_display_types.h    |  5 +++
> >  drivers/gpu/drm/i915/intel_pm.c               | 40 +++++++++----------
> >  2 files changed, 25 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 176ab5f1e867..523e0444b373 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -682,6 +682,11 @@ struct skl_plane_wm {
> >  	bool is_planar;
> >  };
> >  
> > +enum color_plane {
> > +	COLOR_PLANE_Y,
> > +	COLOR_PLANE_UV
> > +};
> > +
> >  struct skl_pipe_wm {
> >  	struct skl_plane_wm planes[I915_MAX_PLANES];
> >  };
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index b632b6bb9c3e..9e9a4612d842 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -4013,7 +4013,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> >  				 int width, const struct drm_format_info *format,
> >  				 u64 modifier, unsigned int rotation,
> >  				 u32 plane_pixel_rate, struct skl_wm_params *wp,
> > -				 int color_plane);
> > +				 enum color_plane);
> >  static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
> >  				 int level,
> >  				 unsigned int latency,
> > @@ -4035,7 +4035,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
> >  				    drm_format_info(DRM_FORMAT_ARGB8888),
> >  				    DRM_FORMAT_MOD_LINEAR,
> >  				    DRM_MODE_ROTATE_0,
> > -				    crtc_state->pixel_rate, &wp, 0);
> > +				    crtc_state->pixel_rate, &wp, COLOR_PLANE_Y);
> >  	drm_WARN_ON(&dev_priv->drm, ret);
> >  
> >  	for (level = 0; level <= max_level; level++) {
> > @@ -4431,7 +4431,7 @@ static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
> >  static u64
> >  skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> >  			     const struct intel_plane_state *plane_state,
> > -			     int color_plane)
> > +			     enum color_plane color_plane)
> >  {
> >  	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> >  	const struct drm_framebuffer *fb = plane_state->hw.fb;
> > @@ -4446,7 +4446,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> >  	if (plane->id == PLANE_CURSOR)
> >  		return 0;
> >  
> > -	if (color_plane == 1 &&
> > +	if (color_plane == COLOR_PLANE_UV &&
> >  	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> >  		return 0;
> >  
> > @@ -4459,7 +4459,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> >  	height = drm_rect_height(&plane_state->uapi.src) >> 16;
> >  
> >  	/* UV plane does 1/2 pixel sub-sampling */
> > -	if (color_plane == 1) {
> > +	if (color_plane == COLOR_PLANE_UV) {
> >  		width /= 2;
> >  		height /= 2;
> >  	}
> > @@ -4489,12 +4489,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> >  		u64 rate;
> >  
> >  		/* packed/y */
> > -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> >  		plane_data_rate[plane_id] = rate;
> >  		total_data_rate += rate;
> >  
> >  		/* uv-plane */
> > -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> > +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
> >  		uv_plane_data_rate[plane_id] = rate;
> >  		total_data_rate += rate;
> >  	}
> > @@ -4516,7 +4516,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> >  		u64 rate;
> >  
> >  		if (!plane_state->planar_linked_plane) {
> > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> >  			plane_data_rate[plane_id] = rate;
> >  			total_data_rate += rate;
> >  		} else {
> > @@ -4533,12 +4533,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> >  				continue;
> >  
> >  			/* Y plane rate is calculated on the slave */
> > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> >  			y_plane_id = plane_state->planar_linked_plane->id;
> >  			plane_data_rate[y_plane_id] = rate;
> >  			total_data_rate += rate;
> >  
> > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
> >  			plane_data_rate[plane_id] = rate;
> >  			total_data_rate += rate;
> >  		}
> > @@ -4854,14 +4854,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> >  		      int width, const struct drm_format_info *format,
> >  		      u64 modifier, unsigned int rotation,
> >  		      u32 plane_pixel_rate, struct skl_wm_params *wp,
> > -		      int color_plane)
> > +		      enum color_plane color_plane)
> >  {
> >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >  	u32 interm_pbpl;
> >  
> >  	/* only planar format has two planes */
> > -	if (color_plane == 1 &&
> > +	if (color_plane == COLOR_PLANE_UV &&
> >  	    !intel_format_info_is_yuv_semiplanar(format, modifier)) {
> >  		drm_dbg_kms(&dev_priv->drm,
> >  			    "Non planar format have single plane\n");
> > @@ -4878,7 +4878,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> >  	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
> >  
> >  	wp->width = width;
> > -	if (color_plane == 1 && wp->is_planar)
> > +	if (color_plane == COLOR_PLANE_UV && wp->is_planar)
> >  		wp->width /= 2;
> >  
> >  	wp->cpp = format->cpp[color_plane];
> > @@ -4945,7 +4945,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> >  static int
> >  skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
> >  			    const struct intel_plane_state *plane_state,
> > -			    struct skl_wm_params *wp, int color_plane)
> > +			    struct skl_wm_params *wp, enum color_plane color_plane)
> >  {
> >  	const struct drm_framebuffer *fb = plane_state->hw.fb;
> >  	int width;
> > @@ -5187,7 +5187,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
> >  
> >  static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
> >  				     const struct intel_plane_state *plane_state,
> > -				     enum plane_id plane_id, int color_plane)
> > +				     enum plane_id plane_id, enum color_plane color_plane)
> >  {
> >  	struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
> >  	struct skl_wm_params wm_params;
> > @@ -5216,7 +5216,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
> >  
> >  	/* uv plane watermarks must also be validated for NV12/Planar */
> >  	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
> > -					  &wm_params, 1);
> > +					  &wm_params, COLOR_PLANE_UV);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -5237,7 +5237,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
> >  		return 0;
> >  
> >  	ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > -					plane_id, 0);
> > +					plane_id, COLOR_PLANE_Y);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -5270,17 +5270,17 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
> >  			fb->format->num_planes == 1);
> >  
> >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > -						y_plane_id, 0);
> > +						y_plane_id, COLOR_PLANE_Y);
> >  		if (ret)
> >  			return ret;
> >  
> >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > -						plane_id, 1);
> > +						plane_id, COLOR_PLANE_UV);
> >  		if (ret)
> >  			return ret;
> >  	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
> >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > -						plane_id, 0);
> > +						plane_id, COLOR_PLANE_Y);
> >  		if (ret)
> >  			return ret;
> >  	}
> > -- 
> > 2.24.1.485.gad05a3d8e5
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane
  2020-04-02 16:28     ` Lisovskiy, Stanislav
@ 2020-04-02 16:41       ` Ville Syrjälä
  0 siblings, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 16:41 UTC (permalink / raw)
  To: Lisovskiy, Stanislav; +Cc: jani.nikula, intel-gfx

On Thu, Apr 02, 2020 at 07:28:43PM +0300, Lisovskiy, Stanislav wrote:
> On Thu, Apr 02, 2020 at 07:17:52PM +0300, Ville Syrjälä wrote:
> > On Thu, Mar 26, 2020 at 08:09:57PM +0200, Stanislav Lisovskiy wrote:
> > > According to many computer science sources - magic values
> > > in code _are_ _bad_. For many reasons: the reason is that "0"
> > > or "1" or whatever magic values confuses and doesn't give any
> > > info why this parameter is this value and what it's meaning
> > > is.
> > > I renamed "0" to COLOR_PLANE_Y and "1" to COLOR_PLANE_UV,
> > > because we in fact already use this naming in many other places
> > > and function names, when dealing with color planes.
> > 
> > And now it's incosistent with all the rest of the codebase :(
> 
> ]I think functions like func(0,1,2) is more than ugly.
> 
> I can find dozens of sources from credible people stating why it's
> wrong.
> 
> If the existing code base is inspiring people to do it that way
>  - then it's wrong.
> 
> And I honestly don't even know what is more stupid here:
> passing magic numbers into functions, making it look non-obvious
> or arguing about that. Kind of competition.
> 
> I think we have also enum values passed into functions in our
> code and that seems fine(may be because that code wasn't written by me?). 
> 
> For instance you do use PIPE_A, PIPE_B instead of 0,1,2 right?

color_plane is just an index into the fb metadata. It's not a specific
named thing as such. Again, if we want to introduce some new convention
for this stuff we should do it across the whole driver (and probably
also drm core) otherewise you're just introducing inconsistencies
between different parts of the codebase. Different conventions between
different parts just increases the load on the poor brain when you have
to convert between thenm to figure out what's going on.

> 
> Or sure I can find another examples.
> 
> 
> > 
> > > 
> > > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > > ---
> > >  .../drm/i915/display/intel_display_types.h    |  5 +++
> > >  drivers/gpu/drm/i915/intel_pm.c               | 40 +++++++++----------
> > >  2 files changed, 25 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 176ab5f1e867..523e0444b373 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -682,6 +682,11 @@ struct skl_plane_wm {
> > >  	bool is_planar;
> > >  };
> > >  
> > > +enum color_plane {
> > > +	COLOR_PLANE_Y,
> > > +	COLOR_PLANE_UV
> > > +};
> > > +
> > >  struct skl_pipe_wm {
> > >  	struct skl_plane_wm planes[I915_MAX_PLANES];
> > >  };
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > index b632b6bb9c3e..9e9a4612d842 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -4013,7 +4013,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> > >  				 int width, const struct drm_format_info *format,
> > >  				 u64 modifier, unsigned int rotation,
> > >  				 u32 plane_pixel_rate, struct skl_wm_params *wp,
> > > -				 int color_plane);
> > > +				 enum color_plane);
> > >  static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
> > >  				 int level,
> > >  				 unsigned int latency,
> > > @@ -4035,7 +4035,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
> > >  				    drm_format_info(DRM_FORMAT_ARGB8888),
> > >  				    DRM_FORMAT_MOD_LINEAR,
> > >  				    DRM_MODE_ROTATE_0,
> > > -				    crtc_state->pixel_rate, &wp, 0);
> > > +				    crtc_state->pixel_rate, &wp, COLOR_PLANE_Y);
> > >  	drm_WARN_ON(&dev_priv->drm, ret);
> > >  
> > >  	for (level = 0; level <= max_level; level++) {
> > > @@ -4431,7 +4431,7 @@ static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
> > >  static u64
> > >  skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> > >  			     const struct intel_plane_state *plane_state,
> > > -			     int color_plane)
> > > +			     enum color_plane color_plane)
> > >  {
> > >  	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> > >  	const struct drm_framebuffer *fb = plane_state->hw.fb;
> > > @@ -4446,7 +4446,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> > >  	if (plane->id == PLANE_CURSOR)
> > >  		return 0;
> > >  
> > > -	if (color_plane == 1 &&
> > > +	if (color_plane == COLOR_PLANE_UV &&
> > >  	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> > >  		return 0;
> > >  
> > > @@ -4459,7 +4459,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
> > >  	height = drm_rect_height(&plane_state->uapi.src) >> 16;
> > >  
> > >  	/* UV plane does 1/2 pixel sub-sampling */
> > > -	if (color_plane == 1) {
> > > +	if (color_plane == COLOR_PLANE_UV) {
> > >  		width /= 2;
> > >  		height /= 2;
> > >  	}
> > > @@ -4489,12 +4489,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > >  		u64 rate;
> > >  
> > >  		/* packed/y */
> > > -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > > +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> > >  		plane_data_rate[plane_id] = rate;
> > >  		total_data_rate += rate;
> > >  
> > >  		/* uv-plane */
> > > -		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> > > +		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
> > >  		uv_plane_data_rate[plane_id] = rate;
> > >  		total_data_rate += rate;
> > >  	}
> > > @@ -4516,7 +4516,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > >  		u64 rate;
> > >  
> > >  		if (!plane_state->planar_linked_plane) {
> > > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> > >  			plane_data_rate[plane_id] = rate;
> > >  			total_data_rate += rate;
> > >  		} else {
> > > @@ -4533,12 +4533,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > >  				continue;
> > >  
> > >  			/* Y plane rate is calculated on the slave */
> > > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> > > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
> > >  			y_plane_id = plane_state->planar_linked_plane->id;
> > >  			plane_data_rate[y_plane_id] = rate;
> > >  			total_data_rate += rate;
> > >  
> > > -			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
> > > +			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
> > >  			plane_data_rate[plane_id] = rate;
> > >  			total_data_rate += rate;
> > >  		}
> > > @@ -4854,14 +4854,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> > >  		      int width, const struct drm_format_info *format,
> > >  		      u64 modifier, unsigned int rotation,
> > >  		      u32 plane_pixel_rate, struct skl_wm_params *wp,
> > > -		      int color_plane)
> > > +		      enum color_plane color_plane)
> > >  {
> > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > >  	u32 interm_pbpl;
> > >  
> > >  	/* only planar format has two planes */
> > > -	if (color_plane == 1 &&
> > > +	if (color_plane == COLOR_PLANE_UV &&
> > >  	    !intel_format_info_is_yuv_semiplanar(format, modifier)) {
> > >  		drm_dbg_kms(&dev_priv->drm,
> > >  			    "Non planar format have single plane\n");
> > > @@ -4878,7 +4878,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> > >  	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
> > >  
> > >  	wp->width = width;
> > > -	if (color_plane == 1 && wp->is_planar)
> > > +	if (color_plane == COLOR_PLANE_UV && wp->is_planar)
> > >  		wp->width /= 2;
> > >  
> > >  	wp->cpp = format->cpp[color_plane];
> > > @@ -4945,7 +4945,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
> > >  static int
> > >  skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
> > >  			    const struct intel_plane_state *plane_state,
> > > -			    struct skl_wm_params *wp, int color_plane)
> > > +			    struct skl_wm_params *wp, enum color_plane color_plane)
> > >  {
> > >  	const struct drm_framebuffer *fb = plane_state->hw.fb;
> > >  	int width;
> > > @@ -5187,7 +5187,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
> > >  
> > >  static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
> > >  				     const struct intel_plane_state *plane_state,
> > > -				     enum plane_id plane_id, int color_plane)
> > > +				     enum plane_id plane_id, enum color_plane color_plane)
> > >  {
> > >  	struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
> > >  	struct skl_wm_params wm_params;
> > > @@ -5216,7 +5216,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
> > >  
> > >  	/* uv plane watermarks must also be validated for NV12/Planar */
> > >  	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
> > > -					  &wm_params, 1);
> > > +					  &wm_params, COLOR_PLANE_UV);
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > @@ -5237,7 +5237,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
> > >  		return 0;
> > >  
> > >  	ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > > -					plane_id, 0);
> > > +					plane_id, COLOR_PLANE_Y);
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > @@ -5270,17 +5270,17 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
> > >  			fb->format->num_planes == 1);
> > >  
> > >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > > -						y_plane_id, 0);
> > > +						y_plane_id, COLOR_PLANE_Y);
> > >  		if (ret)
> > >  			return ret;
> > >  
> > >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > > -						plane_id, 1);
> > > +						plane_id, COLOR_PLANE_UV);
> > >  		if (ret)
> > >  			return ret;
> > >  	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
> > >  		ret = skl_build_plane_wm_single(crtc_state, plane_state,
> > > -						plane_id, 0);
> > > +						plane_id, COLOR_PLANE_Y);
> > >  		if (ret)
> > >  			return ret;
> > >  	}
> > > -- 
> > > 2.24.1.485.gad05a3d8e5
> > 
> > -- 
> > Ville Syrjälä
> > Intel

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv Stanislav Lisovskiy
@ 2020-04-02 16:44   ` Ville Syrjälä
  2020-04-03  6:20   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 16:44 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:10:00PM +0200, Stanislav Lisovskiy wrote:
> Addressing one of the comments, recommending to extract platform
> specific code from intel_can_enable_sagv as a preparation, before
> we are going to add support for tgl+.
> 
> Current code in intel_can_enable_sagv is valid only for skl,
> so this patch adds also proper support for icl, subsequent
> patches will add support for tgl+, combined with other required
> changes.
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 89 ++++++++++++++++++++++-----------
>  1 file changed, 61 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f8d62d1977ac..64193b098175 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3757,41 +3757,24 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
>  	return 0;
>  }
>  
> -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> +static bool icl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)

icl_crtc_can_enable_sagv()/etc. would be more consistent with existing
practices. crtc_state can be const.

>  {
> -	struct drm_device *dev = state->base.dev;
> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;

IMO just remove this 'dev' variable.

>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *crtc;
>  	struct intel_plane *plane;
> -	struct intel_crtc_state *crtc_state;
> -	enum pipe pipe;
> +	struct intel_plane_state *plane_state;

const

>  	int level, latency;
>  
> -	if (!intel_has_sagv(dev_priv))
> -		return false;
> +	crtc = to_intel_crtc(crtc_state->uapi.crtc);

Initialize when declaring.

>  
> -	/*
> -	 * If there are no active CRTCs, no additional checks need be performed
> -	 */
> -	if (hweight8(state->active_pipes) == 0)
> -		return true;
> -
> -	/*
> -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> -	 * more then one pipe enabled
> -	 */
> -	if (hweight8(state->active_pipes) > 1)
> -		return false;
> -
> -	/* Since we're now guaranteed to only have one active CRTC... */
> -	pipe = ffs(state->active_pipes) - 1;
> -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> -	crtc_state = to_intel_crtc_state(crtc->base.state);

We seem to be missing a hw.active check.

> -
> -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> +			      pipe_name(crtc->pipe));
>  		return false;
> +	}
>  
> -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
>  		struct skl_plane_wm *wm =
>  			&crtc_state->wm.skl.optimal.planes[plane->id];
>  
> @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>  		latency = dev_priv->wm.skl_latency[level];
>  
>  		if (skl_needs_memory_bw_wa(dev_priv) &&
> -		    plane->base.state->fb->modifier ==
> +		    plane_state->uapi.fb->modifier ==
>  		    I915_FORMAT_MOD_X_TILED)
>  			latency += 15;
>  
> @@ -3816,8 +3799,58 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>  		 * incur memory latencies higher than sagv_block_time_us we
>  		 * can't enable SAGV.
>  		 */
> -		if (latency < dev_priv->sagv_block_time_us)
> +		if (latency < dev_priv->sagv_block_time_us) {
> +			DRM_DEBUG_KMS("Latency %d < sagv block time %d, no SAGV for pipe %c\n",
> +				      latency, dev_priv->sagv_block_time_us, pipe_name(crtc->pipe));
>  			return false;

How much noise will these debugs generate?

> +		}
> +	}
> +
> +	return true;
> +}
> +
> +static bool skl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> +
> +	/*
> +	 * It has been recommended that for Gen 9 we switch SAGV off when
> +	 * multiple pipes are used.
> +	 */
> +	if (hweight8(state->active_pipes) > 1)
> +		return false;
> +
> +	/*
> +	 * Besides active pipe limitation, rest of checks pretty much match ICL
> +	 * so no need to duplicate code
> +	 */
> +	return icl_can_enable_sagv_on_pipe(crtc_state);
> +}
> +
> +bool intel_can_enable_sagv(struct intel_atomic_state *state)
> +{
> +	struct drm_device *dev = state->base.dev;

Pls don't add needless 'dev' variables.

> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;

const

> +	int i;
> +
> +	if (!intel_has_sagv(dev_priv))
> +		return false;
> +
> +	/*
> +	 * If there are no active CRTCs, no additional checks need be performed
> +	 */
> +	if (hweight8(state->active_pipes) == 0)
> +		return true;

Seems pointless.

> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {

Hmm. I think this is now temporarily busted since we only consider
the crtcs in the state. Would seem like we need to introduce the
sagv bitmaks first/at the same time as we do this.

> +		if (INTEL_GEN(dev_priv) <= 9) {
> +			if (!skl_can_enable_sagv_on_pipe(crtc_state))
> +				return false;
> +		} else if (!icl_can_enable_sagv_on_pipe(crtc_state)) {
> +			return false;
> +		}

Very hard to read if-else construct. Plase make it consistent for both
branches, and put the icl+ case first.

>  	}
>  
>  	return true;
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers
  2020-04-02 16:20   ` Ville Syrjälä
@ 2020-04-02 16:49     ` Ville Syrjälä
  0 siblings, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 16:49 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Apr 02, 2020 at 07:20:59PM +0300, Ville Syrjälä wrote:
> On Thu, Mar 26, 2020 at 08:09:59PM +0200, Stanislav Lisovskiy wrote:
> > Add correspondent helpers to be able to get old/new bandwidth
> > global state object.
> > 
> > v2: - Fixed typo in function call
> > v3: - Changed new functions naming to use convention proposed
> >       by Jani Nikula, i.e intel_bw_* in intel_bw.c file.
> > v4: - Change function naming back to intel_atomic* pattern,
> >       was decided to rename in a separate patch series.
> > 
> > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c | 29 ++++++++++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_bw.h |  9 ++++++++
> >  2 files changed, 37 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> > index 58b264bc318d..a8b2038db4d2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -374,7 +374,34 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
> >  	return data_rate;
> >  }
> >  
> > -static struct intel_bw_state *
> > +struct intel_bw_state *
> > +intel_atomic_get_bw_old_state(struct intel_atomic_state *state)

Also these names aren't consistent wrt. existing practices.

Should be intel_atomic_get_{new,old}_bw_state()

> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	struct intel_global_state *bw_state;
> > +
> > +	bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
> > +	if (IS_ERR(bw_state))
> > +		return ERR_CAST(bw_state);
> 
> These can't return an error.
>
> > +
> > +	return to_intel_bw_state(bw_state);
> > +}
> > +
> > +struct intel_bw_state *
> > +intel_atomic_get_bw_new_state(struct intel_atomic_state *state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	struct intel_global_state *bw_state;
> > +
> > +	bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
> > +
> > +	if (IS_ERR(bw_state))
> > +		return ERR_CAST(bw_state);
> > +
> > +	return to_intel_bw_state(bw_state);
> > +}
> > +
> > +struct intel_bw_state *
> >  intel_atomic_get_bw_state(struct intel_atomic_state *state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
> > index a8aa7624c5aa..fe6579c952f5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.h
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> > @@ -24,6 +24,15 @@ struct intel_bw_state {
> >  
> >  #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
> >  
> > +struct intel_bw_state *
> > +intel_atomic_get_bw_old_state(struct intel_atomic_state *state);
> > +
> > +struct intel_bw_state *
> > +intel_atomic_get_bw_new_state(struct intel_atomic_state *state);
> > +
> > +struct intel_bw_state *
> > +intel_atomic_get_bw_state(struct intel_atomic_state *state);
> > +
> >  void intel_bw_init_hw(struct drm_i915_private *dev_priv);
> >  int intel_bw_init(struct drm_i915_private *dev_priv);
> >  int intel_bw_atomic_check(struct intel_atomic_state *state);
> > -- 
> > 2.24.1.485.gad05a3d8e5
> 
> -- 
> Ville Syrjälä
> Intel

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+
  2020-03-26 18:39   ` Stanislav Lisovskiy
@ 2020-04-02 17:22     ` Ville Syrjälä
  2020-04-03  6:29     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 17:22 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:39:59PM +0200, Stanislav Lisovskiy wrote:
> Let's refactor the whole SAGV logic, moving
> the main calculations from intel_can_enable_sagv
> to intel_compute_sagv_mask, which also handles
> this in a unified way calling gen specific
> functions to evaluate if SAGV is allowed for
> each crtc. If crtc sagv mask have been changed
> we serialize access and modify global state.
> 
> intel_can_enable_sagv now uses bw_state which
> stores all information related to SAGV and
> is now a trivial helper.
> 
> v2:
>     - Rework watermark calculation algorithm to
>       attempt to calculate Level 0 watermark
>       with added sagv block time latency and
>       check if it fits in DBuf in order to
>       determine if SAGV can be enabled already
>       at this stage, just as BSpec 49325 states.
>       if that fails rollback to usual Level 0
>       latency and disable SAGV.
>     - Remove unneeded tabs(James Ausmus)
> 
> v3: Rebased the patch
> 
> v4: - Added back interlaced check for Gen12 and
>       added separate function for TGL SAGV check
>       (thanks to James Ausmus for spotting)
>     - Removed unneeded gen check
>     - Extracted Gen12 SAGV decision making code
>       to a separate function from skl_compute_wm
> 
> v5: - Added SAGV global state to dev_priv, because
>       we need to track all pipes, not only those
>       in atomic state. Each pipe has now correspondent
>       bit mask reflecting, whether it can tolerate
>       SAGV or not(thanks to Ville Syrjala for suggestions).
>     - Now using active flag instead of enable in crc
>       usage check.
> 
> v6: - Fixed rebase conflicts
> 
> v7: - kms_cursor_legacy seems to get broken because of multiple memcpy
>       calls when copying level 0 water marks for enabled SAGV, to
>       fix this now simply using that field right away, without copying,
>       for that introduced a new wm_level accessor which decides which
>       wm_level to return based on SAGV state.
> 
> v8: - Protect crtc_sagv_mask same way as we do for other global state
>       changes: i.e check if changes are needed, then grab all crtc locks
>       to serialize the changes(Ville Syrjälä)
>     - Add crtc_sagv_mask caching in order to avoid needless recalculations
>       (Matthew Roper)
>     - Put back Gen12 SAGV switch in order to get it enabled in separate
>       patch(Matthew Roper)
>     - Rename *_set_sagv_mask to *_compute_sagv_mask(Matthew Roper)
>     - Check if there are no active pipes in intel_can_enable_sagv
>       instead of platform specific functions(Matthew Roper), same
>       for intel_has_sagv check.
> 
> v9  - Switched to u8 for crtc_sagv_mask(Ville Syrjälä)
>     - crtc_sagv_mask now is pipe_sagv_mask(Ville Syrjälä)
>     - Extracted sagv checking logic from skl/icl/tgl_compute_sagv_mask
>     - Extracted skl_plane_wm_level function and passing latency to
>       separate patches(Ville Syrjälä)
>     - Removed part of unneeded copy-paste from tgl_check_pipe_fits_sagv_wm
>       (Ville Syrjälä)
>     - Now using simple assignment for sagv_wm0 as it contains only
>       pod types and no pointers(Ville Syrjälä)
>     - Fixed intel_can_enable_sagv not to do double duty, now it only
>       check SAGV bits by ANDing those between local and global state.
>       The SAGV masks are now computed after watermarks are available,
>       in order to be able to figure out if ddb ranges are fitting nicely.
>       (Ville Syrjälä)
>     - Now having uv_sagv_wm0 and sagv_wm0, otherwise we have wrong logic
>       when using skl_plane_wm_level accessor, as we had previously for
>       Gen11+ color plane and regular wm levels, so probably both
>       has to be recalculated with additional SAGV block time for Level 0.
> 
> v10: - Starting to use new global state for storing pipe_sagv_mask
> 
> v11: - Fixed rebase conflict with recent drm-tip
>      - Check if we really need to recalculate SAGV mask, otherwise
>        bail out without making any changes.
>      - Use cached SAGV result, instead of recalculating it everytime,
>        if bw_state hasn't changed.
> 
> v12: - Removed WARN from intel_can_enable_sagv, in some of the commits
>        if we don't recalculated watermarks, bw_state is not recalculated,
>        thus leading to SAGV state not recalculated by the commit state,
>        which is still calling intel_can_enable_sagv function. Fix that
>        by just analyzing the current global bw_state object - because
>        we simply have no other objects related to that.
> 
> v13: - Rebased, fixed warnings regarding long lines
>      - Changed function call sites from intel_atomic_bw* to
>        intel_wb_* as was suggested.(Jani Nikula)
>      - Taken ddb_state_changed and bw_state_changed into use.
> 
> v14: - total_affected_planes is no longer needed to check for ddb changes,
>        just as active_pipe_changes.
> 
> v15: - Fixed stupid mistake with uninitialized crtc in
>        skl_compute_sagv_mask.
> 
> v16: - Convert pipe_sagv_mask to pipe_sagv_reject and now using inverted
>        flag to indicate SAGV readiness for the pipe(Ville Syrjälä)
>      - Added return value to intel_compute_sagv_mask which call
>        intel_atomic_serialize_global_state in order to properly
>        propagate EDEADLCK to drm.
>      - Based on the discussion with Ville, removed active_pipe_changes
>        check and also there seems to be no need for checking
>        ddb_state_changes as well.
>        Instead we just iterate through crtcs in state - having
>        crtc in a state already guarantees that it is at least read-locked
>        Having additional flag to check if there actually were some plane
>        wm/ddb changes would be probably added later as an optimization.
>      - We can't get parent atomic state from crtc_state at commit stage
>        (nice drm feature), also propagating state through function call
>        chain seems to be overkill and not possible(cursor legacy updates)
>        Querying for bw_state object from global state is not possible as
>        it might get swapped with other global state.
>        So... just sticked can_sagv boolean into wm crtc state.
> 
> v17: - Skip inactive crtcs, when checking for SAGV-readiness.
> 
> v18: - Switch to use intel_atomic_crtc_state_for_each_plane_state
>        instead of for_each_intel_plane_on_crtc and fixed previous
>        code, which was using old plane state, which caused NULL ptr
>        dereference, bacause that code is now called before we swap the
>        state.
> 
> v19: - Use intel_atomic_bw_* pattern again
>      - Optimized sagv checks in verify_wm_state(Ville Syrjälä)
>      - Do intel_compute_sagv_mask after ddb is allocated(Ville Syrjälä),
>        using it's results
>      - Use bw_state in intel_can_enable_sagv
>      - Use COLOR_PLANE enum instead of boolean yuv or "0", "1" magic
>      - Extracted sagv wm0 calculation into separate skl_compute_sagv_wm
>        function(Ville Syrjälä)
> 
> v20: - Added check for NULL for bw_state in commit_tail
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@intel.com>
> Cc: James Ausmus <james.ausmus@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.h       |   6 +
>  drivers/gpu/drm/i915/display/intel_display.c  |  30 ++-
>  .../drm/i915/display/intel_display_types.h    |   3 +
>  drivers/gpu/drm/i915/intel_pm.c               | 244 ++++++++++++++++--
>  drivers/gpu/drm/i915/intel_pm.h               |   4 +-
>  5 files changed, 256 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
> index fe6579c952f5..6ad3ea7cedfe 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -18,6 +18,12 @@ struct intel_crtc_state;
>  struct intel_bw_state {
>  	struct intel_global_state base;
>  
> +	/*
> +	 * Contains a bit mask, used to determine, whether correspondent
> +	 * pipe allows SAGV or not.
> +	 */
> +	u8 pipe_sagv_reject;
> +
>  	unsigned int data_rate[I915_MAX_PIPES];
>  	u8 num_active_planes[I915_MAX_PIPES];
>  };
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index e630429af2c0..8a0d952c67bf 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14009,7 +14009,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
>  		/* Watermarks */
>  		for (level = 0; level <= max_level; level++) {
>  			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
> -						&sw_plane_wm->wm[level]))
> +						&sw_plane_wm->wm[level]) ||
> +			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
> +							       &sw_plane_wm->sagv_wm0)))
>  				continue;
>  
>  			drm_err(&dev_priv->drm,
> @@ -14064,7 +14066,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
>  		/* Watermarks */
>  		for (level = 0; level <= max_level; level++) {
>  			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
> -						&sw_plane_wm->wm[level]))
> +						&sw_plane_wm->wm[level]) ||
> +			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
> +							       &sw_plane_wm->sagv_wm0)))
>  				continue;
>  
>  			drm_err(&dev_priv->drm,
> @@ -15535,6 +15539,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  		crtc->config = new_crtc_state;
>  
>  	if (state->modeset) {
> +		struct intel_bw_state *bw_state;
> +		bw_state = intel_atomic_get_bw_new_state(state);

Needlessly wide scope. Can declare+init at the same time. Also const.

> +
>  		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
>  
>  		intel_set_cdclk_pre_plane_update(state);
> @@ -15543,8 +15551,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  		 * SKL workaround: bspec recommends we disable the SAGV when we
>  		 * have more then one pipe enabled
>  		 */
> -		if (!intel_can_enable_sagv(state))
> -			intel_disable_sagv(dev_priv);
> +		if (INTEL_GEN(dev_priv) < 11) {
> +			if (bw_state && !intel_can_enable_sagv(bw_state))
> +				intel_disable_sagv(dev_priv);
> +		}
>  
>  		intel_modeset_verify_disabled(dev_priv, state);
>  	}
> @@ -15644,8 +15654,15 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  	if (state->modeset)
>  		intel_verify_planes(state);
>  
> -	if (state->modeset && intel_can_enable_sagv(state))
> -		intel_enable_sagv(dev_priv);
> +	if (INTEL_GEN(dev_priv) < 11) {
> +		struct intel_bw_state *bw_state;
> +
> +		bw_state = intel_atomic_get_bw_new_state(state);
> +
> +		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state)) {
> +			intel_enable_sagv(dev_priv);
> +		}

Pointless {}

The different strcuture of the nested ifs also irks me a bit. But meh
for now I guess.

> +	}
>  
>  	drm_atomic_helper_commit_hw_done(&state->base);
>  
> @@ -15797,7 +15814,6 @@ static int intel_atomic_commit(struct drm_device *dev,
>  
>  	if (state->global_state_changed) {
>  		assert_global_state_locked(dev_priv);
> -

Spurious change

>  		dev_priv->active_pipes = state->active_pipes;
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 523e0444b373..51fa5a746a5f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -679,6 +679,8 @@ struct skl_plane_wm {
>  	struct skl_wm_level wm[8];
>  	struct skl_wm_level uv_wm[8];
>  	struct skl_wm_level trans_wm;
> +	struct skl_wm_level sagv_wm0;
> +	struct skl_wm_level uv_sagv_wm0;
>  	bool is_planar;
>  };
>  
> @@ -689,6 +691,7 @@ enum color_plane {
>  
>  struct skl_pipe_wm {
>  	struct skl_plane_wm planes[I915_MAX_PLANES];
> +	bool can_sagv;
>  };
>  
>  enum vlv_wm_level {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 64193b098175..63c46918d1ed 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -43,6 +43,7 @@
>  #include "i915_fixed.h"
>  #include "i915_irq.h"
>  #include "i915_trace.h"
> +#include "display/intel_bw.h"
>  #include "intel_pm.h"
>  #include "intel_sideband.h"
>  #include "../../../platform/x86/intel_ips.h"
> @@ -3634,7 +3635,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
>  	return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv);
>  }
>  
> -static bool
> +bool
>  intel_has_sagv(struct drm_i915_private *dev_priv)
>  {
>  	/* HACK! */
> @@ -3827,33 +3828,106 @@ static bool skl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
>  	return icl_can_enable_sagv_on_pipe(crtc_state);
>  }
>  
> -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> +static bool
> +tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state);
> +
> +bool intel_can_enable_sagv(struct intel_bw_state *bw_state)
> +{
> +	return bw_state->pipe_sagv_reject == 0;
> +}
> +
> +static int intel_compute_sagv_mask(struct intel_atomic_state *state)
>  {
> +	int ret;
>  	struct drm_device *dev = state->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *crtc;
> -	struct intel_crtc_state *crtc_state;
> +	struct intel_crtc_state *new_crtc_state;
> +	struct intel_bw_state *new_bw_state = NULL;
> +	struct intel_bw_state *old_bw_state = NULL;
>  	int i;
> +	bool can_sagv;
>  
> +	/*
> +	 * If SAGV is not supported we just can't do anything
> +	 * not even set or reject SAGV points - just bail out.
> +	 * Thus avoid needless calculations.
> +	 */

Seems overly verbose. I'd just drop the entire comment.
Rule of thumb: never add comments, unless absolutely necessary.

>  	if (!intel_has_sagv(dev_priv))
> -		return false;
> +		return 0;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc,
> +					 new_crtc_state, i) {
> +		bool pipe_sagv_enable;
> +
> +		new_bw_state = intel_atomic_get_bw_state(state);
> +		if (IS_ERR(new_bw_state)) {
> +			WARN(1, "Could not get bw_state\n");

What's with the warn?

> +			return PTR_ERR(new_bw_state);
> +		}
> +
> +		old_bw_state = intel_atomic_get_bw_old_state(state);
> +
> +		if (!new_crtc_state->hw.active)
> +			continue;

There's the missing active check!. Just move into the functions(s)
below.

> +
> +		if (INTEL_GEN(dev_priv) >= 12) {
> +			pipe_sagv_enable = tgl_can_enable_sagv_on_pipe(new_crtc_state);
> +		} else if (INTEL_GEN(dev_priv) >= 11) {
> +			pipe_sagv_enable = icl_can_enable_sagv_on_pipe(new_crtc_state);
> +		} else {
> +			pipe_sagv_enable = skl_can_enable_sagv_on_pipe(new_crtc_state);
> +		}

I would put that if ladder into a separate function to reduce the noise
here. At which point we don't even need this 'pipe_sagv_enable' bool
anymore and the code will read better.

> +
> +		if (pipe_sagv_enable)
> +			new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
> +		else
> +			new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
> +	}
> +
> +	if (!new_bw_state || !old_bw_state)
> +		return 0;
> +
> +	can_sagv = new_bw_state->pipe_sagv_reject == 0;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc,
> +					 new_crtc_state, i) {
> +		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
> +
> +		/*
> +		 * Due to drm limitation at commit state, when
> +		 * changes are written the whole atomic state is
> +		 * zeroed away => which prevents from using it,
> +		 * so just sticking it into pipe wm state for
> +		 * keeping it simple - anyway this is related to wm.
> +		 * Proper way in ideal universe would be of course not
> +		 * to lose parent atomic state object from child crtc_state,
> +		 * and stick to OOP programming principles, which had been
> +		 * scientifically proven to work.
> +		 */
> +		pipe_wm->can_sagv = can_sagv;
> +	}
>  
>  	/*
> -	 * If there are no active CRTCs, no additional checks need be performed
> +	 * For SAGV we need to account all the pipes,
> +	 * not only the ones which are in state currently.
> +	 * Grab all locks if we detect that we are actually
> +	 * going to do something.
>  	 */

More overly verbose comments. IMO just nuke.

> -	if (hweight8(state->active_pipes) == 0)
> -		return true;
> +	if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
> +		DRM_DEBUG_KMS("State %p: old sagv mask 0x%x, new sagv mask 0x%x\n",
> +			      state,
> +			      old_bw_state->pipe_sagv_reject,
> +			      new_bw_state->pipe_sagv_reject);

Very temporary looking debug.

>  
> -	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (INTEL_GEN(dev_priv) <= 9) {
> -			if (!skl_can_enable_sagv_on_pipe(crtc_state))
> -				return false;
> -		} else if (!icl_can_enable_sagv_on_pipe(crtc_state)) {
> -			return false;
> +		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
> +		if (ret) {
> +			DRM_DEBUG_KMS("Could not serialize global state\n");

No debugs for these pls.

> +			return ret;
>  		}
>  	}
>  
> -	return true;
> +	return 0;
>  }
>  
>  /*
> @@ -4075,6 +4149,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
>  		unsigned int latency = dev_priv->wm.skl_latency[level];
>  
>  		skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm);
> +

Spurious change.

>  		if (wm.min_ddb_alloc == U16_MAX)
>  			break;
>  
> @@ -4589,9 +4664,66 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
>  	const struct skl_plane_wm *wm =
>  		&crtc_state->wm.skl.optimal.planes[plane_id];
>  
> +	if (!level) {
> +		const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;

Why is this here instead of higher up?

> +
> +		if (pipe_wm->can_sagv)
> +			return color_plane == COLOR_PLANE_Y ? &wm->sagv_wm0 : &wm->uv_sagv_wm0;
> +	}
> +
>  	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
>  }
>  
> +static bool
> +tgl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
const

> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);

'crtc'

> +	enum plane_id plane_id;
> +
> +	/*
> +	 * If pipe is not active it can't affect SAGV rejection
> +	 * Checking it here is needed to leave only cases when
> +	 * alloc_size is 0 for any other reasons, except inactive
> +	 * pipe. As inactive pipe is fine, however having no ddb
> +	 * space available is already problematic - so need to
> +	 * to separate those.
> +	 */
> +	if (!crtc_state->hw.active)
> +		return true;
> +
> +	/*
> +	 * skl_allocate_pipe_ddb already done it's job to allocate
> +	 * as much blocks as possible for each plane - let's now
> +	 * evaluate if those were enough to enable SAGV.
> +	 * Criteria is that we need to have wm0 + sagv_block_time blocks
> +	 * for level 0 for each plane.
> +	 */

The comment-to-code ratio seems way too high to me.

> +	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
> +		struct skl_ddb_entry *plane_alloc =
> +			&crtc_state->wm.skl.plane_ddb_y[plane_id];
> +		struct skl_ddb_entry *uv_plane_alloc =
> +			&crtc_state->wm.skl.plane_ddb_uv[plane_id];

consts missing

> +		const struct skl_plane_wm *wm =
> +			&crtc_state->wm.skl.optimal.planes[plane_id];
> +
> +		if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc) {
> +			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV plane %d pipe %c\n",
> +				      plane_alloc->start, plane_alloc->end, plane_id,
> +				      pipe_name(intel_crtc->pipe));

Are we going to drown in debug noise?

> +			return false;
> +		}
> +
> +		if (skl_ddb_entry_size(uv_plane_alloc) < wm->uv_sagv_wm0.min_ddb_alloc) {
> +			DRM_DEBUG_KMS("Not enough ddb blocks(%d-%d) for SAGV uv plane %d pipe %c\n",
> +				      plane_alloc->start, plane_alloc->end, plane_id,
> +				      pipe_name(intel_crtc->pipe));
> +			return false;
> +		}

uv_wm isn't a thing on icl+.

> +	}
> +
> +	return true;
> +}
> +
>  static int
>  skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
>  {
> @@ -5173,10 +5305,17 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>  static void
>  skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>  		      const struct skl_wm_params *wm_params,
> -		      struct skl_wm_level *levels)
> +		      struct skl_plane_wm *plane_wm,
> +		      enum color_plane color_plane)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	int level, max_level = ilk_wm_max_level(dev_priv);
> +	/*
> +	 * Check which kind of plane is it and based on that calculate
> +	 * correspondent WM levels.
> +	 */
> +	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
> +				      plane_wm->uv_wm : plane_wm->wm;
>  	struct skl_wm_level *result_prev = &levels[0];

Why are we chancing this function? I see no reason for it.

>  
>  	for (level = 0; level <= max_level; level++) {
> @@ -5190,6 +5329,40 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>  	}
>  }
>  
> +static void skl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
> +				const struct skl_wm_params *wm_params,
> +				struct skl_plane_wm *plane_wm,
> +				enum color_plane color_plane)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct skl_wm_level *sagv_wm = color_plane == COLOR_PLANE_UV ?
> +				&plane_wm->uv_sagv_wm0 : &plane_wm->sagv_wm0;
> +	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
> +				plane_wm->uv_wm : plane_wm->wm;

Seems wrong here too. uv_wm isn't a thing on icl+.

> +
> +	/*
> +	 * For Gen12 if it is an L0 we need to also
> +	 * consider sagv_block_time when calculating
> +	 * L0 watermark - we will need that when making
> +	 * a decision whether enable SAGV or not.
> +	 * For older gens we agreed to copy L0 value for
> +	 * compatibility.
> +	 */
> +	if ((INTEL_GEN(dev_priv) >= 12)) {
> +		u32 latency = dev_priv->wm.skl_latency[0];
> +
> +		latency += dev_priv->sagv_block_time_us;
> +		skl_compute_plane_wm(crtc_state, 0, latency,
> +				     wm_params, &levels[0],
> +				     sagv_wm);
> +		DRM_DEBUG_KMS("%d L0 blocks required for SAGV vs %d for non-SAGV\n",
> +			      sagv_wm->min_ddb_alloc, levels[0].min_ddb_alloc);
> +	} else {
> +		/* Since all members are POD */
> +		*sagv_wm = levels[0];
> +	}
> +}
> +
>  static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
>  				      const struct skl_wm_params *wp,
>  				      struct skl_plane_wm *wm)
> @@ -5270,7 +5443,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
>  	if (ret)
>  		return ret;
>  
> -	skl_compute_wm_levels(crtc_state, &wm_params, wm->wm);
> +	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
> +	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
>  	skl_compute_transition_wm(crtc_state, &wm_params, wm);
>  
>  	return 0;
> @@ -5292,7 +5466,8 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
>  	if (ret)
>  		return ret;
>  
> -	skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm);
> +	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
> +	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
>  
>  	return 0;
>  }
> @@ -5631,9 +5806,25 @@ skl_print_wm_changes(struct intel_atomic_state *state)
>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
>  			enum plane_id plane_id = plane->id;
>  			const struct skl_plane_wm *old_wm, *new_wm;
> +			const struct skl_wm_level *old_wm_level, *new_wm_level;
> +			u16 old_plane_res_l, new_plane_res_l;
> +			u8  old_plane_res_b, new_plane_res_b;
> +			u16 old_min_ddb_alloc, new_min_ddb_alloc;
> +			int color_plane = 0;
>  
>  			old_wm = &old_pipe_wm->planes[plane_id];
>  			new_wm = &new_pipe_wm->planes[plane_id];
> +			old_wm_level = skl_plane_wm_level(old_crtc_state, plane_id, 0, color_plane);
> +			new_wm_level = skl_plane_wm_level(new_crtc_state, plane_id, 0, color_plane);
> +
> +			old_plane_res_l = old_wm_level->plane_res_l;
> +			old_plane_res_b = old_wm_level->plane_res_b;
> +
> +			new_plane_res_l = new_wm_level->plane_res_l;
> +			new_plane_res_b = new_wm_level->plane_res_b;
> +
> +			old_min_ddb_alloc = old_wm_level->min_ddb_alloc;
> +			new_min_ddb_alloc = new_wm_level->min_ddb_alloc;
>  
>  			if (skl_plane_wm_equals(dev_priv, old_wm, new_wm))
>  				continue;
> @@ -5657,7 +5848,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
>  				    "[PLANE:%d:%s]   lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d"
>  				      " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d\n",
>  				    plane->base.base.id, plane->base.name,
> -				    enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].plane_res_l,
> +				    enast(old_wm->wm[0].ignore_lines), old_plane_res_l,
>  				    enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].plane_res_l,
>  				    enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].plane_res_l,
>  				    enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].plane_res_l,
> @@ -5667,7 +5858,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
>  				    enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].plane_res_l,
>  				    enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.plane_res_l,
>  
> -				    enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].plane_res_l,
> +				    enast(new_wm->wm[0].ignore_lines), new_plane_res_l,
>  				    enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].plane_res_l,
>  				    enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].plane_res_l,
>  				    enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].plane_res_l,
> @@ -5681,12 +5872,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
>  				    "[PLANE:%d:%s]  blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
>  				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
>  				    plane->base.base.id, plane->base.name,
> -				    old_wm->wm[0].plane_res_b, old_wm->wm[1].plane_res_b,
> +				    old_plane_res_b, old_wm->wm[1].plane_res_b,
>  				    old_wm->wm[2].plane_res_b, old_wm->wm[3].plane_res_b,
>  				    old_wm->wm[4].plane_res_b, old_wm->wm[5].plane_res_b,
>  				    old_wm->wm[6].plane_res_b, old_wm->wm[7].plane_res_b,
>  				    old_wm->trans_wm.plane_res_b,
> -				    new_wm->wm[0].plane_res_b, new_wm->wm[1].plane_res_b,
> +				    new_plane_res_b, new_wm->wm[1].plane_res_b,
>  				    new_wm->wm[2].plane_res_b, new_wm->wm[3].plane_res_b,
>  				    new_wm->wm[4].plane_res_b, new_wm->wm[5].plane_res_b,
>  				    new_wm->wm[6].plane_res_b, new_wm->wm[7].plane_res_b,
> @@ -5696,12 +5887,12 @@ skl_print_wm_changes(struct intel_atomic_state *state)
>  				    "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
>  				    " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n",
>  				    plane->base.base.id, plane->base.name,
> -				    old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
> +				    old_min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
>  				    old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc,
>  				    old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc,
>  				    old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc,
>  				    old_wm->trans_wm.min_ddb_alloc,
> -				    new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
> +				    new_min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
>  				    new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc,
>  				    new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
>  				    new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,

I think I mentioned it before already, but I think we may want to just
dump the sagv wm0 as its own thing here.

> @@ -5866,6 +6057,10 @@ skl_compute_wm(struct intel_atomic_state *state)
>  	if (ret)
>  		return ret;
>  
> +	ret = intel_compute_sagv_mask(state);
> +	if (ret)
> +		return ret;
> +
>  	/*
>  	 * skl_compute_ddb() will have adjusted the final watermarks
>  	 * based on how much ddb is available. Now we can actually
> @@ -5993,6 +6188,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
>  				val = I915_READ(CUR_WM(pipe, level));
>  
>  			skl_wm_level_from_reg_val(val, &wm->wm[level]);
> +			if (level == 0)
> +				memcpy(&wm->sagv_wm0, &wm->wm[level],
> +				       sizeof(struct skl_wm_level));

A bit pointless to do that inside the loop.

>  		}
>  
>  		if (plane_id != PLANE_CURSOR)
> diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
> index d60a85421c5a..5fb32db4abc5 100644
> --- a/drivers/gpu/drm/i915/intel_pm.h
> +++ b/drivers/gpu/drm/i915/intel_pm.h
> @@ -9,6 +9,7 @@
>  #include <linux/types.h>
>  
>  #include "i915_reg.h"
> +#include "display/intel_bw.h"
>  
>  struct drm_device;
>  struct drm_i915_private;
> @@ -41,7 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
>  			      struct skl_pipe_wm *out);
>  void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
>  void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
> -bool intel_can_enable_sagv(struct intel_atomic_state *state);
> +bool intel_has_sagv(struct drm_i915_private *dev_priv);
> +bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
>  int intel_enable_sagv(struct drm_i915_private *dev_priv);
>  int intel_disable_sagv(struct drm_i915_private *dev_priv);
>  bool skl_wm_level_equals(const struct skl_wm_level *l1,
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands Stanislav Lisovskiy
@ 2020-04-02 17:27   ` Ville Syrjälä
  2020-04-03  6:32   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 17:27 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:10:02PM +0200, Stanislav Lisovskiy wrote:
> We need a new PCode request commands and reply codes
> to be added as a prepartion patch for QGV points
> restricting for new SAGV support.
> 
> v2: - Extracted those changes into separate patch
>       (Ville Syrjälä)
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h       | 4 ++++
>  drivers/gpu/drm/i915/intel_sideband.c | 2 ++
>  2 files changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 9c53fe918be6..1a61db746c7e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8994,6 +8994,7 @@ enum {
>  #define     GEN7_PCODE_ILLEGAL_DATA		0x3
>  #define     GEN11_PCODE_ILLEGAL_SUBCOMMAND	0x4
>  #define     GEN11_PCODE_LOCKED			0x6
> +#define     GEN11_PCODE_REJECTED		0x11
>  #define     GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10
>  #define   GEN6_PCODE_WRITE_RC6VIDS		0x4
>  #define   GEN6_PCODE_READ_RC6VIDS		0x5
> @@ -9015,6 +9016,7 @@ enum {
>  #define   ICL_PCODE_MEM_SUBSYSYSTEM_INFO	0xd
>  #define     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO	(0x0 << 8)
>  #define     ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point)	(((point) << 16) | (0x1 << 8))
> +#define   ICL_PCODE_SAGV_DE_MEM_SS_CONFIG	0xe
>  #define   GEN6_PCODE_READ_D_COMP		0x10
>  #define   GEN6_PCODE_WRITE_D_COMP		0x11
>  #define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
> @@ -9027,6 +9029,8 @@ enum {
>  #define     GEN9_SAGV_IS_DISABLED		0x1
>  #define     GEN9_SAGV_ENABLE			0x3
>  #define GEN12_PCODE_READ_SAGV_BLOCK_TIME_US	0x23
> +#define GEN11_PCODE_POINTS_RESTRICTED		0x0
> +#define GEN11_PCODE_POINTS_RESTRICTED_MASK	0x1

What are these? The indentation makes me thingk they are new commands,
but the placement totally disagrees with that.

>  #define GEN6_PCODE_DATA				_MMIO(0x138128)
>  #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
>  #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
> diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
> index 1447e7516cb7..1e7dd6b6f103 100644
> --- a/drivers/gpu/drm/i915/intel_sideband.c
> +++ b/drivers/gpu/drm/i915/intel_sideband.c
> @@ -370,6 +370,8 @@ static inline int gen7_check_mailbox_status(u32 mbox)
>  		return -ENXIO;
>  	case GEN11_PCODE_LOCKED:
>  		return -EBUSY;
> +	case GEN11_PCODE_REJECTED:
> +		return -EACCES;
>  	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
>  		return -EOVERFLOW;
>  	default:
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state Stanislav Lisovskiy
@ 2020-04-02 17:30   ` Ville Syrjälä
  2020-04-03  6:34   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 17:30 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:10:03PM +0200, Stanislav Lisovskiy wrote:
> That is a preparation patch before next one where we
> introduce old_bw_state and a bunch of other changes
> as well.
> In a review comment it was suggested to split out
> at least that renaming into a separate patch, what
> is done here.
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index a8b2038db4d2..d16771dd2b10 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -418,7 +418,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> -	struct intel_bw_state *bw_state = NULL;
> +	struct intel_bw_state *new_bw_state = NULL;
>  	unsigned int data_rate, max_data_rate;
>  	unsigned int num_active_planes;
>  	struct intel_crtc *crtc;
> @@ -447,29 +447,29 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  		    old_active_planes == new_active_planes)
>  			continue;
>  
> -		bw_state  = intel_atomic_get_bw_state(state);
> -		if (IS_ERR(bw_state))
> -			return PTR_ERR(bw_state);
> +		new_bw_state  = intel_atomic_get_bw_state(state);
                            ^

Pls remove the spurious space while at it.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +		if (IS_ERR(new_bw_state))
> +			return PTR_ERR(new_bw_state);
>  
> -		bw_state->data_rate[crtc->pipe] = new_data_rate;
> -		bw_state->num_active_planes[crtc->pipe] = new_active_planes;
> +		new_bw_state->data_rate[crtc->pipe] = new_data_rate;
> +		new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
>  
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "pipe %c data rate %u num active planes %u\n",
>  			    pipe_name(crtc->pipe),
> -			    bw_state->data_rate[crtc->pipe],
> -			    bw_state->num_active_planes[crtc->pipe]);
> +			    new_bw_state->data_rate[crtc->pipe],
> +			    new_bw_state->num_active_planes[crtc->pipe]);
>  	}
>  
> -	if (!bw_state)
> +	if (!new_bw_state)
>  		return 0;
>  
> -	ret = intel_atomic_lock_global_state(&bw_state->base);
> +	ret = intel_atomic_lock_global_state(&new_bw_state->base);
>  	if (ret)
>  		return ret;
>  
> -	data_rate = intel_bw_data_rate(dev_priv, bw_state);
> -	num_active_planes = intel_bw_num_active_planes(dev_priv, bw_state);
> +	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
> +	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
>  
>  	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
>  
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth.
  2020-03-26 18:36   ` Stanislav Lisovskiy
@ 2020-04-02 17:50     ` Ville Syrjälä
  2020-04-03  6:37     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-02 17:50 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Thu, Mar 26, 2020 at 08:36:57PM +0200, Stanislav Lisovskiy wrote:
> According to BSpec 53998, we should try to
> restrict qgv points, which can't provide
> enough bandwidth for desired display configuration.
> 
> Currently we are just comparing against all of
> those and take minimum(worst case).
> 
> v2: Fixed wrong PCode reply mask, removed hardcoded
>     values.
> 
> v3: Forbid simultaneous legacy SAGV PCode requests and
>     restricting qgv points. Put the actual restriction
>     to commit function, added serialization(thanks to Ville)
>     to prevent commit being applied out of order in case of
>     nonblocking and/or nomodeset commits.
> 
> v4:
>     - Minor code refactoring, fixed few typos(thanks to James Ausmus)
>     - Change the naming of qgv point
>       masking/unmasking functions(James Ausmus).
>     - Simplify the masking/unmasking operation itself,
>       as we don't need to mask only single point per request(James Ausmus)
>     - Reject and stick to highest bandwidth point if SAGV
>       can't be enabled(BSpec)
> 
> v5:
>     - Add new mailbox reply codes, which seems to happen during boot
>       time for TGL and indicate that QGV setting is not yet available.
> 
> v6:
>     - Increase number of supported QGV points to be in sync with BSpec.
> 
> v7: - Rebased and resolved conflict to fix build failure.
>     - Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
> 
> v8: - Don't report an error if we can't restrict qgv points, as SAGV
>       can be disabled by BIOS, which is completely legal. So don't
>       make CI panic. Instead if we detect that there is only 1 QGV
>       point accessible just analyze if we can fit the required bandwidth
>       requirements, but no need in restricting.
> 
> v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
>       simultaneously.
> 
> v10: - Fix CDCLK corruption, because of global state getting serialized
>        without modeset, which caused copying of non-calculated cdclk
>        to be copied to dev_priv(thanks to Ville for the hint).
> 
> v11: - Remove unneeded headers and spaces(Matthew Roper)
>      - Remove unneeded intel_qgv_info qi struct from bw check and zero
>        out the needed one(Matthew Roper)
>      - Changed QGV error message to have more clear meaning(Matthew Roper)
>      - Use state->modeset_set instead of any_ms(Matthew Roper)
>      - Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
>      - Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
>      - Moved unrelated changes to other patch(using latency as parameter
>        for plane wm calculation, moved to SAGV refactoring patch)
> 
> v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
>      - Remove unnecessary mask being zero check when unmasking
>        qgv points as this is completely legal(Matt Roper)
>      - Check if we are setting the same mask as already being set
>        in hardware to prevent error from PCode.
>      - Fix error message when restricting/unrestricting qgv points
>        to "mask/unmask" which sounds more accurate(Matt Roper)
>      - Move sagv status setting to icl_get_bw_info from atomic check
>        as this should be calculated only once.(Matt Roper)
>      - Edited comments for the case when we can't enable SAGV and
>        use only 1 QGV point with highest bandwidth to be more
>        understandable.(Matt Roper)
> 
> v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
>      - Changed comment for zero new_mask in qgv points masking function
>        to better reflect reality(Ville Syrjälä)
>      - Simplified bit mask operation in qgv points masking function
>        (Ville Syrjälä)
>      - Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
>        however this still can't be under modeset condition(Ville Syrjälä)
>      - Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
>        (Ville Syrjälä)
>      - Extracted PCode changes to separate patch.(Ville Syrjälä)
>      - Now treat num_planes 0 same as 1 to avoid confusion and
>        returning max_bw as 0, which would prevent choosing QGV
>        point having max bandwidth in case if SAGV is not allowed,
>        as per BSpec(Ville Syrjälä)
>      - Do the actual qgv_points_mask swap in the same place as
>        all other global state parts like cdclk are swapped.
>        In the next patch, this all will be moved to bw state as
>        global state, once new global state patch series from Ville
>        lands
> 
> v14: - Now using global state to serialize access to qgv points
>      - Added global state locking back, otherwise we seem to read
>        bw state in a wrong way.
> 
> v15: - Added TODO comment for near atomic global state locking in
>        bw code.
> 
> v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
>        with Jani Nikula.
>      - Take bw_state_changed flag into use.
> 
> v17: - Moved qgv point related manipulations next to SAGV code, as
>        those are semantically related(Ville Syrjälä)
>      - Renamed those into intel_sagv_(pre)|(post)_plane_update
>        (Ville Syrjälä)
> 
> v18: - Move sagv related calls from commit tail into
>        intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
> 
> v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
>        for commit tail stage.
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@intel.com>
> Cc: James Ausmus <james.ausmus@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c       | 147 +++++++++++++-----
>  drivers/gpu/drm/i915/display/intel_bw.h       |   9 ++
>  drivers/gpu/drm/i915/display/intel_display.c  |  29 +---
>  .../drm/i915/display/intel_display_types.h    |   3 +
>  drivers/gpu/drm/i915/intel_pm.c               | 119 ++++++++++++++
>  drivers/gpu/drm/i915/intel_pm.h               |   2 +
>  6 files changed, 251 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index d16771dd2b10..d5a93e8f7134 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -8,6 +8,9 @@
>  #include "intel_bw.h"
>  #include "intel_display_types.h"
>  #include "intel_sideband.h"
> +#include "intel_atomic.h"
> +#include "intel_pm.h"
> +
>  
>  /* Parameters for Qclk Geyserville (QGV) */
>  struct intel_qgv_point {
> @@ -113,6 +116,26 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
>  	return 0;
>  }
>  
> +int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
> +				  u32 points_mask)
> +{
> +	int ret;
> +
> +	/* bspec says to keep retrying for at least 1 ms */
> +	ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
> +				points_mask,
> +				GEN11_PCODE_POINTS_RESTRICTED_MASK,
> +				GEN11_PCODE_POINTS_RESTRICTED,
> +				1);
> +
> +	if (ret < 0) {
> +		DRM_ERROR("Failed to disable qgv points (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
>  			      struct intel_qgv_info *qi)
>  {
> @@ -240,6 +263,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
>  			break;
>  	}
>  
> +	/*
> +	 * In case if SAGV is disabled in BIOS, we always get 1
> +	 * SAGV point, but we can't send PCode commands to restrict it
> +	 * as it will fail and pointless anyway.
> +	 */
> +	if (qi.num_points == 1)
> +		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
> +	else
> +		dev_priv->sagv_status = I915_SAGV_ENABLED;
> +
>  	return 0;
>  }
>  
> @@ -259,7 +292,7 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
>  		if (qgv_point >= bi->num_qgv_points)
>  			return UINT_MAX;
>  
> -		if (num_planes >= bi->num_planes)
> +		if (num_planes >= bi->num_planes || !num_planes)

So we're returning the first bandwidth number here? Isn't that the
lowest bandwidth (ie. max num_planes)?

I would think we want to return the max bandwidth. So I'd just do the
'num_planes = num_planes ?: 1'/etc. trick instead.

>  			return bi->deratedbw[qgv_point];
>  	}
>  
> @@ -277,34 +310,6 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
>  		icl_get_bw_info(dev_priv, &icl_sa_info);
>  }
>  
> -static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
> -					int num_planes)
> -{
> -	if (INTEL_GEN(dev_priv) >= 11) {
> -		/*
> -		 * Any bw group has same amount of QGV points
> -		 */
> -		const struct intel_bw_info *bi =
> -			&dev_priv->max_bw[0];
> -		unsigned int min_bw = UINT_MAX;
> -		int i;
> -
> -		/*
> -		 * FIXME with SAGV disabled maybe we can assume
> -		 * point 1 will always be used? Seems to match
> -		 * the behaviour observed in the wild.
> -		 */
> -		for (i = 0; i < bi->num_qgv_points; i++) {
> -			unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
> -
> -			min_bw = min(bw, min_bw);
> -		}
> -		return min_bw;
> -	} else {
> -		return UINT_MAX;
> -	}
> -}
> -
>  static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
>  {
>  	/*
> @@ -419,10 +424,15 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>  	struct intel_bw_state *new_bw_state = NULL;
> -	unsigned int data_rate, max_data_rate;
> +	struct intel_bw_state *old_bw_state = NULL;

const

> +	unsigned int data_rate;
>  	unsigned int num_active_planes;
>  	struct intel_crtc *crtc;
>  	int i, ret;
> +	u32 allowed_points = 0;
> +	unsigned int max_bw_point = 0, max_bw = 0;
> +	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
> +	u32 mask = (1 << num_qgv_points) - 1;
>  
>  	/* FIXME earlier gens need some checks too */
>  	if (INTEL_GEN(dev_priv) < 11)
> @@ -465,23 +475,86 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  		return 0;
>  
>  	ret = intel_atomic_lock_global_state(&new_bw_state->base);
> -	if (ret)
> +	if (ret) {
> +		DRM_DEBUG_KMS("Could not lock global state\n");

Again, no debugs pls.

>  		return ret;
> +	}
>  
>  	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
> +	data_rate = DIV_ROUND_UP(data_rate, 1000);
> +
>  	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
>  
> -	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
> +	for (i = 0; i < num_qgv_points; i++) {
> +		unsigned int max_data_rate;
>  
> -	data_rate = DIV_ROUND_UP(data_rate, 1000);
> +		max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
> +		/*
> +		 * We need to know which qgv point gives us
> +		 * maximum bandwidth in order to disable SAGV
> +		 * if we find that we exceed SAGV block time
> +		 * with watermarks. By that moment we already
> +		 * have those, as it is calculated earlier in
> +		 * intel_atomic_check,
> +		 */
> +		if (max_data_rate > max_bw) {
> +			max_bw_point = i;
> +			max_bw = max_data_rate;
> +		}
> +		if (max_data_rate >= data_rate)
> +			allowed_points |= BIT(i);
> +		DRM_DEBUG_KMS("QGV point %d: max bw %d required %d\n",
> +			      i, max_data_rate, data_rate);
> +	}
>  
> -	if (data_rate > max_data_rate) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
> -			    data_rate, max_data_rate, num_active_planes);
> +	/*
> +	 * BSpec states that we always should have at least one allowed point
> +	 * left, so if we couldn't - simply reject the configuration for obvious
> +	 * reasons.
> +	 */
> +	if (allowed_points == 0) {
> +		DRM_DEBUG_KMS("No QGV points provide sufficient memory"
> +			      " bandwidth for display configuration.\n");

We lost the numbers here? Also pls switch to per-device debugs all over.

>  		return -EINVAL;
>  	}
>  
> +	/*
> +	 * Leave only single point with highest bandwidth, if
> +	 * we can't enable SAGV due to the increased memory latency it may
> +	 * cause.
> +	 */
> +	if (!intel_can_enable_sagv(new_bw_state)) {
> +		allowed_points = 1 << max_bw_point;

BIT()

> +		DRM_DEBUG_KMS("No SAGV, using single QGV point %d\n",
> +			      max_bw_point);
> +	}
> +	/*
> +	 * We store the ones which need to be masked as that is what PCode
> +	 * actually accepts as a parameter.
> +	 */
> +	new_bw_state->qgv_points_mask = (~allowed_points) & mask;
> +
> +	DRM_DEBUG_KMS("New state %p qgv mask %x\n",
> +		      state, new_bw_state->qgv_points_mask);

The debugs seem a bit excessive in general.

> +
> +	old_bw_state = intel_atomic_get_bw_old_state(state);
> +	if (IS_ERR(old_bw_state)) {

Can't error.

> +		DRM_DEBUG_KMS("Could not get old bw state!\n");
> +		return PTR_ERR(old_bw_state);
> +	}
> +
> +	/*
> +	 * If the actual mask had changed we need to make sure that
> +	 * the commits are serialized(in case this is a nomodeset, nonblocking)
> +	 */
> +	if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
> +		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
> +		if (ret) {
> +			DRM_DEBUG_KMS("Could not serialize global state\n");
> +			return ret;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
> index 6ad3ea7cedfe..5cb0717c2df8 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -24,6 +24,13 @@ struct intel_bw_state {
>  	 */
>  	u8 pipe_sagv_reject;
>  
> +	/*
> +	 * Current QGV points mask, which restricts
> +	 * some particular SAGV states, not to confuse
> +	 * with pipe_sagv_mask.
> +	 */
> +	u8 qgv_points_mask;
> +
>  	unsigned int data_rate[I915_MAX_PIPES];
>  	u8 num_active_planes[I915_MAX_PIPES];
>  };
> @@ -44,5 +51,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv);
>  int intel_bw_atomic_check(struct intel_atomic_state *state);
>  void intel_bw_crtc_update(struct intel_bw_state *bw_state,
>  			  const struct intel_crtc_state *crtc_state);
> +int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
> +				  u32 points_mask);
>  
>  #endif /* __INTEL_BW_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8a0d952c67bf..ab3d94e3e97e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -15539,23 +15539,17 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  		crtc->config = new_crtc_state;
>  
>  	if (state->modeset) {
> -		struct intel_bw_state *bw_state;
> -
> -		bw_state = intel_atomic_get_bw_new_state(state);
> +		/*
> +		 * Now we need to check if SAGV needs to be disabled(i.e QGV points
> +		 * modified even, when no modeset is done(for example plane updates
> +		 * can now trigger that).
> +		 */

Too many comments.

> +		intel_sagv_pre_plane_update(state);
>  
>  		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
>  
>  		intel_set_cdclk_pre_plane_update(state);
>  
> -		/*
> -		 * SKL workaround: bspec recommends we disable the SAGV when we
> -		 * have more then one pipe enabled
> -		 */
> -		if (INTEL_GEN(dev_priv) < 11) {
> -			if (bw_state && !intel_can_enable_sagv(bw_state))
> -				intel_disable_sagv(dev_priv);
> -		}
> -
>  		intel_modeset_verify_disabled(dev_priv, state);
>  	}
>  
> @@ -15651,17 +15645,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  	intel_check_cpu_fifo_underruns(dev_priv);
>  	intel_check_pch_fifo_underruns(dev_priv);
>  
> -	if (state->modeset)
> +	if (state->modeset) {
>  		intel_verify_planes(state);
>  
> -	if (INTEL_GEN(dev_priv) < 11) {
> -		struct intel_bw_state *bw_state;
> -
> -		bw_state = intel_atomic_get_bw_new_state(state);
> -
> -		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state)) {
> -			intel_enable_sagv(dev_priv);
> -		}
> +		intel_sagv_post_plane_update(state);
>  	}
>  
>  	drm_atomic_helper_commit_hw_done(&state->base);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 51fa5a746a5f..8655038bafe7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -689,6 +689,9 @@ enum color_plane {
>  	COLOR_PLANE_UV
>  };
>  
> +/* BSpec precisely defines this */
> +#define NUM_SAGV_POINTS 8
> +
>  struct skl_pipe_wm {
>  	struct skl_plane_wm planes[I915_MAX_PLANES];
>  	bool can_sagv;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 63c46918d1ed..4b96c14f9361 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3758,6 +3758,125 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
>  	return 0;
>  }
>  
> +void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
> +{
> +	struct drm_device *dev = state->base.dev;

No redundant 'dev' variables pls.

> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	int ret;
> +	struct intel_bw_state *new_bw_state = NULL;
> +	struct intel_bw_state *old_bw_state = NULL;
> +	u32 new_mask = 0;
> +
> +	/*
> +	 * Just return if we can't control SAGV or don't have it.
> +	 * This is different from situation when we have SAGV but just can't
> +	 * afford it due to DBuf limitation - in case if SAGV is completely
> +	 * disabled in a BIOS, we are not even allowed to send a PCode request,
> +	 * as it will throw an error. So have to check it here.
> +	 */
> +	if (!intel_has_sagv(dev_priv))
> +		return;
> +
> +	new_bw_state = intel_atomic_get_bw_new_state(state);
> +	if (!new_bw_state) {
> +		WARN(1, "Could not get new bw_state\n");

Argh.

> +		return;
> +	}
> +
> +	if ((INTEL_GEN(dev_priv) < 11) && !intel_can_enable_sagv(new_bw_state)) {

Pointless parens.

> +		intel_disable_sagv(dev_priv);
> +		return;
> +	}
> +
> +	old_bw_state = intel_atomic_get_bw_old_state(state);
> +	if (!old_bw_state) {
> +		WARN(1, "Could not get old bw_state\n");
> +		return;
> +	}
> +
> +	/*
> +	 * Nothing to mask
> +	 */
> +	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> +		return;
> +
> +	new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
> +
> +	/*
> +	 * If new mask is zero - means there is nothing to mask,
> +	 * we can only unmask, which should be done in unmask.
> +	 */
> +	if (!new_mask)
> +		return;
> +
> +	/*
> +	 * Restrict required qgv points before updating the configuration.
> +	 * According to BSpec we can't mask and unmask qgv points at the same
> +	 * time. Also masking should be done before updating the configuration
> +	 * and unmasking afterwards.
> +	 *
> +	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
> +	if (ret < 0)
> +		DRM_DEBUG_KMS("Could not mask required qgv points(%d)\n",
> +			      ret);

Maybe error print instead?

> +}
> +
> +void intel_sagv_post_plane_update(struct intel_atomic_state *state)
> +{
> +	struct drm_device *dev = state->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	int ret;
> +	struct intel_bw_state *new_bw_state = NULL;
> +	struct intel_bw_state *old_bw_state = NULL;
> +	u32 new_mask = 0;
> +
> +	/*
> +	 * Just return if we can't control SAGV or don't have it.
> +	 * This is different from situation when we have SAGV but just can't
> +	 * afford it due to DBuf limitation - in case if SAGV is completely
> +	 * disabled in a BIOS, we are not even allowed to send a PCode request,
> +	 * as it will throw an error. So have to check it here.
> +	 */
> +	if (!intel_has_sagv(dev_priv))
> +		return;
> +
> +	new_bw_state = intel_atomic_get_bw_new_state(state);
> +	if (!new_bw_state) {
> +		WARN(1, "Could not get new bw_state\n");
> +		return;
> +	}
> +
> +	if ((INTEL_GEN(dev_priv) < 11) && intel_can_enable_sagv(new_bw_state)) {
> +		intel_enable_sagv(dev_priv);
> +		return;
> +	}
> +
> +	old_bw_state = intel_atomic_get_bw_old_state(state);
> +	if (!old_bw_state) {
> +		WARN(1, "Could not get old bw_state\n");
> +		return;
> +	}
> +
> +	/*
> +	 * Nothing to unmask
> +	 */
> +	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> +		return;
> +
> +	new_mask = new_bw_state->qgv_points_mask;
> +
> +	/*
> +	 * Allow required qgv points after updating the configuration.
> +	 * According to BSpec we can't mask and unmask qgv points at the same
> +	 * time. Also masking should be done before updating the configuration
> +	 * and unmasking afterwards.
> +	 */
> +	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
> +	if (ret < 0)
> +		DRM_DEBUG_KMS("Could not unmask required qgv points(%d)\n",
> +			      ret);
> +}
> +
>  static bool icl_can_enable_sagv_on_pipe(struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_device *dev = crtc_state->uapi.crtc->dev;
> diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
> index 5fb32db4abc5..793a4add9831 100644
> --- a/drivers/gpu/drm/i915/intel_pm.h
> +++ b/drivers/gpu/drm/i915/intel_pm.h
> @@ -42,6 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
>  			      struct skl_pipe_wm *out);
>  void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
>  void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
> +void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
> +void intel_sagv_post_plane_update(struct intel_atomic_state *state);
>  bool intel_has_sagv(struct drm_i915_private *dev_priv);
>  bool intel_can_enable_sagv(struct intel_bw_state *bw_state);
>  int intel_enable_sagv(struct drm_i915_private *dev_priv);
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
  2020-04-02 16:20   ` Ville Syrjälä
@ 2020-04-03  6:11   ` Stanislav Lisovskiy
  2020-04-03  6:15   ` Stanislav Lisovskiy
  2 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:11 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Add correspondent helpers to be able to get old/new bandwidth
global state object.

v2: - Fixed typo in function call
v3: - Changed new functions naming to use convention proposed
      by Jani Nikula, i.e intel_bw_* in intel_bw.c file.
v4: - Change function naming back to intel_atomic* pattern,
      was decided to rename in a separate patch series.
v5: - Fix function naming to match existing practices(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 29 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_bw.h |  9 ++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 58b264bc318d..49794f36dbe7 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -374,7 +374,34 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
 	return data_rate;
 }
 
-static struct intel_bw_state *
+struct intel_bw_state *
+intel_atomic_get_old_bw_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
+	if (!bw_state)
+		return NULL;
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
+intel_atomic_get_new_bw_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
+
+	if (!bw_state)
+		return NULL;
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
 intel_atomic_get_bw_state(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index a8aa7624c5aa..ac004d6f4276 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,15 @@ struct intel_bw_state {
 
 #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
 
+struct intel_bw_state *
+intel_atomic_get_old_bw_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_new_bw_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_bw_state(struct intel_atomic_state *state);
+
 void intel_bw_init_hw(struct drm_i915_private *dev_priv);
 int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
  2020-04-02 16:20   ` Ville Syrjälä
  2020-04-03  6:11   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
@ 2020-04-03  6:15   ` Stanislav Lisovskiy
  2 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:15 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Add correspondent helpers to be able to get old/new bandwidth
global state object.

v2: - Fixed typo in function call
v3: - Changed new functions naming to use convention proposed
      by Jani Nikula, i.e intel_bw_* in intel_bw.c file.
v4: - Change function naming back to intel_atomic* pattern,
      was decided to rename in a separate patch series.
v5: - Fix function naming to match existing practices(Ville)
v6: - Removed spurious whitespace

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 28 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_bw.h |  9 ++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 58b264bc318d..d5f5c2f49af2 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -374,7 +374,33 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
 	return data_rate;
 }
 
-static struct intel_bw_state *
+struct intel_bw_state *
+intel_atomic_get_old_bw_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
+	if (!bw_state)
+		return NULL;
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
+intel_atomic_get_new_bw_state(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_global_state *bw_state;
+
+	bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
+	if (!bw_state)
+		return NULL;
+
+	return to_intel_bw_state(bw_state);
+}
+
+struct intel_bw_state *
 intel_atomic_get_bw_state(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index a8aa7624c5aa..ac004d6f4276 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,15 @@ struct intel_bw_state {
 
 #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
 
+struct intel_bw_state *
+intel_atomic_get_old_bw_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_new_bw_state(struct intel_atomic_state *state);
+
+struct intel_bw_state *
+intel_atomic_get_bw_state(struct intel_atomic_state *state);
+
 void intel_bw_init_hw(struct drm_i915_private *dev_priv);
 int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev4)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (12 preceding siblings ...)
  2020-03-27 11:58 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
@ 2020-04-03  6:19 ` Patchwork
  2020-04-03  6:22 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev5) Patchwork
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03  6:19 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev4)
URL   : https://patchwork.freedesktop.org/series/75129/
State : failure

== Summary ==

CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  DESCEND  objtool
  CHK     include/generated/compile.h
  CC [M]  drivers/gpu/drm/i915/intel_pm.o
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_sagv_pre_plane_update’:
drivers/gpu/drm/i915/intel_pm.c:3776:17: error: implicit declaration of function ‘intel_atomic_get_bw_new_state’; did you mean ‘intel_atomic_get_bw_state’? [-Werror=implicit-function-declaration]
  new_bw_state = intel_atomic_get_bw_new_state(state);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 intel_atomic_get_bw_state
drivers/gpu/drm/i915/intel_pm.c:3776:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  new_bw_state = intel_atomic_get_bw_new_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c:3787:17: error: implicit declaration of function ‘intel_atomic_get_bw_old_state’; did you mean ‘intel_atomic_get_bw_state’? [-Werror=implicit-function-declaration]
  old_bw_state = intel_atomic_get_bw_old_state(state);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 intel_atomic_get_bw_state
drivers/gpu/drm/i915/intel_pm.c:3787:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  old_bw_state = intel_atomic_get_bw_old_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_sagv_post_plane_update’:
drivers/gpu/drm/i915/intel_pm.c:3839:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  new_bw_state = intel_atomic_get_bw_new_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c:3850:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  old_bw_state = intel_atomic_get_bw_old_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_compute_sagv_mask’:
drivers/gpu/drm/i915/intel_pm.c:3984:16: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
   old_bw_state = intel_atomic_get_bw_old_state(state);
                ^
cc1: all warnings being treated as errors
scripts/Makefile.build:267: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1
scripts/Makefile.build:505: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:505: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:505: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1683: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv Stanislav Lisovskiy
  2020-04-02 16:44   ` Ville Syrjälä
@ 2020-04-03  6:20   ` Stanislav Lisovskiy
  2020-04-07 19:01     ` Ville Syrjälä
  1 sibling, 1 reply; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:20 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Addressing one of the comments, recommending to extract platform
specific code from intel_can_enable_sagv as a preparation, before
we are going to add support for tgl+.

Current code in intel_can_enable_sagv is valid only for skl,
so this patch adds also proper support for icl, subsequent
patches will add support for tgl+, combined with other required
changes.

v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
    - Removed dev variables(Ville)
    - Constified crtc/plane_state in icl_crtc_can_enable_sagv
      function(Ville)
    - Added hw.active check(Ville)
    - Refactored if ladder(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
 1 file changed, 55 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f8d62d1977ac..27d4d626cb34 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = state->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *crtc;
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_plane *plane;
-	struct intel_crtc_state *crtc_state;
-	enum pipe pipe;
+	const struct intel_plane_state *plane_state;
 	int level, latency;
 
-	if (!intel_has_sagv(dev_priv))
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
+			      pipe_name(crtc->pipe));
 		return false;
+	}
 
-	/*
-	 * If there are no active CRTCs, no additional checks need be performed
-	 */
-	if (hweight8(state->active_pipes) == 0)
+	if (!crtc_state->hw.active)
 		return true;
 
-	/*
-	 * SKL+ workaround: bspec recommends we disable SAGV when we have
-	 * more then one pipe enabled
-	 */
-	if (hweight8(state->active_pipes) > 1)
-		return false;
-
-	/* Since we're now guaranteed to only have one active CRTC... */
-	pipe = ffs(state->active_pipes) - 1;
-	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
-	crtc_state = to_intel_crtc_state(crtc->base.state);
-
-	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
-		return false;
-
-	for_each_intel_plane_on_crtc(dev, crtc, plane) {
-		struct skl_plane_wm *wm =
+	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+		const struct skl_plane_wm *wm =
 			&crtc_state->wm.skl.optimal.planes[plane->id];
 
 		/* Skip this plane if it's not enabled */
@@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
 		latency = dev_priv->wm.skl_latency[level];
 
 		if (skl_needs_memory_bw_wa(dev_priv) &&
-		    plane->base.state->fb->modifier ==
+		    plane_state->uapi.fb->modifier ==
 		    I915_FORMAT_MOD_X_TILED)
 			latency += 15;
 
@@ -3823,6 +3806,49 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
 	return true;
 }
 
+static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+
+	/*
+	 * It has been recommended that for Gen 9 we switch SAGV off when
+	 * multiple pipes are used.
+	 */
+	if (hweight8(state->active_pipes) > 1)
+		return false;
+
+	/*
+	 * Besides active pipe limitation, rest of checks pretty much match ICL
+	 * so no need to duplicate code
+	 */
+	return icl_crtc_can_enable_sagv(crtc_state);
+}
+
+bool intel_can_enable_sagv(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_crtc *crtc;
+	const struct intel_crtc_state *crtc_state;
+	int i;
+
+	if (!intel_has_sagv(dev_priv))
+		return false;
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		bool can_sagv;
+
+		if (INTEL_GEN(dev_priv) >= 11)
+			can_sagv = icl_crtc_can_enable_sagv(crtc_state);
+		else
+			can_sagv = skl_crtc_can_enable_sagv(crtc_state);
+
+		if (!can_sagv)
+			return false;
+	}
+
+	return true;
+}
+
 /*
  * Calculate initial DBuf slice offset, based on slice size
  * and mask(i.e if slice size is 1024 and second slice is enabled
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev5)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (13 preceding siblings ...)
  2020-04-03  6:19 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev4) Patchwork
@ 2020-04-03  6:22 ` Patchwork
  2020-04-03  6:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev10) Patchwork
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03  6:22 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev5)
URL   : https://patchwork.freedesktop.org/series/75129/
State : failure

== Summary ==

CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  DESCEND  objtool
  CHK     include/generated/compile.h
  CC [M]  drivers/gpu/drm/i915/intel_pm.o
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_sagv_pre_plane_update’:
drivers/gpu/drm/i915/intel_pm.c:3776:17: error: implicit declaration of function ‘intel_atomic_get_bw_new_state’; did you mean ‘intel_atomic_get_bw_state’? [-Werror=implicit-function-declaration]
  new_bw_state = intel_atomic_get_bw_new_state(state);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 intel_atomic_get_bw_state
drivers/gpu/drm/i915/intel_pm.c:3776:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  new_bw_state = intel_atomic_get_bw_new_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c:3787:17: error: implicit declaration of function ‘intel_atomic_get_bw_old_state’; did you mean ‘intel_atomic_get_bw_state’? [-Werror=implicit-function-declaration]
  old_bw_state = intel_atomic_get_bw_old_state(state);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 intel_atomic_get_bw_state
drivers/gpu/drm/i915/intel_pm.c:3787:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  old_bw_state = intel_atomic_get_bw_old_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_sagv_post_plane_update’:
drivers/gpu/drm/i915/intel_pm.c:3839:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  new_bw_state = intel_atomic_get_bw_new_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c:3850:15: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
  old_bw_state = intel_atomic_get_bw_old_state(state);
               ^
drivers/gpu/drm/i915/intel_pm.c: In function ‘intel_compute_sagv_mask’:
drivers/gpu/drm/i915/intel_pm.c:3984:16: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
   old_bw_state = intel_atomic_get_bw_old_state(state);
                ^
cc1: all warnings being treated as errors
scripts/Makefile.build:267: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1
scripts/Makefile.build:505: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:505: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:505: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1683: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 06/10] drm/i915: Add proper SAGV support for TGL+
  2020-03-26 18:39   ` Stanislav Lisovskiy
  2020-04-02 17:22     ` Ville Syrjälä
@ 2020-04-03  6:29     ` Stanislav Lisovskiy
  2020-04-03 15:43       ` Stanislav Lisovskiy
  1 sibling, 1 reply; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:29 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Let's refactor the whole SAGV logic, moving
the main calculations from intel_can_enable_sagv
to intel_compute_sagv_mask, which also handles
this in a unified way calling gen specific
functions to evaluate if SAGV is allowed for
each crtc. If crtc sagv mask have been changed
we serialize access and modify global state.

intel_can_enable_sagv now uses bw_state which
stores all information related to SAGV and
is now a trivial helper.

v2:
    - Rework watermark calculation algorithm to
      attempt to calculate Level 0 watermark
      with added sagv block time latency and
      check if it fits in DBuf in order to
      determine if SAGV can be enabled already
      at this stage, just as BSpec 49325 states.
      if that fails rollback to usual Level 0
      latency and disable SAGV.
    - Remove unneeded tabs(James Ausmus)

v3: Rebased the patch

v4: - Added back interlaced check for Gen12 and
      added separate function for TGL SAGV check
      (thanks to James Ausmus for spotting)
    - Removed unneeded gen check
    - Extracted Gen12 SAGV decision making code
      to a separate function from skl_compute_wm

v5: - Added SAGV global state to dev_priv, because
      we need to track all pipes, not only those
      in atomic state. Each pipe has now correspondent
      bit mask reflecting, whether it can tolerate
      SAGV or not(thanks to Ville Syrjala for suggestions).
    - Now using active flag instead of enable in crc
      usage check.

v6: - Fixed rebase conflicts

v7: - kms_cursor_legacy seems to get broken because of multiple memcpy
      calls when copying level 0 water marks for enabled SAGV, to
      fix this now simply using that field right away, without copying,
      for that introduced a new wm_level accessor which decides which
      wm_level to return based on SAGV state.

v8: - Protect crtc_sagv_mask same way as we do for other global state
      changes: i.e check if changes are needed, then grab all crtc locks
      to serialize the changes(Ville Syrjälä)
    - Add crtc_sagv_mask caching in order to avoid needless recalculations
      (Matthew Roper)
    - Put back Gen12 SAGV switch in order to get it enabled in separate
      patch(Matthew Roper)
    - Rename *_set_sagv_mask to *_compute_sagv_mask(Matthew Roper)
    - Check if there are no active pipes in intel_can_enable_sagv
      instead of platform specific functions(Matthew Roper), same
      for intel_has_sagv check.

v9  - Switched to u8 for crtc_sagv_mask(Ville Syrjälä)
    - crtc_sagv_mask now is pipe_sagv_mask(Ville Syrjälä)
    - Extracted sagv checking logic from skl/icl/tgl_compute_sagv_mask
    - Extracted skl_plane_wm_level function and passing latency to
      separate patches(Ville Syrjälä)
    - Removed part of unneeded copy-paste from tgl_check_pipe_fits_sagv_wm
      (Ville Syrjälä)
    - Now using simple assignment for sagv_wm0 as it contains only
      pod types and no pointers(Ville Syrjälä)
    - Fixed intel_can_enable_sagv not to do double duty, now it only
      check SAGV bits by ANDing those between local and global state.
      The SAGV masks are now computed after watermarks are available,
      in order to be able to figure out if ddb ranges are fitting nicely.
      (Ville Syrjälä)
    - Now having uv_sagv_wm0 and sagv_wm0, otherwise we have wrong logic
      when using skl_plane_wm_level accessor, as we had previously for
      Gen11+ color plane and regular wm levels, so probably both
      has to be recalculated with additional SAGV block time for Level 0.

v10: - Starting to use new global state for storing pipe_sagv_mask

v11: - Fixed rebase conflict with recent drm-tip
     - Check if we really need to recalculate SAGV mask, otherwise
       bail out without making any changes.
     - Use cached SAGV result, instead of recalculating it everytime,
       if bw_state hasn't changed.

v12: - Removed WARN from intel_can_enable_sagv, in some of the commits
       if we don't recalculated watermarks, bw_state is not recalculated,
       thus leading to SAGV state not recalculated by the commit state,
       which is still calling intel_can_enable_sagv function. Fix that
       by just analyzing the current global bw_state object - because
       we simply have no other objects related to that.

v13: - Rebased, fixed warnings regarding long lines
     - Changed function call sites from intel_atomic_bw* to
       intel_wb_* as was suggested.(Jani Nikula)
     - Taken ddb_state_changed and bw_state_changed into use.

v14: - total_affected_planes is no longer needed to check for ddb changes,
       just as active_pipe_changes.

v15: - Fixed stupid mistake with uninitialized crtc in
       skl_compute_sagv_mask.

v16: - Convert pipe_sagv_mask to pipe_sagv_reject and now using inverted
       flag to indicate SAGV readiness for the pipe(Ville Syrjälä)
     - Added return value to intel_compute_sagv_mask which call
       intel_atomic_serialize_global_state in order to properly
       propagate EDEADLCK to drm.
     - Based on the discussion with Ville, removed active_pipe_changes
       check and also there seems to be no need for checking
       ddb_state_changes as well.
       Instead we just iterate through crtcs in state - having
       crtc in a state already guarantees that it is at least read-locked
       Having additional flag to check if there actually were some plane
       wm/ddb changes would be probably added later as an optimization.
     - We can't get parent atomic state from crtc_state at commit stage
       (nice drm feature), also propagating state through function call
       chain seems to be overkill and not possible(cursor legacy updates)
       Querying for bw_state object from global state is not possible as
       it might get swapped with other global state.
       So... just sticked can_sagv boolean into wm crtc state.

v17: - Skip inactive crtcs, when checking for SAGV-readiness.

v18: - Switch to use intel_atomic_crtc_state_for_each_plane_state
       instead of for_each_intel_plane_on_crtc and fixed previous
       code, which was using old plane state, which caused NULL ptr
       dereference, bacause that code is now called before we swap the
       state.

v19: - Use intel_atomic_bw_* pattern again
     - Optimized sagv checks in verify_wm_state(Ville Syrjälä)
     - Do intel_compute_sagv_mask after ddb is allocated(Ville Syrjälä),
       using it's results
     - Use bw_state in intel_can_enable_sagv
     - Use COLOR_PLANE enum instead of boolean yuv or "0", "1" magic
     - Extracted sagv wm0 calculation into separate skl_compute_sagv_wm
       function(Ville Syrjälä)

v20: - Added check for NULL for bw_state in commit_tail
     - Removed long comments and warns(Ville)
     - Extracted if ladder from compute_sagv(Ville)
     - Removed some debugs(Ville)
     - Extracted sagv_wm0 init from the loop in skl_pipe_wm_get_hw_state
       (Ville)
     - Now printing sagv_wm0 separately(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.h       |   6 +
 drivers/gpu/drm/i915/display/intel_display.c  |  28 ++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 179 ++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.h               |   4 +-
 5 files changed, 196 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index ac004d6f4276..d6df91058223 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -18,6 +18,12 @@ struct intel_crtc_state;
 struct intel_bw_state {
 	struct intel_global_state base;
 
+	/*
+	 * Contains a bit mask, used to determine, whether correspondent
+	 * pipe allows SAGV or not.
+	 */
+	u8 pipe_sagv_reject;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e630429af2c0..a601177b21ab 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14009,7 +14009,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -14064,7 +14066,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -15535,6 +15539,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
+
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
@@ -15543,8 +15548,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * SKL workaround: bspec recommends we disable the SAGV when we
 		 * have more then one pipe enabled
 		 */
-		if (!intel_can_enable_sagv(state))
-			intel_disable_sagv(dev_priv);
+		if (INTEL_GEN(dev_priv) < 11) {
+			const struct intel_bw_state *bw_state =
+				intel_atomic_get_new_bw_state(state);
+
+			if (bw_state && !intel_can_enable_sagv(bw_state))
+				intel_disable_sagv(dev_priv);
+		}
 
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
@@ -15644,8 +15654,14 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	if (state->modeset)
 		intel_verify_planes(state);
 
-	if (state->modeset && intel_can_enable_sagv(state))
-		intel_enable_sagv(dev_priv);
+	if (INTEL_GEN(dev_priv) < 11) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_new_bw_state(state);
+
+		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state))
+			intel_enable_sagv(dev_priv);
+	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 523e0444b373..51fa5a746a5f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -679,6 +679,8 @@ struct skl_plane_wm {
 	struct skl_wm_level wm[8];
 	struct skl_wm_level uv_wm[8];
 	struct skl_wm_level trans_wm;
+	struct skl_wm_level sagv_wm0;
+	struct skl_wm_level uv_sagv_wm0;
 	bool is_planar;
 };
 
@@ -689,6 +691,7 @@ enum color_plane {
 
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
+	bool can_sagv;
 };
 
 enum vlv_wm_level {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 27d4d626cb34..994c6dc0fa4f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -43,6 +43,7 @@
 #include "i915_fixed.h"
 #include "i915_irq.h"
 #include "i915_trace.h"
+#include "display/intel_bw.h"
 #include "intel_pm.h"
 #include "intel_sideband.h"
 #include "../../../platform/x86/intel_ips.h"
@@ -3634,7 +3635,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
 	return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv);
 }
 
-static bool
+bool
 intel_has_sagv(struct drm_i915_private *dev_priv)
 {
 	/* HACK! */
@@ -3824,29 +3825,88 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 	return icl_crtc_can_enable_sagv(crtc_state);
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool
+tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state);
+
+bool intel_can_enable_sagv(const struct intel_bw_state *bw_state)
+{
+	return bw_state->pipe_sagv_reject == 0;
+}
+
+bool intel_can_enable_sagv_on_pipe(const struct intel_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
+	bool res;
+
+	if (INTEL_GEN(dev_priv) >= 12)
+		res = tgl_crtc_can_enable_sagv(new_crtc_state);
+	else if (INTEL_GEN(dev_priv) >= 11)
+		res = icl_crtc_can_enable_sagv(new_crtc_state);
+	else
+		res = skl_crtc_can_enable_sagv(new_crtc_state);
+
+	return res;
+}
+
+static int intel_compute_sagv_mask(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
 	struct intel_crtc *crtc;
-	const struct intel_crtc_state *crtc_state;
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_bw_state *new_bw_state = NULL;
+	const struct intel_bw_state *old_bw_state = NULL;
 	int i;
+	bool can_sagv;
 
 	if (!intel_has_sagv(dev_priv))
-		return false;
+		return 0;
 
-	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		bool can_sagv;
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
 
-		if (INTEL_GEN(dev_priv) >= 11)
-			can_sagv = icl_crtc_can_enable_sagv(crtc_state);
+		new_bw_state = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state))
+			return PTR_ERR(new_bw_state);
+
+		old_bw_state = intel_atomic_get_old_bw_state(state);
+
+		if (intel_can_enable_sagv_on_pipe(new_crtc_state))
+			new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
 		else
-			can_sagv = skl_crtc_can_enable_sagv(crtc_state);
+			new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
+	}
 
-		if (!can_sagv)
-			return false;
+	if (!new_bw_state || !old_bw_state)
+		return 0;
+
+	can_sagv = new_bw_state->pipe_sagv_reject == 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
+
+		/*
+		 * Due to drm limitation at commit state, when
+		 * changes are written the whole atomic state is
+		 * zeroed away => which prevents from using it,
+		 * so just sticking it into pipe wm state for
+		 * keeping it simple - anyway this is related to wm.
+		 * Proper way in ideal universe would be of course not
+		 * to lose parent atomic state object from child crtc_state,
+		 * and stick to OOP programming principles, which had been
+		 * scientifically proven to work.
+		 */
+		pipe_wm->can_sagv = can_sagv;
 	}
 
-	return true;
+	if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 /*
@@ -4579,12 +4639,39 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
 		   int level,
 		   enum color_plane color_plane)
 {
-	const struct skl_plane_wm *wm =
-		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+	const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
+	if (!level) {
+		if (pipe_wm->can_sagv)
+			return color_plane == COLOR_PLANE_Y ? &wm->sagv_wm0 : &wm->uv_sagv_wm0;
+	}
 
 	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
 }
 
+static bool
+tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	enum plane_id plane_id;
+
+	if (!crtc_state->hw.active)
+		return true;
+
+	for_each_plane_id_on_crtc(crtc, plane_id) {
+		const struct skl_ddb_entry *plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_y[plane_id];
+		const struct skl_plane_wm *wm =
+			&crtc_state->wm.skl.optimal.planes[plane_id];
+
+		if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc)
+			return false;
+	}
+
+	return true;
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 {
@@ -5166,10 +5253,17 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 static void
 skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_wm_level *levels)
+		      struct skl_plane_wm *plane_wm,
+		      enum color_plane color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
+	/*
+	 * Check which kind of plane is it and based on that calculate
+	 * correspondent WM levels.
+	 */
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				      plane_wm->uv_wm : plane_wm->wm;
 	struct skl_wm_level *result_prev = &levels[0];
 
 	for (level = 0; level <= max_level; level++) {
@@ -5183,6 +5277,40 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 	}
 }
 
+static void skl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
+				const struct skl_wm_params *wm_params,
+				struct skl_plane_wm *plane_wm,
+				enum color_plane color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct skl_wm_level *sagv_wm = color_plane == COLOR_PLANE_UV ?
+				&plane_wm->uv_sagv_wm0 : &plane_wm->sagv_wm0;
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				plane_wm->uv_wm : plane_wm->wm;
+
+	/*
+	 * For Gen12 if it is an L0 we need to also
+	 * consider sagv_block_time when calculating
+	 * L0 watermark - we will need that when making
+	 * a decision whether enable SAGV or not.
+	 * For older gens we agreed to copy L0 value for
+	 * compatibility.
+	 */
+	if ((INTEL_GEN(dev_priv) >= 12)) {
+		u32 latency = dev_priv->wm.skl_latency[0];
+
+		latency += dev_priv->sagv_block_time_us;
+		skl_compute_plane_wm(crtc_state, 0, latency,
+				     wm_params, &levels[0],
+				     sagv_wm);
+		DRM_DEBUG_KMS("%d L0 blocks required for SAGV vs %d for non-SAGV\n",
+			      sagv_wm->min_ddb_alloc, levels[0].min_ddb_alloc);
+	} else {
+		/* Since all members are POD */
+		*sagv_wm = levels[0];
+	}
+}
+
 static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 				      const struct skl_wm_params *wp,
 				      struct skl_plane_wm *wm)
@@ -5263,7 +5391,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
 	skl_compute_transition_wm(crtc_state, &wm_params, wm);
 
 	return 0;
@@ -5285,7 +5414,8 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
 
 	return 0;
 }
@@ -5699,6 +5829,14 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
 				    new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
 				    new_wm->trans_wm.min_ddb_alloc);
+
+			drm_dbg_kms(&dev_priv->drm,
+				    "[PLANE:%d:%s] sagv wm0 min ddb %4d blocks %4d lines %4d\n"
+				    "-> min_ddb %4d blocks %4d lines %4d\n",
+				    plane->base.base.id, plane->base.name, old_wm->sagv_wm0.min_ddb_alloc,
+				    old_wm->sagv_wm0.plane_res_b, old_wm->sagv_wm0.plane_res_l,
+				    new_wm->sagv_wm0.min_ddb_alloc, new_wm->sagv_wm0.plane_res_b,
+				    new_wm->sagv_wm0.plane_res_l);
 		}
 	}
 }
@@ -5859,6 +5997,10 @@ skl_compute_wm(struct intel_atomic_state *state)
 	if (ret)
 		return ret;
 
+	ret = intel_compute_sagv_mask(state);
+	if (ret)
+		return ret;
+
 	/*
 	 * skl_compute_ddb() will have adjusted the final watermarks
 	 * based on how much ddb is available. Now we can actually
@@ -5988,6 +6130,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			skl_wm_level_from_reg_val(val, &wm->wm[level]);
 		}
 
+		memcpy(&wm->sagv_wm0, &wm->wm[0],
+		       sizeof(struct skl_wm_level));
+
 		if (plane_id != PLANE_CURSOR)
 			val = I915_READ(PLANE_WM_TRANS(pipe, plane_id));
 		else
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index d60a85421c5a..e41637b3a05d 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 
 #include "i915_reg.h"
+#include "display/intel_bw.h"
 
 struct drm_device;
 struct drm_i915_private;
@@ -41,7 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
-bool intel_can_enable_sagv(struct intel_atomic_state *state);
+bool intel_has_sagv(struct drm_i915_private *dev_priv);
+bool intel_can_enable_sagv(const struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
 int intel_disable_sagv(struct drm_i915_private *dev_priv);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 07/10] drm/i915: Added required new PCode commands
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands Stanislav Lisovskiy
  2020-04-02 17:27   ` Ville Syrjälä
@ 2020-04-03  6:32   ` Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:32 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We need a new PCode request commands and reply codes
to be added as a prepartion patch for QGV points
restricting for new SAGV support.

v2: - Extracted those changes into separate patch
      (Ville Syrjälä)

v3: - Moved new PCode masks to another place from
      PCode commands(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h       | 5 +++++
 drivers/gpu/drm/i915/intel_sideband.c | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9c53fe918be6..db38aee0a977 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8994,6 +8994,7 @@ enum {
 #define     GEN7_PCODE_ILLEGAL_DATA		0x3
 #define     GEN11_PCODE_ILLEGAL_SUBCOMMAND	0x4
 #define     GEN11_PCODE_LOCKED			0x6
+#define     GEN11_PCODE_REJECTED		0x11
 #define     GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10
 #define   GEN6_PCODE_WRITE_RC6VIDS		0x4
 #define   GEN6_PCODE_READ_RC6VIDS		0x5
@@ -9015,6 +9016,7 @@ enum {
 #define   ICL_PCODE_MEM_SUBSYSYSTEM_INFO	0xd
 #define     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO	(0x0 << 8)
 #define     ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point)	(((point) << 16) | (0x1 << 8))
+#define   ICL_PCODE_SAGV_DE_MEM_SS_CONFIG	0xe
 #define   GEN6_PCODE_READ_D_COMP		0x10
 #define   GEN6_PCODE_WRITE_D_COMP		0x11
 #define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
@@ -9043,6 +9045,9 @@ enum {
 #define GEN8_GT_SLICE_INFO		_MMIO(0x138064)
 #define   GEN8_LSLICESTAT_MASK		0x7
 
+#define GEN11_PCODE_POINTS_RESTRICTED		0x0
+#define GEN11_PCODE_POINTS_RESTRICTED_MASK	0x1
+
 #define CHV_POWER_SS0_SIG1		_MMIO(0xa720)
 #define CHV_POWER_SS1_SIG1		_MMIO(0xa728)
 #define   CHV_SS_PG_ENABLE		(1 << 1)
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 1447e7516cb7..1e7dd6b6f103 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -370,6 +370,8 @@ static inline int gen7_check_mailbox_status(u32 mbox)
 		return -ENXIO;
 	case GEN11_PCODE_LOCKED:
 		return -EBUSY;
+	case GEN11_PCODE_REJECTED:
+		return -EACCES;
 	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
 		return -EOVERFLOW;
 	default:
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 08/10] drm/i915: Rename bw_state to new_bw_state
  2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state Stanislav Lisovskiy
  2020-04-02 17:30   ` Ville Syrjälä
@ 2020-04-03  6:34   ` Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:34 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

That is a preparation patch before next one where we
introduce old_bw_state and a bunch of other changes
as well.
In a review comment it was suggested to split out
at least that renaming into a separate patch, what
is done here.

v2: Removed spurious space

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index d5f5c2f49af2..3c279e0ae1d7 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -417,7 +417,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
-	struct intel_bw_state *bw_state = NULL;
+	struct intel_bw_state *new_bw_state = NULL;
 	unsigned int data_rate, max_data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
@@ -446,29 +446,29 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		    old_active_planes == new_active_planes)
 			continue;
 
-		bw_state  = intel_atomic_get_bw_state(state);
-		if (IS_ERR(bw_state))
-			return PTR_ERR(bw_state);
+		new_bw_state = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state))
+			return PTR_ERR(new_bw_state);
 
-		bw_state->data_rate[crtc->pipe] = new_data_rate;
-		bw_state->num_active_planes[crtc->pipe] = new_active_planes;
+		new_bw_state->data_rate[crtc->pipe] = new_data_rate;
+		new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
 
 		drm_dbg_kms(&dev_priv->drm,
 			    "pipe %c data rate %u num active planes %u\n",
 			    pipe_name(crtc->pipe),
-			    bw_state->data_rate[crtc->pipe],
-			    bw_state->num_active_planes[crtc->pipe]);
+			    new_bw_state->data_rate[crtc->pipe],
+			    new_bw_state->num_active_planes[crtc->pipe]);
 	}
 
-	if (!bw_state)
+	if (!new_bw_state)
 		return 0;
 
-	ret = intel_atomic_lock_global_state(&bw_state->base);
+	ret = intel_atomic_lock_global_state(&new_bw_state->base);
 	if (ret)
 		return ret;
 
-	data_rate = intel_bw_data_rate(dev_priv, bw_state);
-	num_active_planes = intel_bw_num_active_planes(dev_priv, bw_state);
+	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
 	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
 
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth.
  2020-03-26 18:36   ` Stanislav Lisovskiy
  2020-04-02 17:50     ` Ville Syrjälä
@ 2020-04-03  6:37     ` Stanislav Lisovskiy
  2020-04-03 16:41       ` Stanislav Lisovskiy
  1 sibling, 1 reply; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03  6:37 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.

Currently we are just comparing against all of
those and take minimum(worst case).

v2: Fixed wrong PCode reply mask, removed hardcoded
    values.

v3: Forbid simultaneous legacy SAGV PCode requests and
    restricting qgv points. Put the actual restriction
    to commit function, added serialization(thanks to Ville)
    to prevent commit being applied out of order in case of
    nonblocking and/or nomodeset commits.

v4:
    - Minor code refactoring, fixed few typos(thanks to James Ausmus)
    - Change the naming of qgv point
      masking/unmasking functions(James Ausmus).
    - Simplify the masking/unmasking operation itself,
      as we don't need to mask only single point per request(James Ausmus)
    - Reject and stick to highest bandwidth point if SAGV
      can't be enabled(BSpec)

v5:
    - Add new mailbox reply codes, which seems to happen during boot
      time for TGL and indicate that QGV setting is not yet available.

v6:
    - Increase number of supported QGV points to be in sync with BSpec.

v7: - Rebased and resolved conflict to fix build failure.
    - Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)

v8: - Don't report an error if we can't restrict qgv points, as SAGV
      can be disabled by BIOS, which is completely legal. So don't
      make CI panic. Instead if we detect that there is only 1 QGV
      point accessible just analyze if we can fit the required bandwidth
      requirements, but no need in restricting.

v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
      simultaneously.

v10: - Fix CDCLK corruption, because of global state getting serialized
       without modeset, which caused copying of non-calculated cdclk
       to be copied to dev_priv(thanks to Ville for the hint).

v11: - Remove unneeded headers and spaces(Matthew Roper)
     - Remove unneeded intel_qgv_info qi struct from bw check and zero
       out the needed one(Matthew Roper)
     - Changed QGV error message to have more clear meaning(Matthew Roper)
     - Use state->modeset_set instead of any_ms(Matthew Roper)
     - Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
     - Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
     - Moved unrelated changes to other patch(using latency as parameter
       for plane wm calculation, moved to SAGV refactoring patch)

v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
     - Remove unnecessary mask being zero check when unmasking
       qgv points as this is completely legal(Matt Roper)
     - Check if we are setting the same mask as already being set
       in hardware to prevent error from PCode.
     - Fix error message when restricting/unrestricting qgv points
       to "mask/unmask" which sounds more accurate(Matt Roper)
     - Move sagv status setting to icl_get_bw_info from atomic check
       as this should be calculated only once.(Matt Roper)
     - Edited comments for the case when we can't enable SAGV and
       use only 1 QGV point with highest bandwidth to be more
       understandable.(Matt Roper)

v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
     - Changed comment for zero new_mask in qgv points masking function
       to better reflect reality(Ville Syrjälä)
     - Simplified bit mask operation in qgv points masking function
       (Ville Syrjälä)
     - Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
       however this still can't be under modeset condition(Ville Syrjälä)
     - Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
       (Ville Syrjälä)
     - Extracted PCode changes to separate patch.(Ville Syrjälä)
     - Now treat num_planes 0 same as 1 to avoid confusion and
       returning max_bw as 0, which would prevent choosing QGV
       point having max bandwidth in case if SAGV is not allowed,
       as per BSpec(Ville Syrjälä)
     - Do the actual qgv_points_mask swap in the same place as
       all other global state parts like cdclk are swapped.
       In the next patch, this all will be moved to bw state as
       global state, once new global state patch series from Ville
       lands

v14: - Now using global state to serialize access to qgv points
     - Added global state locking back, otherwise we seem to read
       bw state in a wrong way.

v15: - Added TODO comment for near atomic global state locking in
       bw code.

v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
       with Jani Nikula.
     - Take bw_state_changed flag into use.

v17: - Moved qgv point related manipulations next to SAGV code, as
       those are semantically related(Ville Syrjälä)
     - Renamed those into intel_sagv_(pre)|(post)_plane_update
       (Ville Syrjälä)

v18: - Move sagv related calls from commit tail into
       intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)

v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
       for commit tail stage.

v20: - Return max bandwidth for 0 planes(Ville)
     - Constify old_bw_state in bw_atomic_check(Ville)
     - Removed some debugs(Ville)
     - Added data rate to debug print when no QGV points(Ville)
     - Removed some comments(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c       | 139 +++++++++++++-----
 drivers/gpu/drm/i915/display/intel_bw.h       |   9 ++
 drivers/gpu/drm/i915/display/intel_display.c  |  24 +--
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 107 ++++++++++++++
 drivers/gpu/drm/i915/intel_pm.h               |   2 +
 6 files changed, 229 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 3c279e0ae1d7..39f3ed510107 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -8,6 +8,9 @@
 #include "intel_bw.h"
 #include "intel_display_types.h"
 #include "intel_sideband.h"
+#include "intel_atomic.h"
+#include "intel_pm.h"
+
 
 /* Parameters for Qclk Geyserville (QGV) */
 struct intel_qgv_point {
@@ -113,6 +116,26 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask)
+{
+	int ret;
+
+	/* bspec says to keep retrying for at least 1 ms */
+	ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
+				points_mask,
+				GEN11_PCODE_POINTS_RESTRICTED_MASK,
+				GEN11_PCODE_POINTS_RESTRICTED,
+				1);
+
+	if (ret < 0) {
+		DRM_ERROR("Failed to disable qgv points (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 			      struct intel_qgv_info *qi)
 {
@@ -240,6 +263,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
 			break;
 	}
 
+	/*
+	 * In case if SAGV is disabled in BIOS, we always get 1
+	 * SAGV point, but we can't send PCode commands to restrict it
+	 * as it will fail and pointless anyway.
+	 */
+	if (qi.num_points == 1)
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+	else
+		dev_priv->sagv_status = I915_SAGV_ENABLED;
+
 	return 0;
 }
 
@@ -248,6 +281,11 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
 {
 	int i;
 
+	/*
+	 * Let's return max bw for 0 planes
+	 */
+	num_planes = max(1, num_planes);
+
 	for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
 		const struct intel_bw_info *bi =
 			&dev_priv->max_bw[i];
@@ -277,34 +315,6 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 		icl_get_bw_info(dev_priv, &icl_sa_info);
 }
 
-static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
-					int num_planes)
-{
-	if (INTEL_GEN(dev_priv) >= 11) {
-		/*
-		 * Any bw group has same amount of QGV points
-		 */
-		const struct intel_bw_info *bi =
-			&dev_priv->max_bw[0];
-		unsigned int min_bw = UINT_MAX;
-		int i;
-
-		/*
-		 * FIXME with SAGV disabled maybe we can assume
-		 * point 1 will always be used? Seems to match
-		 * the behaviour observed in the wild.
-		 */
-		for (i = 0; i < bi->num_qgv_points; i++) {
-			unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
-
-			min_bw = min(bw, min_bw);
-		}
-		return min_bw;
-	} else {
-		return UINT_MAX;
-	}
-}
-
 static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
 {
 	/*
@@ -418,10 +428,15 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_bw_state *new_bw_state = NULL;
-	unsigned int data_rate, max_data_rate;
+	const struct intel_bw_state *old_bw_state = NULL;
+	unsigned int data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
 	int i, ret;
+	u32 allowed_points = 0;
+	unsigned int max_bw_point = 0, max_bw = 0;
+	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
+	u32 mask = (1 << num_qgv_points) - 1;
 
 	/* FIXME earlier gens need some checks too */
 	if (INTEL_GEN(dev_priv) < 11)
@@ -468,19 +483,73 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		return ret;
 
 	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	data_rate = DIV_ROUND_UP(data_rate, 1000);
+
 	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
-	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
+	for (i = 0; i < num_qgv_points; i++) {
+		unsigned int max_data_rate;
 
-	data_rate = DIV_ROUND_UP(data_rate, 1000);
+		max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
+		/*
+		 * We need to know which qgv point gives us
+		 * maximum bandwidth in order to disable SAGV
+		 * if we find that we exceed SAGV block time
+		 * with watermarks. By that moment we already
+		 * have those, as it is calculated earlier in
+		 * intel_atomic_check,
+		 */
+		if (max_data_rate > max_bw) {
+			max_bw_point = i;
+			max_bw = max_data_rate;
+		}
+		if (max_data_rate >= data_rate)
+			allowed_points |= BIT(i);
+		DRM_DEBUG_KMS("QGV point %d: max bw %d required %d\n",
+			      i, max_data_rate, data_rate);
+	}
 
-	if (data_rate > max_data_rate) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
-			    data_rate, max_data_rate, num_active_planes);
+	/*
+	 * BSpec states that we always should have at least one allowed point
+	 * left, so if we couldn't - simply reject the configuration for obvious
+	 * reasons.
+	 */
+	if (allowed_points == 0) {
+		DRM_DEBUG_KMS("No QGV points provide sufficient memory"
+			      " bandwidth %d for display configuration.\n", data_rate);
 		return -EINVAL;
 	}
 
+	/*
+	 * Leave only single point with highest bandwidth, if
+	 * we can't enable SAGV due to the increased memory latency it may
+	 * cause.
+	 */
+	if (!intel_can_enable_sagv(new_bw_state)) {
+		allowed_points = BIT(max_bw_point);
+		DRM_DEBUG_KMS("No SAGV, using single QGV point %d\n",
+			      max_bw_point);
+	}
+	/*
+	 * We store the ones which need to be masked as that is what PCode
+	 * actually accepts as a parameter.
+	 */
+	new_bw_state->qgv_points_mask = (~allowed_points) & mask;
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return -EINVAL;
+
+	/*
+	 * If the actual mask had changed we need to make sure that
+	 * the commits are serialized(in case this is a nomodeset, nonblocking)
+	 */
+	if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index d6df91058223..ecc086e1f30f 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,13 @@ struct intel_bw_state {
 	 */
 	u8 pipe_sagv_reject;
 
+	/*
+	 * Current QGV points mask, which restricts
+	 * some particular SAGV states, not to confuse
+	 * with pipe_sagv_mask.
+	 */
+	u8 qgv_points_mask;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
@@ -44,5 +51,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state);
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask);
 
 #endif /* __INTEL_BW_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index a601177b21ab..6a29d1673de4 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -15540,22 +15540,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 
 	if (state->modeset) {
 
+		intel_sagv_pre_plane_update(state);
+
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
 
-		/*
-		 * SKL workaround: bspec recommends we disable the SAGV when we
-		 * have more then one pipe enabled
-		 */
-		if (INTEL_GEN(dev_priv) < 11) {
-			const struct intel_bw_state *bw_state =
-				intel_atomic_get_new_bw_state(state);
-
-			if (bw_state && !intel_can_enable_sagv(bw_state))
-				intel_disable_sagv(dev_priv);
-		}
-
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
 
@@ -15651,16 +15641,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	intel_check_cpu_fifo_underruns(dev_priv);
 	intel_check_pch_fifo_underruns(dev_priv);
 
-	if (state->modeset)
+	if (state->modeset) {
 		intel_verify_planes(state);
 
-	if (INTEL_GEN(dev_priv) < 11) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_new_bw_state(state);
-
-		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state))
-			intel_enable_sagv(dev_priv);
+		intel_sagv_post_plane_update(state);
 	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 51fa5a746a5f..8655038bafe7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -689,6 +689,9 @@ enum color_plane {
 	COLOR_PLANE_UV
 };
 
+/* BSpec precisely defines this */
+#define NUM_SAGV_POINTS 8
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 	bool can_sagv;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 994c6dc0fa4f..6517b32f1b23 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3758,6 +3758,113 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_new_bw_state(state);
+	if (!new_bw_state)
+		return;
+
+	if (INTEL_GEN(dev_priv) < 11 && !intel_can_enable_sagv(new_bw_state)) {
+		intel_disable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return;
+
+	/*
+	 * Nothing to mask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
+
+	/*
+	 * If new mask is zero - means there is nothing to mask,
+	 * we can only unmask, which should be done in unmask.
+	 */
+	if (!new_mask)
+		return;
+
+	/*
+	 * Restrict required qgv points before updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		drm_err(&dev_priv->drm, "Could not mask required qgv points(%d)\n", ret);
+}
+
+void intel_sagv_post_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_new_bw_state(state);
+	if (!new_bw_state)
+		return;
+
+	if (INTEL_GEN(dev_priv) < 11 && intel_can_enable_sagv(new_bw_state)) {
+		intel_enable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return;
+
+	/*
+	 * Nothing to unmask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = new_bw_state->qgv_points_mask;
+
+	/*
+	 * Allow required qgv points after updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		drm_err(&dev_priv->drm, "Could not unmask required qgv points(%d)\n", ret);
+}
+
 static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index e41637b3a05d..ebeb28879d78 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -42,6 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
+void intel_sagv_post_plane_update(struct intel_atomic_state *state);
 bool intel_has_sagv(struct drm_i915_private *dev_priv);
 bool intel_can_enable_sagv(const struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev10)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (14 preceding siblings ...)
  2020-04-03  6:22 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev5) Patchwork
@ 2020-04-03  6:50 ` Patchwork
  2020-04-03  6:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03  6:50 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev10)
URL   : https://patchwork.freedesktop.org/series/75129/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
39ffd9923dd5 drm/i915: Start passing latency as parameter
a35112134535 drm/i915: Eliminate magic numbers "0" and "1" from color plane
-:118: WARNING:LONG_LINE: line over 100 characters
#118: FILE: drivers/gpu/drm/i915/intel_pm.c:4541:
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);

total: 0 errors, 1 warnings, 0 checks, 163 lines checked
94034283d7ed drm/i915: Introduce skl_plane_wm_level accessor.
5fc52d157ac3 drm/i915: Add intel_atomic_get_bw_*_state helpers
cd2178aba4dc drm/i915: Extract gen specific functions from intel_can_enable_sagv
0e0085943e7f drm/i915: Add proper SAGV support for TGL+
-:209: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#209: FILE: drivers/gpu/drm/i915/display/intel_display.c:15452:
 	if (state->modeset) {
+

-:518: WARNING:LONG_LINE: line over 100 characters
#518: FILE: drivers/gpu/drm/i915/intel_pm.c:5836:
+				    plane->base.base.id, plane->base.name, old_wm->sagv_wm0.min_ddb_alloc,

total: 0 errors, 1 warnings, 1 checks, 365 lines checked
239a48d2167c drm/i915: Added required new PCode commands
ff752f1ff8c0 drm/i915: Rename bw_state to new_bw_state
9e821cd38de0 drm/i915: Restrict qgv points which don't have enough bandwidth.
1ba579e5a9a2 drm/i915: Enable SAGV support for Gen12

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for SAGV support for Gen12+ (rev10)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (15 preceding siblings ...)
  2020-04-03  6:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev10) Patchwork
@ 2020-04-03  6:54 ` Patchwork
  2020-04-03  7:16 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03  6:54 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev10)
URL   : https://patchwork.freedesktop.org/series/75129/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.6.0
Commit: drm/i915: Start passing latency as parameter
Okay!

Commit: drm/i915: Eliminate magic numbers "0" and "1" from color plane
Okay!

Commit: drm/i915: Introduce skl_plane_wm_level accessor.
Okay!

Commit: drm/i915: Add intel_atomic_get_bw_*_state helpers
Okay!

Commit: drm/i915: Extract gen specific functions from intel_can_enable_sagv
Okay!

Commit: drm/i915: Add proper SAGV support for TGL+
+drivers/gpu/drm/i915/intel_pm.c:3836:6: warning: symbol 'intel_can_enable_sagv_on_pipe' was not declared. Should it be static?

Commit: drm/i915: Added required new PCode commands
Okay!

Commit: drm/i915: Rename bw_state to new_bw_state
Okay!

Commit: drm/i915: Restrict qgv points which don't have enough bandwidth.
Okay!

Commit: drm/i915: Enable SAGV support for Gen12
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for SAGV support for Gen12+ (rev10)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (16 preceding siblings ...)
  2020-04-03  6:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-04-03  7:16 ` Patchwork
  2020-04-03 16:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev12) Patchwork
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03  7:16 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev10)
URL   : https://patchwork.freedesktop.org/series/75129/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8243 -> Patchwork_17194
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_17194:

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * {igt@gem_wait@busy@all}:
    - fi-gdg-551:         [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/fi-gdg-551/igt@gem_wait@busy@all.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/fi-gdg-551/igt@gem_wait@busy@all.html

  
Known issues
------------

  Here are the changes found in Patchwork_17194 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@dp-crc-fast:
    - fi-cml-u2:          [PASS][3] -> [FAIL][4] ([i915#262])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/fi-cml-u2/igt@kms_chamelium@dp-crc-fast.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/fi-cml-u2/igt@kms_chamelium@dp-crc-fast.html

  
#### Possible fixes ####

  * igt@i915_pm_rpm@module-reload:
    - fi-icl-dsi:         [INCOMPLETE][5] ([i915#189]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/fi-icl-dsi/igt@i915_pm_rpm@module-reload.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/fi-icl-dsi/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@execlists:
    - fi-bxt-dsi:         [INCOMPLETE][7] ([i915#656]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/fi-bxt-dsi/igt@i915_selftest@live@execlists.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/fi-bxt-dsi/igt@i915_selftest@live@execlists.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [i915#189]: https://gitlab.freedesktop.org/drm/intel/issues/189
  [i915#262]: https://gitlab.freedesktop.org/drm/intel/issues/262
  [i915#656]: https://gitlab.freedesktop.org/drm/intel/issues/656


Participating hosts (41 -> 38)
------------------------------

  Additional (4): fi-cfl-8109u fi-byt-n2820 fi-bwr-2160 fi-snb-2520m 
  Missing    (7): fi-hsw-4200u fi-byt-j1900 fi-byt-squawks fi-bsw-cyan fi-kbl-7500u fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8243 -> Patchwork_17194

  CI-20190529: 20190529
  CI_DRM_8243: 45ccb1b8606b6ba1a5d4f8a8b4dda27bd8dbb04c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5560: 213062c7dcf0cbc8069cbb5f91acbc494def33fd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17194: 1ba579e5a9a2d41717a5666c74ed5444f2c6b73f @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

1ba579e5a9a2 drm/i915: Enable SAGV support for Gen12
9e821cd38de0 drm/i915: Restrict qgv points which don't have enough bandwidth.
ff752f1ff8c0 drm/i915: Rename bw_state to new_bw_state
239a48d2167c drm/i915: Added required new PCode commands
0e0085943e7f drm/i915: Add proper SAGV support for TGL+
cd2178aba4dc drm/i915: Extract gen specific functions from intel_can_enable_sagv
5fc52d157ac3 drm/i915: Add intel_atomic_get_bw_*_state helpers
94034283d7ed drm/i915: Introduce skl_plane_wm_level accessor.
a35112134535 drm/i915: Eliminate magic numbers "0" and "1" from color plane
39ffd9923dd5 drm/i915: Start passing latency as parameter

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane
  2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane Stanislav Lisovskiy
  2020-04-02 16:17   ` Ville Syrjälä
@ 2020-04-03 15:41   ` Stanislav Lisovskiy
  1 sibling, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03 15:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to many computer science sources - magic values
in code _are_ _bad_. For many reasons: the reason is that "0"
or "1" or whatever magic values confuses and doesn't give any
info why this parameter is this value and what it's meaning
is.
I renamed "0" to COLOR_PLANE_Y and "1" to COLOR_PLANE_UV,
because we in fact already use this naming in many other places
and function names, when dealing with color planes.

v2: Removed long line to make checkpatch happy.

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  5 +++
 drivers/gpu/drm/i915/intel_pm.c               | 42 ++++++++++---------
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 176ab5f1e867..523e0444b373 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -682,6 +682,11 @@ struct skl_plane_wm {
 	bool is_planar;
 };
 
+enum color_plane {
+	COLOR_PLANE_Y,
+	COLOR_PLANE_UV
+};
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 };
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b632b6bb9c3e..176a28d71822 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4013,7 +4013,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 				 int width, const struct drm_format_info *format,
 				 u64 modifier, unsigned int rotation,
 				 u32 plane_pixel_rate, struct skl_wm_params *wp,
-				 int color_plane);
+				 enum color_plane);
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
 				 unsigned int latency,
@@ -4035,7 +4035,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 				    drm_format_info(DRM_FORMAT_ARGB8888),
 				    DRM_FORMAT_MOD_LINEAR,
 				    DRM_MODE_ROTATE_0,
-				    crtc_state->pixel_rate, &wp, 0);
+				    crtc_state->pixel_rate, &wp, COLOR_PLANE_Y);
 	drm_WARN_ON(&dev_priv->drm, ret);
 
 	for (level = 0; level <= max_level; level++) {
@@ -4431,7 +4431,7 @@ static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
 static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 			     const struct intel_plane_state *plane_state,
-			     int color_plane)
+			     enum color_plane color_plane)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	const struct drm_framebuffer *fb = plane_state->hw.fb;
@@ -4446,7 +4446,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 	if (plane->id == PLANE_CURSOR)
 		return 0;
 
-	if (color_plane == 1 &&
+	if (color_plane == COLOR_PLANE_UV &&
 	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
 		return 0;
 
@@ -4459,7 +4459,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 	height = drm_rect_height(&plane_state->uapi.src) >> 16;
 
 	/* UV plane does 1/2 pixel sub-sampling */
-	if (color_plane == 1) {
+	if (color_plane == COLOR_PLANE_UV) {
 		width /= 2;
 		height /= 2;
 	}
@@ -4489,12 +4489,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		u64 rate;
 
 		/* packed/y */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
 		plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 
 		/* uv-plane */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_UV);
 		uv_plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 	}
@@ -4516,7 +4516,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		u64 rate;
 
 		if (!plane_state->planar_linked_plane) {
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state, COLOR_PLANE_Y);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
 		} else {
@@ -4533,12 +4533,14 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				continue;
 
 			/* Y plane rate is calculated on the slave */
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state,
+							    COLOR_PLANE_Y);
 			y_plane_id = plane_state->planar_linked_plane->id;
 			plane_data_rate[y_plane_id] = rate;
 			total_data_rate += rate;
 
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+			rate = skl_plane_relative_data_rate(crtc_state, plane_state,
+							    COLOR_PLANE_UV);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
 		}
@@ -4854,14 +4856,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 		      int width, const struct drm_format_info *format,
 		      u64 modifier, unsigned int rotation,
 		      u32 plane_pixel_rate, struct skl_wm_params *wp,
-		      int color_plane)
+		      enum color_plane color_plane)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 interm_pbpl;
 
 	/* only planar format has two planes */
-	if (color_plane == 1 &&
+	if (color_plane == COLOR_PLANE_UV &&
 	    !intel_format_info_is_yuv_semiplanar(format, modifier)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "Non planar format have single plane\n");
@@ -4878,7 +4880,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
 
 	wp->width = width;
-	if (color_plane == 1 && wp->is_planar)
+	if (color_plane == COLOR_PLANE_UV && wp->is_planar)
 		wp->width /= 2;
 
 	wp->cpp = format->cpp[color_plane];
@@ -4945,7 +4947,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 static int
 skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
 			    const struct intel_plane_state *plane_state,
-			    struct skl_wm_params *wp, int color_plane)
+			    struct skl_wm_params *wp, enum color_plane color_plane)
 {
 	const struct drm_framebuffer *fb = plane_state->hw.fb;
 	int width;
@@ -5187,7 +5189,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 
 static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 				     const struct intel_plane_state *plane_state,
-				     enum plane_id plane_id, int color_plane)
+				     enum plane_id plane_id, enum color_plane color_plane)
 {
 	struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
 	struct skl_wm_params wm_params;
@@ -5216,7 +5218,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 
 	/* uv plane watermarks must also be validated for NV12/Planar */
 	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
-					  &wm_params, 1);
+					  &wm_params, COLOR_PLANE_UV);
 	if (ret)
 		return ret;
 
@@ -5237,7 +5239,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	ret = skl_build_plane_wm_single(crtc_state, plane_state,
-					plane_id, 0);
+					plane_id, COLOR_PLANE_Y);
 	if (ret)
 		return ret;
 
@@ -5270,17 +5272,17 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 			fb->format->num_planes == 1);
 
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						y_plane_id, 0);
+						y_plane_id, COLOR_PLANE_Y);
 		if (ret)
 			return ret;
 
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 1);
+						plane_id, COLOR_PLANE_UV);
 		if (ret)
 			return ret;
 	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
 		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 0);
+						plane_id, COLOR_PLANE_Y);
 		if (ret)
 			return ret;
 	}
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 06/10] drm/i915: Add proper SAGV support for TGL+
  2020-04-03  6:29     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
@ 2020-04-03 15:43       ` Stanislav Lisovskiy
  0 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03 15:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Let's refactor the whole SAGV logic, moving
the main calculations from intel_can_enable_sagv
to intel_compute_sagv_mask, which also handles
this in a unified way calling gen specific
functions to evaluate if SAGV is allowed for
each crtc. If crtc sagv mask have been changed
we serialize access and modify global state.

intel_can_enable_sagv now uses bw_state which
stores all information related to SAGV and
is now a trivial helper.

v2:
    - Rework watermark calculation algorithm to
      attempt to calculate Level 0 watermark
      with added sagv block time latency and
      check if it fits in DBuf in order to
      determine if SAGV can be enabled already
      at this stage, just as BSpec 49325 states.
      if that fails rollback to usual Level 0
      latency and disable SAGV.
    - Remove unneeded tabs(James Ausmus)

v3: Rebased the patch

v4: - Added back interlaced check for Gen12 and
      added separate function for TGL SAGV check
      (thanks to James Ausmus for spotting)
    - Removed unneeded gen check
    - Extracted Gen12 SAGV decision making code
      to a separate function from skl_compute_wm

v5: - Added SAGV global state to dev_priv, because
      we need to track all pipes, not only those
      in atomic state. Each pipe has now correspondent
      bit mask reflecting, whether it can tolerate
      SAGV or not(thanks to Ville Syrjala for suggestions).
    - Now using active flag instead of enable in crc
      usage check.

v6: - Fixed rebase conflicts

v7: - kms_cursor_legacy seems to get broken because of multiple memcpy
      calls when copying level 0 water marks for enabled SAGV, to
      fix this now simply using that field right away, without copying,
      for that introduced a new wm_level accessor which decides which
      wm_level to return based on SAGV state.

v8: - Protect crtc_sagv_mask same way as we do for other global state
      changes: i.e check if changes are needed, then grab all crtc locks
      to serialize the changes(Ville Syrjälä)
    - Add crtc_sagv_mask caching in order to avoid needless recalculations
      (Matthew Roper)
    - Put back Gen12 SAGV switch in order to get it enabled in separate
      patch(Matthew Roper)
    - Rename *_set_sagv_mask to *_compute_sagv_mask(Matthew Roper)
    - Check if there are no active pipes in intel_can_enable_sagv
      instead of platform specific functions(Matthew Roper), same
      for intel_has_sagv check.

v9  - Switched to u8 for crtc_sagv_mask(Ville Syrjälä)
    - crtc_sagv_mask now is pipe_sagv_mask(Ville Syrjälä)
    - Extracted sagv checking logic from skl/icl/tgl_compute_sagv_mask
    - Extracted skl_plane_wm_level function and passing latency to
      separate patches(Ville Syrjälä)
    - Removed part of unneeded copy-paste from tgl_check_pipe_fits_sagv_wm
      (Ville Syrjälä)
    - Now using simple assignment for sagv_wm0 as it contains only
      pod types and no pointers(Ville Syrjälä)
    - Fixed intel_can_enable_sagv not to do double duty, now it only
      check SAGV bits by ANDing those between local and global state.
      The SAGV masks are now computed after watermarks are available,
      in order to be able to figure out if ddb ranges are fitting nicely.
      (Ville Syrjälä)
    - Now having uv_sagv_wm0 and sagv_wm0, otherwise we have wrong logic
      when using skl_plane_wm_level accessor, as we had previously for
      Gen11+ color plane and regular wm levels, so probably both
      has to be recalculated with additional SAGV block time for Level 0.

v10: - Starting to use new global state for storing pipe_sagv_mask

v11: - Fixed rebase conflict with recent drm-tip
     - Check if we really need to recalculate SAGV mask, otherwise
       bail out without making any changes.
     - Use cached SAGV result, instead of recalculating it everytime,
       if bw_state hasn't changed.

v12: - Removed WARN from intel_can_enable_sagv, in some of the commits
       if we don't recalculated watermarks, bw_state is not recalculated,
       thus leading to SAGV state not recalculated by the commit state,
       which is still calling intel_can_enable_sagv function. Fix that
       by just analyzing the current global bw_state object - because
       we simply have no other objects related to that.

v13: - Rebased, fixed warnings regarding long lines
     - Changed function call sites from intel_atomic_bw* to
       intel_wb_* as was suggested.(Jani Nikula)
     - Taken ddb_state_changed and bw_state_changed into use.

v14: - total_affected_planes is no longer needed to check for ddb changes,
       just as active_pipe_changes.

v15: - Fixed stupid mistake with uninitialized crtc in
       skl_compute_sagv_mask.

v16: - Convert pipe_sagv_mask to pipe_sagv_reject and now using inverted
       flag to indicate SAGV readiness for the pipe(Ville Syrjälä)
     - Added return value to intel_compute_sagv_mask which call
       intel_atomic_serialize_global_state in order to properly
       propagate EDEADLCK to drm.
     - Based on the discussion with Ville, removed active_pipe_changes
       check and also there seems to be no need for checking
       ddb_state_changes as well.
       Instead we just iterate through crtcs in state - having
       crtc in a state already guarantees that it is at least read-locked
       Having additional flag to check if there actually were some plane
       wm/ddb changes would be probably added later as an optimization.
     - We can't get parent atomic state from crtc_state at commit stage
       (nice drm feature), also propagating state through function call
       chain seems to be overkill and not possible(cursor legacy updates)
       Querying for bw_state object from global state is not possible as
       it might get swapped with other global state.
       So... just sticked can_sagv boolean into wm crtc state.

v17: - Skip inactive crtcs, when checking for SAGV-readiness.

v18: - Switch to use intel_atomic_crtc_state_for_each_plane_state
       instead of for_each_intel_plane_on_crtc and fixed previous
       code, which was using old plane state, which caused NULL ptr
       dereference, bacause that code is now called before we swap the
       state.

v19: - Use intel_atomic_bw_* pattern again
     - Optimized sagv checks in verify_wm_state(Ville Syrjälä)
     - Do intel_compute_sagv_mask after ddb is allocated(Ville Syrjälä),
       using it's results
     - Use bw_state in intel_can_enable_sagv
     - Use COLOR_PLANE enum instead of boolean yuv or "0", "1" magic
     - Extracted sagv wm0 calculation into separate skl_compute_sagv_wm
       function(Ville Syrjälä)

v20: - Added check for NULL for bw_state in commit_tail
     - Removed long comments and warns(Ville)
     - Extracted if ladder from compute_sagv(Ville)
     - Removed some debugs(Ville)
     - Extracted sagv_wm0 init from the loop in skl_pipe_wm_get_hw_state
       (Ville)
     - Now printing sagv_wm0 separately(Ville)

v21: - Fix some nitpicks to make checkpatch happy

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.h       |   6 +
 drivers/gpu/drm/i915/display/intel_display.c  |  27 ++-
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 179 ++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.h               |   4 +-
 5 files changed, 195 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index ac004d6f4276..d6df91058223 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -18,6 +18,12 @@ struct intel_crtc_state;
 struct intel_bw_state {
 	struct intel_global_state base;
 
+	/*
+	 * Contains a bit mask, used to determine, whether correspondent
+	 * pipe allows SAGV or not.
+	 */
+	u8 pipe_sagv_reject;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e630429af2c0..a8a36407ab96 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14009,7 +14009,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -14064,7 +14066,9 @@ static void verify_wm_state(struct intel_crtc *crtc,
 		/* Watermarks */
 		for (level = 0; level <= max_level; level++) {
 			if (skl_wm_level_equals(&hw_plane_wm->wm[level],
-						&sw_plane_wm->wm[level]))
+						&sw_plane_wm->wm[level]) ||
+			    (level == 0 && skl_wm_level_equals(&hw_plane_wm->wm[level],
+							       &sw_plane_wm->sagv_wm0)))
 				continue;
 
 			drm_err(&dev_priv->drm,
@@ -15543,8 +15547,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * SKL workaround: bspec recommends we disable the SAGV when we
 		 * have more then one pipe enabled
 		 */
-		if (!intel_can_enable_sagv(state))
-			intel_disable_sagv(dev_priv);
+		if (INTEL_GEN(dev_priv) < 11) {
+			const struct intel_bw_state *bw_state =
+				intel_atomic_get_new_bw_state(state);
+
+			if (bw_state && !intel_can_enable_sagv(bw_state))
+				intel_disable_sagv(dev_priv);
+		}
 
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
@@ -15644,8 +15653,14 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	if (state->modeset)
 		intel_verify_planes(state);
 
-	if (state->modeset && intel_can_enable_sagv(state))
-		intel_enable_sagv(dev_priv);
+	if (INTEL_GEN(dev_priv) < 11) {
+		struct intel_bw_state *bw_state;
+
+		bw_state = intel_atomic_get_new_bw_state(state);
+
+		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state))
+			intel_enable_sagv(dev_priv);
+	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 523e0444b373..51fa5a746a5f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -679,6 +679,8 @@ struct skl_plane_wm {
 	struct skl_wm_level wm[8];
 	struct skl_wm_level uv_wm[8];
 	struct skl_wm_level trans_wm;
+	struct skl_wm_level sagv_wm0;
+	struct skl_wm_level uv_sagv_wm0;
 	bool is_planar;
 };
 
@@ -689,6 +691,7 @@ enum color_plane {
 
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
+	bool can_sagv;
 };
 
 enum vlv_wm_level {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e1217867dbdc..177d7ecb0cdd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -43,6 +43,7 @@
 #include "i915_fixed.h"
 #include "i915_irq.h"
 #include "i915_trace.h"
+#include "display/intel_bw.h"
 #include "intel_pm.h"
 #include "intel_sideband.h"
 #include "../../../platform/x86/intel_ips.h"
@@ -3634,7 +3635,7 @@ static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv)
 	return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv);
 }
 
-static bool
+bool
 intel_has_sagv(struct drm_i915_private *dev_priv)
 {
 	/* HACK! */
@@ -3824,29 +3825,88 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 	return icl_crtc_can_enable_sagv(crtc_state);
 }
 
-bool intel_can_enable_sagv(struct intel_atomic_state *state)
+static bool
+tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state);
+
+bool intel_can_enable_sagv(const struct intel_bw_state *bw_state)
+{
+	return bw_state->pipe_sagv_reject == 0;
+}
+
+static bool intel_can_enable_sagv_on_pipe(const struct intel_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
+	bool res;
+
+	if (INTEL_GEN(dev_priv) >= 12)
+		res = tgl_crtc_can_enable_sagv(new_crtc_state);
+	else if (INTEL_GEN(dev_priv) >= 11)
+		res = icl_crtc_can_enable_sagv(new_crtc_state);
+	else
+		res = skl_crtc_can_enable_sagv(new_crtc_state);
+
+	return res;
+}
+
+static int intel_compute_sagv_mask(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
 	struct intel_crtc *crtc;
-	const struct intel_crtc_state *crtc_state;
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_bw_state *new_bw_state = NULL;
+	const struct intel_bw_state *old_bw_state = NULL;
 	int i;
+	bool can_sagv;
 
 	if (!intel_has_sagv(dev_priv))
-		return false;
+		return 0;
 
-	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		bool can_sagv;
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
 
-		if (INTEL_GEN(dev_priv) >= 11)
-			can_sagv = icl_crtc_can_enable_sagv(crtc_state);
+		new_bw_state = intel_atomic_get_bw_state(state);
+		if (IS_ERR(new_bw_state))
+			return PTR_ERR(new_bw_state);
+
+		old_bw_state = intel_atomic_get_old_bw_state(state);
+
+		if (intel_can_enable_sagv_on_pipe(new_crtc_state))
+			new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
 		else
-			can_sagv = skl_crtc_can_enable_sagv(crtc_state);
+			new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
+	}
 
-		if (!can_sagv)
-			return false;
+	if (!new_bw_state || !old_bw_state)
+		return 0;
+
+	can_sagv = new_bw_state->pipe_sagv_reject == 0;
+
+	for_each_new_intel_crtc_in_state(state, crtc,
+					 new_crtc_state, i) {
+		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
+
+		/*
+		 * Due to drm limitation at commit state, when
+		 * changes are written the whole atomic state is
+		 * zeroed away => which prevents from using it,
+		 * so just sticking it into pipe wm state for
+		 * keeping it simple - anyway this is related to wm.
+		 * Proper way in ideal universe would be of course not
+		 * to lose parent atomic state object from child crtc_state,
+		 * and stick to OOP programming principles, which had been
+		 * scientifically proven to work.
+		 */
+		pipe_wm->can_sagv = can_sagv;
 	}
 
-	return true;
+	if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 /*
@@ -4581,12 +4641,39 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
 		   int level,
 		   enum color_plane color_plane)
 {
-	const struct skl_plane_wm *wm =
-		&crtc_state->wm.skl.optimal.planes[plane_id];
+	const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+	const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
+	if (!level) {
+		if (pipe_wm->can_sagv)
+			return color_plane == COLOR_PLANE_Y ? &wm->sagv_wm0 : &wm->uv_sagv_wm0;
+	}
 
 	return color_plane == COLOR_PLANE_Y ? &wm->wm[level] : &wm->uv_wm[level];
 }
 
+static bool
+tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	enum plane_id plane_id;
+
+	if (!crtc_state->hw.active)
+		return true;
+
+	for_each_plane_id_on_crtc(crtc, plane_id) {
+		const struct skl_ddb_entry *plane_alloc =
+			&crtc_state->wm.skl.plane_ddb_y[plane_id];
+		const struct skl_plane_wm *wm =
+			&crtc_state->wm.skl.optimal.planes[plane_id];
+
+		if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc)
+			return false;
+	}
+
+	return true;
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
 {
@@ -5168,10 +5255,17 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 static void
 skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 		      const struct skl_wm_params *wm_params,
-		      struct skl_wm_level *levels)
+		      struct skl_plane_wm *plane_wm,
+		      enum color_plane color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
+	/*
+	 * Check which kind of plane is it and based on that calculate
+	 * correspondent WM levels.
+	 */
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				      plane_wm->uv_wm : plane_wm->wm;
 	struct skl_wm_level *result_prev = &levels[0];
 
 	for (level = 0; level <= max_level; level++) {
@@ -5185,6 +5279,40 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 	}
 }
 
+static void skl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
+				const struct skl_wm_params *wm_params,
+				struct skl_plane_wm *plane_wm,
+				enum color_plane color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct skl_wm_level *sagv_wm = color_plane == COLOR_PLANE_UV ?
+				&plane_wm->uv_sagv_wm0 : &plane_wm->sagv_wm0;
+	struct skl_wm_level *levels = color_plane == COLOR_PLANE_UV ?
+				plane_wm->uv_wm : plane_wm->wm;
+
+	/*
+	 * For Gen12 if it is an L0 we need to also
+	 * consider sagv_block_time when calculating
+	 * L0 watermark - we will need that when making
+	 * a decision whether enable SAGV or not.
+	 * For older gens we agreed to copy L0 value for
+	 * compatibility.
+	 */
+	if ((INTEL_GEN(dev_priv) >= 12)) {
+		u32 latency = dev_priv->wm.skl_latency[0];
+
+		latency += dev_priv->sagv_block_time_us;
+		skl_compute_plane_wm(crtc_state, 0, latency,
+				     wm_params, &levels[0],
+				     sagv_wm);
+		DRM_DEBUG_KMS("%d L0 blocks required for SAGV vs %d for non-SAGV\n",
+			      sagv_wm->min_ddb_alloc, levels[0].min_ddb_alloc);
+	} else {
+		/* Since all members are POD */
+		*sagv_wm = levels[0];
+	}
+}
+
 static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 				      const struct skl_wm_params *wp,
 				      struct skl_plane_wm *wm)
@@ -5265,7 +5393,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_Y);
 	skl_compute_transition_wm(crtc_state, &wm_params, wm);
 
 	return 0;
@@ -5287,7 +5416,8 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm);
+	skl_compute_wm_levels(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
+	skl_compute_sagv_wm(crtc_state, &wm_params, wm, COLOR_PLANE_UV);
 
 	return 0;
 }
@@ -5701,6 +5831,14 @@ skl_print_wm_changes(struct intel_atomic_state *state)
 				    new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
 				    new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
 				    new_wm->trans_wm.min_ddb_alloc);
+
+			drm_dbg_kms(&dev_priv->drm,
+				    "[PLANE:%d:%s] sagv wm0 min ddb %4d blocks %4d lines %4d\n"
+				    "-> min_ddb %4d blocks %4d lines %4d\n",
+				    plane->base.base.id, plane->base.name, old_wm->sagv_wm0.min_ddb_alloc,
+				    old_wm->sagv_wm0.plane_res_b, old_wm->sagv_wm0.plane_res_l,
+				    new_wm->sagv_wm0.min_ddb_alloc, new_wm->sagv_wm0.plane_res_b,
+				    new_wm->sagv_wm0.plane_res_l);
 		}
 	}
 }
@@ -5861,6 +5999,10 @@ skl_compute_wm(struct intel_atomic_state *state)
 	if (ret)
 		return ret;
 
+	ret = intel_compute_sagv_mask(state);
+	if (ret)
+		return ret;
+
 	/*
 	 * skl_compute_ddb() will have adjusted the final watermarks
 	 * based on how much ddb is available. Now we can actually
@@ -5990,6 +6132,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			skl_wm_level_from_reg_val(val, &wm->wm[level]);
 		}
 
+		memcpy(&wm->sagv_wm0, &wm->wm[0],
+		       sizeof(struct skl_wm_level));
+
 		if (plane_id != PLANE_CURSOR)
 			val = I915_READ(PLANE_WM_TRANS(pipe, plane_id));
 		else
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index d60a85421c5a..e41637b3a05d 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 
 #include "i915_reg.h"
+#include "display/intel_bw.h"
 
 struct drm_device;
 struct drm_i915_private;
@@ -41,7 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
-bool intel_can_enable_sagv(struct intel_atomic_state *state);
+bool intel_has_sagv(struct drm_i915_private *dev_priv);
+bool intel_can_enable_sagv(const struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
 int intel_disable_sagv(struct drm_i915_private *dev_priv);
 bool skl_wm_level_equals(const struct skl_wm_level *l1,
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev12)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (17 preceding siblings ...)
  2020-04-03  7:16 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-04-03 16:29 ` Patchwork
  2020-04-03 16:40 ` [Intel-gfx] ✗ Fi.CI.IGT: failure for SAGV support for Gen12+ (rev10) Patchwork
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03 16:29 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev12)
URL   : https://patchwork.freedesktop.org/series/75129/
State : failure

== Summary ==

Applying: drm/i915: Start passing latency as parameter
Applying: drm/i915: Eliminate magic numbers "0" and "1" from color plane
Applying: drm/i915: Introduce skl_plane_wm_level accessor.
Applying: drm/i915: Add intel_atomic_get_bw_*_state helpers
Applying: drm/i915: Extract gen specific functions from intel_can_enable_sagv
Applying: drm/i915: Add proper SAGV support for TGL+
Applying: drm/i915: Added required new PCode commands
Applying: drm/i915: Rename bw_state to new_bw_state
Applying: drm/i915: Restrict qgv points which don't have enough bandwidth.
error: sha1 information is lacking or useless (drivers/gpu/drm/i915/display/intel_display.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0009 drm/i915: Restrict qgv points which don't have enough bandwidth.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.IGT: failure for SAGV support for Gen12+ (rev10)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (18 preceding siblings ...)
  2020-04-03 16:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev12) Patchwork
@ 2020-04-03 16:40 ` Patchwork
  2020-04-03 17:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev13) Patchwork
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03 16:40 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev10)
URL   : https://patchwork.freedesktop.org/series/75129/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_8243_full -> Patchwork_17194_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_17194_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_17194_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_17194_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_mmap_gtt@cpuset-medium-copy-xy:
    - shard-apl:          [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl7/igt@gem_mmap_gtt@cpuset-medium-copy-xy.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl2/igt@gem_mmap_gtt@cpuset-medium-copy-xy.html

  * igt@gem_mmap_gtt@hang:
    - shard-iclb:         [PASS][3] -> [FAIL][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb2/igt@gem_mmap_gtt@hang.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb7/igt@gem_mmap_gtt@hang.html

  
Known issues
------------

  Here are the changes found in Patchwork_17194_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][5] -> [SKIP][6] ([fdo#110854])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb4/igt@gem_exec_balancer@smoke.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb8/igt@gem_exec_balancer@smoke.html

  * igt@gem_tiled_swapping@non-threaded:
    - shard-apl:          [PASS][7] -> [FAIL][8] ([i915#95])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl2/igt@gem_tiled_swapping@non-threaded.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl6/igt@gem_tiled_swapping@non-threaded.html

  * igt@i915_selftest@live@requests:
    - shard-tglb:         [PASS][9] -> [INCOMPLETE][10] ([i915#1531])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-tglb3/igt@i915_selftest@live@requests.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-tglb7/igt@i915_selftest@live@requests.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-apl:          [PASS][11] -> [DMESG-WARN][12] ([i915#180]) +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl3/igt@kms_cursor_crc@pipe-a-cursor-suspend.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl1/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_draw_crc@draw-method-xrgb8888-mmap-gtt-untiled:
    - shard-apl:          [PASS][13] -> [FAIL][14] ([i915#52] / [i915#54] / [i915#95])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl4/igt@kms_draw_crc@draw-method-xrgb8888-mmap-gtt-untiled.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl3/igt@kms_draw_crc@draw-method-xrgb8888-mmap-gtt-untiled.html

  * igt@kms_flip@wf_vblank-ts-check:
    - shard-skl:          [PASS][15] -> [FAIL][16] ([i915#34])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl8/igt@kms_flip@wf_vblank-ts-check.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl2/igt@kms_flip@wf_vblank-ts-check.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [PASS][17] -> [FAIL][18] ([i915#1188])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl8/igt@kms_hdr@bpc-switch-dpms.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl2/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min:
    - shard-skl:          [PASS][19] -> [FAIL][20] ([fdo#108145] / [i915#265])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl5/igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl7/igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min.html

  * igt@kms_psr@psr2_sprite_blt:
    - shard-iclb:         [PASS][21] -> [SKIP][22] ([fdo#109441]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb2/igt@kms_psr@psr2_sprite_blt.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb7/igt@kms_psr@psr2_sprite_blt.html

  * igt@kms_setmode@basic:
    - shard-apl:          [PASS][23] -> [FAIL][24] ([i915#31])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl8/igt@kms_setmode@basic.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl7/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-c-query-forked-hang:
    - shard-glk:          [PASS][25] -> [INCOMPLETE][26] ([i915#58] / [k.org#198133])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-glk1/igt@kms_vblank@pipe-c-query-forked-hang.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-glk8/igt@kms_vblank@pipe-c-query-forked-hang.html

  * igt@prime_vgem@wait-bsd2:
    - shard-iclb:         [PASS][27] -> [SKIP][28] ([fdo#109276]) +4 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb2/igt@prime_vgem@wait-bsd2.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb5/igt@prime_vgem@wait-bsd2.html

  
#### Possible fixes ####

  * igt@gem_ctx_persistence@engines-mixed-process@vecs0:
    - shard-skl:          [FAIL][29] ([i915#1528]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl5/igt@gem_ctx_persistence@engines-mixed-process@vecs0.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl7/igt@gem_ctx_persistence@engines-mixed-process@vecs0.html

  * igt@gem_ctx_persistence@legacy-engines-mixed-process@blt:
    - shard-apl:          [FAIL][31] ([i915#1528]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl6/igt@gem_ctx_persistence@legacy-engines-mixed-process@blt.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl6/igt@gem_ctx_persistence@legacy-engines-mixed-process@blt.html

  * igt@gem_mmap_gtt@cpuset-basic-small-copy-odd:
    - shard-skl:          [FAIL][33] -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl5/igt@gem_mmap_gtt@cpuset-basic-small-copy-odd.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl7/igt@gem_mmap_gtt@cpuset-basic-small-copy-odd.html

  * igt@gem_tiled_swapping@non-threaded:
    - shard-hsw:          [FAIL][35] -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-hsw4/igt@gem_tiled_swapping@non-threaded.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-hsw4/igt@gem_tiled_swapping@non-threaded.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-hsw:          [FAIL][37] ([i915#1066]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-hsw6/igt@i915_pm_rc6_residency@rc6-idle.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-hsw1/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x64-onscreen:
    - shard-apl:          [FAIL][39] ([i915#54] / [i915#95]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl8/igt@kms_cursor_crc@pipe-a-cursor-64x64-onscreen.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl7/igt@kms_cursor_crc@pipe-a-cursor-64x64-onscreen.html

  * igt@kms_cursor_legacy@flip-vs-cursor-legacy:
    - shard-skl:          [FAIL][41] ([IGT#5]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl7/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl8/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html

  * igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled:
    - shard-glk:          [FAIL][43] ([i915#177] / [i915#52] / [i915#54]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-glk2/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-glk2/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-hsw:          [INCOMPLETE][45] ([i915#61]) -> [PASS][46] +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-hsw6/igt@kms_flip@flip-vs-suspend.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-hsw6/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-kbl:          [DMESG-WARN][47] ([i915#180]) -> [PASS][48] +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-kbl7/igt@kms_flip@flip-vs-suspend-interruptible.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-kbl1/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
    - shard-apl:          [DMESG-WARN][49] ([i915#180]) -> [PASS][50] +1 similar issue
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-apl1/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-apl4/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][51] ([fdo#108145] / [i915#265]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl5/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][53] ([fdo#109441]) -> [PASS][54] +3 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb8/igt@kms_psr@psr2_sprite_plane_move.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_psr@suspend:
    - shard-skl:          [INCOMPLETE][55] ([i915#198]) -> [PASS][56]
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-skl6/igt@kms_psr@suspend.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-skl5/igt@kms_psr@suspend.html

  * igt@kms_setmode@basic:
    - shard-hsw:          [FAIL][57] ([i915#31]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-hsw1/igt@kms_setmode@basic.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-hsw1/igt@kms_setmode@basic.html
    - shard-kbl:          [FAIL][59] ([i915#31]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-kbl4/igt@kms_setmode@basic.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-kbl7/igt@kms_setmode@basic.html

  * igt@prime_vgem@fence-wait-bsd2:
    - shard-iclb:         [SKIP][61] ([fdo#109276]) -> [PASS][62] +1 similar issue
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb6/igt@prime_vgem@fence-wait-bsd2.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb4/igt@prime_vgem@fence-wait-bsd2.html

  
#### Warnings ####

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         [SKIP][63] ([i915#658]) -> [SKIP][64] ([i915#588])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb3/igt@i915_pm_dc@dc3co-vpb-simulation.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [SKIP][65] ([fdo#109642] / [fdo#111068]) -> [FAIL][66] ([i915#608])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8243/shard-iclb8/igt@kms_psr2_su@page_flip.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/shard-iclb2/igt@kms_psr2_su@page_flip.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [IGT#5]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/5
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110854]: https://bugs.freedesktop.org/show_bug.cgi?id=110854
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [i915#1066]: https://gitlab.freedesktop.org/drm/intel/issues/1066
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1528]: https://gitlab.freedesktop.org/drm/intel/issues/1528
  [i915#1531]: https://gitlab.freedesktop.org/drm/intel/issues/1531
  [i915#177]: https://gitlab.freedesktop.org/drm/intel/issues/177
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
  [i915#34]: https://gitlab.freedesktop.org/drm/intel/issues/34
  [i915#52]: https://gitlab.freedesktop.org/drm/intel/issues/52
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#58]: https://gitlab.freedesktop.org/drm/intel/issues/58
  [i915#588]: https://gitlab.freedesktop.org/drm/intel/issues/588
  [i915#608]: https://gitlab.freedesktop.org/drm/intel/issues/608
  [i915#61]: https://gitlab.freedesktop.org/drm/intel/issues/61
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
  [k.org#198133]: https://bugzilla.kernel.org/show_bug.cgi?id=198133


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8243 -> Patchwork_17194

  CI-20190529: 20190529
  CI_DRM_8243: 45ccb1b8606b6ba1a5d4f8a8b4dda27bd8dbb04c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5560: 213062c7dcf0cbc8069cbb5f91acbc494def33fd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17194: 1ba579e5a9a2d41717a5666c74ed5444f2c6b73f @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17194/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] [PATCH v21 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth.
  2020-04-03  6:37     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
@ 2020-04-03 16:41       ` Stanislav Lisovskiy
  0 siblings, 0 replies; 52+ messages in thread
From: Stanislav Lisovskiy @ 2020-04-03 16:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.

Currently we are just comparing against all of
those and take minimum(worst case).

v2: Fixed wrong PCode reply mask, removed hardcoded
    values.

v3: Forbid simultaneous legacy SAGV PCode requests and
    restricting qgv points. Put the actual restriction
    to commit function, added serialization(thanks to Ville)
    to prevent commit being applied out of order in case of
    nonblocking and/or nomodeset commits.

v4:
    - Minor code refactoring, fixed few typos(thanks to James Ausmus)
    - Change the naming of qgv point
      masking/unmasking functions(James Ausmus).
    - Simplify the masking/unmasking operation itself,
      as we don't need to mask only single point per request(James Ausmus)
    - Reject and stick to highest bandwidth point if SAGV
      can't be enabled(BSpec)

v5:
    - Add new mailbox reply codes, which seems to happen during boot
      time for TGL and indicate that QGV setting is not yet available.

v6:
    - Increase number of supported QGV points to be in sync with BSpec.

v7: - Rebased and resolved conflict to fix build failure.
    - Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)

v8: - Don't report an error if we can't restrict qgv points, as SAGV
      can be disabled by BIOS, which is completely legal. So don't
      make CI panic. Instead if we detect that there is only 1 QGV
      point accessible just analyze if we can fit the required bandwidth
      requirements, but no need in restricting.

v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
      simultaneously.

v10: - Fix CDCLK corruption, because of global state getting serialized
       without modeset, which caused copying of non-calculated cdclk
       to be copied to dev_priv(thanks to Ville for the hint).

v11: - Remove unneeded headers and spaces(Matthew Roper)
     - Remove unneeded intel_qgv_info qi struct from bw check and zero
       out the needed one(Matthew Roper)
     - Changed QGV error message to have more clear meaning(Matthew Roper)
     - Use state->modeset_set instead of any_ms(Matthew Roper)
     - Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
     - Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
     - Moved unrelated changes to other patch(using latency as parameter
       for plane wm calculation, moved to SAGV refactoring patch)

v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
     - Remove unnecessary mask being zero check when unmasking
       qgv points as this is completely legal(Matt Roper)
     - Check if we are setting the same mask as already being set
       in hardware to prevent error from PCode.
     - Fix error message when restricting/unrestricting qgv points
       to "mask/unmask" which sounds more accurate(Matt Roper)
     - Move sagv status setting to icl_get_bw_info from atomic check
       as this should be calculated only once.(Matt Roper)
     - Edited comments for the case when we can't enable SAGV and
       use only 1 QGV point with highest bandwidth to be more
       understandable.(Matt Roper)

v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
     - Changed comment for zero new_mask in qgv points masking function
       to better reflect reality(Ville Syrjälä)
     - Simplified bit mask operation in qgv points masking function
       (Ville Syrjälä)
     - Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
       however this still can't be under modeset condition(Ville Syrjälä)
     - Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
       (Ville Syrjälä)
     - Extracted PCode changes to separate patch.(Ville Syrjälä)
     - Now treat num_planes 0 same as 1 to avoid confusion and
       returning max_bw as 0, which would prevent choosing QGV
       point having max bandwidth in case if SAGV is not allowed,
       as per BSpec(Ville Syrjälä)
     - Do the actual qgv_points_mask swap in the same place as
       all other global state parts like cdclk are swapped.
       In the next patch, this all will be moved to bw state as
       global state, once new global state patch series from Ville
       lands

v14: - Now using global state to serialize access to qgv points
     - Added global state locking back, otherwise we seem to read
       bw state in a wrong way.

v15: - Added TODO comment for near atomic global state locking in
       bw code.

v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
       with Jani Nikula.
     - Take bw_state_changed flag into use.

v17: - Moved qgv point related manipulations next to SAGV code, as
       those are semantically related(Ville Syrjälä)
     - Renamed those into intel_sagv_(pre)|(post)_plane_update
       (Ville Syrjälä)

v18: - Move sagv related calls from commit tail into
       intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)

v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
       for commit tail stage.

v20: - Return max bandwidth for 0 planes(Ville)
     - Constify old_bw_state in bw_atomic_check(Ville)
     - Removed some debugs(Ville)
     - Added data rate to debug print when no QGV points(Ville)
     - Removed some comments(Ville)

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c       | 139 +++++++++++++-----
 drivers/gpu/drm/i915/display/intel_bw.h       |   9 ++
 drivers/gpu/drm/i915/display/intel_display.c  |  24 +--
 .../drm/i915/display/intel_display_types.h    |   3 +
 drivers/gpu/drm/i915/intel_pm.c               | 107 ++++++++++++++
 drivers/gpu/drm/i915/intel_pm.h               |   2 +
 6 files changed, 229 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 3c279e0ae1d7..39f3ed510107 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -8,6 +8,9 @@
 #include "intel_bw.h"
 #include "intel_display_types.h"
 #include "intel_sideband.h"
+#include "intel_atomic.h"
+#include "intel_pm.h"
+
 
 /* Parameters for Qclk Geyserville (QGV) */
 struct intel_qgv_point {
@@ -113,6 +116,26 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask)
+{
+	int ret;
+
+	/* bspec says to keep retrying for at least 1 ms */
+	ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
+				points_mask,
+				GEN11_PCODE_POINTS_RESTRICTED_MASK,
+				GEN11_PCODE_POINTS_RESTRICTED,
+				1);
+
+	if (ret < 0) {
+		DRM_ERROR("Failed to disable qgv points (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 			      struct intel_qgv_info *qi)
 {
@@ -240,6 +263,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
 			break;
 	}
 
+	/*
+	 * In case if SAGV is disabled in BIOS, we always get 1
+	 * SAGV point, but we can't send PCode commands to restrict it
+	 * as it will fail and pointless anyway.
+	 */
+	if (qi.num_points == 1)
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+	else
+		dev_priv->sagv_status = I915_SAGV_ENABLED;
+
 	return 0;
 }
 
@@ -248,6 +281,11 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
 {
 	int i;
 
+	/*
+	 * Let's return max bw for 0 planes
+	 */
+	num_planes = max(1, num_planes);
+
 	for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
 		const struct intel_bw_info *bi =
 			&dev_priv->max_bw[i];
@@ -277,34 +315,6 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 		icl_get_bw_info(dev_priv, &icl_sa_info);
 }
 
-static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
-					int num_planes)
-{
-	if (INTEL_GEN(dev_priv) >= 11) {
-		/*
-		 * Any bw group has same amount of QGV points
-		 */
-		const struct intel_bw_info *bi =
-			&dev_priv->max_bw[0];
-		unsigned int min_bw = UINT_MAX;
-		int i;
-
-		/*
-		 * FIXME with SAGV disabled maybe we can assume
-		 * point 1 will always be used? Seems to match
-		 * the behaviour observed in the wild.
-		 */
-		for (i = 0; i < bi->num_qgv_points; i++) {
-			unsigned int bw = icl_max_bw(dev_priv, num_planes, i);
-
-			min_bw = min(bw, min_bw);
-		}
-		return min_bw;
-	} else {
-		return UINT_MAX;
-	}
-}
-
 static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
 {
 	/*
@@ -418,10 +428,15 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
 	struct intel_bw_state *new_bw_state = NULL;
-	unsigned int data_rate, max_data_rate;
+	const struct intel_bw_state *old_bw_state = NULL;
+	unsigned int data_rate;
 	unsigned int num_active_planes;
 	struct intel_crtc *crtc;
 	int i, ret;
+	u32 allowed_points = 0;
+	unsigned int max_bw_point = 0, max_bw = 0;
+	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
+	u32 mask = (1 << num_qgv_points) - 1;
 
 	/* FIXME earlier gens need some checks too */
 	if (INTEL_GEN(dev_priv) < 11)
@@ -468,19 +483,73 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
 		return ret;
 
 	data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
+	data_rate = DIV_ROUND_UP(data_rate, 1000);
+
 	num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
 
-	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
+	for (i = 0; i < num_qgv_points; i++) {
+		unsigned int max_data_rate;
 
-	data_rate = DIV_ROUND_UP(data_rate, 1000);
+		max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
+		/*
+		 * We need to know which qgv point gives us
+		 * maximum bandwidth in order to disable SAGV
+		 * if we find that we exceed SAGV block time
+		 * with watermarks. By that moment we already
+		 * have those, as it is calculated earlier in
+		 * intel_atomic_check,
+		 */
+		if (max_data_rate > max_bw) {
+			max_bw_point = i;
+			max_bw = max_data_rate;
+		}
+		if (max_data_rate >= data_rate)
+			allowed_points |= BIT(i);
+		DRM_DEBUG_KMS("QGV point %d: max bw %d required %d\n",
+			      i, max_data_rate, data_rate);
+	}
 
-	if (data_rate > max_data_rate) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
-			    data_rate, max_data_rate, num_active_planes);
+	/*
+	 * BSpec states that we always should have at least one allowed point
+	 * left, so if we couldn't - simply reject the configuration for obvious
+	 * reasons.
+	 */
+	if (allowed_points == 0) {
+		DRM_DEBUG_KMS("No QGV points provide sufficient memory"
+			      " bandwidth %d for display configuration.\n", data_rate);
 		return -EINVAL;
 	}
 
+	/*
+	 * Leave only single point with highest bandwidth, if
+	 * we can't enable SAGV due to the increased memory latency it may
+	 * cause.
+	 */
+	if (!intel_can_enable_sagv(new_bw_state)) {
+		allowed_points = BIT(max_bw_point);
+		DRM_DEBUG_KMS("No SAGV, using single QGV point %d\n",
+			      max_bw_point);
+	}
+	/*
+	 * We store the ones which need to be masked as that is what PCode
+	 * actually accepts as a parameter.
+	 */
+	new_bw_state->qgv_points_mask = (~allowed_points) & mask;
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return -EINVAL;
+
+	/*
+	 * If the actual mask had changed we need to make sure that
+	 * the commits are serialized(in case this is a nomodeset, nonblocking)
+	 */
+	if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
+		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index d6df91058223..ecc086e1f30f 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -24,6 +24,13 @@ struct intel_bw_state {
 	 */
 	u8 pipe_sagv_reject;
 
+	/*
+	 * Current QGV points mask, which restricts
+	 * some particular SAGV states, not to confuse
+	 * with pipe_sagv_mask.
+	 */
+	u8 qgv_points_mask;
+
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
 };
@@ -44,5 +51,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state);
+int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
+				  u32 points_mask);
 
 #endif /* __INTEL_BW_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 04d49a518652..03e965b28cd6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -15449,22 +15449,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		crtc->config = new_crtc_state;
 
 	if (state->modeset) {
+		intel_sagv_pre_plane_update(state);
+
 		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
 
 		intel_set_cdclk_pre_plane_update(state);
 
-		/*
-		 * SKL workaround: bspec recommends we disable the SAGV when we
-		 * have more then one pipe enabled
-		 */
-		if (INTEL_GEN(dev_priv) < 11) {
-			const struct intel_bw_state *bw_state =
-				intel_atomic_get_new_bw_state(state);
-
-			if (bw_state && !intel_can_enable_sagv(bw_state))
-				intel_disable_sagv(dev_priv);
-		}
-
 		intel_modeset_verify_disabled(dev_priv, state);
 	}
 
@@ -15560,16 +15550,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	intel_check_cpu_fifo_underruns(dev_priv);
 	intel_check_pch_fifo_underruns(dev_priv);
 
-	if (state->modeset)
+	if (state->modeset) {
 		intel_verify_planes(state);
 
-	if (INTEL_GEN(dev_priv) < 11) {
-		struct intel_bw_state *bw_state;
-
-		bw_state = intel_atomic_get_new_bw_state(state);
-
-		if (bw_state && state->modeset && intel_can_enable_sagv(bw_state))
-			intel_enable_sagv(dev_priv);
+		intel_sagv_post_plane_update(state);
 	}
 
 	drm_atomic_helper_commit_hw_done(&state->base);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 51fa5a746a5f..8655038bafe7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -689,6 +689,9 @@ enum color_plane {
 	COLOR_PLANE_UV
 };
 
+/* BSpec precisely defines this */
+#define NUM_SAGV_POINTS 8
+
 struct skl_pipe_wm {
 	struct skl_plane_wm planes[I915_MAX_PLANES];
 	bool can_sagv;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 177d7ecb0cdd..79c996a82ce7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3758,6 +3758,113 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_new_bw_state(state);
+	if (!new_bw_state)
+		return;
+
+	if (INTEL_GEN(dev_priv) < 11 && !intel_can_enable_sagv(new_bw_state)) {
+		intel_disable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return;
+
+	/*
+	 * Nothing to mask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
+
+	/*
+	 * If new mask is zero - means there is nothing to mask,
+	 * we can only unmask, which should be done in unmask.
+	 */
+	if (!new_mask)
+		return;
+
+	/*
+	 * Restrict required qgv points before updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		drm_err(&dev_priv->drm, "Could not mask required qgv points(%d)\n", ret);
+}
+
+void intel_sagv_post_plane_update(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	int ret;
+	struct intel_bw_state *new_bw_state = NULL;
+	struct intel_bw_state *old_bw_state = NULL;
+	u32 new_mask = 0;
+
+	/*
+	 * Just return if we can't control SAGV or don't have it.
+	 * This is different from situation when we have SAGV but just can't
+	 * afford it due to DBuf limitation - in case if SAGV is completely
+	 * disabled in a BIOS, we are not even allowed to send a PCode request,
+	 * as it will throw an error. So have to check it here.
+	 */
+	if (!intel_has_sagv(dev_priv))
+		return;
+
+	new_bw_state = intel_atomic_get_new_bw_state(state);
+	if (!new_bw_state)
+		return;
+
+	if (INTEL_GEN(dev_priv) < 11 && intel_can_enable_sagv(new_bw_state)) {
+		intel_enable_sagv(dev_priv);
+		return;
+	}
+
+	old_bw_state = intel_atomic_get_old_bw_state(state);
+	if (!old_bw_state)
+		return;
+
+	/*
+	 * Nothing to unmask
+	 */
+	if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
+		return;
+
+	new_mask = new_bw_state->qgv_points_mask;
+
+	/*
+	 * Allow required qgv points after updating the configuration.
+	 * According to BSpec we can't mask and unmask qgv points at the same
+	 * time. Also masking should be done before updating the configuration
+	 * and unmasking afterwards.
+	 */
+	ret = icl_pcode_restrict_qgv_points(dev_priv, new_mask);
+	if (ret < 0)
+		drm_err(&dev_priv->drm, "Could not unmask required qgv points(%d)\n", ret);
+}
+
 static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index e41637b3a05d..ebeb28879d78 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -42,6 +42,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
 			      struct skl_pipe_wm *out);
 void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
 void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
+void intel_sagv_post_plane_update(struct intel_atomic_state *state);
 bool intel_has_sagv(struct drm_i915_private *dev_priv);
 bool intel_can_enable_sagv(const struct intel_bw_state *bw_state);
 int intel_enable_sagv(struct drm_i915_private *dev_priv);
-- 
2.24.1.485.gad05a3d8e5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev13)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (19 preceding siblings ...)
  2020-04-03 16:40 ` [Intel-gfx] ✗ Fi.CI.IGT: failure for SAGV support for Gen12+ (rev10) Patchwork
@ 2020-04-03 17:05 ` Patchwork
  2020-04-03 17:29 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
  2020-04-04  2:33 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03 17:05 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev13)
URL   : https://patchwork.freedesktop.org/series/75129/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
f121c205f975 drm/i915: Start passing latency as parameter
2cb942fadfcf drm/i915: Eliminate magic numbers "0" and "1" from color plane
9fd3eb581b6a drm/i915: Introduce skl_plane_wm_level accessor.
32a8f02d9693 drm/i915: Add intel_atomic_get_bw_*_state helpers
b7d98af9e158 drm/i915: Extract gen specific functions from intel_can_enable_sagv
b493687dd5af drm/i915: Add proper SAGV support for TGL+
-:512: WARNING:LONG_LINE: line over 100 characters
#512: FILE: drivers/gpu/drm/i915/intel_pm.c:5838:
+				    plane->base.base.id, plane->base.name, old_wm->sagv_wm0.min_ddb_alloc,

total: 0 errors, 1 warnings, 0 checks, 358 lines checked
22bc551a31f5 drm/i915: Added required new PCode commands
86922c9a6deb drm/i915: Rename bw_state to new_bw_state
24c7d7d3c6b3 drm/i915: Restrict qgv points which don't have enough bandwidth.
893ba5a63c98 drm/i915: Enable SAGV support for Gen12

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for SAGV support for Gen12+ (rev13)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (20 preceding siblings ...)
  2020-04-03 17:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev13) Patchwork
@ 2020-04-03 17:29 ` Patchwork
  2020-04-04  2:33 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-03 17:29 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev13)
URL   : https://patchwork.freedesktop.org/series/75129/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8247 -> Patchwork_17204
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/index.html

Known issues
------------

  Here are the changes found in Patchwork_17204 that come from known issues:

### IGT changes ###

#### Possible fixes ####

  * igt@gem_tiled_fence_blits@basic:
    - fi-blb-e6850:       [DMESG-WARN][1] ([i915#1612]) -> [PASS][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-blb-e6850/igt@gem_tiled_fence_blits@basic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-blb-e6850/igt@gem_tiled_fence_blits@basic.html

  * igt@i915_module_load@reload:
    - fi-skl-6770hq:      [DMESG-WARN][3] ([i915#203]) -> [PASS][4] +1 similar issue
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-skl-6770hq/igt@i915_module_load@reload.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-skl-6770hq/igt@i915_module_load@reload.html

  * igt@i915_pm_rpm@basic-rte:
    - fi-icl-dsi:         [INCOMPLETE][5] ([i915#189]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-icl-dsi/igt@i915_pm_rpm@basic-rte.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-icl-dsi/igt@i915_pm_rpm@basic-rte.html

  * igt@i915_selftest@live@execlists:
    - fi-skl-guc:         [INCOMPLETE][7] ([i915#656]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-skl-guc/igt@i915_selftest@live@execlists.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-skl-guc/igt@i915_selftest@live@execlists.html

  * igt@kms_chamelium@dp-edid-read:
    - fi-cml-u2:          [FAIL][9] ([i915#976]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-cml-u2/igt@kms_chamelium@dp-edid-read.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-cml-u2/igt@kms_chamelium@dp-edid-read.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
    - fi-skl-6770hq:      [SKIP][11] ([fdo#109271]) -> [PASS][12] +4 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-skl-6770hq/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-skl-6770hq/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-c:
    - fi-skl-6770hq:      [DMESG-WARN][13] ([i915#106]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/fi-skl-6770hq/igt@kms_pipe_crc_basic@read-crc-pipe-c.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/fi-skl-6770hq/igt@kms_pipe_crc_basic@read-crc-pipe-c.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#106]: https://gitlab.freedesktop.org/drm/intel/issues/106
  [i915#1612]: https://gitlab.freedesktop.org/drm/intel/issues/1612
  [i915#189]: https://gitlab.freedesktop.org/drm/intel/issues/189
  [i915#203]: https://gitlab.freedesktop.org/drm/intel/issues/203
  [i915#656]: https://gitlab.freedesktop.org/drm/intel/issues/656
  [i915#976]: https://gitlab.freedesktop.org/drm/intel/issues/976


Participating hosts (51 -> 44)
------------------------------

  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-kbl-7560u fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8247 -> Patchwork_17204

  CI-20190529: 20190529
  CI_DRM_8247: 4ceaa00bfb032d9f29a485596fbc02fdeab06bc9 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5562: 4770480c8c1f105ff9225e8eb07b652ca954e06a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17204: 893ba5a63c98048f77ddbd19ba4f10d0bad98148 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

893ba5a63c98 drm/i915: Enable SAGV support for Gen12
24c7d7d3c6b3 drm/i915: Restrict qgv points which don't have enough bandwidth.
86922c9a6deb drm/i915: Rename bw_state to new_bw_state
22bc551a31f5 drm/i915: Added required new PCode commands
b493687dd5af drm/i915: Add proper SAGV support for TGL+
b7d98af9e158 drm/i915: Extract gen specific functions from intel_can_enable_sagv
32a8f02d9693 drm/i915: Add intel_atomic_get_bw_*_state helpers
9fd3eb581b6a drm/i915: Introduce skl_plane_wm_level accessor.
2cb942fadfcf drm/i915: Eliminate magic numbers "0" and "1" from color plane
f121c205f975 drm/i915: Start passing latency as parameter

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for SAGV support for Gen12+ (rev13)
  2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
                   ` (21 preceding siblings ...)
  2020-04-03 17:29 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-04-04  2:33 ` Patchwork
  22 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2020-04-04  2:33 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: intel-gfx

== Series Details ==

Series: SAGV support for Gen12+ (rev13)
URL   : https://patchwork.freedesktop.org/series/75129/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8247_full -> Patchwork_17204_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

New tests
---------

  New tests have been introduced between CI_DRM_8247_full and Patchwork_17204_full:

### New IGT tests (7) ###

  * igt@perf_pmu@faulting-read:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_busy@after:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_busy@after-wait:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_busy@before:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_busy@hang:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_busy@hang-wait:
    - Statuses :
    - Exec time: [None] s

  * igt@prime_vgem@busy:
    - Statuses :
    - Exec time: [None] s

  

Known issues
------------

  Here are the changes found in Patchwork_17204_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_tiled_swapping@non-threaded:
    - shard-snb:          [PASS][1] -> [FAIL][2] ([i915#1618])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-snb5/igt@gem_tiled_swapping@non-threaded.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-snb2/igt@gem_tiled_swapping@non-threaded.html

  * igt@gem_workarounds@suspend-resume:
    - shard-apl:          [PASS][3] -> [DMESG-WARN][4] ([i915#180]) +3 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-apl7/igt@gem_workarounds@suspend-resume.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-apl8/igt@gem_workarounds@suspend-resume.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-skl:          [PASS][5] -> [INCOMPLETE][6] ([i915#69])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl1/igt@gem_workarounds@suspend-resume-fd.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl5/igt@gem_workarounds@suspend-resume-fd.html

  * igt@kms_dp_dsc@basic-dsc-enable-edp:
    - shard-iclb:         [PASS][7] -> [SKIP][8] ([fdo#109349])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-iclb2/igt@kms_dp_dsc@basic-dsc-enable-edp.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-iclb7/igt@kms_dp_dsc@basic-dsc-enable-edp.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-skl:          [PASS][9] -> [FAIL][10] ([i915#1188]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl3/igt@kms_hdr@bpc-switch-suspend.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl5/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [PASS][11] -> [DMESG-WARN][12] ([i915#180]) +3 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-kbl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-kbl2/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [PASS][13] -> [FAIL][14] ([fdo#108145] / [i915#265])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl4/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl1/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [PASS][15] -> [SKIP][16] ([fdo#109441]) +2 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-iclb7/igt@kms_psr@psr2_sprite_plane_move.html

  
#### Possible fixes ####

  * igt@gem_mmap_gtt@hang:
    - shard-iclb:         [FAIL][17] ([i915#1621]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-iclb3/igt@gem_mmap_gtt@hang.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-iclb8/igt@gem_mmap_gtt@hang.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [DMESG-WARN][19] ([i915#180] / [i915#93] / [i915#95]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-kbl2/igt@gem_workarounds@suspend-resume-fd.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-kbl7/igt@gem_workarounds@suspend-resume-fd.html

  * igt@i915_selftest@live@execlists:
    - shard-tglb:         [INCOMPLETE][21] ([i915#647]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-tglb6/igt@i915_selftest@live@execlists.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-tglb6/igt@i915_selftest@live@execlists.html

  * igt@i915_suspend@debugfs-reader:
    - shard-kbl:          [DMESG-WARN][23] ([i915#180]) -> [PASS][24] +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-kbl1/igt@i915_suspend@debugfs-reader.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-kbl4/igt@i915_suspend@debugfs-reader.html

  * igt@kms_draw_crc@draw-method-rgb565-mmap-gtt-xtiled:
    - shard-glk:          [FAIL][25] ([i915#52] / [i915#54]) -> [PASS][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-glk8/igt@kms_draw_crc@draw-method-rgb565-mmap-gtt-xtiled.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-glk2/igt@kms_draw_crc@draw-method-rgb565-mmap-gtt-xtiled.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-skl:          [INCOMPLETE][27] ([i915#221]) -> [PASS][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl10/igt@kms_flip@flip-vs-suspend.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl3/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-apl:          [DMESG-WARN][29] ([i915#180]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible.html
    - shard-snb:          [INCOMPLETE][31] ([i915#82]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-snb1/igt@kms_flip@flip-vs-suspend-interruptible.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-snb6/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [FAIL][33] ([i915#1188]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl10/igt@kms_hdr@bpc-switch-dpms.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl4/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][35] ([fdo#108145] / [i915#265]) -> [PASS][36] +2 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-skl4/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-skl2/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_no_drrs:
    - shard-iclb:         [SKIP][37] ([fdo#109441]) -> [PASS][38] +2 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-iclb8/igt@kms_psr@psr2_no_drrs.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-iclb2/igt@kms_psr@psr2_no_drrs.html

  
#### Warnings ####

  * igt@i915_pm_dc@dc6-dpms:
    - shard-tglb:         [FAIL][39] ([i915#454]) -> [SKIP][40] ([i915#468])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-tglb3/igt@i915_pm_dc@dc6-dpms.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-tglb2/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_pm_rpm@gem-pread:
    - shard-snb:          [SKIP][41] ([fdo#109271]) -> [INCOMPLETE][42] ([i915#82])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8247/shard-snb2/igt@i915_pm_rpm@gem-pread.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/shard-snb4/igt@i915_pm_rpm@gem-pread.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109349]: https://bugs.freedesktop.org/show_bug.cgi?id=109349
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#1618]: https://gitlab.freedesktop.org/drm/intel/issues/1618
  [i915#1621]: https://gitlab.freedesktop.org/drm/intel/issues/1621
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#221]: https://gitlab.freedesktop.org/drm/intel/issues/221
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#468]: https://gitlab.freedesktop.org/drm/intel/issues/468
  [i915#52]: https://gitlab.freedesktop.org/drm/intel/issues/52
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#647]: https://gitlab.freedesktop.org/drm/intel/issues/647
  [i915#69]: https://gitlab.freedesktop.org/drm/intel/issues/69
  [i915#82]: https://gitlab.freedesktop.org/drm/intel/issues/82
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8247 -> Patchwork_17204

  CI-20190529: 20190529
  CI_DRM_8247: 4ceaa00bfb032d9f29a485596fbc02fdeab06bc9 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5562: 4770480c8c1f105ff9225e8eb07b652ca954e06a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17204: 893ba5a63c98048f77ddbd19ba4f10d0bad98148 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17204/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-03  6:20   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
@ 2020-04-07 19:01     ` Ville Syrjälä
  2020-04-08  7:58       ` Lisovskiy, Stanislav
  0 siblings, 1 reply; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-07 19:01 UTC (permalink / raw)
  To: Stanislav Lisovskiy; +Cc: jani.nikula, intel-gfx

On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> Addressing one of the comments, recommending to extract platform
> specific code from intel_can_enable_sagv as a preparation, before
> we are going to add support for tgl+.
> 
> Current code in intel_can_enable_sagv is valid only for skl,
> so this patch adds also proper support for icl, subsequent
> patches will add support for tgl+, combined with other required
> changes.
> 
> v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
>     - Removed dev variables(Ville)
>     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
>       function(Ville)
>     - Added hw.active check(Ville)
>     - Refactored if ladder(Ville)
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
>  1 file changed, 55 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f8d62d1977ac..27d4d626cb34 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
>  	return 0;
>  }
>  
> -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_device *dev = state->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *crtc;
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_plane *plane;
> -	struct intel_crtc_state *crtc_state;
> -	enum pipe pipe;
> +	const struct intel_plane_state *plane_state;
>  	int level, latency;
>  
> -	if (!intel_has_sagv(dev_priv))
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> +			      pipe_name(crtc->pipe));
>  		return false;
> +	}
>  
> -	/*
> -	 * If there are no active CRTCs, no additional checks need be performed
> -	 */
> -	if (hweight8(state->active_pipes) == 0)
> +	if (!crtc_state->hw.active)

Should really be checked before anything else. Doesn't matter too much
anymore since I made us clear the crtc state always, but still a bit
inconsistent to look at other stuff in the state before we even know if
the crtc is even enabled.

>  		return true;
>  
> -	/*
> -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> -	 * more then one pipe enabled
> -	 */
> -	if (hweight8(state->active_pipes) > 1)
> -		return false;
> -
> -	/* Since we're now guaranteed to only have one active CRTC... */
> -	pipe = ffs(state->active_pipes) - 1;
> -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> -	crtc_state = to_intel_crtc_state(crtc->base.state);
> -
> -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> -		return false;
> -
> -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> -		struct skl_plane_wm *wm =
> +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> +		const struct skl_plane_wm *wm =
>  			&crtc_state->wm.skl.optimal.planes[plane->id];
>  
>  		/* Skip this plane if it's not enabled */
> @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>  		latency = dev_priv->wm.skl_latency[level];
>  
>  		if (skl_needs_memory_bw_wa(dev_priv) &&
> -		    plane->base.state->fb->modifier ==
> +		    plane_state->uapi.fb->modifier ==

hw.fb

With those this is basically good, but still need to think how to avoid
the regression due to only checking the crtcs in the state.

>  		    I915_FORMAT_MOD_X_TILED)
>  			latency += 15;
>  
> @@ -3823,6 +3806,49 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>  	return true;
>  }
>  
> +static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> +
> +	/*
> +	 * It has been recommended that for Gen 9 we switch SAGV off when
> +	 * multiple pipes are used.
> +	 */
> +	if (hweight8(state->active_pipes) > 1)
> +		return false;
> +
> +	/*
> +	 * Besides active pipe limitation, rest of checks pretty much match ICL
> +	 * so no need to duplicate code
> +	 */
> +	return icl_crtc_can_enable_sagv(crtc_state);
> +}
> +
> +bool intel_can_enable_sagv(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc *crtc;
> +	const struct intel_crtc_state *crtc_state;
> +	int i;
> +
> +	if (!intel_has_sagv(dev_priv))
> +		return false;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> +		bool can_sagv;
> +
> +		if (INTEL_GEN(dev_priv) >= 11)
> +			can_sagv = icl_crtc_can_enable_sagv(crtc_state);
> +		else
> +			can_sagv = skl_crtc_can_enable_sagv(crtc_state);
> +
> +		if (!can_sagv)
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>  /*
>   * Calculate initial DBuf slice offset, based on slice size
>   * and mask(i.e if slice size is 1024 and second slice is enabled
> -- 
> 2.24.1.485.gad05a3d8e5

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-07 19:01     ` Ville Syrjälä
@ 2020-04-08  7:58       ` Lisovskiy, Stanislav
  2020-04-08 14:55         ` Ville Syrjälä
  0 siblings, 1 reply; 52+ messages in thread
From: Lisovskiy, Stanislav @ 2020-04-08  7:58 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: jani.nikula, intel-gfx

On Tue, Apr 07, 2020 at 10:01:28PM +0300, Ville Syrjälä wrote:
> On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> > Addressing one of the comments, recommending to extract platform
> > specific code from intel_can_enable_sagv as a preparation, before
> > we are going to add support for tgl+.
> > 
> > Current code in intel_can_enable_sagv is valid only for skl,
> > so this patch adds also proper support for icl, subsequent
> > patches will add support for tgl+, combined with other required
> > changes.
> > 
> > v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
> >     - Removed dev variables(Ville)
> >     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
> >       function(Ville)
> >     - Added hw.active check(Ville)
> >     - Refactored if ladder(Ville)
> > 
> > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
> >  1 file changed, 55 insertions(+), 29 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index f8d62d1977ac..27d4d626cb34 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
> >  	return 0;
> >  }
> >  
> > -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_device *dev = state->base.dev;
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > -	struct intel_crtc *crtc;
> > +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  	struct intel_plane *plane;
> > -	struct intel_crtc_state *crtc_state;
> > -	enum pipe pipe;
> > +	const struct intel_plane_state *plane_state;
> >  	int level, latency;
> >  
> > -	if (!intel_has_sagv(dev_priv))
> > +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> > +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> > +			      pipe_name(crtc->pipe));
> >  		return false;
> > +	}
> >  
> > -	/*
> > -	 * If there are no active CRTCs, no additional checks need be performed
> > -	 */
> > -	if (hweight8(state->active_pipes) == 0)
> > +	if (!crtc_state->hw.active)
> 
> Should really be checked before anything else. Doesn't matter too much
> anymore since I made us clear the crtc state always, but still a bit
> inconsistent to look at other stuff in the state before we even know if
> the crtc is even enabled.
> 
> >  		return true;
> >  
> > -	/*
> > -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> > -	 * more then one pipe enabled
> > -	 */
> > -	if (hweight8(state->active_pipes) > 1)
> > -		return false;
> > -
> > -	/* Since we're now guaranteed to only have one active CRTC... */
> > -	pipe = ffs(state->active_pipes) - 1;
> > -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> > -	crtc_state = to_intel_crtc_state(crtc->base.state);
> > -
> > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > -		return false;
> > -
> > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > -		struct skl_plane_wm *wm =
> > +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > +		const struct skl_plane_wm *wm =
> >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> >  
> >  		/* Skip this plane if it's not enabled */
> > @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> >  		latency = dev_priv->wm.skl_latency[level];
> >  
> >  		if (skl_needs_memory_bw_wa(dev_priv) &&
> > -		    plane->base.state->fb->modifier ==
> > +		    plane_state->uapi.fb->modifier ==
> 
> hw.fb
> 
> With those this is basically good, but still need to think how to avoid
> the regression due to only checking the crtcs in the state.

Well tbh, initially you told me that this *_crtc_can_enable_sagv function extraction
can be "trivially" done as a separate patch :)) So I followed your instruction, and 
then I got a comment saying that "this is now temporary busted because we are checking
only crtcs in a state". This kind of contraversial requirements - in order not to 
have it "temporary busted", we should have introduced it at the same time with SAGV mask,
at the same time you wanted it to be extracted as a separate patch.

In my opinion we are chasing own tail here. 1) Anyway this patch is transient and moreover
it is quite likely that if wm/ddb allocations had changed we anyway now have all of those
added into the state. 2) We could have just introduced it at the same time with a mask
in bw_state thus avoiding that problem, what I actually had done in my _initial_ patch.

Stan

> 
> >  		    I915_FORMAT_MOD_X_TILED)
> >  			latency += 15;
> >  
> > @@ -3823,6 +3806,49 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> >  	return true;
> >  }
> >  
> > +static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> > +
> > +	/*
> > +	 * It has been recommended that for Gen 9 we switch SAGV off when
> > +	 * multiple pipes are used.
> > +	 */
> > +	if (hweight8(state->active_pipes) > 1)
> > +		return false;
> > +
> > +	/*
> > +	 * Besides active pipe limitation, rest of checks pretty much match ICL
> > +	 * so no need to duplicate code
> > +	 */
> > +	return icl_crtc_can_enable_sagv(crtc_state);
> > +}
> > +
> > +bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	struct intel_crtc *crtc;
> > +	const struct intel_crtc_state *crtc_state;
> > +	int i;
> > +
> > +	if (!intel_has_sagv(dev_priv))
> > +		return false;
> > +
> > +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> > +		bool can_sagv;
> > +
> > +		if (INTEL_GEN(dev_priv) >= 11)
> > +			can_sagv = icl_crtc_can_enable_sagv(crtc_state);
> > +		else
> > +			can_sagv = skl_crtc_can_enable_sagv(crtc_state);
> > +
> > +		if (!can_sagv)
> > +			return false;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> >  /*
> >   * Calculate initial DBuf slice offset, based on slice size
> >   * and mask(i.e if slice size is 1024 and second slice is enabled
> > -- 
> > 2.24.1.485.gad05a3d8e5
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-08  7:58       ` Lisovskiy, Stanislav
@ 2020-04-08 14:55         ` Ville Syrjälä
  2020-04-08 15:54           ` Lisovskiy, Stanislav
  0 siblings, 1 reply; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-08 14:55 UTC (permalink / raw)
  To: Lisovskiy, Stanislav; +Cc: jani.nikula, intel-gfx

On Wed, Apr 08, 2020 at 10:58:04AM +0300, Lisovskiy, Stanislav wrote:
> On Tue, Apr 07, 2020 at 10:01:28PM +0300, Ville Syrjälä wrote:
> > On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> > > Addressing one of the comments, recommending to extract platform
> > > specific code from intel_can_enable_sagv as a preparation, before
> > > we are going to add support for tgl+.
> > > 
> > > Current code in intel_can_enable_sagv is valid only for skl,
> > > so this patch adds also proper support for icl, subsequent
> > > patches will add support for tgl+, combined with other required
> > > changes.
> > > 
> > > v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
> > >     - Removed dev variables(Ville)
> > >     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
> > >       function(Ville)
> > >     - Added hw.active check(Ville)
> > >     - Refactored if ladder(Ville)
> > > 
> > > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
> > >  1 file changed, 55 insertions(+), 29 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > index f8d62d1977ac..27d4d626cb34 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
> > >  	return 0;
> > >  }
> > >  
> > > -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > >  {
> > > -	struct drm_device *dev = state->base.dev;
> > > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > > -	struct intel_crtc *crtc;
> > > +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > >  	struct intel_plane *plane;
> > > -	struct intel_crtc_state *crtc_state;
> > > -	enum pipe pipe;
> > > +	const struct intel_plane_state *plane_state;
> > >  	int level, latency;
> > >  
> > > -	if (!intel_has_sagv(dev_priv))
> > > +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> > > +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> > > +			      pipe_name(crtc->pipe));
> > >  		return false;
> > > +	}
> > >  
> > > -	/*
> > > -	 * If there are no active CRTCs, no additional checks need be performed
> > > -	 */
> > > -	if (hweight8(state->active_pipes) == 0)
> > > +	if (!crtc_state->hw.active)
> > 
> > Should really be checked before anything else. Doesn't matter too much
> > anymore since I made us clear the crtc state always, but still a bit
> > inconsistent to look at other stuff in the state before we even know if
> > the crtc is even enabled.
> > 
> > >  		return true;
> > >  
> > > -	/*
> > > -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> > > -	 * more then one pipe enabled
> > > -	 */
> > > -	if (hweight8(state->active_pipes) > 1)
> > > -		return false;
> > > -
> > > -	/* Since we're now guaranteed to only have one active CRTC... */
> > > -	pipe = ffs(state->active_pipes) - 1;
> > > -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> > > -	crtc_state = to_intel_crtc_state(crtc->base.state);
> > > -
> > > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > -		return false;
> > > -
> > > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > > -		struct skl_plane_wm *wm =
> > > +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > > +		const struct skl_plane_wm *wm =
> > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > >  
> > >  		/* Skip this plane if it's not enabled */
> > > @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > >  		latency = dev_priv->wm.skl_latency[level];
> > >  
> > >  		if (skl_needs_memory_bw_wa(dev_priv) &&
> > > -		    plane->base.state->fb->modifier ==
> > > +		    plane_state->uapi.fb->modifier ==
> > 
> > hw.fb
> > 
> > With those this is basically good, but still need to think how to avoid
> > the regression due to only checking the crtcs in the state.
> 
> Well tbh, initially you told me that this *_crtc_can_enable_sagv function extraction
> can be "trivially" done as a separate patch :)) So I followed your instruction, and 
> then I got a comment saying that "this is now temporary busted because we are checking
> only crtcs in a state". This kind of contraversial requirements - in order not to 
> have it "temporary busted", we should have introduced it at the same time with SAGV mask,
> at the same time you wanted it to be extracted as a separate patch.

TBF this patch does quite a bit more than extract the current code.

What I think would work as a series is something like:
patch 1:
+intel_crtc_can_enable_sagv(crtc_state)
{
+	stuff
}

intel_can_enable_sagv(state)
{
	...
	crtc_state = to_intel_crtc_state(crtc->base.state);

-	stuff
+	return intel_crtc_can_eanble_sagv(crtc_state);
}

patch 2:
+sagv_pre_plane_update(state)
+{
+	if (!intel_can_enable_sagv(state))
+		intel_disable_sagv(dev_priv);
+}

intel_atomic_commit_tail()
{
	...
-	if (!intel_can_enable_sagv(state))
-		intel_disable_sagv(dev_priv);
+	sagv_pre_plane_update(state);
	...
}

(+ identical changes for post_plane_update())

So far everything has been pure refactoring.

patch 3:
Introduce the sagv mask in bw state and precompute it using
intel_crtc_can_enable_sagv() (while fixing the iterator issue therein),
and update the pre/post hooks to consult said mask. Not quite pure
refactoring anymore but seems like a bit more straightforward change
now.

At this point we should have a nicely precomputed sagv mask without
intentional changes to current behaviour. After which it should be
easier to extend this for new platforms.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-08 14:55         ` Ville Syrjälä
@ 2020-04-08 15:54           ` Lisovskiy, Stanislav
  2020-04-08 16:18             ` Lisovskiy, Stanislav
  0 siblings, 1 reply; 52+ messages in thread
From: Lisovskiy, Stanislav @ 2020-04-08 15:54 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: jani.nikula, intel-gfx

On Wed, Apr 08, 2020 at 05:55:02PM +0300, Ville Syrjälä wrote:
> On Wed, Apr 08, 2020 at 10:58:04AM +0300, Lisovskiy, Stanislav wrote:
> > On Tue, Apr 07, 2020 at 10:01:28PM +0300, Ville Syrjälä wrote:
> > > On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> > > > Addressing one of the comments, recommending to extract platform
> > > > specific code from intel_can_enable_sagv as a preparation, before
> > > > we are going to add support for tgl+.
> > > > 
> > > > Current code in intel_can_enable_sagv is valid only for skl,
> > > > so this patch adds also proper support for icl, subsequent
> > > > patches will add support for tgl+, combined with other required
> > > > changes.
> > > > 
> > > > v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
> > > >     - Removed dev variables(Ville)
> > > >     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
> > > >       function(Ville)
> > > >     - Added hw.active check(Ville)
> > > >     - Refactored if ladder(Ville)
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
> > > >  1 file changed, 55 insertions(+), 29 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > > index f8d62d1977ac..27d4d626cb34 100644
> > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
> > > >  	return 0;
> > > >  }
> > > >  
> > > > -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > > +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > >  {
> > > > -	struct drm_device *dev = state->base.dev;
> > > > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > -	struct intel_crtc *crtc;
> > > > +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > >  	struct intel_plane *plane;
> > > > -	struct intel_crtc_state *crtc_state;
> > > > -	enum pipe pipe;
> > > > +	const struct intel_plane_state *plane_state;
> > > >  	int level, latency;
> > > >  
> > > > -	if (!intel_has_sagv(dev_priv))
> > > > +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> > > > +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> > > > +			      pipe_name(crtc->pipe));
> > > >  		return false;
> > > > +	}
> > > >  
> > > > -	/*
> > > > -	 * If there are no active CRTCs, no additional checks need be performed
> > > > -	 */
> > > > -	if (hweight8(state->active_pipes) == 0)
> > > > +	if (!crtc_state->hw.active)
> > > 
> > > Should really be checked before anything else. Doesn't matter too much
> > > anymore since I made us clear the crtc state always, but still a bit
> > > inconsistent to look at other stuff in the state before we even know if
> > > the crtc is even enabled.
> > > 
> > > >  		return true;
> > > >  
> > > > -	/*
> > > > -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> > > > -	 * more then one pipe enabled
> > > > -	 */
> > > > -	if (hweight8(state->active_pipes) > 1)
> > > > -		return false;
> > > > -
> > > > -	/* Since we're now guaranteed to only have one active CRTC... */
> > > > -	pipe = ffs(state->active_pipes) - 1;
> > > > -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> > > > -	crtc_state = to_intel_crtc_state(crtc->base.state);
> > > > -
> > > > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > -		return false;
> > > > -
> > > > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > > > -		struct skl_plane_wm *wm =
> > > > +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > > > +		const struct skl_plane_wm *wm =
> > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > >  
> > > >  		/* Skip this plane if it's not enabled */
> > > > @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > >  		latency = dev_priv->wm.skl_latency[level];
> > > >  
> > > >  		if (skl_needs_memory_bw_wa(dev_priv) &&
> > > > -		    plane->base.state->fb->modifier ==
> > > > +		    plane_state->uapi.fb->modifier ==
> > > 
> > > hw.fb
> > > 
> > > With those this is basically good, but still need to think how to avoid
> > > the regression due to only checking the crtcs in the state.
> > 
> > Well tbh, initially you told me that this *_crtc_can_enable_sagv function extraction
> > can be "trivially" done as a separate patch :)) So I followed your instruction, and 
> > then I got a comment saying that "this is now temporary busted because we are checking
> > only crtcs in a state". This kind of contraversial requirements - in order not to 
> > have it "temporary busted", we should have introduced it at the same time with SAGV mask,
> > at the same time you wanted it to be extracted as a separate patch.
> 
> TBF this patch does quite a bit more than extract the current code.
> 
> What I think would work as a series is something like:
> patch 1:
> +intel_crtc_can_enable_sagv(crtc_state)
> {
> +	stuff
> }
> 
> intel_can_enable_sagv(state)
> {
> 	...
> 	crtc_state = to_intel_crtc_state(crtc->base.state);
> 
> -	stuff
> +	return intel_crtc_can_eanble_sagv(crtc_state);
> }
> 
> patch 2:
> +sagv_pre_plane_update(state)
> +{
> +	if (!intel_can_enable_sagv(state))
> +		intel_disable_sagv(dev_priv);
> +}
> 
> intel_atomic_commit_tail()
> {
> 	...
> -	if (!intel_can_enable_sagv(state))
> -		intel_disable_sagv(dev_priv);
> +	sagv_pre_plane_update(state);
> 	...
> }
> 
> (+ identical changes for post_plane_update())
> 
> So far everything has been pure refactoring.
> 
> patch 3:
> Introduce the sagv mask in bw state and precompute it using
> intel_crtc_can_enable_sagv() (while fixing the iterator issue therein),
> and update the pre/post hooks to consult said mask. Not quite pure
> refactoring anymore but seems like a bit more straightforward change
> now.
> 
> At this point we should have a nicely precomputed sagv mask without
> intentional changes to current behaviour. After which it should be
> easier to extend this for new platforms.

This all makes sense, however in the end we'll have the same result as now, however this would
require to reshuffle the whole series...again. 
Will try do it, the least painful way :) 

> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-08 15:54           ` Lisovskiy, Stanislav
@ 2020-04-08 16:18             ` Lisovskiy, Stanislav
  2020-04-09 15:58               ` Ville Syrjälä
  0 siblings, 1 reply; 52+ messages in thread
From: Lisovskiy, Stanislav @ 2020-04-08 16:18 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: jani.nikula, intel-gfx

On Wed, Apr 08, 2020 at 06:54:09PM +0300, Lisovskiy, Stanislav wrote:
> On Wed, Apr 08, 2020 at 05:55:02PM +0300, Ville Syrjälä wrote:
> > On Wed, Apr 08, 2020 at 10:58:04AM +0300, Lisovskiy, Stanislav wrote:
> > > On Tue, Apr 07, 2020 at 10:01:28PM +0300, Ville Syrjälä wrote:
> > > > On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> > > > > Addressing one of the comments, recommending to extract platform
> > > > > specific code from intel_can_enable_sagv as a preparation, before
> > > > > we are going to add support for tgl+.
> > > > > 
> > > > > Current code in intel_can_enable_sagv is valid only for skl,
> > > > > so this patch adds also proper support for icl, subsequent
> > > > > patches will add support for tgl+, combined with other required
> > > > > changes.
> > > > > 
> > > > > v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
> > > > >     - Removed dev variables(Ville)
> > > > >     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
> > > > >       function(Ville)
> > > > >     - Added hw.active check(Ville)
> > > > >     - Refactored if ladder(Ville)
> > > > > 
> > > > > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
> > > > >  1 file changed, 55 insertions(+), 29 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > > > index f8d62d1977ac..27d4d626cb34 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
> > > > >  	return 0;
> > > > >  }
> > > > >  
> > > > > -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > > > +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > >  {
> > > > > -	struct drm_device *dev = state->base.dev;
> > > > > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > > -	struct intel_crtc *crtc;
> > > > > +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > >  	struct intel_plane *plane;
> > > > > -	struct intel_crtc_state *crtc_state;
> > > > > -	enum pipe pipe;
> > > > > +	const struct intel_plane_state *plane_state;
> > > > >  	int level, latency;
> > > > >  
> > > > > -	if (!intel_has_sagv(dev_priv))
> > > > > +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> > > > > +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> > > > > +			      pipe_name(crtc->pipe));
> > > > >  		return false;
> > > > > +	}
> > > > >  
> > > > > -	/*
> > > > > -	 * If there are no active CRTCs, no additional checks need be performed
> > > > > -	 */
> > > > > -	if (hweight8(state->active_pipes) == 0)
> > > > > +	if (!crtc_state->hw.active)
> > > > 
> > > > Should really be checked before anything else. Doesn't matter too much
> > > > anymore since I made us clear the crtc state always, but still a bit
> > > > inconsistent to look at other stuff in the state before we even know if
> > > > the crtc is even enabled.
> > > > 
> > > > >  		return true;
> > > > >  
> > > > > -	/*
> > > > > -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> > > > > -	 * more then one pipe enabled
> > > > > -	 */
> > > > > -	if (hweight8(state->active_pipes) > 1)
> > > > > -		return false;
> > > > > -
> > > > > -	/* Since we're now guaranteed to only have one active CRTC... */
> > > > > -	pipe = ffs(state->active_pipes) - 1;
> > > > > -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> > > > > -	crtc_state = to_intel_crtc_state(crtc->base.state);
> > > > > -
> > > > > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > > -		return false;
> > > > > -
> > > > > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > > > > -		struct skl_plane_wm *wm =
> > > > > +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > > > > +		const struct skl_plane_wm *wm =
> > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > >  
> > > > >  		/* Skip this plane if it's not enabled */
> > > > > @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > > >  		latency = dev_priv->wm.skl_latency[level];
> > > > >  
> > > > >  		if (skl_needs_memory_bw_wa(dev_priv) &&
> > > > > -		    plane->base.state->fb->modifier ==
> > > > > +		    plane_state->uapi.fb->modifier ==
> > > > 
> > > > hw.fb
> > > > 
> > > > With those this is basically good, but still need to think how to avoid
> > > > the regression due to only checking the crtcs in the state.
> > > 
> > > Well tbh, initially you told me that this *_crtc_can_enable_sagv function extraction
> > > can be "trivially" done as a separate patch :)) So I followed your instruction, and 
> > > then I got a comment saying that "this is now temporary busted because we are checking
> > > only crtcs in a state". This kind of contraversial requirements - in order not to 
> > > have it "temporary busted", we should have introduced it at the same time with SAGV mask,
> > > at the same time you wanted it to be extracted as a separate patch.
> > 
> > TBF this patch does quite a bit more than extract the current code.
> > 
> > What I think would work as a series is something like:
> > patch 1:
> > +intel_crtc_can_enable_sagv(crtc_state)
> > {
> > +	stuff
> > }
> > 
> > intel_can_enable_sagv(state)
> > {
> > 	...
> > 	crtc_state = to_intel_crtc_state(crtc->base.state);
> > 
> > -	stuff
> > +	return intel_crtc_can_eanble_sagv(crtc_state);
> > }
> > 
> > patch 2:
> > +sagv_pre_plane_update(state)
> > +{
> > +	if (!intel_can_enable_sagv(state))
> > +		intel_disable_sagv(dev_priv);
> > +}
> > 
> > intel_atomic_commit_tail()
> > {
> > 	...
> > -	if (!intel_can_enable_sagv(state))
> > -		intel_disable_sagv(dev_priv);
> > +	sagv_pre_plane_update(state);
> > 	...
> > }
> > 
> > (+ identical changes for post_plane_update())
> > 
> > So far everything has been pure refactoring.
> > 
> > patch 3:
> > Introduce the sagv mask in bw state and precompute it using
> > intel_crtc_can_enable_sagv() (while fixing the iterator issue therein),
> > and update the pre/post hooks to consult said mask. Not quite pure
> > refactoring anymore but seems like a bit more straightforward change
> > now.
> > 
> > At this point we should have a nicely precomputed sagv mask without
> > intentional changes to current behaviour. After which it should be
> > easier to extend this for new platforms.
> 
> This all makes sense, however in the end we'll have the same result as now, however this would
> require to reshuffle the whole series...again. 
> Will try do it, the least painful way :) 

Also the only weird thing with this approach is that it is going to stay
this ugly _one_ crtc way, until sagv mask and bw state is introduced:

bool intel_can_enable_sagv(struct intel_atomic_state *state)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct intel_crtc *crtc;
	const struct intel_crtc_state *crtc_state;
	int i;

	if (!intel_has_sagv(dev_priv))
		return false;

	/*
	 * SKL+ workaround: bspec recommends we disable SAGV when we have
	 * more then one pipe enabled
	 */
	if (hweight8(state->active_pipes) > 1)
		return false;

	/* Since we're now guaranteed to only have one active CRTC... */
	pipe = ffs(state->active_pipes) - 1;
	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
	crtc_state = to_intel_crtc_state(crtc->base.state);

	return intel_crtc_can_enable_sagv(crtc_state);
}

because you can't iterate crtcs anyway so that patch would be 
just a name change basically. 
The I can add pre/post plane update and only once bw state->sagv_mask
is in place - the real SAGV changes can come. So SAGV logic would be
anyway wrong in the middle of that series.

Stan

> 
> > 
> > -- 
> > Ville Syrjälä
> > Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-gfx] [PATCH v21 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv
  2020-04-08 16:18             ` Lisovskiy, Stanislav
@ 2020-04-09 15:58               ` Ville Syrjälä
  0 siblings, 0 replies; 52+ messages in thread
From: Ville Syrjälä @ 2020-04-09 15:58 UTC (permalink / raw)
  To: Lisovskiy, Stanislav; +Cc: jani.nikula, intel-gfx

On Wed, Apr 08, 2020 at 07:18:11PM +0300, Lisovskiy, Stanislav wrote:
> On Wed, Apr 08, 2020 at 06:54:09PM +0300, Lisovskiy, Stanislav wrote:
> > On Wed, Apr 08, 2020 at 05:55:02PM +0300, Ville Syrjälä wrote:
> > > On Wed, Apr 08, 2020 at 10:58:04AM +0300, Lisovskiy, Stanislav wrote:
> > > > On Tue, Apr 07, 2020 at 10:01:28PM +0300, Ville Syrjälä wrote:
> > > > > On Fri, Apr 03, 2020 at 09:20:03AM +0300, Stanislav Lisovskiy wrote:
> > > > > > Addressing one of the comments, recommending to extract platform
> > > > > > specific code from intel_can_enable_sagv as a preparation, before
> > > > > > we are going to add support for tgl+.
> > > > > > 
> > > > > > Current code in intel_can_enable_sagv is valid only for skl,
> > > > > > so this patch adds also proper support for icl, subsequent
> > > > > > patches will add support for tgl+, combined with other required
> > > > > > changes.
> > > > > > 
> > > > > > v2: - Renamed icl_can_enable_sagv into icl_crtc_can_enable_sagv(Ville)
> > > > > >     - Removed dev variables(Ville)
> > > > > >     - Constified crtc/plane_state in icl_crtc_can_enable_sagv
> > > > > >       function(Ville)
> > > > > >     - Added hw.active check(Ville)
> > > > > >     - Refactored if ladder(Ville)
> > > > > > 
> > > > > > Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/intel_pm.c | 84 +++++++++++++++++++++------------
> > > > > >  1 file changed, 55 insertions(+), 29 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > > > > index f8d62d1977ac..27d4d626cb34 100644
> > > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > > @@ -3757,42 +3757,25 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > -bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > > > > +static bool icl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > >  {
> > > > > > -	struct drm_device *dev = state->base.dev;
> > > > > > -	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > > > -	struct intel_crtc *crtc;
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > > >  	struct intel_plane *plane;
> > > > > > -	struct intel_crtc_state *crtc_state;
> > > > > > -	enum pipe pipe;
> > > > > > +	const struct intel_plane_state *plane_state;
> > > > > >  	int level, latency;
> > > > > >  
> > > > > > -	if (!intel_has_sagv(dev_priv))
> > > > > > +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> > > > > > +		DRM_DEBUG_KMS("No SAGV for interlaced mode on pipe %c\n",
> > > > > > +			      pipe_name(crtc->pipe));
> > > > > >  		return false;
> > > > > > +	}
> > > > > >  
> > > > > > -	/*
> > > > > > -	 * If there are no active CRTCs, no additional checks need be performed
> > > > > > -	 */
> > > > > > -	if (hweight8(state->active_pipes) == 0)
> > > > > > +	if (!crtc_state->hw.active)
> > > > > 
> > > > > Should really be checked before anything else. Doesn't matter too much
> > > > > anymore since I made us clear the crtc state always, but still a bit
> > > > > inconsistent to look at other stuff in the state before we even know if
> > > > > the crtc is even enabled.
> > > > > 
> > > > > >  		return true;
> > > > > >  
> > > > > > -	/*
> > > > > > -	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> > > > > > -	 * more then one pipe enabled
> > > > > > -	 */
> > > > > > -	if (hweight8(state->active_pipes) > 1)
> > > > > > -		return false;
> > > > > > -
> > > > > > -	/* Since we're now guaranteed to only have one active CRTC... */
> > > > > > -	pipe = ffs(state->active_pipes) - 1;
> > > > > > -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> > > > > > -	crtc_state = to_intel_crtc_state(crtc->base.state);
> > > > > > -
> > > > > > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > -		return false;
> > > > > > -
> > > > > > -	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> > > > > > -		struct skl_plane_wm *wm =
> > > > > > +	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > > > > > +		const struct skl_plane_wm *wm =
> > > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > > >  
> > > > > >  		/* Skip this plane if it's not enabled */
> > > > > > @@ -3807,7 +3790,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
> > > > > >  		latency = dev_priv->wm.skl_latency[level];
> > > > > >  
> > > > > >  		if (skl_needs_memory_bw_wa(dev_priv) &&
> > > > > > -		    plane->base.state->fb->modifier ==
> > > > > > +		    plane_state->uapi.fb->modifier ==
> > > > > 
> > > > > hw.fb
> > > > > 
> > > > > With those this is basically good, but still need to think how to avoid
> > > > > the regression due to only checking the crtcs in the state.
> > > > 
> > > > Well tbh, initially you told me that this *_crtc_can_enable_sagv function extraction
> > > > can be "trivially" done as a separate patch :)) So I followed your instruction, and 
> > > > then I got a comment saying that "this is now temporary busted because we are checking
> > > > only crtcs in a state". This kind of contraversial requirements - in order not to 
> > > > have it "temporary busted", we should have introduced it at the same time with SAGV mask,
> > > > at the same time you wanted it to be extracted as a separate patch.
> > > 
> > > TBF this patch does quite a bit more than extract the current code.
> > > 
> > > What I think would work as a series is something like:
> > > patch 1:
> > > +intel_crtc_can_enable_sagv(crtc_state)
> > > {
> > > +	stuff
> > > }
> > > 
> > > intel_can_enable_sagv(state)
> > > {
> > > 	...
> > > 	crtc_state = to_intel_crtc_state(crtc->base.state);
> > > 
> > > -	stuff
> > > +	return intel_crtc_can_eanble_sagv(crtc_state);
> > > }
> > > 
> > > patch 2:
> > > +sagv_pre_plane_update(state)
> > > +{
> > > +	if (!intel_can_enable_sagv(state))
> > > +		intel_disable_sagv(dev_priv);
> > > +}
> > > 
> > > intel_atomic_commit_tail()
> > > {
> > > 	...
> > > -	if (!intel_can_enable_sagv(state))
> > > -		intel_disable_sagv(dev_priv);
> > > +	sagv_pre_plane_update(state);
> > > 	...
> > > }
> > > 
> > > (+ identical changes for post_plane_update())
> > > 
> > > So far everything has been pure refactoring.
> > > 
> > > patch 3:
> > > Introduce the sagv mask in bw state and precompute it using
> > > intel_crtc_can_enable_sagv() (while fixing the iterator issue therein),
> > > and update the pre/post hooks to consult said mask. Not quite pure
> > > refactoring anymore but seems like a bit more straightforward change
> > > now.
> > > 
> > > At this point we should have a nicely precomputed sagv mask without
> > > intentional changes to current behaviour. After which it should be
> > > easier to extend this for new platforms.
> > 
> > This all makes sense, however in the end we'll have the same result as now, however this would
> > require to reshuffle the whole series...again. 
> > Will try do it, the least painful way :) 
> 
> Also the only weird thing with this approach is that it is going to stay
> this ugly _one_ crtc way, until sagv mask and bw state is introduced:
> 
> bool intel_can_enable_sagv(struct intel_atomic_state *state)
> {
> 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> 	struct intel_crtc *crtc;
> 	const struct intel_crtc_state *crtc_state;
> 	int i;
> 
> 	if (!intel_has_sagv(dev_priv))
> 		return false;
> 
> 	/*
> 	 * SKL+ workaround: bspec recommends we disable SAGV when we have
> 	 * more then one pipe enabled
> 	 */
> 	if (hweight8(state->active_pipes) > 1)
> 		return false;
> 
> 	/* Since we're now guaranteed to only have one active CRTC... */
> 	pipe = ffs(state->active_pipes) - 1;
> 	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> 	crtc_state = to_intel_crtc_state(crtc->base.state);
> 
> 	return intel_crtc_can_enable_sagv(crtc_state);
> }
> 
> because you can't iterate crtcs anyway so that patch would be 
> just a name change basically. 
> The I can add pre/post plane update and only once bw state->sagv_mask
> is in place - the real SAGV changes can come. So SAGV logic would be
> anyway wrong in the middle of that series.

No more wrong than it is now.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2020-04-09 15:58 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26 18:09 [Intel-gfx] [PATCH v20 00/10] SAGV support for Gen12+ Stanislav Lisovskiy
2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 01/10] drm/i915: Start passing latency as parameter Stanislav Lisovskiy
2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 02/10] drm/i915: Eliminate magic numbers "0" and "1" from color plane Stanislav Lisovskiy
2020-04-02 16:17   ` Ville Syrjälä
2020-04-02 16:28     ` Lisovskiy, Stanislav
2020-04-02 16:41       ` Ville Syrjälä
2020-04-03 15:41   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 03/10] drm/i915: Introduce skl_plane_wm_level accessor Stanislav Lisovskiy
2020-03-26 18:09 ` [Intel-gfx] [PATCH v20 04/10] drm/i915: Add intel_atomic_get_bw_*_state helpers Stanislav Lisovskiy
2020-04-02 16:20   ` Ville Syrjälä
2020-04-02 16:49     ` Ville Syrjälä
2020-04-03  6:11   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-04-03  6:15   ` Stanislav Lisovskiy
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 05/10] drm/i915: Extract gen specific functions from intel_can_enable_sagv Stanislav Lisovskiy
2020-04-02 16:44   ` Ville Syrjälä
2020-04-03  6:20   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-04-07 19:01     ` Ville Syrjälä
2020-04-08  7:58       ` Lisovskiy, Stanislav
2020-04-08 14:55         ` Ville Syrjälä
2020-04-08 15:54           ` Lisovskiy, Stanislav
2020-04-08 16:18             ` Lisovskiy, Stanislav
2020-04-09 15:58               ` Ville Syrjälä
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 06/10] drm/i915: Add proper SAGV support for TGL+ Stanislav Lisovskiy
2020-03-26 18:39   ` Stanislav Lisovskiy
2020-04-02 17:22     ` Ville Syrjälä
2020-04-03  6:29     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-04-03 15:43       ` Stanislav Lisovskiy
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 07/10] drm/i915: Added required new PCode commands Stanislav Lisovskiy
2020-04-02 17:27   ` Ville Syrjälä
2020-04-03  6:32   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 08/10] drm/i915: Rename bw_state to new_bw_state Stanislav Lisovskiy
2020-04-02 17:30   ` Ville Syrjälä
2020-04-03  6:34   ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 09/10] drm/i915: Restrict qgv points which don't have enough bandwidth Stanislav Lisovskiy
2020-03-26 18:36   ` Stanislav Lisovskiy
2020-04-02 17:50     ` Ville Syrjälä
2020-04-03  6:37     ` [Intel-gfx] [PATCH v21 " Stanislav Lisovskiy
2020-04-03 16:41       ` Stanislav Lisovskiy
2020-03-26 18:10 ` [Intel-gfx] [PATCH v20 10/10] drm/i915: Enable SAGV support for Gen12 Stanislav Lisovskiy
2020-03-26 20:59 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev3) Patchwork
2020-03-26 21:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-03-27 11:58 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2020-04-03  6:19 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev4) Patchwork
2020-04-03  6:22 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev5) Patchwork
2020-04-03  6:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev10) Patchwork
2020-04-03  6:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-04-03  7:16 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-04-03 16:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for SAGV support for Gen12+ (rev12) Patchwork
2020-04-03 16:40 ` [Intel-gfx] ✗ Fi.CI.IGT: failure for SAGV support for Gen12+ (rev10) Patchwork
2020-04-03 17:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for SAGV support for Gen12+ (rev13) Patchwork
2020-04-03 17:29 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-04-04  2:33 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.