All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format.
@ 2018-10-18 11:51 Maarten Lankhorst
  2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
                   ` (16 more replies)
  0 siblings, 17 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

New version, with a lot of reworking to incorporate all the feedback.

We currently don't set the plane input CSC correctly, so colors are a
bit off. As a result I can't verify for 100% we program the chroma
upsampler correctly, but I still want to put out this series for review.

Maarten Lankhorst (8):
  drm/i915: Fix unsigned overflow when calculating total data rate
  drm/i915/gen11: Enable 6 sprites on gen11
  drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes,
    v2.
  drm/i915/gen11: Program the scalers correctly for planar formats, v3.
  drm/i915/gen11: Program the chroma upsampler for HDR planes.
  drm/i915/gen11: Program the Y and UV plane for planar mode correctly,
    v3.
  drm/i915/gen11: Expose planar format support on gen11.

 drivers/gpu/drm/i915/i915_reg.h           |  27 +-
 drivers/gpu/drm/i915/intel_atomic.c       |  16 +-
 drivers/gpu/drm/i915/intel_atomic_plane.c |  74 ++++-
 drivers/gpu/drm/i915/intel_device_info.c  |  22 +-
 drivers/gpu/drm/i915/intel_display.c      | 120 ++++++--
 drivers/gpu/drm/i915/intel_display.h      |   3 +
 drivers/gpu/drm/i915/intel_drv.h          |  61 ++++
 drivers/gpu/drm/i915/intel_pm.c           | 360 ++++++++++++++--------
 drivers/gpu/drm/i915/intel_sprite.c       |  72 ++++-
 9 files changed, 575 insertions(+), 180 deletions(-)

-- 
2.19.1

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

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

* [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 14:53   ` Ville Syrjälä
  2018-10-18 15:11   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 2/8] drm/i915/gen11: Enable 6 sprites on gen11 Maarten Lankhorst
                   ` (15 subsequent siblings)
  16 siblings, 2 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

On gen11, we can definitely smash the 32-bits barrier with just a
when we enable all planes in the next patch.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 67a4d0735291..3b136fdfd24f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
 
 static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 			      const struct intel_crtc_state *cstate,
-			      const unsigned int total_data_rate,
+			      const u64 total_data_rate,
 			      const int num_active,
 			      struct skl_ddb_allocation *ddb)
 {
@@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 		return ddb_size - 4; /* 4 blocks for bypass path allocation */
 
 	adjusted_mode = &cstate->base.adjusted_mode;
-	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
+	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
 
 	/*
 	 * 12GB/s is maximum BW supported by single DBuf slice.
 	 */
-	if (total_data_bw >= GBps(12) || num_active > 1) {
+	if (num_active > 1 || total_data_bw >= GBps(12)) {
 		ddb->enabled_slices = 2;
 	} else {
 		ddb->enabled_slices = 1;
@@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 				   const struct intel_crtc_state *cstate,
-				   const unsigned int total_data_rate,
+				   const u64 total_data_rate,
 				   struct skl_ddb_allocation *ddb,
 				   struct skl_ddb_entry *alloc, /* out */
 				   int *num_active /* out */)
@@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 	return 0;
 }
 
-static unsigned int
+static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 			     const struct drm_plane_state *pstate,
 			     const int plane)
@@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 	struct drm_framebuffer *fb;
 	u32 format;
 	uint_fixed_16_16_t down_scale_amount;
+	u64 rate;
 
 	if (!intel_pstate->base.visible)
 		return 0;
@@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 		height /= 2;
 	}
 
-	data_rate = width * height * fb->format->cpp[plane];
+	data_rate = width * height;
 
 	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
 
-	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
+	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
+
+	rate *= fb->format->cpp[plane];
+	return rate;
 }
 
-/*
- * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
- * a 8192x4096@32bpp framebuffer:
- *   3 * 4096 * 8192  * 4 < 2^32
- */
-static unsigned int
+static u64
 skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
-				 unsigned int *plane_data_rate,
-				 unsigned int *uv_plane_data_rate)
+				 u64 *plane_data_rate,
+				 u64 *uv_plane_data_rate)
 {
 	struct drm_crtc_state *cstate = &intel_cstate->base;
 	struct drm_atomic_state *state = cstate->state;
 	struct drm_plane *plane;
 	const struct drm_plane_state *pstate;
-	unsigned int total_data_rate = 0;
+	u64 total_data_rate = 0;
 
 	if (WARN_ON(!state))
 		return 0;
@@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
 	/* Calculate and cache data rate for each plane */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
 		enum plane_id plane_id = to_intel_plane(plane)->id;
-		unsigned int rate;
+		u64 rate;
 
 		/* packed/y */
 		rate = skl_plane_relative_data_rate(intel_cstate,
@@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	uint16_t alloc_size, start;
 	uint16_t minimum[I915_MAX_PLANES] = {};
 	uint16_t uv_minimum[I915_MAX_PLANES] = {};
-	unsigned int total_data_rate;
+	u64 total_data_rate;
 	enum plane_id plane_id;
 	int num_active;
-	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
-	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
+	u64 plane_data_rate[I915_MAX_PLANES] = {};
+	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
 	uint16_t total_min_blocks = 0;
 
 	/* Clear the partitioning for disabled planes. */
@@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
 	start = alloc->start;
 	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
-		unsigned int data_rate, uv_data_rate;
+		u64 data_rate, uv_data_rate;
 		uint16_t plane_blocks, uv_plane_blocks;
 
 		if (plane_id == PLANE_CURSOR)
@@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		 * result is < available as data_rate / total_data_rate < 1
 		 */
 		plane_blocks = minimum[plane_id];
-		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
-					total_data_rate);
+		plane_blocks += alloc_size * data_rate / total_data_rate;
 
 		/* Leave disabled planes at (0,0) */
 		if (data_rate) {
@@ -4417,8 +4415,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		uv_data_rate = uv_plane_data_rate[plane_id];
 
 		uv_plane_blocks = uv_minimum[plane_id];
-		uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
-					   total_data_rate);
+		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
 
 		if (uv_data_rate) {
 			ddb->uv_plane[pipe][plane_id].start = start;
-- 
2.19.1

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

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

* [PATCH v2 2/8] drm/i915/gen11: Enable 6 sprites on gen11
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
  2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 11:51 ` [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4 Maarten Lankhorst
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

Gen11 supports 7 planes + 1 cursor on each pipe. Bump
I915_MAX_PLANES to 8, and set num_sprites correctly.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
[mlankhorst: Move the skl/bxt comment to the BXT branch. (Matt)]
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_device_info.c | 22 +++++++++++++---------
 drivers/gpu/drm/i915/intel_display.h     |  3 +++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 03df4e33763d..6d9ea541a09c 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -752,18 +752,22 @@ void intel_device_info_runtime_init(struct intel_device_info *info)
 
 	BUILD_BUG_ON(I915_NUM_ENGINES > BITS_PER_TYPE(intel_ring_mask_t));
 
-	/*
-	 * Skylake and Broxton currently don't expose the topmost plane as its
-	 * use is exclusive with the legacy cursor and we only want to expose
-	 * one of those, not both. Until we can safely expose the topmost plane
-	 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
-	 * we don't expose the topmost plane at all to prevent ABI breakage
-	 * down the line.
-	 */
-	if (IS_GEN10(dev_priv) || IS_GEMINILAKE(dev_priv))
+	if (IS_GEN11(dev_priv))
+		for_each_pipe(dev_priv, pipe)
+			info->num_sprites[pipe] = 6;
+	else if (IS_GEN10(dev_priv) || IS_GEMINILAKE(dev_priv))
 		for_each_pipe(dev_priv, pipe)
 			info->num_sprites[pipe] = 3;
 	else if (IS_BROXTON(dev_priv)) {
+		/*
+		 * Skylake and Broxton currently don't expose the topmost plane as its
+		 * use is exclusive with the legacy cursor and we only want to expose
+		 * one of those, not both. Until we can safely expose the topmost plane
+		 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
+		 * we don't expose the topmost plane at all to prevent ABI breakage
+		 * down the line.
+		 */
+
 		info->num_sprites[PIPE_A] = 2;
 		info->num_sprites[PIPE_B] = 2;
 		info->num_sprites[PIPE_C] = 1;
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index 9fac67e31205..47000b25f1ff 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -120,6 +120,9 @@ enum plane_id {
 	PLANE_SPRITE0,
 	PLANE_SPRITE1,
 	PLANE_SPRITE2,
+	PLANE_SPRITE3,
+	PLANE_SPRITE4,
+	PLANE_SPRITE5,
 	PLANE_CURSOR,
 
 	I915_MAX_PLANES,
-- 
2.19.1

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

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

* [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
  2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
  2018-10-18 11:51 ` [PATCH v2 2/8] drm/i915/gen11: Enable 6 sprites on gen11 Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 16:00   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2 Maarten Lankhorst
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.

The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.

Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
  a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
  it's a cleaner way to do this. (Ville)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c | 74 ++++++++++++++++-----
 drivers/gpu/drm/i915/intel_display.c      | 81 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++++
 drivers/gpu/drm/i915/intel_pm.c           | 12 +++-
 4 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index b957ad63cd87..154ea3dc344f 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -122,7 +122,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 	crtc_state->nv12_planes &= ~BIT(intel_plane->id);
 	intel_state->base.visible = false;
 
-	/* If this is a cursor plane, no further checks are needed. */
+	/* Destroy the link */
+	intel_state->linked_plane = NULL;
+	intel_state->slave = false;
+
+	/* If this is a cursor or Y plane, no further checks are needed. */
 	if (!intel_state->base.crtc && !old_plane_state->base.crtc)
 		return 0;
 
@@ -143,27 +147,44 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					       state);
 }
 
-static int intel_plane_atomic_check(struct drm_plane *plane,
-				    struct drm_plane_state *new_plane_state)
+static int intel_plane_atomic_check(struct drm_plane *drm_plane,
+				    struct drm_plane_state *new_drm_plane_state)
 {
-	struct drm_atomic_state *state = new_plane_state->state;
-	const struct drm_plane_state *old_plane_state =
-		drm_atomic_get_old_plane_state(state, plane);
-	struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
-	const struct drm_crtc_state *old_crtc_state;
-	struct drm_crtc_state *new_crtc_state;
-
-	new_plane_state->visible = false;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(new_drm_plane_state->state);
+	struct intel_plane *plane = to_intel_plane(drm_plane);
+	const struct intel_plane_state *old_plane_state =
+		intel_atomic_get_old_plane_state(state, plane);
+	struct intel_plane_state *new_plane_state =
+		to_intel_plane_state(new_drm_plane_state);
+	struct intel_crtc *crtc =
+		to_intel_crtc(new_plane_state->base.crtc ?:
+			      old_plane_state->base.crtc);
+	const struct intel_crtc_state *old_crtc_state;
+	struct intel_crtc_state *new_crtc_state;
+	struct intel_plane *linked = old_plane_state->linked_plane;
+
+	if (linked && !crtc) {
+		const struct intel_plane_state *old_linked_state =
+			intel_atomic_get_old_plane_state(state, linked);
+
+		if (WARN_ON(!old_linked_state))
+			return -EINVAL;
+
+		crtc = to_intel_crtc(old_linked_state->base.crtc);
+		if (WARN_ON(!crtc))
+			return -EINVAL;
+	}
+
+	new_plane_state->base.visible = false;
 	if (!crtc)
 		return 0;
 
-	old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
-	new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
+	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 
-	return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state),
-						   to_intel_crtc_state(new_crtc_state),
-						   to_intel_plane_state(old_plane_state),
-						   to_intel_plane_state(new_plane_state));
+	return intel_plane_atomic_check_with_state(old_crtc_state, new_crtc_state,
+						   old_plane_state, new_plane_state);
 }
 
 void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
@@ -188,6 +209,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
 			trace_intel_update_plane(&plane->base, crtc);
 
 			plane->update_plane(plane, new_crtc_state, new_plane_state);
+		} else if (new_plane_state->slave) {
+			struct intel_plane *master =
+				new_plane_state->linked_plane;
+
+			/*
+			 * We update the slave plane from this function because
+			 * programming it from the master plane's update_plane
+			 * callback runs into issues when the Y plane is
+			 * reassigned, disabled or used by a different plane.
+			 *
+			 * The slave plane is updated with the master plane's
+			 * plane_state.
+			 */
+			new_plane_state =
+				intel_atomic_get_new_plane_state(old_state, master);
+
+			trace_intel_update_plane(&plane->base, crtc);
+
+			plane->update_slave(plane, new_crtc_state, new_plane_state);
 		} else {
 			trace_intel_disable_plane(&plane->base, crtc);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8e1b3677e131..cbb3fb1d5ad4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10721,6 +10721,80 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
 	return true;
 }
 
+static int icl_add_linked_planes(struct intel_atomic_state *state)
+{
+	struct intel_plane *plane, *linked;
+	struct intel_plane_state *plane_state, *linked_plane_state;
+	int i;
+
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		linked = plane_state->linked_plane;
+
+		if (!linked)
+			continue;
+
+		linked_plane_state = intel_atomic_get_plane_state(state, linked);
+		if (IS_ERR(linked_plane_state))
+			return PTR_ERR(linked_plane_state);
+	}
+
+	return 0;
+}
+
+static int icl_check_nv12_planes(struct drm_i915_private *dev_priv,
+				 struct intel_crtc *crtc,
+				 struct intel_crtc_state *crtc_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
+	struct intel_plane *plane, *aux;
+
+	if (INTEL_GEN(dev_priv) < 11 || !crtc_state->nv12_planes)
+		return 0;
+
+	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+		struct intel_plane_state *plane_state, *aux_state;
+		struct drm_plane_state *drm_aux_state = NULL;
+
+		if (!(crtc_state->nv12_planes & BIT(plane->id)))
+			continue;
+
+		plane_state = intel_atomic_get_new_plane_state(state, plane);
+		if (!plane_state)
+			continue;
+
+		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, aux) {
+			if (!icl_is_nv12_y_plane(aux->id))
+				continue;
+
+			if (crtc_state->active_planes & BIT(aux->id))
+				continue;
+
+			drm_aux_state = drm_atomic_get_plane_state(&state->base, &aux->base);
+			if (IS_ERR(drm_aux_state))
+				return PTR_ERR(drm_aux_state);
+
+			break;
+		}
+
+		if (!drm_aux_state) {
+			DRM_DEBUG_KMS("Need %d free Y planes for NV12\n",
+				      hweight8(crtc_state->nv12_planes));
+
+			return -EINVAL;
+		}
+
+		plane_state->linked_plane = aux;
+
+		aux_state = to_intel_plane_state(drm_aux_state);
+		aux_state->slave = true;
+		aux_state->linked_plane = plane;
+		crtc_state->active_planes |= BIT(aux->id);
+		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", aux->base.name, plane->base.name);
+	}
+
+	return 0;
+}
+
 static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 				   struct drm_crtc_state *crtc_state)
 {
@@ -10792,6 +10866,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 		if (mode_changed)
 			ret = skl_update_scaler_crtc(pipe_config);
 
+		if (!ret)
+			ret = icl_check_nv12_planes(dev_priv, intel_crtc,
+						    pipe_config);
 		if (!ret)
 			ret = skl_check_pipe_max_pixel_rate(intel_crtc,
 							    pipe_config);
@@ -12458,6 +12535,10 @@ static int intel_atomic_check(struct drm_device *dev,
 		intel_state->cdclk.logical = dev_priv->cdclk.logical;
 	}
 
+	ret = icl_add_linked_planes(intel_state);
+	if (ret)
+		return ret;
+
 	ret = drm_atomic_helper_check_planes(dev, state);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b5d6f6887c13..272de906a001 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -539,6 +539,26 @@ struct intel_plane_state {
 	 */
 	int scaler_id;
 
+	/*
+	 * linked_plane:
+	 *
+	 * ICL planar formats require 2 planes that are updated as pairs.
+	 * This member is used to make sure the other plane is also updated
+	 * when required, and for update_slave() to find the correct
+	 * plane_state to pass as argument.
+	 */
+	struct intel_plane *linked_plane;
+
+	/*
+	 * slave:
+	 * If set don't update use the linked plane's state for updating
+	 * this plane during atomic commit with the update_slave() callback.
+	 *
+	 * It's also used by the watermark code to ignore wm calculations on
+	 * this plane. They're calculated by the linked plane's wm code.
+	 */
+	bool slave;
+
 	struct drm_intel_sprite_colorkey ckey;
 };
 
@@ -983,6 +1003,9 @@ struct intel_plane {
 	void (*update_plane)(struct intel_plane *plane,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct intel_plane_state *plane_state);
+	void (*update_slave)(struct intel_plane *plane,
+			     const struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *plane_state);
 	void (*disable_plane)(struct intel_plane *plane,
 			      struct intel_crtc *crtc);
 	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
@@ -1351,6 +1374,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
 }
 
+static inline struct intel_plane_state *
+intel_atomic_get_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)
+{
+	struct drm_plane_state *ret =
+		drm_atomic_get_plane_state(&state->base, &plane->base);
+
+	if (IS_ERR(ret))
+		return ERR_CAST(ret);
+
+	return to_intel_plane_state(ret);
+}
+
+static inline struct intel_plane_state *
+intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)
+{
+	return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
+								   &plane->base));
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
 				 struct intel_plane *plane)
@@ -2158,6 +2202,15 @@ struct intel_plane *
 skl_universal_plane_create(struct drm_i915_private *dev_priv,
 			   enum pipe pipe, enum plane_id plane_id);
 
+static inline bool icl_is_nv12_y_plane(enum plane_id id)
+{
+	/* Don't need to do a gen check, these planes are only available on gen11 */
+	if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
+		return true;
+
+	return false;
+}
+
 /* intel_tv.c */
 void intel_tv_init(struct drm_i915_private *dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3b136fdfd24f..d003c08bd9e4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5153,11 +5153,12 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
 	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
-	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	enum pipe pipe = intel_crtc->pipe;
 
 	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
+		struct drm_plane_state *plane_state;
+		struct intel_plane *linked;
 		enum plane_id plane_id = to_intel_plane(plane)->id;
 
 		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
@@ -5169,6 +5170,15 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state))
 			return PTR_ERR(plane_state);
+
+		/* Make sure linked plane is updated too */
+		linked = to_intel_plane_state(plane_state)->linked_plane;
+		if (!linked)
+			continue;
+
+		plane_state = drm_atomic_get_plane_state(state, &linked->base);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
 	}
 
 	return 0;
-- 
2.19.1

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

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

* [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4 Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 16:17   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3 Maarten Lankhorst
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

Skylake style watermarks program the UV parameters into wm->uv_wm,
and have a separate DDB allocation for UV blocks into the same plane.

Gen11 watermarks have a separate plane for Y and UV, with separate
mechanisms. The simplest way to make it work is to keep the current
way of programming watermarks and calculate the Y and UV plane
watermarks from the master plane.

Changes since v1:
- Constify crtc_state where possible.
- Make separate paths for planar formats in skl_build_pipe_wm() (Matt)
- Make separate paths for calculating total data rate. (Matt)
- Make sure UV watermarks are unused on gen11+ by adding a WARN. (Matt)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 301 ++++++++++++++++++++++----------
 1 file changed, 207 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d003c08bd9e4..ef95b9d7884b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3814,7 +3814,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 }
 
 static void
-skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 				   const struct intel_crtc_state *cstate,
 				   const u64 total_data_rate,
 				   struct skl_ddb_allocation *ddb,
@@ -3823,7 +3823,6 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 {
 	struct drm_atomic_state *state = cstate->base.state;
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct drm_crtc *for_crtc = cstate->base.crtc;
 	const struct drm_crtc_state *crtc_state;
 	const struct drm_crtc *crtc;
@@ -3945,14 +3944,9 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
 				      val & PLANE_CTL_ALPHA_MASK);
 
 	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
-	/*
-	 * FIXME: add proper NV12 support for ICL. Avoid reading unclaimed
-	 * registers for now.
-	 */
-	if (INTEL_GEN(dev_priv) < 11)
+	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
 		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
 
-	if (fourcc == DRM_FORMAT_NV12) {
 		skl_ddb_entry_init_from_hw(dev_priv,
 					   &ddb->plane[pipe][plane_id], val2);
 		skl_ddb_entry_init_from_hw(dev_priv,
@@ -4141,11 +4135,11 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 
 static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
-			     const struct drm_plane_state *pstate,
+			     const struct intel_plane_state *intel_pstate,
 			     const int plane)
 {
-	struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
-	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+	struct intel_plane *intel_plane =
+		to_intel_plane(intel_pstate->base.plane);
 	uint32_t data_rate;
 	uint32_t width = 0, height = 0;
 	struct drm_framebuffer *fb;
@@ -4156,7 +4150,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 	if (!intel_pstate->base.visible)
 		return 0;
 
-	fb = pstate->fb;
+	fb = intel_pstate->base.fb;
 	format = fb->format->format;
 
 	if (intel_plane->id == PLANE_CURSOR)
@@ -4206,25 +4200,80 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
 		enum plane_id plane_id = to_intel_plane(plane)->id;
 		u64 rate;
+		const struct intel_plane_state *intel_pstate =
+			to_intel_plane_state(pstate);
 
 		/* packed/y */
 		rate = skl_plane_relative_data_rate(intel_cstate,
-						    pstate, 0);
+						    intel_pstate, 0);
 		plane_data_rate[plane_id] = rate;
-
 		total_data_rate += rate;
 
 		/* uv-plane */
 		rate = skl_plane_relative_data_rate(intel_cstate,
-						    pstate, 1);
+						    intel_pstate, 1);
 		uv_plane_data_rate[plane_id] = rate;
-
 		total_data_rate += rate;
 	}
 
 	return total_data_rate;
 }
 
+static u64
+icl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
+				 u64 *plane_data_rate)
+{
+	struct drm_crtc_state *cstate = &intel_cstate->base;
+	struct drm_atomic_state *state = cstate->state;
+	struct drm_plane *plane;
+	const struct drm_plane_state *pstate;
+	u64 total_data_rate = 0;
+
+	if (WARN_ON(!state))
+		return 0;
+
+	/* Calculate and cache data rate for each plane */
+	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
+		const struct intel_plane_state *intel_pstate =
+			to_intel_plane_state(pstate);
+		enum plane_id plane_id = to_intel_plane(plane)->id;
+		u64 rate;
+
+		if (!intel_pstate->linked_plane) {
+			rate = skl_plane_relative_data_rate(intel_cstate,
+							    intel_pstate, 0);
+			plane_data_rate[plane_id] = rate;
+			total_data_rate += rate;
+		} else {
+			enum plane_id y_plane_id;
+
+			/*
+			 * The slave plane might not iterate in
+			 * drm_atomic_crtc_state_for_each_plane_state(),
+			 * and needs the master plane state which may be
+			 * NULL if we try get_new_plane_state(), so we
+			 * always calculate from the master.
+			 */
+			if (intel_pstate->slave)
+				continue;
+
+			/* Y plane rate is calculated on the slave */
+			rate = skl_plane_relative_data_rate(intel_cstate,
+							    intel_pstate, 0);
+			y_plane_id = intel_pstate->linked_plane->id;
+			plane_data_rate[y_plane_id] = rate;
+			total_data_rate += rate;
+
+			rate = skl_plane_relative_data_rate(intel_cstate,
+							    intel_pstate, 1);
+			plane_data_rate[plane_id] = rate;
+			total_data_rate += rate;
+		}
+	}
+
+	return total_data_rate;
+}
+
 static uint16_t
 skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane)
 {
@@ -4297,15 +4346,25 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
 
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, &cstate->base) {
 		enum plane_id plane_id = to_intel_plane(plane)->id;
+		struct intel_plane_state *plane_state = to_intel_plane_state(pstate);
 
 		if (plane_id == PLANE_CURSOR)
 			continue;
 
-		if (!pstate->visible)
+		/* slave plane must be invisible and calculated from master */
+		if (!pstate->visible || WARN_ON(plane_state->slave))
 			continue;
 
-		minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
-		uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
+		if (!plane_state->linked_plane) {
+			minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
+			uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
+		} else {
+			enum plane_id y_plane_id =
+				plane_state->linked_plane->id;
+
+			minimum[y_plane_id] = skl_ddb_min_alloc(pstate, 0);
+			minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
+		}
 	}
 
 	minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
@@ -4317,7 +4376,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 {
 	struct drm_atomic_state *state = cstate->base.state;
 	struct drm_crtc *crtc = cstate->base.crtc;
-	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
@@ -4343,11 +4402,18 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		return 0;
 	}
 
-	total_data_rate = skl_get_total_relative_data_rate(cstate,
-							   plane_data_rate,
-							   uv_plane_data_rate);
-	skl_ddb_get_pipe_allocation_limits(dev, cstate, total_data_rate, ddb,
-					   alloc, &num_active);
+	if (INTEL_GEN(dev_priv) < 11)
+		total_data_rate =
+			skl_get_total_relative_data_rate(cstate,
+							 plane_data_rate,
+							 uv_plane_data_rate);
+	else
+		total_data_rate =
+			icl_get_total_relative_data_rate(cstate,
+							 plane_data_rate);
+
+	skl_ddb_get_pipe_allocation_limits(dev_priv, cstate, total_data_rate,
+					   ddb, alloc, &num_active);
 	alloc_size = skl_ddb_entry_size(alloc);
 	if (alloc_size == 0)
 		return 0;
@@ -4417,6 +4483,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		uv_plane_blocks = uv_minimum[plane_id];
 		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
 
+		/* Gen11+ uses a separate plane for UV watermarks */
+		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
+
 		if (uv_data_rate) {
 			ddb->uv_plane[pipe][plane_id].start = start;
 			ddb->uv_plane[pipe][plane_id].end =
@@ -4473,7 +4542,7 @@ static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
 }
 
 static uint_fixed_16_16_t
-intel_get_linetime_us(struct intel_crtc_state *cstate)
+intel_get_linetime_us(const struct intel_crtc_state *cstate)
 {
 	uint32_t pixel_rate;
 	uint32_t crtc_htotal;
@@ -4517,7 +4586,7 @@ skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate,
 
 static int
 skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
-			    struct intel_crtc_state *cstate,
+			    const struct intel_crtc_state *cstate,
 			    const struct intel_plane_state *intel_pstate,
 			    struct skl_wm_params *wp, int plane_id)
 {
@@ -4624,7 +4693,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
 }
 
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
-				struct intel_crtc_state *cstate,
+				const struct intel_crtc_state *cstate,
 				const struct intel_plane_state *intel_pstate,
 				uint16_t ddb_allocation,
 				int level,
@@ -4784,38 +4853,22 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 static int
 skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
 		      struct skl_ddb_allocation *ddb,
-		      struct intel_crtc_state *cstate,
+		      const struct intel_crtc_state *cstate,
 		      const struct intel_plane_state *intel_pstate,
+		      uint16_t ddb_blocks,
 		      const struct skl_wm_params *wm_params,
 		      struct skl_plane_wm *wm,
-		      int plane_id)
+		      struct skl_wm_level *levels)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
-	struct drm_plane *plane = intel_pstate->base.plane;
-	struct intel_plane *intel_plane = to_intel_plane(plane);
-	uint16_t ddb_blocks;
-	enum pipe pipe = intel_crtc->pipe;
 	int level, max_level = ilk_wm_max_level(dev_priv);
-	enum plane_id intel_plane_id = intel_plane->id;
+	struct skl_wm_level *result_prev = &levels[0];
 	int ret;
 
 	if (WARN_ON(!intel_pstate->base.fb))
 		return -EINVAL;
 
-	ddb_blocks = plane_id ?
-		     skl_ddb_entry_size(&ddb->uv_plane[pipe][intel_plane_id]) :
-		     skl_ddb_entry_size(&ddb->plane[pipe][intel_plane_id]);
-
 	for (level = 0; level <= max_level; level++) {
-		struct skl_wm_level *result = plane_id ? &wm->uv_wm[level] :
-							  &wm->wm[level];
-		struct skl_wm_level *result_prev;
-
-		if (level)
-			result_prev = plane_id ? &wm->uv_wm[level - 1] :
-						  &wm->wm[level - 1];
-		else
-			result_prev = plane_id ? &wm->uv_wm[0] : &wm->wm[0];
+		struct skl_wm_level *result = &levels[level];
 
 		ret = skl_compute_plane_wm(dev_priv,
 					   cstate,
@@ -4827,6 +4880,8 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
 					   result);
 		if (ret)
 			return ret;
+
+		result_prev = result;
 	}
 
 	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
@@ -4836,7 +4891,7 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
 }
 
 static uint32_t
-skl_compute_linetime_wm(struct intel_crtc_state *cstate)
+skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
 {
 	struct drm_atomic_state *state = cstate->base.state;
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
@@ -4858,7 +4913,7 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 	return linetime_wm;
 }
 
-static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
+static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
 				      struct skl_wm_params *wp,
 				      struct skl_wm_level *wm_l0,
 				      uint16_t ddb_allocation,
@@ -4925,16 +4980,101 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
 	trans_wm->plane_en = false;
 }
 
+static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
+				       struct skl_pipe_wm *pipe_wm,
+				       enum plane_id plane_id,
+				       const struct intel_crtc_state *cstate,
+				       const struct intel_plane_state *pstate,
+				       int color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
+	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
+	struct skl_wm_params wm_params;
+	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
+	int ret;
+
+	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
+					  &wm_params, color_plane);
+	if (ret)
+		return ret;
+
+	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
+				    ddb_blocks, &wm_params, wm, wm->wm);
+
+	if (ret)
+		return ret;
+
+	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
+				  ddb_blocks, &wm->trans_wm);
+
+	return 0;
+}
+
+static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
+				     struct skl_pipe_wm *pipe_wm,
+				     const struct intel_crtc_state *cstate,
+				     const struct intel_plane_state *pstate)
+{
+	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
+
+	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
+}
+
+static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
+				     struct skl_pipe_wm *pipe_wm,
+				     const struct intel_crtc_state *cstate,
+				     const struct intel_plane_state *pstate)
+{
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	enum plane_id plane_id = plane->id;
+	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+	struct skl_wm_params wm_params;
+	enum pipe pipe = plane->pipe;
+	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
+	int ret;
+
+	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
+	if (ret)
+		return ret;
+
+	/* uv plane watermarks must also be validated for NV12/Planar */
+	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
+
+	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
+	if (ret)
+		return ret;
+
+	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
+				     ddb_blocks, &wm_params, wm, wm->uv_wm);
+}
+
+static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
+				     struct skl_pipe_wm *pipe_wm,
+				     const struct intel_crtc_state *cstate,
+				     const struct intel_plane_state *pstate)
+{
+	int ret;
+	enum plane_id y_plane_id = pstate->linked_plane->id;
+	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
+
+	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
+					  cstate, pstate, 0);
+	if (ret)
+		return ret;
+
+	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
+					   cstate, pstate, 1);
+}
+
 static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
 			     struct skl_ddb_allocation *ddb,
 			     struct skl_pipe_wm *pipe_wm)
 {
-	struct drm_device *dev = cstate->base.crtc->dev;
 	struct drm_crtc_state *crtc_state = &cstate->base;
-	const struct drm_i915_private *dev_priv = to_i915(dev);
 	struct drm_plane *plane;
 	const struct drm_plane_state *pstate;
-	struct skl_plane_wm *wm;
 	int ret;
 
 	/*
@@ -4946,44 +5086,21 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		const struct intel_plane_state *intel_pstate =
 						to_intel_plane_state(pstate);
-		enum plane_id plane_id = to_intel_plane(plane)->id;
-		struct skl_wm_params wm_params;
-		enum pipe pipe = to_intel_crtc(cstate->base.crtc)->pipe;
-		uint16_t ddb_blocks;
 
-		wm = &pipe_wm->planes[plane_id];
-		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
+		/* Watermarks calculated in master */
+		if (intel_pstate->slave)
+			continue;
 
-		ret = skl_compute_plane_wm_params(dev_priv, cstate,
-						  intel_pstate, &wm_params, 0);
-		if (ret)
-			return ret;
+		if (intel_pstate->linked_plane)
+			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
+		else if (intel_pstate->base.fb &&
+			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
+			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
+		else
+			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
 
-		ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
-					    intel_pstate, &wm_params, wm, 0);
 		if (ret)
 			return ret;
-
-		skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
-					  ddb_blocks, &wm->trans_wm);
-
-		/* uv plane watermarks must also be validated for NV12/Planar */
-		if (wm_params.is_planar) {
-			memset(&wm_params, 0, sizeof(struct skl_wm_params));
-			wm->is_planar = true;
-
-			ret = skl_compute_plane_wm_params(dev_priv, cstate,
-							  intel_pstate,
-							  &wm_params, 1);
-			if (ret)
-				return ret;
-
-			ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
-						    intel_pstate, &wm_params,
-						    wm, 1);
-			if (ret)
-				return ret;
-		}
 	}
 
 	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
@@ -5034,12 +5151,7 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
 			   &wm->trans_wm);
 
-	/* FIXME: add proper NV12 support for ICL. */
-	if (INTEL_GEN(dev_priv) >= 11)
-		return skl_ddb_entry_write(dev_priv,
-					   PLANE_BUF_CFG(pipe, plane_id),
-					   &ddb->plane[pipe][plane_id]);
-	if (wm->is_planar) {
+	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
 		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
 				    &ddb->uv_plane[pipe][plane_id]);
 		skl_ddb_entry_write(dev_priv,
@@ -5048,7 +5160,8 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 	} else {
 		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
 				    &ddb->plane[pipe][plane_id]);
-		I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
+		if (INTEL_GEN(dev_priv) < 11)
+			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
 	}
 }
 
-- 
2.19.1

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

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

* [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2 Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 14:47   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes Maarten Lankhorst
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

The first 3 planes (primary, sprite 0 and 1) have a dedicated chroma
upsampler to upscale YUV420 to YUV444 and the scaler should only be
used for upscaling. Because of this we shouldn't program the scalers
in planar mode if NV12 and the chroma upsampler are used. Instead
program the scalers like on normal planes.

Sprite 2 and 3 have no dedicated scaler, and need to program the
selected Y plane in the scaler mode.

Changes since v1:
- Make the comment less confusing.
Changes since v2:
- Fix checkpatch warning (Matt)
- gen10- -> Pre-gen11 (Ville)
- PS_SCALER_MODE_PACKED -> PS_SCALER_MODE_NORMAL. (Matt)
- Add comment about scaler mode in intel_atomic_setup_scaler(). (Matt)
- Rename need_scaling to need_scaler. (Matt)
- Move the crtc need_scaling check to skl_update_scaler_crtc().

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |  4 ++-
 drivers/gpu/drm/i915/intel_atomic.c  | 16 +++++++++---
 drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++--------------
 drivers/gpu/drm/i915/intel_drv.h     |  8 ++++++
 drivers/gpu/drm/i915/intel_sprite.c  |  3 ++-
 5 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 81f1c601987d..8a81e7c2fe25 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6819,7 +6819,7 @@ enum {
 #define SKL_PS_SCALER_MODE_HQ  (1 << 28)
 #define SKL_PS_SCALER_MODE_NV12 (2 << 28)
 #define PS_SCALER_MODE_PLANAR (1 << 29)
-#define PS_SCALER_MODE_PACKED (0 << 29)
+#define PS_SCALER_MODE_NORMAL (0 << 29)
 #define PS_PLANE_SEL_MASK  (7 << 25)
 #define PS_PLANE_SEL(plane) (((plane) + 1) << 25)
 #define PS_FILTER_MASK         (3 << 23)
@@ -6836,6 +6836,8 @@ enum {
 #define PS_VADAPT_MODE_LEAST_ADAPT (0 << 5)
 #define PS_VADAPT_MODE_MOD_ADAPT   (1 << 5)
 #define PS_VADAPT_MODE_MOST_ADAPT  (3 << 5)
+#define PS_PLANE_Y_SEL_MASK  (7 << 5)
+#define PS_PLANE_Y_SEL(plane) (((plane) + 1) << 5)
 
 #define _PS_PWR_GATE_1A     0x68160
 #define _PS_PWR_GATE_2A     0x68260
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 20bfc89c652c..7238ab615548 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -233,13 +233,23 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
 	    plane_state->base.fb->format->is_yuv &&
 	    plane_state->base.fb->format->num_planes > 1) {
 		if (INTEL_GEN(dev_priv) == 9 &&
-		    !IS_GEMINILAKE(dev_priv))
+		    !IS_GEMINILAKE(dev_priv)) {
 			mode = SKL_PS_SCALER_MODE_NV12;
-		else
+		} else if (icl_is_hdr_plane(to_intel_plane(plane_state->base.plane))) {
+			/*
+			 * On gen11+'s HDR planes we only use the scaler for
+			 * scaling. They have a dedicated chroma upsampler, so
+			 * we don't need the scaler to upsample the UV plane.
+			 */
+			mode = PS_SCALER_MODE_NORMAL;
+		} else {
 			mode = PS_SCALER_MODE_PLANAR;
 
+			if (plane_state->linked_plane)
+				mode |= PS_PLANE_Y_SEL(plane_state->linked_plane->id);
+		}
 	} else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) {
-		mode = PS_SCALER_MODE_PACKED;
+		mode = PS_SCALER_MODE_NORMAL;
 	} else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) {
 		/*
 		 * when only 1 scaler is in use on a pipe with 2 scalers
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cbb3fb1d5ad4..5997097177e9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4836,8 +4836,7 @@ static int
 skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 		  unsigned int scaler_user, int *scaler_id,
 		  int src_w, int src_h, int dst_w, int dst_h,
-		  bool plane_scaler_check,
-		  uint32_t pixel_format)
+		  const struct drm_format_info *format, bool need_scaler)
 {
 	struct intel_crtc_scaler_state *scaler_state =
 		&crtc_state->scaler_state;
@@ -4846,22 +4845,14 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->base.adjusted_mode;
-	int need_scaling;
 
 	/*
 	 * Src coordinates are already rotated by 270 degrees for
 	 * the 90/270 degree plane rotation cases (to match the
 	 * GTT mapping), hence no need to account for rotation here.
 	 */
-	need_scaling = src_w != dst_w || src_h != dst_h;
-
-	if (plane_scaler_check)
-		if (pixel_format == DRM_FORMAT_NV12)
-			need_scaling = true;
-
-	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
-	    scaler_user == SKL_CRTC_INDEX)
-		need_scaling = true;
+	if (src_w != dst_w || src_h != dst_h)
+		need_scaler = true;
 
 	/*
 	 * Scaling/fitting not supported in IF-ID mode in GEN9+
@@ -4870,7 +4861,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 	 * for NV12.
 	 */
 	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
-	    need_scaling && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+	    need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
 		return -EINVAL;
 	}
@@ -4885,7 +4876,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 	 * update to free the scaler is done in plane/panel-fit programming.
 	 * For this purpose crtc/plane_state->scaler_id isn't reset here.
 	 */
-	if (force_detach || !need_scaling) {
+	if (force_detach || !need_scaler) {
 		if (*scaler_id >= 0) {
 			scaler_state->scaler_users &= ~(1 << scaler_user);
 			scaler_state->scalers[*scaler_id].in_use = 0;
@@ -4899,7 +4890,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 		return 0;
 	}
 
-	if (plane_scaler_check && pixel_format == DRM_FORMAT_NV12 &&
+	if (format && format->format == DRM_FORMAT_NV12 &&
 	    (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) {
 		DRM_DEBUG_KMS("NV12: src dimensions not met\n");
 		return -EINVAL;
@@ -4942,12 +4933,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 int skl_update_scaler_crtc(struct intel_crtc_state *state)
 {
 	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
+	bool need_scaler = false;
+
+	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+		need_scaler = true;
 
 	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
 				 &state->scaler_state.scaler_id,
 				 state->pipe_src_w, state->pipe_src_h,
 				 adjusted_mode->crtc_hdisplay,
-				 adjusted_mode->crtc_vdisplay, false, 0);
+				 adjusted_mode->crtc_vdisplay, NULL, need_scaler);
 }
 
 /**
@@ -4962,13 +4957,17 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
 static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
 				   struct intel_plane_state *plane_state)
 {
-
 	struct intel_plane *intel_plane =
 		to_intel_plane(plane_state->base.plane);
 	struct drm_framebuffer *fb = plane_state->base.fb;
 	int ret;
-
 	bool force_detach = !fb || !plane_state->base.visible;
+	bool need_scaler = false;
+
+	/* Pre-gen11 and SDR planes always need a scaler for planar formats. */
+	if (!icl_is_hdr_plane(intel_plane) &&
+	    fb && fb->format->format == DRM_FORMAT_NV12)
+		need_scaler = true;
 
 	ret = skl_update_scaler(crtc_state, force_detach,
 				drm_plane_index(&intel_plane->base),
@@ -4977,7 +4976,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
 				drm_rect_height(&plane_state->base.src) >> 16,
 				drm_rect_width(&plane_state->base.dst),
 				drm_rect_height(&plane_state->base.dst),
-				fb ? true : false, fb ? fb->format->format : 0);
+				fb ? fb->format : NULL, need_scaler);
 
 	if (ret || plane_state->scaler_id < 0)
 		return ret;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 272de906a001..f1d196bcdb66 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2211,6 +2211,14 @@ static inline bool icl_is_nv12_y_plane(enum plane_id id)
 	return false;
 }
 
+static inline bool icl_is_hdr_plane(struct intel_plane *plane)
+{
+	if (INTEL_GEN(to_i915(plane->base.dev)) < 11)
+		return false;
+
+	return plane->id < PLANE_SPRITE2;
+}
+
 /* intel_tv.c */
 void intel_tv_init(struct drm_i915_private *dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 7cd59eee5cad..a2a4328107b6 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -332,7 +332,8 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 	crtc_h--;
 
 	/* TODO: handle sub-pixel coordinates */
-	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
+	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
+	    !icl_is_hdr_plane(plane)) {
 		y_hphase = skl_scaler_calc_phase(1, false);
 		y_vphase = skl_scaler_calc_phase(1, false);
 
-- 
2.19.1

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

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

* [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (4 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3 Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 14:50   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3 Maarten Lankhorst
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

We configure the chroma upsampler with the same chroma siting as
used by the scaler for consistency, the chroma upsampler is used
instead of the scaler for YUV 4:2:0 on ICL's HDR planes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
Can't test this completely until we have correct colors by programming
the input CSC, but should be easy to fix the phases afterwards..

 drivers/gpu/drm/i915/i915_reg.h     | 22 ++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sprite.c | 22 ++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8a81e7c2fe25..17b38ccbff6e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6524,6 +6524,19 @@ enum {
 #define _PLANE_AUX_DIST_2_A			0x702c0
 #define _PLANE_AUX_OFFSET_1_A			0x701c4
 #define _PLANE_AUX_OFFSET_2_A			0x702c4
+#define _PLANE_CUS_CTL_1_A			0x701c8
+#define _PLANE_CUS_CTL_2_A			0x702c8
+#define  PLANE_CUS_ENABLE			(1 << 31)
+#define  PLANE_CUS_PLANE_6			(0 << 30)
+#define  PLANE_CUS_PLANE_7			(1 << 30)
+#define  PLANE_CUS_HPHASE_SIGN_NEGATIVE		(1 << 19)
+#define  PLANE_CUS_HPHASE_0			(0 << 16)
+#define  PLANE_CUS_HPHASE_0_25			(1 << 16)
+#define  PLANE_CUS_HPHASE_0_5			(2 << 16)
+#define  PLANE_CUS_VPHASE_SIGN_NEGATIVE		(1 << 15)
+#define  PLANE_CUS_VPHASE_0			(0 << 12)
+#define  PLANE_CUS_VPHASE_0_25			(1 << 12)
+#define  PLANE_CUS_VPHASE_0_5			(2 << 12)
 #define _PLANE_COLOR_CTL_1_A			0x701CC /* GLK+ */
 #define _PLANE_COLOR_CTL_2_A			0x702CC /* GLK+ */
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
@@ -6661,6 +6674,15 @@ enum {
 #define PLANE_AUX_OFFSET(pipe, plane)   \
 	_MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
 
+#define _PLANE_CUS_CTL_1_B		0x711c8
+#define _PLANE_CUS_CTL_2_B		0x712c8
+#define _PLANE_CUS_CTL_1(pipe)       \
+		_PIPE(pipe, _PLANE_CUS_CTL_1_A, _PLANE_CUS_CTL_1_B)
+#define _PLANE_CUS_CTL_2(pipe)       \
+		_PIPE(pipe, _PLANE_CUS_CTL_2_A, _PLANE_CUS_CTL_2_B)
+#define PLANE_CUS_CTL(pipe, plane)   \
+	_MMIO_PLANE(plane, _PLANE_CUS_CTL_1(pipe), _PLANE_CUS_CTL_2(pipe))
+
 #define _PLANE_COLOR_CTL_1_B			0x711CC
 #define _PLANE_COLOR_CTL_2_B			0x712CC
 #define _PLANE_COLOR_CTL_3_B			0x713CC
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index a2a4328107b6..2ec5c5df0d24 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -380,6 +380,7 @@ skl_update_plane(struct intel_plane *plane,
 	uint32_t y = plane_state->color_plane[0].y;
 	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
 	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
+	struct intel_plane *linked = plane_state->linked_plane;
 	unsigned long irqflags;
 	u32 keymsk = 0, keymax = 0;
 
@@ -417,6 +418,27 @@ skl_update_plane(struct intel_plane *plane,
 		      (plane_state->color_plane[1].y << 16) |
 		      plane_state->color_plane[1].x);
 
+	if (icl_is_hdr_plane(plane)) {
+		u32 cus_ctl = 0;
+
+		if (linked) {
+			/* Enable and use MPEG-2 chroma siting */
+			cus_ctl = PLANE_CUS_ENABLE |
+				PLANE_CUS_HPHASE_0 |
+				PLANE_CUS_VPHASE_SIGN_NEGATIVE |
+				PLANE_CUS_VPHASE_0_25;
+
+			if (linked->id == PLANE_SPRITE5)
+				cus_ctl |= PLANE_CUS_PLANE_7;
+			else if (linked->id == PLANE_SPRITE4)
+				cus_ctl |= PLANE_CUS_PLANE_6;
+			else
+				MISSING_CASE(linked->id);
+		}
+
+		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
+	}
+
 	/* program plane scaler */
 	if (plane_state->scaler_id >= 0) {
 		skl_program_scaler(dev_priv, plane, crtc_state, plane_state);
-- 
2.19.1

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

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

* [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (5 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 14:51   ` Ville Syrjälä
  2018-10-18 11:51 ` [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11 Maarten Lankhorst
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

The UV plane is the master plane that does all color correction etc.
It needs to be programmed with the dimensions for color plane 1 (UV).

The Y plane just feeds the Y pixels to it. Program the scaler from the
master only, and set PLANE_CTL_YUV420_Y_PLANE on the slave plane.

Changes since v1:
- Make a common skl_program_plane, and use it for both plane updates.
Changes since v2:
- Make color_plane explicit, to clarify skl_update_plane(). (Ville)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h     |  1 +
 drivers/gpu/drm/i915/intel_sprite.c | 47 +++++++++++++++++++++++------
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 17b38ccbff6e..f8e68e88f98d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6473,6 +6473,7 @@ enum {
 #define   PLANE_CTL_KEY_ENABLE_DESTINATION	(2 << 21)
 #define   PLANE_CTL_ORDER_BGRX			(0 << 20)
 #define   PLANE_CTL_ORDER_RGBX			(1 << 20)
+#define   PLANE_CTL_YUV420_Y_PLANE		(1 << 19)
 #define   PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709	(1 << 18)
 #define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
 #define   PLANE_CTL_YUV422_YUYV			(0 << 16)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 2ec5c5df0d24..5d04983a28ec 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -362,22 +362,22 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
 }
 
 static void
-skl_update_plane(struct intel_plane *plane,
-		 const struct intel_crtc_state *crtc_state,
-		 const struct intel_plane_state *plane_state)
+skl_program_plane(struct intel_plane *plane,
+		  const struct intel_crtc_state *crtc_state,
+		  const struct intel_plane_state *plane_state,
+		  int color_plane, bool slave, u32 plane_ctl)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum plane_id plane_id = plane->id;
 	enum pipe pipe = plane->pipe;
-	u32 plane_ctl = plane_state->ctl;
 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
-	u32 surf_addr = plane_state->color_plane[0].offset;
-	u32 stride = skl_plane_stride(plane_state, 0);
+	u32 surf_addr = plane_state->color_plane[color_plane].offset;
+	u32 stride = skl_plane_stride(plane_state, color_plane);
 	u32 aux_stride = skl_plane_stride(plane_state, 1);
 	int crtc_x = plane_state->base.dst.x1;
 	int crtc_y = plane_state->base.dst.y1;
-	uint32_t x = plane_state->color_plane[0].x;
-	uint32_t y = plane_state->color_plane[0].y;
+	uint32_t x = plane_state->color_plane[color_plane].x;
+	uint32_t y = plane_state->color_plane[color_plane].y;
 	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
 	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
 	struct intel_plane *linked = plane_state->linked_plane;
@@ -441,7 +441,9 @@ skl_update_plane(struct intel_plane *plane,
 
 	/* program plane scaler */
 	if (plane_state->scaler_id >= 0) {
-		skl_program_scaler(dev_priv, plane, crtc_state, plane_state);
+		if (!slave)
+			skl_program_scaler(dev_priv, plane,
+					   crtc_state, plane_state);
 
 		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
 	} else {
@@ -456,7 +458,32 @@ skl_update_plane(struct intel_plane *plane,
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
+void
+skl_update_plane(struct intel_plane *plane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	int color_plane = 0;
+
+	if (plane_state->linked_plane) {
+		/* Program the UV plane */
+		color_plane = 1;
+	}
+
+	skl_program_plane(plane, crtc_state, plane_state,
+			  color_plane, false, plane_state->ctl);
+}
+
 static void
+icl_update_slave(struct intel_plane *plane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	skl_program_plane(plane, crtc_state, plane_state, 0, true,
+			  plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
+}
+
+void
 skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
@@ -1909,6 +1936,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 	plane->disable_plane = skl_disable_plane;
 	plane->get_hw_state = skl_plane_get_hw_state;
 	plane->check_plane = skl_plane_check;
+	if (icl_is_nv12_y_plane(plane_id))
+		plane->update_slave = icl_update_slave;
 
 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
 		formats = skl_planar_formats;
-- 
2.19.1

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

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

* [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (6 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3 Maarten Lankhorst
@ 2018-10-18 11:51 ` Maarten Lankhorst
  2018-10-18 16:20   ` Ville Syrjälä
  2018-10-18 12:03 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format Patchwork
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 11:51 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5997097177e9..8299eb9193b4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14508,7 +14508,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 		break;
 	case DRM_FORMAT_NV12:
 		if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
-		    IS_BROXTON(dev_priv) || INTEL_GEN(dev_priv) >= 11) {
+		    IS_BROXTON(dev_priv)) {
 			DRM_DEBUG_KMS("unsupported pixel format: %s\n",
 				      drm_get_format_name(mode_cmd->pixel_format,
 							  &format_name));
-- 
2.19.1

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

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

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (7 preceding siblings ...)
  2018-10-18 11:51 ` [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11 Maarten Lankhorst
@ 2018-10-18 12:03 ` Patchwork
  2018-10-18 12:06 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-18 12:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format.
URL   : https://patchwork.freedesktop.org/series/51178/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
0cce6a850fe7 drm/i915: Fix unsigned overflow when calculating total data rate
-:36: CHECK:CAMELCASE: Avoid CamelCase: <GBps>
#36: FILE: drivers/gpu/drm/i915/intel_pm.c:3806:
+	if (num_active > 1 || total_data_bw >= GBps(12)) {

total: 0 errors, 0 warnings, 1 checks, 130 lines checked
da30fc0fcbea drm/i915/gen11: Enable 6 sprites on gen11
cc5dddbae715 drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
-:18: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#18: 
- Put all the state updating login in intel_plane_atomic_check_with_state().

-:268: CHECK:BOOL_MEMBER: Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384
#268: FILE: drivers/gpu/drm/i915/intel_drv.h:560:
+	bool slave;

-:289: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#289: FILE: drivers/gpu/drm/i915/intel_drv.h:1379:
+intel_atomic_get_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)

total: 0 errors, 1 warnings, 2 checks, 301 lines checked
129dfb4612d2 drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
0148ba7a688e drm/i915/gen11: Program the scalers correctly for planar formats, v3.
3d086656de25 drm/i915/gen11: Program the chroma upsampler for HDR planes.
-:46: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#46: FILE: drivers/gpu/drm/i915/i915_reg.h:6683:
+#define PLANE_CUS_CTL(pipe, plane)   \
+	_MMIO_PLANE(plane, _PLANE_CUS_CTL_1(pipe), _PLANE_CUS_CTL_2(pipe))

total: 0 errors, 0 warnings, 1 checks, 68 lines checked
71ec9be923cf drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
149684076366 drm/i915/gen11: Expose planar format support on gen11.
-:7: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

total: 0 errors, 1 warnings, 0 checks, 8 lines checked

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

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

* ✗ Fi.CI.SPARSE: warning for drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (8 preceding siblings ...)
  2018-10-18 12:03 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format Patchwork
@ 2018-10-18 12:06 ` Patchwork
  2018-10-18 12:19 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-18 12:06 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format.
URL   : https://patchwork.freedesktop.org/series/51178/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Fix unsigned overflow when calculating total data rate
Okay!

Commit: drm/i915/gen11: Enable 6 sprites on gen11
Okay!

Commit: drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
Okay!

Commit: drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
Okay!

Commit: drm/i915/gen11: Program the scalers correctly for planar formats, v3.
Okay!

Commit: drm/i915/gen11: Program the chroma upsampler for HDR planes.
Okay!

Commit: drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
+drivers/gpu/drm/i915/intel_sprite.c:462:1: warning: symbol 'skl_update_plane' was not declared. Should it be static?
+drivers/gpu/drm/i915/intel_sprite.c:487:1: warning: symbol 'skl_disable_plane' was not declared. Should it be static?

Commit: drm/i915/gen11: Expose planar format support on gen11.
Okay!

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

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

* ✓ Fi.CI.BAT: success for drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (9 preceding siblings ...)
  2018-10-18 12:06 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-10-18 12:19 ` Patchwork
  2018-10-18 15:16 ` [PATCH v2 0/8] " Ville Syrjälä
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-18 12:19 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format.
URL   : https://patchwork.freedesktop.org/series/51178/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5005 -> Patchwork_10503 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/51178/revisions/1/mbox/

== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_exec_suspend@basic-s4-devices:
      fi-blb-e6850:       PASS -> INCOMPLETE (fdo#107718)

    igt@kms_flip@basic-flip-vs-modeset:
      fi-skl-6700hq:      PASS -> DMESG-WARN (fdo#105998)

    igt@kms_frontbuffer_tracking@basic:
      fi-hsw-peppy:       PASS -> DMESG-WARN (fdo#102614)

    igt@kms_pipe_crc_basic@read-crc-pipe-b:
      fi-byt-clapper:     PASS -> FAIL (fdo#107362) +1

    
  fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614
  fdo#105998 https://bugs.freedesktop.org/show_bug.cgi?id=105998
  fdo#107362 https://bugs.freedesktop.org/show_bug.cgi?id=107362
  fdo#107718 https://bugs.freedesktop.org/show_bug.cgi?id=107718


== Participating hosts (42 -> 40) ==

  Additional (1): fi-icl-u2 
  Missing    (3): fi-ilk-m540 fi-byt-squawks fi-bsw-cyan 


== Build changes ==

    * Linux: CI_DRM_5005 -> Patchwork_10503

  CI_DRM_5005: 7a27ee6b5f714f6852abb0098990a05675bd9d55 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4683: 7766b1e2348b32cc8ed58a972c6fd53b20279549 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10503: 14968407636696c468f4da00b159adc0b447ff49 @ git://anongit.freedesktop.org/gfx-ci/linux


== Kernel 32bit build ==

Warning: Kernel 32bit buildtest failed:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10503/build_32bit.log

  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
Kernel: arch/x86/boot/bzImage is ready  (#1)
  Building modules, stage 2.
  MODPOST 110 modules
ERROR: "__udivdi3" [drivers/gpu/drm/i915/i915.ko] undefined!
scripts/Makefile.modpost:92: recipe for target '__modpost' failed
make[1]: *** [__modpost] Error 1
Makefile:1227: recipe for target 'modules' failed
make: *** [modules] Error 2


== Linux commits ==

149684076366 drm/i915/gen11: Expose planar format support on gen11.
71ec9be923cf drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
3d086656de25 drm/i915/gen11: Program the chroma upsampler for HDR planes.
0148ba7a688e drm/i915/gen11: Program the scalers correctly for planar formats, v3.
129dfb4612d2 drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
cc5dddbae715 drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
da30fc0fcbea drm/i915/gen11: Enable 6 sprites on gen11
0cce6a850fe7 drm/i915: Fix unsigned overflow when calculating total data rate

== Logs ==

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

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

* Re: [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3.
  2018-10-18 11:51 ` [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3 Maarten Lankhorst
@ 2018-10-18 14:47   ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 14:47 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:31PM +0200, Maarten Lankhorst wrote:
> The first 3 planes (primary, sprite 0 and 1) have a dedicated chroma
> upsampler to upscale YUV420 to YUV444 and the scaler should only be
> used for upscaling. Because of this we shouldn't program the scalers
> in planar mode if NV12 and the chroma upsampler are used. Instead
> program the scalers like on normal planes.
> 
> Sprite 2 and 3 have no dedicated scaler, and need to program the
> selected Y plane in the scaler mode.
> 
> Changes since v1:
> - Make the comment less confusing.
> Changes since v2:
> - Fix checkpatch warning (Matt)
> - gen10- -> Pre-gen11 (Ville)
> - PS_SCALER_MODE_PACKED -> PS_SCALER_MODE_NORMAL. (Matt)
> - Add comment about scaler mode in intel_atomic_setup_scaler(). (Matt)
> - Rename need_scaling to need_scaler. (Matt)
> - Move the crtc need_scaling check to skl_update_scaler_crtc().
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I like it.

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

> ---
>  drivers/gpu/drm/i915/i915_reg.h      |  4 ++-
>  drivers/gpu/drm/i915/intel_atomic.c  | 16 +++++++++---
>  drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++--------------
>  drivers/gpu/drm/i915/intel_drv.h     |  8 ++++++
>  drivers/gpu/drm/i915/intel_sprite.c  |  3 ++-
>  5 files changed, 44 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 81f1c601987d..8a81e7c2fe25 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6819,7 +6819,7 @@ enum {
>  #define SKL_PS_SCALER_MODE_HQ  (1 << 28)
>  #define SKL_PS_SCALER_MODE_NV12 (2 << 28)
>  #define PS_SCALER_MODE_PLANAR (1 << 29)
> -#define PS_SCALER_MODE_PACKED (0 << 29)
> +#define PS_SCALER_MODE_NORMAL (0 << 29)
>  #define PS_PLANE_SEL_MASK  (7 << 25)
>  #define PS_PLANE_SEL(plane) (((plane) + 1) << 25)
>  #define PS_FILTER_MASK         (3 << 23)
> @@ -6836,6 +6836,8 @@ enum {
>  #define PS_VADAPT_MODE_LEAST_ADAPT (0 << 5)
>  #define PS_VADAPT_MODE_MOD_ADAPT   (1 << 5)
>  #define PS_VADAPT_MODE_MOST_ADAPT  (3 << 5)
> +#define PS_PLANE_Y_SEL_MASK  (7 << 5)
> +#define PS_PLANE_Y_SEL(plane) (((plane) + 1) << 5)
>  
>  #define _PS_PWR_GATE_1A     0x68160
>  #define _PS_PWR_GATE_2A     0x68260
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 20bfc89c652c..7238ab615548 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -233,13 +233,23 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
>  	    plane_state->base.fb->format->is_yuv &&
>  	    plane_state->base.fb->format->num_planes > 1) {
>  		if (INTEL_GEN(dev_priv) == 9 &&
> -		    !IS_GEMINILAKE(dev_priv))
> +		    !IS_GEMINILAKE(dev_priv)) {
>  			mode = SKL_PS_SCALER_MODE_NV12;
> -		else
> +		} else if (icl_is_hdr_plane(to_intel_plane(plane_state->base.plane))) {
> +			/*
> +			 * On gen11+'s HDR planes we only use the scaler for
> +			 * scaling. They have a dedicated chroma upsampler, so
> +			 * we don't need the scaler to upsample the UV plane.
> +			 */
> +			mode = PS_SCALER_MODE_NORMAL;
> +		} else {
>  			mode = PS_SCALER_MODE_PLANAR;
>  
> +			if (plane_state->linked_plane)
> +				mode |= PS_PLANE_Y_SEL(plane_state->linked_plane->id);
> +		}
>  	} else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) {
> -		mode = PS_SCALER_MODE_PACKED;
> +		mode = PS_SCALER_MODE_NORMAL;
>  	} else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) {
>  		/*
>  		 * when only 1 scaler is in use on a pipe with 2 scalers
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index cbb3fb1d5ad4..5997097177e9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4836,8 +4836,7 @@ static int
>  skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  		  unsigned int scaler_user, int *scaler_id,
>  		  int src_w, int src_h, int dst_w, int dst_h,
> -		  bool plane_scaler_check,
> -		  uint32_t pixel_format)
> +		  const struct drm_format_info *format, bool need_scaler)
>  {
>  	struct intel_crtc_scaler_state *scaler_state =
>  		&crtc_state->scaler_state;
> @@ -4846,22 +4845,14 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>  	const struct drm_display_mode *adjusted_mode =
>  		&crtc_state->base.adjusted_mode;
> -	int need_scaling;
>  
>  	/*
>  	 * Src coordinates are already rotated by 270 degrees for
>  	 * the 90/270 degree plane rotation cases (to match the
>  	 * GTT mapping), hence no need to account for rotation here.
>  	 */
> -	need_scaling = src_w != dst_w || src_h != dst_h;
> -
> -	if (plane_scaler_check)
> -		if (pixel_format == DRM_FORMAT_NV12)
> -			need_scaling = true;
> -
> -	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
> -	    scaler_user == SKL_CRTC_INDEX)
> -		need_scaling = true;
> +	if (src_w != dst_w || src_h != dst_h)
> +		need_scaler = true;
>  
>  	/*
>  	 * Scaling/fitting not supported in IF-ID mode in GEN9+
> @@ -4870,7 +4861,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  	 * for NV12.
>  	 */
>  	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
> -	    need_scaling && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> +	    need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>  		DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
>  		return -EINVAL;
>  	}
> @@ -4885,7 +4876,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  	 * update to free the scaler is done in plane/panel-fit programming.
>  	 * For this purpose crtc/plane_state->scaler_id isn't reset here.
>  	 */
> -	if (force_detach || !need_scaling) {
> +	if (force_detach || !need_scaler) {
>  		if (*scaler_id >= 0) {
>  			scaler_state->scaler_users &= ~(1 << scaler_user);
>  			scaler_state->scalers[*scaler_id].in_use = 0;
> @@ -4899,7 +4890,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  		return 0;
>  	}
>  
> -	if (plane_scaler_check && pixel_format == DRM_FORMAT_NV12 &&
> +	if (format && format->format == DRM_FORMAT_NV12 &&
>  	    (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) {
>  		DRM_DEBUG_KMS("NV12: src dimensions not met\n");
>  		return -EINVAL;
> @@ -4942,12 +4933,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  int skl_update_scaler_crtc(struct intel_crtc_state *state)
>  {
>  	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
> +	bool need_scaler = false;
> +
> +	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
> +		need_scaler = true;
>  
>  	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
>  				 &state->scaler_state.scaler_id,
>  				 state->pipe_src_w, state->pipe_src_h,
>  				 adjusted_mode->crtc_hdisplay,
> -				 adjusted_mode->crtc_vdisplay, false, 0);
> +				 adjusted_mode->crtc_vdisplay, NULL, need_scaler);
>  }
>  
>  /**
> @@ -4962,13 +4957,17 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
>  static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
>  				   struct intel_plane_state *plane_state)
>  {
> -
>  	struct intel_plane *intel_plane =
>  		to_intel_plane(plane_state->base.plane);
>  	struct drm_framebuffer *fb = plane_state->base.fb;
>  	int ret;
> -
>  	bool force_detach = !fb || !plane_state->base.visible;
> +	bool need_scaler = false;
> +
> +	/* Pre-gen11 and SDR planes always need a scaler for planar formats. */
> +	if (!icl_is_hdr_plane(intel_plane) &&
> +	    fb && fb->format->format == DRM_FORMAT_NV12)
> +		need_scaler = true;
>  
>  	ret = skl_update_scaler(crtc_state, force_detach,
>  				drm_plane_index(&intel_plane->base),
> @@ -4977,7 +4976,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
>  				drm_rect_height(&plane_state->base.src) >> 16,
>  				drm_rect_width(&plane_state->base.dst),
>  				drm_rect_height(&plane_state->base.dst),
> -				fb ? true : false, fb ? fb->format->format : 0);
> +				fb ? fb->format : NULL, need_scaler);
>  
>  	if (ret || plane_state->scaler_id < 0)
>  		return ret;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 272de906a001..f1d196bcdb66 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -2211,6 +2211,14 @@ static inline bool icl_is_nv12_y_plane(enum plane_id id)
>  	return false;
>  }
>  
> +static inline bool icl_is_hdr_plane(struct intel_plane *plane)
> +{
> +	if (INTEL_GEN(to_i915(plane->base.dev)) < 11)
> +		return false;
> +
> +	return plane->id < PLANE_SPRITE2;
> +}
> +
>  /* intel_tv.c */
>  void intel_tv_init(struct drm_i915_private *dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 7cd59eee5cad..a2a4328107b6 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -332,7 +332,8 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
>  	crtc_h--;
>  
>  	/* TODO: handle sub-pixel coordinates */
> -	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
> +	if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
> +	    !icl_is_hdr_plane(plane)) {
>  		y_hphase = skl_scaler_calc_phase(1, false);
>  		y_vphase = skl_scaler_calc_phase(1, false);
>  
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes.
  2018-10-18 11:51 ` [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes Maarten Lankhorst
@ 2018-10-18 14:50   ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 14:50 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:32PM +0200, Maarten Lankhorst wrote:
> We configure the chroma upsampler with the same chroma siting as
> used by the scaler for consistency, the chroma upsampler is used
> instead of the scaler for YUV 4:2:0 on ICL's HDR planes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> Can't test this completely until we have correct colors by programming
> the input CSC, but should be easy to fix the phases afterwards..

Aye. The current numbers can make sense, but testing would be nice
indeed. But as you say it's easy to change later.

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

> 
>  drivers/gpu/drm/i915/i915_reg.h     | 22 ++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_sprite.c | 22 ++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8a81e7c2fe25..17b38ccbff6e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6524,6 +6524,19 @@ enum {
>  #define _PLANE_AUX_DIST_2_A			0x702c0
>  #define _PLANE_AUX_OFFSET_1_A			0x701c4
>  #define _PLANE_AUX_OFFSET_2_A			0x702c4
> +#define _PLANE_CUS_CTL_1_A			0x701c8
> +#define _PLANE_CUS_CTL_2_A			0x702c8
> +#define  PLANE_CUS_ENABLE			(1 << 31)
> +#define  PLANE_CUS_PLANE_6			(0 << 30)
> +#define  PLANE_CUS_PLANE_7			(1 << 30)
> +#define  PLANE_CUS_HPHASE_SIGN_NEGATIVE		(1 << 19)
> +#define  PLANE_CUS_HPHASE_0			(0 << 16)
> +#define  PLANE_CUS_HPHASE_0_25			(1 << 16)
> +#define  PLANE_CUS_HPHASE_0_5			(2 << 16)
> +#define  PLANE_CUS_VPHASE_SIGN_NEGATIVE		(1 << 15)
> +#define  PLANE_CUS_VPHASE_0			(0 << 12)
> +#define  PLANE_CUS_VPHASE_0_25			(1 << 12)
> +#define  PLANE_CUS_VPHASE_0_5			(2 << 12)
>  #define _PLANE_COLOR_CTL_1_A			0x701CC /* GLK+ */
>  #define _PLANE_COLOR_CTL_2_A			0x702CC /* GLK+ */
>  #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
> @@ -6661,6 +6674,15 @@ enum {
>  #define PLANE_AUX_OFFSET(pipe, plane)   \
>  	_MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
>  
> +#define _PLANE_CUS_CTL_1_B		0x711c8
> +#define _PLANE_CUS_CTL_2_B		0x712c8
> +#define _PLANE_CUS_CTL_1(pipe)       \
> +		_PIPE(pipe, _PLANE_CUS_CTL_1_A, _PLANE_CUS_CTL_1_B)
> +#define _PLANE_CUS_CTL_2(pipe)       \
> +		_PIPE(pipe, _PLANE_CUS_CTL_2_A, _PLANE_CUS_CTL_2_B)
> +#define PLANE_CUS_CTL(pipe, plane)   \
> +	_MMIO_PLANE(plane, _PLANE_CUS_CTL_1(pipe), _PLANE_CUS_CTL_2(pipe))
> +
>  #define _PLANE_COLOR_CTL_1_B			0x711CC
>  #define _PLANE_COLOR_CTL_2_B			0x712CC
>  #define _PLANE_COLOR_CTL_3_B			0x713CC
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index a2a4328107b6..2ec5c5df0d24 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -380,6 +380,7 @@ skl_update_plane(struct intel_plane *plane,
>  	uint32_t y = plane_state->color_plane[0].y;
>  	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
>  	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
> +	struct intel_plane *linked = plane_state->linked_plane;
>  	unsigned long irqflags;
>  	u32 keymsk = 0, keymax = 0;
>  
> @@ -417,6 +418,27 @@ skl_update_plane(struct intel_plane *plane,
>  		      (plane_state->color_plane[1].y << 16) |
>  		      plane_state->color_plane[1].x);
>  
> +	if (icl_is_hdr_plane(plane)) {
> +		u32 cus_ctl = 0;
> +
> +		if (linked) {
> +			/* Enable and use MPEG-2 chroma siting */
> +			cus_ctl = PLANE_CUS_ENABLE |
> +				PLANE_CUS_HPHASE_0 |
> +				PLANE_CUS_VPHASE_SIGN_NEGATIVE |
> +				PLANE_CUS_VPHASE_0_25;
> +
> +			if (linked->id == PLANE_SPRITE5)
> +				cus_ctl |= PLANE_CUS_PLANE_7;
> +			else if (linked->id == PLANE_SPRITE4)
> +				cus_ctl |= PLANE_CUS_PLANE_6;
> +			else
> +				MISSING_CASE(linked->id);
> +		}
> +
> +		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> +	}
> +
>  	/* program plane scaler */
>  	if (plane_state->scaler_id >= 0) {
>  		skl_program_scaler(dev_priv, plane, crtc_state, plane_state);
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
  2018-10-18 11:51 ` [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3 Maarten Lankhorst
@ 2018-10-18 14:51   ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 14:51 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:33PM +0200, Maarten Lankhorst wrote:
> The UV plane is the master plane that does all color correction etc.
> It needs to be programmed with the dimensions for color plane 1 (UV).
> 
> The Y plane just feeds the Y pixels to it. Program the scaler from the
> master only, and set PLANE_CTL_YUV420_Y_PLANE on the slave plane.
> 
> Changes since v1:
> - Make a common skl_program_plane, and use it for both plane updates.
> Changes since v2:
> - Make color_plane explicit, to clarify skl_update_plane(). (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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

> ---
>  drivers/gpu/drm/i915/i915_reg.h     |  1 +
>  drivers/gpu/drm/i915/intel_sprite.c | 47 +++++++++++++++++++++++------
>  2 files changed, 39 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 17b38ccbff6e..f8e68e88f98d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6473,6 +6473,7 @@ enum {
>  #define   PLANE_CTL_KEY_ENABLE_DESTINATION	(2 << 21)
>  #define   PLANE_CTL_ORDER_BGRX			(0 << 20)
>  #define   PLANE_CTL_ORDER_RGBX			(1 << 20)
> +#define   PLANE_CTL_YUV420_Y_PLANE		(1 << 19)
>  #define   PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709	(1 << 18)
>  #define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
>  #define   PLANE_CTL_YUV422_YUYV			(0 << 16)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 2ec5c5df0d24..5d04983a28ec 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -362,22 +362,22 @@ skl_program_scaler(struct drm_i915_private *dev_priv,
>  }
>  
>  static void
> -skl_update_plane(struct intel_plane *plane,
> -		 const struct intel_crtc_state *crtc_state,
> -		 const struct intel_plane_state *plane_state)
> +skl_program_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state,
> +		  const struct intel_plane_state *plane_state,
> +		  int color_plane, bool slave, u32 plane_ctl)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum plane_id plane_id = plane->id;
>  	enum pipe pipe = plane->pipe;
> -	u32 plane_ctl = plane_state->ctl;
>  	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> -	u32 surf_addr = plane_state->color_plane[0].offset;
> -	u32 stride = skl_plane_stride(plane_state, 0);
> +	u32 surf_addr = plane_state->color_plane[color_plane].offset;
> +	u32 stride = skl_plane_stride(plane_state, color_plane);
>  	u32 aux_stride = skl_plane_stride(plane_state, 1);
>  	int crtc_x = plane_state->base.dst.x1;
>  	int crtc_y = plane_state->base.dst.y1;
> -	uint32_t x = plane_state->color_plane[0].x;
> -	uint32_t y = plane_state->color_plane[0].y;
> +	uint32_t x = plane_state->color_plane[color_plane].x;
> +	uint32_t y = plane_state->color_plane[color_plane].y;
>  	uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
>  	uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
>  	struct intel_plane *linked = plane_state->linked_plane;
> @@ -441,7 +441,9 @@ skl_update_plane(struct intel_plane *plane,
>  
>  	/* program plane scaler */
>  	if (plane_state->scaler_id >= 0) {
> -		skl_program_scaler(dev_priv, plane, crtc_state, plane_state);
> +		if (!slave)
> +			skl_program_scaler(dev_priv, plane,
> +					   crtc_state, plane_state);
>  
>  		I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
>  	} else {
> @@ -456,7 +458,32 @@ skl_update_plane(struct intel_plane *plane,
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> +void
> +skl_update_plane(struct intel_plane *plane,
> +		 const struct intel_crtc_state *crtc_state,
> +		 const struct intel_plane_state *plane_state)
> +{
> +	int color_plane = 0;
> +
> +	if (plane_state->linked_plane) {
> +		/* Program the UV plane */
> +		color_plane = 1;
> +	}
> +
> +	skl_program_plane(plane, crtc_state, plane_state,
> +			  color_plane, false, plane_state->ctl);
> +}
> +
>  static void
> +icl_update_slave(struct intel_plane *plane,
> +		 const struct intel_crtc_state *crtc_state,
> +		 const struct intel_plane_state *plane_state)
> +{
> +	skl_program_plane(plane, crtc_state, plane_state, 0, true,
> +			  plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
> +}
> +
> +void
>  skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> @@ -1909,6 +1936,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
>  	plane->disable_plane = skl_disable_plane;
>  	plane->get_hw_state = skl_plane_get_hw_state;
>  	plane->check_plane = skl_plane_check;
> +	if (icl_is_nv12_y_plane(plane_id))
> +		plane->update_slave = icl_update_slave;
>  
>  	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
>  		formats = skl_planar_formats;
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
@ 2018-10-18 14:53   ` Ville Syrjälä
  2018-10-19 12:58     ` Maarten Lankhorst
  2018-10-18 15:11   ` Ville Syrjälä
  1 sibling, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 14:53 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
> On gen11, we can definitely smash the 32-bits barrier with just a
> when we enable all planes in the next patch.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I guess the per-plane data rate is still <32bit (because it doesn't
account for the refresh rate). But making everything 64bit seems safest.

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

Now we could also improve the per-plane data rate to include the
refresh rate and get rid of inaccurate drm_mode_vrefresh() in there.

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
>  1 file changed, 22 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 67a4d0735291..3b136fdfd24f 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
>  
>  static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  			      const struct intel_crtc_state *cstate,
> -			      const unsigned int total_data_rate,
> +			      const u64 total_data_rate,
>  			      const int num_active,
>  			      struct skl_ddb_allocation *ddb)
>  {
> @@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>  
>  	adjusted_mode = &cstate->base.adjusted_mode;
> -	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
> +	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>  
>  	/*
>  	 * 12GB/s is maximum BW supported by single DBuf slice.
>  	 */
> -	if (total_data_bw >= GBps(12) || num_active > 1) {
> +	if (num_active > 1 || total_data_bw >= GBps(12)) {
>  		ddb->enabled_slices = 2;
>  	} else {
>  		ddb->enabled_slices = 1;
> @@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  static void
>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  				   const struct intel_crtc_state *cstate,
> -				   const unsigned int total_data_rate,
> +				   const u64 total_data_rate,
>  				   struct skl_ddb_allocation *ddb,
>  				   struct skl_ddb_entry *alloc, /* out */
>  				   int *num_active /* out */)
> @@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  	return 0;
>  }
>  
> -static unsigned int
> +static u64
>  skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  			     const struct drm_plane_state *pstate,
>  			     const int plane)
> @@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  	struct drm_framebuffer *fb;
>  	u32 format;
>  	uint_fixed_16_16_t down_scale_amount;
> +	u64 rate;
>  
>  	if (!intel_pstate->base.visible)
>  		return 0;
> @@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  		height /= 2;
>  	}
>  
> -	data_rate = width * height * fb->format->cpp[plane];
> +	data_rate = width * height;
>  
>  	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
>  
> -	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
> +	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
> +
> +	rate *= fb->format->cpp[plane];
> +	return rate;
>  }
>  
> -/*
> - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
> - * a 8192x4096@32bpp framebuffer:
> - *   3 * 4096 * 8192  * 4 < 2^32
> - */
> -static unsigned int
> +static u64
>  skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
> -				 unsigned int *plane_data_rate,
> -				 unsigned int *uv_plane_data_rate)
> +				 u64 *plane_data_rate,
> +				 u64 *uv_plane_data_rate)
>  {
>  	struct drm_crtc_state *cstate = &intel_cstate->base;
>  	struct drm_atomic_state *state = cstate->state;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *pstate;
> -	unsigned int total_data_rate = 0;
> +	u64 total_data_rate = 0;
>  
>  	if (WARN_ON(!state))
>  		return 0;
> @@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>  	/* Calculate and cache data rate for each plane */
>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
> -		unsigned int rate;
> +		u64 rate;
>  
>  		/* packed/y */
>  		rate = skl_plane_relative_data_rate(intel_cstate,
> @@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	uint16_t alloc_size, start;
>  	uint16_t minimum[I915_MAX_PLANES] = {};
>  	uint16_t uv_minimum[I915_MAX_PLANES] = {};
> -	unsigned int total_data_rate;
> +	u64 total_data_rate;
>  	enum plane_id plane_id;
>  	int num_active;
> -	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
> -	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
> +	u64 plane_data_rate[I915_MAX_PLANES] = {};
> +	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
>  	uint16_t total_min_blocks = 0;
>  
>  	/* Clear the partitioning for disabled planes. */
> @@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  
>  	start = alloc->start;
>  	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
> -		unsigned int data_rate, uv_data_rate;
> +		u64 data_rate, uv_data_rate;
>  		uint16_t plane_blocks, uv_plane_blocks;
>  
>  		if (plane_id == PLANE_CURSOR)
> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		 * result is < available as data_rate / total_data_rate < 1
>  		 */
>  		plane_blocks = minimum[plane_id];
> -		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> -					total_data_rate);
> +		plane_blocks += alloc_size * data_rate / total_data_rate;
>  
>  		/* Leave disabled planes at (0,0) */
>  		if (data_rate) {
> @@ -4417,8 +4415,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		uv_data_rate = uv_plane_data_rate[plane_id];
>  
>  		uv_plane_blocks = uv_minimum[plane_id];
> -		uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
> -					   total_data_rate);
> +		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
>  
>  		if (uv_data_rate) {
>  			ddb->uv_plane[pipe][plane_id].start = start;
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
  2018-10-18 14:53   ` Ville Syrjälä
@ 2018-10-18 15:11   ` Ville Syrjälä
  2018-10-19 13:03     ` Maarten Lankhorst
  1 sibling, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 15:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
> On gen11, we can definitely smash the 32-bits barrier with just a
> when we enable all planes in the next patch.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
>  1 file changed, 22 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 67a4d0735291..3b136fdfd24f 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
>  
>  static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  			      const struct intel_crtc_state *cstate,
> -			      const unsigned int total_data_rate,
> +			      const u64 total_data_rate,
>  			      const int num_active,
>  			      struct skl_ddb_allocation *ddb)
>  {
> @@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>  
>  	adjusted_mode = &cstate->base.adjusted_mode;
> -	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
> +	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>  
>  	/*
>  	 * 12GB/s is maximum BW supported by single DBuf slice.
>  	 */
> -	if (total_data_bw >= GBps(12) || num_active > 1) {
> +	if (num_active > 1 || total_data_bw >= GBps(12)) {
>  		ddb->enabled_slices = 2;
>  	} else {
>  		ddb->enabled_slices = 1;
> @@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  static void
>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  				   const struct intel_crtc_state *cstate,
> -				   const unsigned int total_data_rate,
> +				   const u64 total_data_rate,
>  				   struct skl_ddb_allocation *ddb,
>  				   struct skl_ddb_entry *alloc, /* out */
>  				   int *num_active /* out */)
> @@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  	return 0;
>  }
>  
> -static unsigned int
> +static u64
>  skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  			     const struct drm_plane_state *pstate,
>  			     const int plane)
> @@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  	struct drm_framebuffer *fb;
>  	u32 format;
>  	uint_fixed_16_16_t down_scale_amount;
> +	u64 rate;
>  
>  	if (!intel_pstate->base.visible)
>  		return 0;
> @@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  		height /= 2;
>  	}
>  
> -	data_rate = width * height * fb->format->cpp[plane];
> +	data_rate = width * height;
>  
>  	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
>  
> -	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
> +	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
> +
> +	rate *= fb->format->cpp[plane];
> +	return rate;
>  }
>  
> -/*
> - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
> - * a 8192x4096@32bpp framebuffer:
> - *   3 * 4096 * 8192  * 4 < 2^32
> - */
> -static unsigned int
> +static u64
>  skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
> -				 unsigned int *plane_data_rate,
> -				 unsigned int *uv_plane_data_rate)
> +				 u64 *plane_data_rate,
> +				 u64 *uv_plane_data_rate)
>  {
>  	struct drm_crtc_state *cstate = &intel_cstate->base;
>  	struct drm_atomic_state *state = cstate->state;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *pstate;
> -	unsigned int total_data_rate = 0;
> +	u64 total_data_rate = 0;
>  
>  	if (WARN_ON(!state))
>  		return 0;
> @@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>  	/* Calculate and cache data rate for each plane */
>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
> -		unsigned int rate;
> +		u64 rate;
>  
>  		/* packed/y */
>  		rate = skl_plane_relative_data_rate(intel_cstate,
> @@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  	uint16_t alloc_size, start;
>  	uint16_t minimum[I915_MAX_PLANES] = {};
>  	uint16_t uv_minimum[I915_MAX_PLANES] = {};
> -	unsigned int total_data_rate;
> +	u64 total_data_rate;
>  	enum plane_id plane_id;
>  	int num_active;
> -	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
> -	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
> +	u64 plane_data_rate[I915_MAX_PLANES] = {};
> +	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
>  	uint16_t total_min_blocks = 0;
>  
>  	/* Clear the partitioning for disabled planes. */
> @@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  
>  	start = alloc->start;
>  	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
> -		unsigned int data_rate, uv_data_rate;
> +		u64 data_rate, uv_data_rate;
>  		uint16_t plane_blocks, uv_plane_blocks;
>  
>  		if (plane_id == PLANE_CURSOR)
> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		 * result is < available as data_rate / total_data_rate < 1
>  		 */
>  		plane_blocks = minimum[plane_id];
> -		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> -					total_data_rate);
> +		plane_blocks += alloc_size * data_rate / total_data_rate;

I failed to spot the raw 64bit divisions here. Fortunately CI caught
them (yay). Need to be fixed.

>  
>  		/* Leave disabled planes at (0,0) */
>  		if (data_rate) {
> @@ -4417,8 +4415,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		uv_data_rate = uv_plane_data_rate[plane_id];
>  
>  		uv_plane_blocks = uv_minimum[plane_id];
> -		uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
> -					   total_data_rate);
> +		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
>  
>  		if (uv_data_rate) {
>  			ddb->uv_plane[pipe][plane_id].start = start;
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (10 preceding siblings ...)
  2018-10-18 12:19 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-10-18 15:16 ` Ville Syrjälä
  2018-10-18 16:20   ` Maarten Lankhorst
  2018-10-22 10:52 ` ✓ Fi.CI.IGT: success for " Patchwork
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 15:16 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:26PM +0200, Maarten Lankhorst wrote:
> New version, with a lot of reworking to incorporate all the feedback.
> 
> We currently don't set the plane input CSC correctly, so colors are a
> bit off. As a result I can't verify for 100% we program the chroma
> upsampler correctly, but I still want to put out this series for review.

I didn't spot a change to skl_plane_has_planar() in this series.
Did that fall off during a rebase or was it never there?

Did you test this version locally? Mainly wondering if we have a
bug in the core that it lets unsupported pixel formats through...

> 
> Maarten Lankhorst (8):
>   drm/i915: Fix unsigned overflow when calculating total data rate
>   drm/i915/gen11: Enable 6 sprites on gen11
>   drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
>   drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes,
>     v2.
>   drm/i915/gen11: Program the scalers correctly for planar formats, v3.
>   drm/i915/gen11: Program the chroma upsampler for HDR planes.
>   drm/i915/gen11: Program the Y and UV plane for planar mode correctly,
>     v3.
>   drm/i915/gen11: Expose planar format support on gen11.
> 
>  drivers/gpu/drm/i915/i915_reg.h           |  27 +-
>  drivers/gpu/drm/i915/intel_atomic.c       |  16 +-
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  74 ++++-
>  drivers/gpu/drm/i915/intel_device_info.c  |  22 +-
>  drivers/gpu/drm/i915/intel_display.c      | 120 ++++++--
>  drivers/gpu/drm/i915/intel_display.h      |   3 +
>  drivers/gpu/drm/i915/intel_drv.h          |  61 ++++
>  drivers/gpu/drm/i915/intel_pm.c           | 360 ++++++++++++++--------
>  drivers/gpu/drm/i915/intel_sprite.c       |  72 ++++-
>  9 files changed, 575 insertions(+), 180 deletions(-)
> 
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  2018-10-18 11:51 ` [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4 Maarten Lankhorst
@ 2018-10-18 16:00   ` Ville Syrjälä
  2018-10-19 14:22     ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 16:00 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:29PM +0200, Maarten Lankhorst wrote:
> To make NV12 working on icl, we need to update 2 planes simultaneously.
> I've chosen to do this in the CRTC step after plane validation is done,
> so we know what planes are (in)visible. The linked Y plane will get
> updated in intel_plane_update_planes_on_crtc(), by the call to
> update_slave, which gets the master's plane_state as argument.
> 
> The link requires both planes for atomic_update to work,
> so make sure skl_ddb_add_affected_planes() adds both states.
> 
> Changes since v1:
> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
> - Put all the state updating login in intel_plane_atomic_check_with_state().
> - Clean up changes in intel_plane_atomic_check().
> Changes since v2:
> - Fix intel_atomic_get_old_plane_state() to actually return old state.
> - Move visibility changes to preparation patch.
> - Only try to find a Y plane on gen11, earlier platforms only require
>   a single plane.
> Changes since v3:
> - Fix checkpatch warning about to_intel_crtc() usage.
> - Add affected planes from icl_add_linked_planes() before check_planes(),
>   it's a cleaner way to do this. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c | 74 ++++++++++++++++-----
>  drivers/gpu/drm/i915/intel_display.c      | 81 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++++
>  drivers/gpu/drm/i915/intel_pm.c           | 12 +++-
>  4 files changed, 202 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index b957ad63cd87..154ea3dc344f 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -122,7 +122,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  	crtc_state->nv12_planes &= ~BIT(intel_plane->id);
>  	intel_state->base.visible = false;
>  
> -	/* If this is a cursor plane, no further checks are needed. */
> +	/* Destroy the link */
> +	intel_state->linked_plane = NULL;
> +	intel_state->slave = false;
> +
> +	/* If this is a cursor or Y plane, no further checks are needed. */
>  	if (!intel_state->base.crtc && !old_plane_state->base.crtc)
>  		return 0;
>  
> @@ -143,27 +147,44 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  					       state);
>  }
>  
> -static int intel_plane_atomic_check(struct drm_plane *plane,
> -				    struct drm_plane_state *new_plane_state)
> +static int intel_plane_atomic_check(struct drm_plane *drm_plane,
> +				    struct drm_plane_state *new_drm_plane_state)

My new cunning plane is to call these _plane, _new_plane_state etc.
It should discourage people from using them and the aliasing
intel_ types at the same time. And it avoids polluting the namespace
for things we don't really want to use. 

I already snuck in some uses of this ;)

>  {
> -	struct drm_atomic_state *state = new_plane_state->state;
> -	const struct drm_plane_state *old_plane_state =
> -		drm_atomic_get_old_plane_state(state, plane);
> -	struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
> -	const struct drm_crtc_state *old_crtc_state;
> -	struct drm_crtc_state *new_crtc_state;
> -
> -	new_plane_state->visible = false;
> +	struct intel_atomic_state *state =
> +		to_intel_atomic_state(new_drm_plane_state->state);
> +	struct intel_plane *plane = to_intel_plane(drm_plane);
> +	const struct intel_plane_state *old_plane_state =
> +		intel_atomic_get_old_plane_state(state, plane);
> +	struct intel_plane_state *new_plane_state =
> +		to_intel_plane_state(new_drm_plane_state);
> +	struct intel_crtc *crtc =
> +		to_intel_crtc(new_plane_state->base.crtc ?:
> +			      old_plane_state->base.crtc);
> +	const struct intel_crtc_state *old_crtc_state;
> +	struct intel_crtc_state *new_crtc_state;
> +	struct intel_plane *linked = old_plane_state->linked_plane;
> +
> +	if (linked && !crtc) {
> +		const struct intel_plane_state *old_linked_state =
> +			intel_atomic_get_old_plane_state(state, linked);

Plane without a crtc that happens to have a linked plane
attached to it...

I guess that implies that 'plane' here is the slave and
it was already active during the previous state (otherwise
it would not have been linked to the other plane). So that
means the master plane must have a valid crtc in its old
plane state.

Did I decode that correctly?

Maybe what we want to do here is to just always clear the
active_planes bit for the slave in the master plane's
old crtc's new crtc state (quite the mouthful), and then
run through the normal check_plane stuff for the slave
with its own crtc (if it has one). In practice it doesn't
really make any difference I suppose since our planes
can't move between crtcs, but logically it would make
more sense to me.

> +
> +		if (WARN_ON(!old_linked_state))
> +			return -EINVAL;
> +
> +		crtc = to_intel_crtc(old_linked_state->base.crtc);
> +		if (WARN_ON(!crtc))
> +			return -EINVAL;
> +	}
> +
> +	new_plane_state->base.visible = false;
>  	if (!crtc)
>  		return 0;
>  
> -	old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
> -	new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
> +	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> +	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>  
> -	return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state),
> -						   to_intel_crtc_state(new_crtc_state),
> -						   to_intel_plane_state(old_plane_state),
> -						   to_intel_plane_state(new_plane_state));
> +	return intel_plane_atomic_check_with_state(old_crtc_state, new_crtc_state,
> +						   old_plane_state, new_plane_state);
>  }
>  
>  void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> @@ -188,6 +209,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  			trace_intel_update_plane(&plane->base, crtc);
>  
>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
> +		} else if (new_plane_state->slave) {
> +			struct intel_plane *master =
> +				new_plane_state->linked_plane;
> +
> +			/*
> +			 * We update the slave plane from this function because
> +			 * programming it from the master plane's update_plane
> +			 * callback runs into issues when the Y plane is
> +			 * reassigned, disabled or used by a different plane.
> +			 *
> +			 * The slave plane is updated with the master plane's
> +			 * plane_state.
> +			 */
> +			new_plane_state =
> +				intel_atomic_get_new_plane_state(old_state, master);
> +
> +			trace_intel_update_plane(&plane->base, crtc);
> +
> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
>  		} else {
>  			trace_intel_disable_plane(&plane->base, crtc);
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8e1b3677e131..cbb3fb1d5ad4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10721,6 +10721,80 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>  	return true;
>  }
>  
> +static int icl_add_linked_planes(struct intel_atomic_state *state)
> +{
> +	struct intel_plane *plane, *linked;
> +	struct intel_plane_state *plane_state, *linked_plane_state;
> +	int i;
> +
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		linked = plane_state->linked_plane;
> +
> +		if (!linked)
> +			continue;
> +
> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> +		if (IS_ERR(linked_plane_state))
> +			return PTR_ERR(linked_plane_state);
> +	}
> +
> +	return 0;
> +}
> +
> +static int icl_check_nv12_planes(struct drm_i915_private *dev_priv,
> +				 struct intel_crtc *crtc,
> +				 struct intel_crtc_state *crtc_state)

Could pass just the crtc_state and dig the rest out here.

> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
> +	struct intel_plane *plane, *aux;
> +
> +	if (INTEL_GEN(dev_priv) < 11 || !crtc_state->nv12_planes)
> +		return 0;
> +
> +	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> +		struct intel_plane_state *plane_state, *aux_state;
> +		struct drm_plane_state *drm_aux_state = NULL;

Still don't like the 'aux' in these names.
Just linked/linked_plane_state' to match the rest of the
code?

> +
> +		if (!(crtc_state->nv12_planes & BIT(plane->id)))
> +			continue;
> +
> +		plane_state = intel_atomic_get_new_plane_state(state, plane);
> +		if (!plane_state)
> +			continue;
> +
> +		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, aux) {
> +			if (!icl_is_nv12_y_plane(aux->id))
> +				continue;
> +
> +			if (crtc_state->active_planes & BIT(aux->id))
> +				continue;
> +
> +			drm_aux_state = drm_atomic_get_plane_state(&state->base, &aux->base);

intel_atomic_get_plane() and get rid of the aliasing states?

> +			if (IS_ERR(drm_aux_state))
> +				return PTR_ERR(drm_aux_state);
> +
> +			break;
> +		}
> +
> +		if (!drm_aux_state) {
> +			DRM_DEBUG_KMS("Need %d free Y planes for NV12\n",
> +				      hweight8(crtc_state->nv12_planes));
> +
> +			return -EINVAL;
> +		}
> +
> +		plane_state->linked_plane = aux;
> +
> +		aux_state = to_intel_plane_state(drm_aux_state);
> +		aux_state->slave = true;
> +		aux_state->linked_plane = plane;
> +		crtc_state->active_planes |= BIT(aux->id);
> +		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", aux->base.name, plane->base.name);
> +	}
> +
> +	return 0;
> +}
> +
>  static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  				   struct drm_crtc_state *crtc_state)
>  {
> @@ -10792,6 +10866,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  		if (mode_changed)
>  			ret = skl_update_scaler_crtc(pipe_config);
>  
> +		if (!ret)
> +			ret = icl_check_nv12_planes(dev_priv, intel_crtc,
> +						    pipe_config);
>  		if (!ret)
>  			ret = skl_check_pipe_max_pixel_rate(intel_crtc,
>  							    pipe_config);
> @@ -12458,6 +12535,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  		intel_state->cdclk.logical = dev_priv->cdclk.logical;
>  	}
>  
> +	ret = icl_add_linked_planes(intel_state);
> +	if (ret)
> +		return ret;
> +
>  	ret = drm_atomic_helper_check_planes(dev, state);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index b5d6f6887c13..272de906a001 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -539,6 +539,26 @@ struct intel_plane_state {
>  	 */
>  	int scaler_id;
>  
> +	/*
> +	 * linked_plane:
> +	 *
> +	 * ICL planar formats require 2 planes that are updated as pairs.
> +	 * This member is used to make sure the other plane is also updated
> +	 * when required, and for update_slave() to find the correct
> +	 * plane_state to pass as argument.
> +	 */
> +	struct intel_plane *linked_plane;
> +
> +	/*
> +	 * slave:
> +	 * If set don't update use the linked plane's state for updating
> +	 * this plane during atomic commit with the update_slave() callback.
> +	 *
> +	 * It's also used by the watermark code to ignore wm calculations on
> +	 * this plane. They're calculated by the linked plane's wm code.
> +	 */
> +	bool slave;
> +
>  	struct drm_intel_sprite_colorkey ckey;
>  };
>  
> @@ -983,6 +1003,9 @@ struct intel_plane {
>  	void (*update_plane)(struct intel_plane *plane,
>  			     const struct intel_crtc_state *crtc_state,
>  			     const struct intel_plane_state *plane_state);
> +	void (*update_slave)(struct intel_plane *plane,
> +			     const struct intel_crtc_state *crtc_state,
> +			     const struct intel_plane_state *plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
>  			      struct intel_crtc *crtc);
>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
> @@ -1351,6 +1374,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
>  	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
>  }
>  
> +static inline struct intel_plane_state *
> +intel_atomic_get_plane_state(struct intel_atomic_state *state,
> +				 struct intel_plane *plane)
> +{
> +	struct drm_plane_state *ret =
> +		drm_atomic_get_plane_state(&state->base, &plane->base);
> +
> +	if (IS_ERR(ret))
> +		return ERR_CAST(ret);
> +
> +	return to_intel_plane_state(ret);
> +}
> +
> +static inline struct intel_plane_state *
> +intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
> +				 struct intel_plane *plane)
> +{
> +	return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
> +								   &plane->base));
> +}
> +
>  static inline struct intel_plane_state *
>  intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
>  				 struct intel_plane *plane)
> @@ -2158,6 +2202,15 @@ struct intel_plane *
>  skl_universal_plane_create(struct drm_i915_private *dev_priv,
>  			   enum pipe pipe, enum plane_id plane_id);
>  
> +static inline bool icl_is_nv12_y_plane(enum plane_id id)
> +{
> +	/* Don't need to do a gen check, these planes are only available on gen11 */
> +	if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
> +		return true;
> +
> +	return false;
> +}
> +
>  /* intel_tv.c */
>  void intel_tv_init(struct drm_i915_private *dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3b136fdfd24f..d003c08bd9e4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5153,11 +5153,12 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
>  	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> -	struct drm_plane_state *plane_state;
>  	struct drm_plane *plane;
>  	enum pipe pipe = intel_crtc->pipe;
>  
>  	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
> +		struct drm_plane_state *plane_state;
> +		struct intel_plane *linked;
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>  
>  		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
> @@ -5169,6 +5170,15 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>  		plane_state = drm_atomic_get_plane_state(state, plane);
>  		if (IS_ERR(plane_state))
>  			return PTR_ERR(plane_state);
> +
> +		/* Make sure linked plane is updated too */
> +		linked = to_intel_plane_state(plane_state)->linked_plane;
> +		if (!linked)
> +			continue;
> +
> +		plane_state = drm_atomic_get_plane_state(state, &linked->base);
> +		if (IS_ERR(plane_state))
> +			return PTR_ERR(plane_state);
>  	}
>  
>  	return 0;
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
  2018-10-18 11:51 ` [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2 Maarten Lankhorst
@ 2018-10-18 16:17   ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 16:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, Paulo Zanoni

On Thu, Oct 18, 2018 at 01:51:30PM +0200, Maarten Lankhorst wrote:
> Skylake style watermarks program the UV parameters into wm->uv_wm,
> and have a separate DDB allocation for UV blocks into the same plane.
> 
> Gen11 watermarks have a separate plane for Y and UV, with separate
> mechanisms. The simplest way to make it work is to keep the current
> way of programming watermarks and calculate the Y and UV plane
> watermarks from the master plane.
> 
> Changes since v1:
> - Constify crtc_state where possible.
> - Make separate paths for planar formats in skl_build_pipe_wm() (Matt)
> - Make separate paths for calculating total data rate. (Matt)
> - Make sure UV watermarks are unused on gen11+ by adding a WARN. (Matt)

This lookd like it should work.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

However it's going to conflict pretty badly with Paulo's watermark
series. One of you is going to have to rebase at least, and not sure if
all of Paulo's stuff even makes sense given this patch...

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 301 ++++++++++++++++++++++----------
>  1 file changed, 207 insertions(+), 94 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d003c08bd9e4..ef95b9d7884b 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3814,7 +3814,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  }
>  
>  static void
> -skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
> +skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  				   const struct intel_crtc_state *cstate,
>  				   const u64 total_data_rate,
>  				   struct skl_ddb_allocation *ddb,
> @@ -3823,7 +3823,6 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  {
>  	struct drm_atomic_state *state = cstate->base.state;
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> -	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct drm_crtc *for_crtc = cstate->base.crtc;
>  	const struct drm_crtc_state *crtc_state;
>  	const struct drm_crtc *crtc;
> @@ -3945,14 +3944,9 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv,
>  				      val & PLANE_CTL_ALPHA_MASK);
>  
>  	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
> -	/*
> -	 * FIXME: add proper NV12 support for ICL. Avoid reading unclaimed
> -	 * registers for now.
> -	 */
> -	if (INTEL_GEN(dev_priv) < 11)
> +	if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) {
>  		val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
>  
> -	if (fourcc == DRM_FORMAT_NV12) {
>  		skl_ddb_entry_init_from_hw(dev_priv,
>  					   &ddb->plane[pipe][plane_id], val2);
>  		skl_ddb_entry_init_from_hw(dev_priv,
> @@ -4141,11 +4135,11 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  
>  static u64
>  skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
> -			     const struct drm_plane_state *pstate,
> +			     const struct intel_plane_state *intel_pstate,
>  			     const int plane)
>  {
> -	struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
> -	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
> +	struct intel_plane *intel_plane =
> +		to_intel_plane(intel_pstate->base.plane);
>  	uint32_t data_rate;
>  	uint32_t width = 0, height = 0;
>  	struct drm_framebuffer *fb;
> @@ -4156,7 +4150,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>  	if (!intel_pstate->base.visible)
>  		return 0;
>  
> -	fb = pstate->fb;
> +	fb = intel_pstate->base.fb;
>  	format = fb->format->format;
>  
>  	if (intel_plane->id == PLANE_CURSOR)
> @@ -4206,25 +4200,80 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>  		u64 rate;
> +		const struct intel_plane_state *intel_pstate =
> +			to_intel_plane_state(pstate);
>  
>  		/* packed/y */
>  		rate = skl_plane_relative_data_rate(intel_cstate,
> -						    pstate, 0);
> +						    intel_pstate, 0);
>  		plane_data_rate[plane_id] = rate;
> -
>  		total_data_rate += rate;
>  
>  		/* uv-plane */
>  		rate = skl_plane_relative_data_rate(intel_cstate,
> -						    pstate, 1);
> +						    intel_pstate, 1);
>  		uv_plane_data_rate[plane_id] = rate;
> -
>  		total_data_rate += rate;
>  	}
>  
>  	return total_data_rate;
>  }
>  
> +static u64
> +icl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
> +				 u64 *plane_data_rate)
> +{
> +	struct drm_crtc_state *cstate = &intel_cstate->base;
> +	struct drm_atomic_state *state = cstate->state;
> +	struct drm_plane *plane;
> +	const struct drm_plane_state *pstate;
> +	u64 total_data_rate = 0;
> +
> +	if (WARN_ON(!state))
> +		return 0;
> +
> +	/* Calculate and cache data rate for each plane */
> +	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
> +		const struct intel_plane_state *intel_pstate =
> +			to_intel_plane_state(pstate);
> +		enum plane_id plane_id = to_intel_plane(plane)->id;
> +		u64 rate;
> +
> +		if (!intel_pstate->linked_plane) {
> +			rate = skl_plane_relative_data_rate(intel_cstate,
> +							    intel_pstate, 0);
> +			plane_data_rate[plane_id] = rate;
> +			total_data_rate += rate;
> +		} else {
> +			enum plane_id y_plane_id;
> +
> +			/*
> +			 * The slave plane might not iterate in
> +			 * drm_atomic_crtc_state_for_each_plane_state(),
> +			 * and needs the master plane state which may be
> +			 * NULL if we try get_new_plane_state(), so we
> +			 * always calculate from the master.
> +			 */
> +			if (intel_pstate->slave)
> +				continue;
> +
> +			/* Y plane rate is calculated on the slave */
> +			rate = skl_plane_relative_data_rate(intel_cstate,
> +							    intel_pstate, 0);
> +			y_plane_id = intel_pstate->linked_plane->id;
> +			plane_data_rate[y_plane_id] = rate;
> +			total_data_rate += rate;
> +
> +			rate = skl_plane_relative_data_rate(intel_cstate,
> +							    intel_pstate, 1);
> +			plane_data_rate[plane_id] = rate;
> +			total_data_rate += rate;
> +		}
> +	}
> +
> +	return total_data_rate;
> +}
> +
>  static uint16_t
>  skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane)
>  {
> @@ -4297,15 +4346,25 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
>  
>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, &cstate->base) {
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
> +		struct intel_plane_state *plane_state = to_intel_plane_state(pstate);
>  
>  		if (plane_id == PLANE_CURSOR)
>  			continue;
>  
> -		if (!pstate->visible)
> +		/* slave plane must be invisible and calculated from master */
> +		if (!pstate->visible || WARN_ON(plane_state->slave))
>  			continue;
>  
> -		minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
> -		uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
> +		if (!plane_state->linked_plane) {
> +			minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
> +			uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
> +		} else {
> +			enum plane_id y_plane_id =
> +				plane_state->linked_plane->id;
> +
> +			minimum[y_plane_id] = skl_ddb_min_alloc(pstate, 0);
> +			minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
> +		}
>  	}
>  
>  	minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
> @@ -4317,7 +4376,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  {
>  	struct drm_atomic_state *state = cstate->base.state;
>  	struct drm_crtc *crtc = cstate->base.crtc;
> -	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
> @@ -4343,11 +4402,18 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		return 0;
>  	}
>  
> -	total_data_rate = skl_get_total_relative_data_rate(cstate,
> -							   plane_data_rate,
> -							   uv_plane_data_rate);
> -	skl_ddb_get_pipe_allocation_limits(dev, cstate, total_data_rate, ddb,
> -					   alloc, &num_active);
> +	if (INTEL_GEN(dev_priv) < 11)
> +		total_data_rate =
> +			skl_get_total_relative_data_rate(cstate,
> +							 plane_data_rate,
> +							 uv_plane_data_rate);
> +	else
> +		total_data_rate =
> +			icl_get_total_relative_data_rate(cstate,
> +							 plane_data_rate);
> +

I would flip these around. I think most people generally prefer the
new first, old last order.

> +	skl_ddb_get_pipe_allocation_limits(dev_priv, cstate, total_data_rate,
> +					   ddb, alloc, &num_active);
>  	alloc_size = skl_ddb_entry_size(alloc);
>  	if (alloc_size == 0)
>  		return 0;
> @@ -4417,6 +4483,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>  		uv_plane_blocks = uv_minimum[plane_id];
>  		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
>  
> +		/* Gen11+ uses a separate plane for UV watermarks */
> +		WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks);
> +
>  		if (uv_data_rate) {
>  			ddb->uv_plane[pipe][plane_id].start = start;
>  			ddb->uv_plane[pipe][plane_id].end =
> @@ -4473,7 +4542,7 @@ static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
>  }
>  
>  static uint_fixed_16_16_t
> -intel_get_linetime_us(struct intel_crtc_state *cstate)
> +intel_get_linetime_us(const struct intel_crtc_state *cstate)
>  {
>  	uint32_t pixel_rate;
>  	uint32_t crtc_htotal;
> @@ -4517,7 +4586,7 @@ skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate,
>  
>  static int
>  skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
> -			    struct intel_crtc_state *cstate,
> +			    const struct intel_crtc_state *cstate,
>  			    const struct intel_plane_state *intel_pstate,
>  			    struct skl_wm_params *wp, int plane_id)
>  {
> @@ -4624,7 +4693,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
>  }
>  
>  static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> -				struct intel_crtc_state *cstate,
> +				const struct intel_crtc_state *cstate,
>  				const struct intel_plane_state *intel_pstate,
>  				uint16_t ddb_allocation,
>  				int level,
> @@ -4784,38 +4853,22 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  static int
>  skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
>  		      struct skl_ddb_allocation *ddb,
> -		      struct intel_crtc_state *cstate,
> +		      const struct intel_crtc_state *cstate,
>  		      const struct intel_plane_state *intel_pstate,
> +		      uint16_t ddb_blocks,
>  		      const struct skl_wm_params *wm_params,
>  		      struct skl_plane_wm *wm,
> -		      int plane_id)
> +		      struct skl_wm_level *levels)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
> -	struct drm_plane *plane = intel_pstate->base.plane;
> -	struct intel_plane *intel_plane = to_intel_plane(plane);
> -	uint16_t ddb_blocks;
> -	enum pipe pipe = intel_crtc->pipe;
>  	int level, max_level = ilk_wm_max_level(dev_priv);
> -	enum plane_id intel_plane_id = intel_plane->id;
> +	struct skl_wm_level *result_prev = &levels[0];
>  	int ret;
>  
>  	if (WARN_ON(!intel_pstate->base.fb))
>  		return -EINVAL;
>  
> -	ddb_blocks = plane_id ?
> -		     skl_ddb_entry_size(&ddb->uv_plane[pipe][intel_plane_id]) :
> -		     skl_ddb_entry_size(&ddb->plane[pipe][intel_plane_id]);
> -
>  	for (level = 0; level <= max_level; level++) {
> -		struct skl_wm_level *result = plane_id ? &wm->uv_wm[level] :
> -							  &wm->wm[level];
> -		struct skl_wm_level *result_prev;
> -
> -		if (level)
> -			result_prev = plane_id ? &wm->uv_wm[level - 1] :
> -						  &wm->wm[level - 1];
> -		else
> -			result_prev = plane_id ? &wm->uv_wm[0] : &wm->wm[0];
> +		struct skl_wm_level *result = &levels[level];
>  
>  		ret = skl_compute_plane_wm(dev_priv,
>  					   cstate,
> @@ -4827,6 +4880,8 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
>  					   result);
>  		if (ret)
>  			return ret;
> +
> +		result_prev = result;
>  	}
>  
>  	if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> @@ -4836,7 +4891,7 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
>  }
>  
>  static uint32_t
> -skl_compute_linetime_wm(struct intel_crtc_state *cstate)
> +skl_compute_linetime_wm(const struct intel_crtc_state *cstate)
>  {
>  	struct drm_atomic_state *state = cstate->base.state;
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> @@ -4858,7 +4913,7 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
>  	return linetime_wm;
>  }
>  
> -static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
> +static void skl_compute_transition_wm(const struct intel_crtc_state *cstate,
>  				      struct skl_wm_params *wp,
>  				      struct skl_wm_level *wm_l0,
>  				      uint16_t ddb_allocation,
> @@ -4925,16 +4980,101 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
>  	trans_wm->plane_en = false;
>  }
>  
> +static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> +				       struct skl_pipe_wm *pipe_wm,
> +				       enum plane_id plane_id,
> +				       const struct intel_crtc_state *cstate,
> +				       const struct intel_plane_state *pstate,

crtc_state/plane_state in new code pls.

> +				       int color_plane)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev);
> +	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> +	enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe;
> +	struct skl_wm_params wm_params;
> +	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
> +	int ret;
> +
> +	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate,
> +					  &wm_params, color_plane);
> +	if (ret)
> +		return ret;
> +
> +	ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> +				    ddb_blocks, &wm_params, wm, wm->wm);
> +
> +	if (ret)
> +		return ret;
> +
> +	skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
> +				  ddb_blocks, &wm->trans_wm);
> +
> +	return 0;
> +}
> +
> +static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb,
> +				     struct skl_pipe_wm *pipe_wm,
> +				     const struct intel_crtc_state *cstate,
> +				     const struct intel_plane_state *pstate)
> +{
> +	enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id;
> +
> +	return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> +}
> +
> +static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> +				     struct skl_pipe_wm *pipe_wm,
> +				     const struct intel_crtc_state *cstate,
> +				     const struct intel_plane_state *pstate)
> +{
> +	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum plane_id plane_id = plane->id;
> +	struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
> +	struct skl_wm_params wm_params;
> +	enum pipe pipe = plane->pipe;
> +	uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
> +	int ret;
> +
> +	ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0);
> +	if (ret)
> +		return ret;
> +
> +	/* uv plane watermarks must also be validated for NV12/Planar */
> +	ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]);
> +
> +	ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1);
> +	if (ret)
> +		return ret;
> +
> +	return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate,
> +				     ddb_blocks, &wm_params, wm, wm->uv_wm);
> +}
> +
> +static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb,
> +				     struct skl_pipe_wm *pipe_wm,
> +				     const struct intel_crtc_state *cstate,
> +				     const struct intel_plane_state *pstate)
> +{
> +	int ret;
> +	enum plane_id y_plane_id = pstate->linked_plane->id;
> +	enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id;
> +
> +	ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id,
> +					  cstate, pstate, 0);
> +	if (ret)
> +		return ret;
> +
> +	return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id,
> +					   cstate, pstate, 1);
> +}
> +
>  static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
>  			     struct skl_ddb_allocation *ddb,
>  			     struct skl_pipe_wm *pipe_wm)
>  {
> -	struct drm_device *dev = cstate->base.crtc->dev;
>  	struct drm_crtc_state *crtc_state = &cstate->base;
> -	const struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *pstate;
> -	struct skl_plane_wm *wm;
>  	int ret;
>  
>  	/*
> @@ -4946,44 +5086,21 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>  		const struct intel_plane_state *intel_pstate =
>  						to_intel_plane_state(pstate);
> -		enum plane_id plane_id = to_intel_plane(plane)->id;
> -		struct skl_wm_params wm_params;
> -		enum pipe pipe = to_intel_crtc(cstate->base.crtc)->pipe;
> -		uint16_t ddb_blocks;
>  
> -		wm = &pipe_wm->planes[plane_id];
> -		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]);
> +		/* Watermarks calculated in master */
> +		if (intel_pstate->slave)
> +			continue;
>  
> -		ret = skl_compute_plane_wm_params(dev_priv, cstate,
> -						  intel_pstate, &wm_params, 0);
> -		if (ret)
> -			return ret;
> +		if (intel_pstate->linked_plane)
> +			ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> +		else if (intel_pstate->base.fb &&
> +			 intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
> +			ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate);
> +		else
> +			ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate);
>  
> -		ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
> -					    intel_pstate, &wm_params, wm, 0);
>  		if (ret)
>  			return ret;
> -
> -		skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0],
> -					  ddb_blocks, &wm->trans_wm);
> -
> -		/* uv plane watermarks must also be validated for NV12/Planar */
> -		if (wm_params.is_planar) {
> -			memset(&wm_params, 0, sizeof(struct skl_wm_params));
> -			wm->is_planar = true;
> -
> -			ret = skl_compute_plane_wm_params(dev_priv, cstate,
> -							  intel_pstate,
> -							  &wm_params, 1);
> -			if (ret)
> -				return ret;
> -
> -			ret = skl_compute_wm_levels(dev_priv, ddb, cstate,
> -						    intel_pstate, &wm_params,
> -						    wm, 1);
> -			if (ret)
> -				return ret;
> -		}
>  	}
>  
>  	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
> @@ -5034,12 +5151,7 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
>  	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
>  			   &wm->trans_wm);
>  
> -	/* FIXME: add proper NV12 support for ICL. */
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		return skl_ddb_entry_write(dev_priv,
> -					   PLANE_BUF_CFG(pipe, plane_id),
> -					   &ddb->plane[pipe][plane_id]);
> -	if (wm->is_planar) {
> +	if (wm->is_planar && INTEL_GEN(dev_priv) < 11) {
>  		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
>  				    &ddb->uv_plane[pipe][plane_id]);
>  		skl_ddb_entry_write(dev_priv,
> @@ -5048,7 +5160,8 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
>  	} else {
>  		skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
>  				    &ddb->plane[pipe][plane_id]);
> -		I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
> +		if (INTEL_GEN(dev_priv) < 11)
> +			I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
>  	}
>  }
>  
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11.
  2018-10-18 11:51 ` [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11 Maarten Lankhorst
@ 2018-10-18 16:20   ` Ville Syrjälä
  2018-10-22 13:45     ` [PATCH] drm/i915/gen11: Expose planar format support on gen11, v2 Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-18 16:20 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Oct 18, 2018 at 01:51:34PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I guess the skl_has_planar() thing should be in this patch..

> ---
>  drivers/gpu/drm/i915/intel_display.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5997097177e9..8299eb9193b4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14508,7 +14508,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
>  		break;
>  	case DRM_FORMAT_NV12:
>  		if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
> -		    IS_BROXTON(dev_priv) || INTEL_GEN(dev_priv) >= 11) {
> +		    IS_BROXTON(dev_priv)) {
>  			DRM_DEBUG_KMS("unsupported pixel format: %s\n",
>  				      drm_get_format_name(mode_cmd->pixel_format,
>  							  &format_name));
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] 42+ messages in thread

* Re: [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 15:16 ` [PATCH v2 0/8] " Ville Syrjälä
@ 2018-10-18 16:20   ` Maarten Lankhorst
  0 siblings, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-18 16:20 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 18-10-18 om 17:16 schreef Ville Syrjälä:
> On Thu, Oct 18, 2018 at 01:51:26PM +0200, Maarten Lankhorst wrote:
>> New version, with a lot of reworking to incorporate all the feedback.
>>
>> We currently don't set the plane input CSC correctly, so colors are a
>> bit off. As a result I can't verify for 100% we program the chroma
>> upsampler correctly, but I still want to put out this series for review.
> I didn't spot a change to skl_plane_has_planar() in this series.
> Did that fall off during a rebase or was it never there?
>
> Did you test this version locally? Mainly wondering if we have a
> bug in the core that it lets unsupported pixel formats through...
Hmm indeed, should have been part of patch 8. Seems I lost it there..

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

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

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-18 14:53   ` Ville Syrjälä
@ 2018-10-19 12:58     ` Maarten Lankhorst
  0 siblings, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-19 12:58 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 18-10-18 om 16:53 schreef Ville Syrjälä:
> On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
>> On gen11, we can definitely smash the 32-bits barrier with just a
>> when we enable all planes in the next patch.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> I guess the per-plane data rate is still <32bit (because it doesn't
> account for the refresh rate). But making everything 64bit seems safest.
With the current limits, we're already awfully close if we ever end up with 16 bits per component formats.
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Now we could also improve the per-plane data rate to include the
> refresh rate and get rid of inaccurate drm_mode_vrefresh() in there.
Yeah would be nice. :)
>> ---
>>  drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
>>  1 file changed, 22 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 67a4d0735291..3b136fdfd24f 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
>>  
>>  static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  			      const struct intel_crtc_state *cstate,
>> -			      const unsigned int total_data_rate,
>> +			      const u64 total_data_rate,
>>  			      const int num_active,
>>  			      struct skl_ddb_allocation *ddb)
>>  {
>> @@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>>  
>>  	adjusted_mode = &cstate->base.adjusted_mode;
>> -	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
>> +	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>>  
>>  	/*
>>  	 * 12GB/s is maximum BW supported by single DBuf slice.
>>  	 */
>> -	if (total_data_bw >= GBps(12) || num_active > 1) {
>> +	if (num_active > 1 || total_data_bw >= GBps(12)) {
>>  		ddb->enabled_slices = 2;
>>  	} else {
>>  		ddb->enabled_slices = 1;
>> @@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  static void
>>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>>  				   const struct intel_crtc_state *cstate,
>> -				   const unsigned int total_data_rate,
>> +				   const u64 total_data_rate,
>>  				   struct skl_ddb_allocation *ddb,
>>  				   struct skl_ddb_entry *alloc, /* out */
>>  				   int *num_active /* out */)
>> @@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>  	return 0;
>>  }
>>  
>> -static unsigned int
>> +static u64
>>  skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  			     const struct drm_plane_state *pstate,
>>  			     const int plane)
>> @@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  	struct drm_framebuffer *fb;
>>  	u32 format;
>>  	uint_fixed_16_16_t down_scale_amount;
>> +	u64 rate;
>>  
>>  	if (!intel_pstate->base.visible)
>>  		return 0;
>> @@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  		height /= 2;
>>  	}
>>  
>> -	data_rate = width * height * fb->format->cpp[plane];
>> +	data_rate = width * height;
>>  
>>  	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
>>  
>> -	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
>> +	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
>> +
>> +	rate *= fb->format->cpp[plane];
>> +	return rate;
>>  }
>>  
>> -/*
>> - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
>> - * a 8192x4096@32bpp framebuffer:
>> - *   3 * 4096 * 8192  * 4 < 2^32
>> - */
>> -static unsigned int
>> +static u64
>>  skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>> -				 unsigned int *plane_data_rate,
>> -				 unsigned int *uv_plane_data_rate)
>> +				 u64 *plane_data_rate,
>> +				 u64 *uv_plane_data_rate)
>>  {
>>  	struct drm_crtc_state *cstate = &intel_cstate->base;
>>  	struct drm_atomic_state *state = cstate->state;
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *pstate;
>> -	unsigned int total_data_rate = 0;
>> +	u64 total_data_rate = 0;
>>  
>>  	if (WARN_ON(!state))
>>  		return 0;
>> @@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>>  	/* Calculate and cache data rate for each plane */
>>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
>>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>> -		unsigned int rate;
>> +		u64 rate;
>>  
>>  		/* packed/y */
>>  		rate = skl_plane_relative_data_rate(intel_cstate,
>> @@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  	uint16_t alloc_size, start;
>>  	uint16_t minimum[I915_MAX_PLANES] = {};
>>  	uint16_t uv_minimum[I915_MAX_PLANES] = {};
>> -	unsigned int total_data_rate;
>> +	u64 total_data_rate;
>>  	enum plane_id plane_id;
>>  	int num_active;
>> -	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
>> -	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
>> +	u64 plane_data_rate[I915_MAX_PLANES] = {};
>> +	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
>>  	uint16_t total_min_blocks = 0;
>>  
>>  	/* Clear the partitioning for disabled planes. */
>> @@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  
>>  	start = alloc->start;
>>  	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
>> -		unsigned int data_rate, uv_data_rate;
>> +		u64 data_rate, uv_data_rate;
>>  		uint16_t plane_blocks, uv_plane_blocks;
>>  
>>  		if (plane_id == PLANE_CURSOR)
>> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  		 * result is < available as data_rate / total_data_rate < 1
>>  		 */
>>  		plane_blocks = minimum[plane_id];
>> -		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
>> -					total_data_rate);
>> +		plane_blocks += alloc_size * data_rate / total_data_rate;
>>  
>>  		/* Leave disabled planes at (0,0) */
>>  		if (data_rate) {
>> @@ -4417,8 +4415,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  		uv_data_rate = uv_plane_data_rate[plane_id];
>>  
>>  		uv_plane_blocks = uv_minimum[plane_id];
>> -		uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
>> -					   total_data_rate);
>> +		uv_plane_blocks += alloc_size * uv_data_rate / total_data_rate;
>>  
>>  		if (uv_data_rate) {
>>  			ddb->uv_plane[pipe][plane_id].start = start;
>> -- 
>> 2.19.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

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

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-18 15:11   ` Ville Syrjälä
@ 2018-10-19 13:03     ` Maarten Lankhorst
  2018-10-19 13:06       ` Chris Wilson
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-19 13:03 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 18-10-18 om 17:11 schreef Ville Syrjälä:
> On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
>> On gen11, we can definitely smash the 32-bits barrier with just a
>> when we enable all planes in the next patch.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
>>  1 file changed, 22 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 67a4d0735291..3b136fdfd24f 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
>>  
>>  static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  			      const struct intel_crtc_state *cstate,
>> -			      const unsigned int total_data_rate,
>> +			      const u64 total_data_rate,
>>  			      const int num_active,
>>  			      struct skl_ddb_allocation *ddb)
>>  {
>> @@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>>  
>>  	adjusted_mode = &cstate->base.adjusted_mode;
>> -	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
>> +	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>>  
>>  	/*
>>  	 * 12GB/s is maximum BW supported by single DBuf slice.
>>  	 */
>> -	if (total_data_bw >= GBps(12) || num_active > 1) {
>> +	if (num_active > 1 || total_data_bw >= GBps(12)) {
>>  		ddb->enabled_slices = 2;
>>  	} else {
>>  		ddb->enabled_slices = 1;
>> @@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  static void
>>  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>>  				   const struct intel_crtc_state *cstate,
>> -				   const unsigned int total_data_rate,
>> +				   const u64 total_data_rate,
>>  				   struct skl_ddb_allocation *ddb,
>>  				   struct skl_ddb_entry *alloc, /* out */
>>  				   int *num_active /* out */)
>> @@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>  	return 0;
>>  }
>>  
>> -static unsigned int
>> +static u64
>>  skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  			     const struct drm_plane_state *pstate,
>>  			     const int plane)
>> @@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  	struct drm_framebuffer *fb;
>>  	u32 format;
>>  	uint_fixed_16_16_t down_scale_amount;
>> +	u64 rate;
>>  
>>  	if (!intel_pstate->base.visible)
>>  		return 0;
>> @@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
>>  		height /= 2;
>>  	}
>>  
>> -	data_rate = width * height * fb->format->cpp[plane];
>> +	data_rate = width * height;
>>  
>>  	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
>>  
>> -	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
>> +	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
>> +
>> +	rate *= fb->format->cpp[plane];
>> +	return rate;
>>  }
>>  
>> -/*
>> - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
>> - * a 8192x4096@32bpp framebuffer:
>> - *   3 * 4096 * 8192  * 4 < 2^32
>> - */
>> -static unsigned int
>> +static u64
>>  skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>> -				 unsigned int *plane_data_rate,
>> -				 unsigned int *uv_plane_data_rate)
>> +				 u64 *plane_data_rate,
>> +				 u64 *uv_plane_data_rate)
>>  {
>>  	struct drm_crtc_state *cstate = &intel_cstate->base;
>>  	struct drm_atomic_state *state = cstate->state;
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *pstate;
>> -	unsigned int total_data_rate = 0;
>> +	u64 total_data_rate = 0;
>>  
>>  	if (WARN_ON(!state))
>>  		return 0;
>> @@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
>>  	/* Calculate and cache data rate for each plane */
>>  	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
>>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>> -		unsigned int rate;
>> +		u64 rate;
>>  
>>  		/* packed/y */
>>  		rate = skl_plane_relative_data_rate(intel_cstate,
>> @@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  	uint16_t alloc_size, start;
>>  	uint16_t minimum[I915_MAX_PLANES] = {};
>>  	uint16_t uv_minimum[I915_MAX_PLANES] = {};
>> -	unsigned int total_data_rate;
>> +	u64 total_data_rate;
>>  	enum plane_id plane_id;
>>  	int num_active;
>> -	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
>> -	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
>> +	u64 plane_data_rate[I915_MAX_PLANES] = {};
>> +	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
>>  	uint16_t total_min_blocks = 0;
>>  
>>  	/* Clear the partitioning for disabled planes. */
>> @@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  
>>  	start = alloc->start;
>>  	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
>> -		unsigned int data_rate, uv_data_rate;
>> +		u64 data_rate, uv_data_rate;
>>  		uint16_t plane_blocks, uv_plane_blocks;
>>  
>>  		if (plane_id == PLANE_CURSOR)
>> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>  		 * result is < available as data_rate / total_data_rate < 1
>>  		 */
>>  		plane_blocks = minimum[plane_id];
>> -		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
>> -					total_data_rate);
>> +		plane_blocks += alloc_size * data_rate / total_data_rate;
> I failed to spot the raw 64bit divisions here. Fortunately CI caught
> them (yay). Need to be fixed.
No we can't, if we make the per plane data rate 64-bits, the divisor will overflow a div_u64..

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

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

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-19 13:03     ` Maarten Lankhorst
@ 2018-10-19 13:06       ` Chris Wilson
  2018-10-19 14:15         ` Maarten Lankhorst
  2018-10-22 10:20         ` [PATCH] drm/i915: Fix unsigned overflow when calculating total data rate, v2 Maarten Lankhorst
  0 siblings, 2 replies; 42+ messages in thread
From: Chris Wilson @ 2018-10-19 13:06 UTC (permalink / raw)
  To: Ville Syrjälä, Maarten Lankhorst; +Cc: intel-gfx

Quoting Maarten Lankhorst (2018-10-19 14:03:47)
> Op 18-10-18 om 17:11 schreef Ville Syrjälä:
> > On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
> >> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >>               * result is < available as data_rate / total_data_rate < 1
> >>               */
> >>              plane_blocks = minimum[plane_id];
> >> -            plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> >> -                                    total_data_rate);
> >> +            plane_blocks += alloc_size * data_rate / total_data_rate;
> > I failed to spot the raw 64bit divisions here. Fortunately CI caught
> > them (yay). Need to be fixed.
> No we can't, if we make the per plane data rate 64-bits, the divisor will overflow a div_u64..

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

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

* Re: [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate
  2018-10-19 13:06       ` Chris Wilson
@ 2018-10-19 14:15         ` Maarten Lankhorst
  2018-10-22 10:20         ` [PATCH] drm/i915: Fix unsigned overflow when calculating total data rate, v2 Maarten Lankhorst
  1 sibling, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-19 14:15 UTC (permalink / raw)
  To: Chris Wilson, Ville Syrjälä; +Cc: intel-gfx

Op 19-10-18 om 15:06 schreef Chris Wilson:
> Quoting Maarten Lankhorst (2018-10-19 14:03:47)
>> Op 18-10-18 om 17:11 schreef Ville Syrjälä:
>>> On Thu, Oct 18, 2018 at 01:51:27PM +0200, Maarten Lankhorst wrote:
>>>> @@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>>>>               * result is < available as data_rate / total_data_rate < 1
>>>>               */
>>>>              plane_blocks = minimum[plane_id];
>>>> -            plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
>>>> -                                    total_data_rate);
>>>> +            plane_blocks += alloc_size * data_rate / total_data_rate;
>>> I failed to spot the raw 64bit divisions here. Fortunately CI caught
>>> them (yay). Need to be fixed.
>> No we can't, if we make the per plane data rate 64-bits, the divisor will overflow a div_u64..
> div64_u64()
> -Chris

Right, will use that.

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

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

* Re: [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  2018-10-18 16:00   ` Ville Syrjälä
@ 2018-10-19 14:22     ` Maarten Lankhorst
  2018-10-19 17:14       ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-19 14:22 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 18-10-18 om 18:00 schreef Ville Syrjälä:
> On Thu, Oct 18, 2018 at 01:51:29PM +0200, Maarten Lankhorst wrote:
>> To make NV12 working on icl, we need to update 2 planes simultaneously.
>> I've chosen to do this in the CRTC step after plane validation is done,
>> so we know what planes are (in)visible. The linked Y plane will get
>> updated in intel_plane_update_planes_on_crtc(), by the call to
>> update_slave, which gets the master's plane_state as argument.
>>
>> The link requires both planes for atomic_update to work,
>> so make sure skl_ddb_add_affected_planes() adds both states.
>>
>> Changes since v1:
>> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
>> - Put all the state updating login in intel_plane_atomic_check_with_state().
>> - Clean up changes in intel_plane_atomic_check().
>> Changes since v2:
>> - Fix intel_atomic_get_old_plane_state() to actually return old state.
>> - Move visibility changes to preparation patch.
>> - Only try to find a Y plane on gen11, earlier platforms only require
>>   a single plane.
>> Changes since v3:
>> - Fix checkpatch warning about to_intel_crtc() usage.
>> - Add affected planes from icl_add_linked_planes() before check_planes(),
>>   it's a cleaner way to do this. (Ville)
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_atomic_plane.c | 74 ++++++++++++++++-----
>>  drivers/gpu/drm/i915/intel_display.c      | 81 +++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++++
>>  drivers/gpu/drm/i915/intel_pm.c           | 12 +++-
>>  4 files changed, 202 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> index b957ad63cd87..154ea3dc344f 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> @@ -122,7 +122,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>>  	crtc_state->nv12_planes &= ~BIT(intel_plane->id);
>>  	intel_state->base.visible = false;
>>  
>> -	/* If this is a cursor plane, no further checks are needed. */
>> +	/* Destroy the link */
>> +	intel_state->linked_plane = NULL;
>> +	intel_state->slave = false;
>> +
>> +	/* If this is a cursor or Y plane, no further checks are needed. */
>>  	if (!intel_state->base.crtc && !old_plane_state->base.crtc)
>>  		return 0;
>>  
>> @@ -143,27 +147,44 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>>  					       state);
>>  }
>>  
>> -static int intel_plane_atomic_check(struct drm_plane *plane,
>> -				    struct drm_plane_state *new_plane_state)
>> +static int intel_plane_atomic_check(struct drm_plane *drm_plane,
>> +				    struct drm_plane_state *new_drm_plane_state)
> My new cunning plane is to call these _plane, _new_plane_state etc.
> It should discourage people from using them and the aliasing
> intel_ types at the same time. And it avoids polluting the namespace
> for things we don't really want to use. 
>
> I already snuck in some uses of this ;)
>
>>  {
>> -	struct drm_atomic_state *state = new_plane_state->state;
>> -	const struct drm_plane_state *old_plane_state =
>> -		drm_atomic_get_old_plane_state(state, plane);
>> -	struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
>> -	const struct drm_crtc_state *old_crtc_state;
>> -	struct drm_crtc_state *new_crtc_state;
>> -
>> -	new_plane_state->visible = false;
>> +	struct intel_atomic_state *state =
>> +		to_intel_atomic_state(new_drm_plane_state->state);
>> +	struct intel_plane *plane = to_intel_plane(drm_plane);
>> +	const struct intel_plane_state *old_plane_state =
>> +		intel_atomic_get_old_plane_state(state, plane);
>> +	struct intel_plane_state *new_plane_state =
>> +		to_intel_plane_state(new_drm_plane_state);
>> +	struct intel_crtc *crtc =
>> +		to_intel_crtc(new_plane_state->base.crtc ?:
>> +			      old_plane_state->base.crtc);
>> +	const struct intel_crtc_state *old_crtc_state;
>> +	struct intel_crtc_state *new_crtc_state;
>> +	struct intel_plane *linked = old_plane_state->linked_plane;
>> +
>> +	if (linked && !crtc) {
>> +		const struct intel_plane_state *old_linked_state =
>> +			intel_atomic_get_old_plane_state(state, linked);
> Plane without a crtc that happens to have a linked plane
> attached to it...
>
> I guess that implies that 'plane' here is the slave and
> it was already active during the previous state (otherwise
> it would not have been linked to the other plane). So that
> means the master plane must have a valid crtc in its old
> plane state.
>
> Did I decode that correctly?
Correct.
> Maybe what we want to do here is to just always clear the
> active_planes bit for the slave in the master plane's
> old crtc's new crtc state (quite the mouthful), and then
> run through the normal check_plane stuff for the slave
> with its own crtc (if it has one). In practice it doesn't
> really make any difference I suppose since our planes
> can't move between crtcs, but logically it would make
> more sense to me.
Even if we could move planes,  we can't move planes between CRTC's in a single atomic commit.
First comes the disabling, then comes the moving.

I think it's less of a mess of doing it this way, it keeps intel_plane_atomic_check_with_state() obvious.
>> +
>> +		if (WARN_ON(!old_linked_state))
>> +			return -EINVAL;
>> +
>> +		crtc = to_intel_crtc(old_linked_state->base.crtc);
>> +		if (WARN_ON(!crtc))
>> +			return -EINVAL;
>> +	}
>> +
>> +	new_plane_state->base.visible = false;
>>  	if (!crtc)
>>  		return 0;
>>  
>> -	old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
>> -	new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
>> +	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
>> +	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>>  
>> -	return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state),
>> -						   to_intel_crtc_state(new_crtc_state),
>> -						   to_intel_plane_state(old_plane_state),
>> -						   to_intel_plane_state(new_plane_state));
>> +	return intel_plane_atomic_check_with_state(old_crtc_state, new_crtc_state,
>> +						   old_plane_state, new_plane_state);
>>  }
>>  
>>  void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>> @@ -188,6 +209,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>>  			trace_intel_update_plane(&plane->base, crtc);
>>  
>>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
>> +		} else if (new_plane_state->slave) {
>> +			struct intel_plane *master =
>> +				new_plane_state->linked_plane;
>> +
>> +			/*
>> +			 * We update the slave plane from this function because
>> +			 * programming it from the master plane's update_plane
>> +			 * callback runs into issues when the Y plane is
>> +			 * reassigned, disabled or used by a different plane.
>> +			 *
>> +			 * The slave plane is updated with the master plane's
>> +			 * plane_state.
>> +			 */
>> +			new_plane_state =
>> +				intel_atomic_get_new_plane_state(old_state, master);
>> +
>> +			trace_intel_update_plane(&plane->base, crtc);
>> +
>> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
>>  		} else {
>>  			trace_intel_disable_plane(&plane->base, crtc);
>>  
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 8e1b3677e131..cbb3fb1d5ad4 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -10721,6 +10721,80 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>>  	return true;
>>  }
>>  
>> +static int icl_add_linked_planes(struct intel_atomic_state *state)
>> +{
>> +	struct intel_plane *plane, *linked;
>> +	struct intel_plane_state *plane_state, *linked_plane_state;
>> +	int i;
>> +
>> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
>> +		linked = plane_state->linked_plane;
>> +
>> +		if (!linked)
>> +			continue;
>> +
>> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
>> +		if (IS_ERR(linked_plane_state))
>> +			return PTR_ERR(linked_plane_state);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int icl_check_nv12_planes(struct drm_i915_private *dev_priv,
>> +				 struct intel_crtc *crtc,
>> +				 struct intel_crtc_state *crtc_state)
> Could pass just the crtc_state and dig the rest out here.
Yeah that's fine.
>> +{
>> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
>> +	struct intel_plane *plane, *aux;
>> +
>> +	if (INTEL_GEN(dev_priv) < 11 || !crtc_state->nv12_planes)
>> +		return 0;
>> +
>> +	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
>> +		struct intel_plane_state *plane_state, *aux_state;
>> +		struct drm_plane_state *drm_aux_state = NULL;
> Still don't like the 'aux' in these names.
> Just linked/linked_plane_state' to match the rest of the
> code?
Ok.
>
>> +
>> +		if (!(crtc_state->nv12_planes & BIT(plane->id)))
>> +			continue;
>> +
>> +		plane_state = intel_atomic_get_new_plane_state(state, plane);
>> +		if (!plane_state)
>> +			continue;
>> +
>> +		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, aux) {
>> +			if (!icl_is_nv12_y_plane(aux->id))
>> +				continue;
>> +
>> +			if (crtc_state->active_planes & BIT(aux->id))
>> +				continue;
>> +
>> +			drm_aux_state = drm_atomic_get_plane_state(&state->base, &aux->base);
> intel_atomic_get_plane() and get rid of the aliasing states?
+1
>> +			if (IS_ERR(drm_aux_state))
>> +				return PTR_ERR(drm_aux_state);
>> +
>> +			break;
>> +		}
>> +
>> +		if (!drm_aux_state) {
>> +			DRM_DEBUG_KMS("Need %d free Y planes for NV12\n",
>> +				      hweight8(crtc_state->nv12_planes));
>> +
>> +			return -EINVAL;
>> +		}
>> +
>> +		plane_state->linked_plane = aux;
>> +
>> +		aux_state = to_intel_plane_state(drm_aux_state);
>> +		aux_state->slave = true;
>> +		aux_state->linked_plane = plane;
>> +		crtc_state->active_planes |= BIT(aux->id);
>> +		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", aux->base.name, plane->base.name);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>>  				   struct drm_crtc_state *crtc_state)
>>  {
>> @@ -10792,6 +10866,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>>  		if (mode_changed)
>>  			ret = skl_update_scaler_crtc(pipe_config);
>>  
>> +		if (!ret)
>> +			ret = icl_check_nv12_planes(dev_priv, intel_crtc,
>> +						    pipe_config);
>>  		if (!ret)
>>  			ret = skl_check_pipe_max_pixel_rate(intel_crtc,
>>  							    pipe_config);
>> @@ -12458,6 +12535,10 @@ static int intel_atomic_check(struct drm_device *dev,
>>  		intel_state->cdclk.logical = dev_priv->cdclk.logical;
>>  	}
>>  
>> +	ret = icl_add_linked_planes(intel_state);
>> +	if (ret)
>> +		return ret;
>> +
>>  	ret = drm_atomic_helper_check_planes(dev, state);
>>  	if (ret)
>>  		return ret;
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index b5d6f6887c13..272de906a001 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -539,6 +539,26 @@ struct intel_plane_state {
>>  	 */
>>  	int scaler_id;
>>  
>> +	/*
>> +	 * linked_plane:
>> +	 *
>> +	 * ICL planar formats require 2 planes that are updated as pairs.
>> +	 * This member is used to make sure the other plane is also updated
>> +	 * when required, and for update_slave() to find the correct
>> +	 * plane_state to pass as argument.
>> +	 */
>> +	struct intel_plane *linked_plane;
>> +
>> +	/*
>> +	 * slave:
>> +	 * If set don't update use the linked plane's state for updating
>> +	 * this plane during atomic commit with the update_slave() callback.
>> +	 *
>> +	 * It's also used by the watermark code to ignore wm calculations on
>> +	 * this plane. They're calculated by the linked plane's wm code.
>> +	 */
>> +	bool slave;
>> +
>>  	struct drm_intel_sprite_colorkey ckey;
>>  };
>>  
>> @@ -983,6 +1003,9 @@ struct intel_plane {
>>  	void (*update_plane)(struct intel_plane *plane,
>>  			     const struct intel_crtc_state *crtc_state,
>>  			     const struct intel_plane_state *plane_state);
>> +	void (*update_slave)(struct intel_plane *plane,
>> +			     const struct intel_crtc_state *crtc_state,
>> +			     const struct intel_plane_state *plane_state);
>>  	void (*disable_plane)(struct intel_plane *plane,
>>  			      struct intel_crtc *crtc);
>>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
>> @@ -1351,6 +1374,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
>>  	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
>>  }
>>  
>> +static inline struct intel_plane_state *
>> +intel_atomic_get_plane_state(struct intel_atomic_state *state,
>> +				 struct intel_plane *plane)
>> +{
>> +	struct drm_plane_state *ret =
>> +		drm_atomic_get_plane_state(&state->base, &plane->base);
>> +
>> +	if (IS_ERR(ret))
>> +		return ERR_CAST(ret);
>> +
>> +	return to_intel_plane_state(ret);
>> +}
>> +
>> +static inline struct intel_plane_state *
>> +intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
>> +				 struct intel_plane *plane)
>> +{
>> +	return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
>> +								   &plane->base));
>> +}
>> +
>>  static inline struct intel_plane_state *
>>  intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
>>  				 struct intel_plane *plane)
>> @@ -2158,6 +2202,15 @@ struct intel_plane *
>>  skl_universal_plane_create(struct drm_i915_private *dev_priv,
>>  			   enum pipe pipe, enum plane_id plane_id);
>>  
>> +static inline bool icl_is_nv12_y_plane(enum plane_id id)
>> +{
>> +	/* Don't need to do a gen check, these planes are only available on gen11 */
>> +	if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
>> +		return true;
>> +
>> +	return false;
>> +}
>> +
>>  /* intel_tv.c */
>>  void intel_tv_init(struct drm_i915_private *dev_priv);
>>  
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 3b136fdfd24f..d003c08bd9e4 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -5153,11 +5153,12 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>>  	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
>>  	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
>> -	struct drm_plane_state *plane_state;
>>  	struct drm_plane *plane;
>>  	enum pipe pipe = intel_crtc->pipe;
>>  
>>  	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
>> +		struct drm_plane_state *plane_state;
>> +		struct intel_plane *linked;
>>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>>  
>>  		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
>> @@ -5169,6 +5170,15 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>>  		plane_state = drm_atomic_get_plane_state(state, plane);
>>  		if (IS_ERR(plane_state))
>>  			return PTR_ERR(plane_state);
>> +
>> +		/* Make sure linked plane is updated too */
>> +		linked = to_intel_plane_state(plane_state)->linked_plane;
>> +		if (!linked)
>> +			continue;
>> +
>> +		plane_state = drm_atomic_get_plane_state(state, &linked->base);
>> +		if (IS_ERR(plane_state))
>> +			return PTR_ERR(plane_state);
>>  	}
>>  
>>  	return 0;
>> -- 
>> 2.19.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

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

* Re: [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  2018-10-19 14:22     ` Maarten Lankhorst
@ 2018-10-19 17:14       ` Ville Syrjälä
  2018-10-22 10:09         ` Maarten Lankhorst
  2018-10-22 13:51         ` [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5 Maarten Lankhorst
  0 siblings, 2 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-19 17:14 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Oct 19, 2018 at 04:22:29PM +0200, Maarten Lankhorst wrote:
> Op 18-10-18 om 18:00 schreef Ville Syrjälä:
> > On Thu, Oct 18, 2018 at 01:51:29PM +0200, Maarten Lankhorst wrote:
> >> To make NV12 working on icl, we need to update 2 planes simultaneously.
> >> I've chosen to do this in the CRTC step after plane validation is done,
> >> so we know what planes are (in)visible. The linked Y plane will get
> >> updated in intel_plane_update_planes_on_crtc(), by the call to
> >> update_slave, which gets the master's plane_state as argument.
> >>
> >> The link requires both planes for atomic_update to work,
> >> so make sure skl_ddb_add_affected_planes() adds both states.
> >>
> >> Changes since v1:
> >> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
> >> - Put all the state updating login in intel_plane_atomic_check_with_state().
> >> - Clean up changes in intel_plane_atomic_check().
> >> Changes since v2:
> >> - Fix intel_atomic_get_old_plane_state() to actually return old state.
> >> - Move visibility changes to preparation patch.
> >> - Only try to find a Y plane on gen11, earlier platforms only require
> >>   a single plane.
> >> Changes since v3:
> >> - Fix checkpatch warning about to_intel_crtc() usage.
> >> - Add affected planes from icl_add_linked_planes() before check_planes(),
> >>   it's a cleaner way to do this. (Ville)
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_atomic_plane.c | 74 ++++++++++++++++-----
> >>  drivers/gpu/drm/i915/intel_display.c      | 81 +++++++++++++++++++++++
> >>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++++
> >>  drivers/gpu/drm/i915/intel_pm.c           | 12 +++-
> >>  4 files changed, 202 insertions(+), 18 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> index b957ad63cd87..154ea3dc344f 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> @@ -122,7 +122,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
> >>  	crtc_state->nv12_planes &= ~BIT(intel_plane->id);
> >>  	intel_state->base.visible = false;
> >>  
> >> -	/* If this is a cursor plane, no further checks are needed. */
> >> +	/* Destroy the link */
> >> +	intel_state->linked_plane = NULL;
> >> +	intel_state->slave = false;
> >> +
> >> +	/* If this is a cursor or Y plane, no further checks are needed. */
> >>  	if (!intel_state->base.crtc && !old_plane_state->base.crtc)
> >>  		return 0;
> >>  
> >> @@ -143,27 +147,44 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
> >>  					       state);
> >>  }
> >>  
> >> -static int intel_plane_atomic_check(struct drm_plane *plane,
> >> -				    struct drm_plane_state *new_plane_state)
> >> +static int intel_plane_atomic_check(struct drm_plane *drm_plane,
> >> +				    struct drm_plane_state *new_drm_plane_state)
> > My new cunning plane is to call these _plane, _new_plane_state etc.
> > It should discourage people from using them and the aliasing
> > intel_ types at the same time. And it avoids polluting the namespace
> > for things we don't really want to use. 
> >
> > I already snuck in some uses of this ;)
> >
> >>  {
> >> -	struct drm_atomic_state *state = new_plane_state->state;
> >> -	const struct drm_plane_state *old_plane_state =
> >> -		drm_atomic_get_old_plane_state(state, plane);
> >> -	struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
> >> -	const struct drm_crtc_state *old_crtc_state;
> >> -	struct drm_crtc_state *new_crtc_state;
> >> -
> >> -	new_plane_state->visible = false;
> >> +	struct intel_atomic_state *state =
> >> +		to_intel_atomic_state(new_drm_plane_state->state);
> >> +	struct intel_plane *plane = to_intel_plane(drm_plane);
> >> +	const struct intel_plane_state *old_plane_state =
> >> +		intel_atomic_get_old_plane_state(state, plane);
> >> +	struct intel_plane_state *new_plane_state =
> >> +		to_intel_plane_state(new_drm_plane_state);
> >> +	struct intel_crtc *crtc =
> >> +		to_intel_crtc(new_plane_state->base.crtc ?:
> >> +			      old_plane_state->base.crtc);
> >> +	const struct intel_crtc_state *old_crtc_state;
> >> +	struct intel_crtc_state *new_crtc_state;
> >> +	struct intel_plane *linked = old_plane_state->linked_plane;
> >> +
> >> +	if (linked && !crtc) {
> >> +		const struct intel_plane_state *old_linked_state =
> >> +			intel_atomic_get_old_plane_state(state, linked);
> > Plane without a crtc that happens to have a linked plane
> > attached to it...
> >
> > I guess that implies that 'plane' here is the slave and
> > it was already active during the previous state (otherwise
> > it would not have been linked to the other plane). So that
> > means the master plane must have a valid crtc in its old
> > plane state.
> >
> > Did I decode that correctly?
> Correct.
> > Maybe what we want to do here is to just always clear the
> > active_planes bit for the slave in the master plane's
> > old crtc's new crtc state (quite the mouthful), and then
> > run through the normal check_plane stuff for the slave
> > with its own crtc (if it has one). In practice it doesn't
> > really make any difference I suppose since our planes
> > can't move between crtcs, but logically it would make
> > more sense to me.
> Even if we could move planes,  we can't move planes between CRTC's in a single atomic commit.
> First comes the disabling, then comes the moving.
> 
> I think it's less of a mess of doing it this way, it keeps intel_plane_atomic_check_with_state() obvious.

It's rather non-obvious. I had to think about it for a while.

I think it would be much clearer to keep it all in one self
contained function instead of spreading it across several
functions.

remove_plane_link()
{
	if (plane_state->linked && plane_state->slave) {
		old_linked_state = get_old_plane_state(plane_state->linked);
		new_crtc_state = get_new_crtc_state(old_linked_state->crtc);
		new_crtc_state->active_planes &= ~BIT(plane->id);
	}

	plane_state->linked = NULL;
	plane_state->slave = false;
}

or something.

-- 
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] 42+ messages in thread

* Re: [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4.
  2018-10-19 17:14       ` Ville Syrjälä
@ 2018-10-22 10:09         ` Maarten Lankhorst
  2018-10-22 13:51         ` [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5 Maarten Lankhorst
  1 sibling, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-22 10:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 19-10-18 om 19:14 schreef Ville Syrjälä:
> On Fri, Oct 19, 2018 at 04:22:29PM +0200, Maarten Lankhorst wrote:
>> Op 18-10-18 om 18:00 schreef Ville Syrjälä:
>>> On Thu, Oct 18, 2018 at 01:51:29PM +0200, Maarten Lankhorst wrote:
>>>> To make NV12 working on icl, we need to update 2 planes simultaneously.
>>>> I've chosen to do this in the CRTC step after plane validation is done,
>>>> so we know what planes are (in)visible. The linked Y plane will get
>>>> updated in intel_plane_update_planes_on_crtc(), by the call to
>>>> update_slave, which gets the master's plane_state as argument.
>>>>
>>>> The link requires both planes for atomic_update to work,
>>>> so make sure skl_ddb_add_affected_planes() adds both states.
>>>>
>>>> Changes since v1:
>>>> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
>>>> - Put all the state updating login in intel_plane_atomic_check_with_state().
>>>> - Clean up changes in intel_plane_atomic_check().
>>>> Changes since v2:
>>>> - Fix intel_atomic_get_old_plane_state() to actually return old state.
>>>> - Move visibility changes to preparation patch.
>>>> - Only try to find a Y plane on gen11, earlier platforms only require
>>>>   a single plane.
>>>> Changes since v3:
>>>> - Fix checkpatch warning about to_intel_crtc() usage.
>>>> - Add affected planes from icl_add_linked_planes() before check_planes(),
>>>>   it's a cleaner way to do this. (Ville)
>>>>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>> ---
>>>>  drivers/gpu/drm/i915/intel_atomic_plane.c | 74 ++++++++++++++++-----
>>>>  drivers/gpu/drm/i915/intel_display.c      | 81 +++++++++++++++++++++++
>>>>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++++
>>>>  drivers/gpu/drm/i915/intel_pm.c           | 12 +++-
>>>>  4 files changed, 202 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> index b957ad63cd87..154ea3dc344f 100644
>>>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> @@ -122,7 +122,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>>>>  	crtc_state->nv12_planes &= ~BIT(intel_plane->id);
>>>>  	intel_state->base.visible = false;
>>>>  
>>>> -	/* If this is a cursor plane, no further checks are needed. */
>>>> +	/* Destroy the link */
>>>> +	intel_state->linked_plane = NULL;
>>>> +	intel_state->slave = false;
>>>> +
>>>> +	/* If this is a cursor or Y plane, no further checks are needed. */
>>>>  	if (!intel_state->base.crtc && !old_plane_state->base.crtc)
>>>>  		return 0;
>>>>  
>>>> @@ -143,27 +147,44 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>>>>  					       state);
>>>>  }
>>>>  
>>>> -static int intel_plane_atomic_check(struct drm_plane *plane,
>>>> -				    struct drm_plane_state *new_plane_state)
>>>> +static int intel_plane_atomic_check(struct drm_plane *drm_plane,
>>>> +				    struct drm_plane_state *new_drm_plane_state)
>>> My new cunning plane is to call these _plane, _new_plane_state etc.
>>> It should discourage people from using them and the aliasing
>>> intel_ types at the same time. And it avoids polluting the namespace
>>> for things we don't really want to use. 
>>>
>>> I already snuck in some uses of this ;)
>>>
>>>>  {
>>>> -	struct drm_atomic_state *state = new_plane_state->state;
>>>> -	const struct drm_plane_state *old_plane_state =
>>>> -		drm_atomic_get_old_plane_state(state, plane);
>>>> -	struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
>>>> -	const struct drm_crtc_state *old_crtc_state;
>>>> -	struct drm_crtc_state *new_crtc_state;
>>>> -
>>>> -	new_plane_state->visible = false;
>>>> +	struct intel_atomic_state *state =
>>>> +		to_intel_atomic_state(new_drm_plane_state->state);
>>>> +	struct intel_plane *plane = to_intel_plane(drm_plane);
>>>> +	const struct intel_plane_state *old_plane_state =
>>>> +		intel_atomic_get_old_plane_state(state, plane);
>>>> +	struct intel_plane_state *new_plane_state =
>>>> +		to_intel_plane_state(new_drm_plane_state);
>>>> +	struct intel_crtc *crtc =
>>>> +		to_intel_crtc(new_plane_state->base.crtc ?:
>>>> +			      old_plane_state->base.crtc);
>>>> +	const struct intel_crtc_state *old_crtc_state;
>>>> +	struct intel_crtc_state *new_crtc_state;
>>>> +	struct intel_plane *linked = old_plane_state->linked_plane;
>>>> +
>>>> +	if (linked && !crtc) {
>>>> +		const struct intel_plane_state *old_linked_state =
>>>> +			intel_atomic_get_old_plane_state(state, linked);
>>> Plane without a crtc that happens to have a linked plane
>>> attached to it...
>>>
>>> I guess that implies that 'plane' here is the slave and
>>> it was already active during the previous state (otherwise
>>> it would not have been linked to the other plane). So that
>>> means the master plane must have a valid crtc in its old
>>> plane state.
>>>
>>> Did I decode that correctly?
>> Correct.
>>> Maybe what we want to do here is to just always clear the
>>> active_planes bit for the slave in the master plane's
>>> old crtc's new crtc state (quite the mouthful), and then
>>> run through the normal check_plane stuff for the slave
>>> with its own crtc (if it has one). In practice it doesn't
>>> really make any difference I suppose since our planes
>>> can't move between crtcs, but logically it would make
>>> more sense to me.
>> Even if we could move planes,  we can't move planes between CRTC's in a single atomic commit.
>> First comes the disabling, then comes the moving.
>>
>> I think it's less of a mess of doing it this way, it keeps intel_plane_atomic_check_with_state() obvious.
> It's rather non-obvious. I had to think about it for a while.
>
> I think it would be much clearer to keep it all in one self
> contained function instead of spreading it across several
> functions.
>
> remove_plane_link()
> {
> 	if (plane_state->linked && plane_state->slave) {
> 		old_linked_state = get_old_plane_state(plane_state->linked);
> 		new_crtc_state = get_new_crtc_state(old_linked_state->crtc);
> 		new_crtc_state->active_planes &= ~BIT(plane->id);
> 	}
>
> 	plane_state->linked = NULL;
> 	plane_state->slave = false;
> }
>
> or something.
>
Ok, v5 coming up, bringing much more clarity. :)

It turns out to be easier and cleaner to remove the plane link as
a separate pass in icl_check_nv12_planes() before restoring new links.

~Maarten

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

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

* [PATCH] drm/i915: Fix unsigned overflow when calculating total data rate, v2.
  2018-10-19 13:06       ` Chris Wilson
  2018-10-19 14:15         ` Maarten Lankhorst
@ 2018-10-22 10:20         ` Maarten Lankhorst
  1 sibling, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-22 10:20 UTC (permalink / raw)
  To: intel-gfx

On gen11, we can definitely smash the 32-bits barrier with just a
when we enable all planes in the next patch.

Changes since v1:
- Use div64_u64 (ickle).

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 47 +++++++++++++++------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 67a4d0735291..f42b8c319046 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3784,7 +3784,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
 
 static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 			      const struct intel_crtc_state *cstate,
-			      const unsigned int total_data_rate,
+			      const u64 total_data_rate,
 			      const int num_active,
 			      struct skl_ddb_allocation *ddb)
 {
@@ -3798,12 +3798,12 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 		return ddb_size - 4; /* 4 blocks for bypass path allocation */
 
 	adjusted_mode = &cstate->base.adjusted_mode;
-	total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode);
+	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
 
 	/*
 	 * 12GB/s is maximum BW supported by single DBuf slice.
 	 */
-	if (total_data_bw >= GBps(12) || num_active > 1) {
+	if (num_active > 1 || total_data_bw >= GBps(12)) {
 		ddb->enabled_slices = 2;
 	} else {
 		ddb->enabled_slices = 1;
@@ -3816,7 +3816,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 				   const struct intel_crtc_state *cstate,
-				   const unsigned int total_data_rate,
+				   const u64 total_data_rate,
 				   struct skl_ddb_allocation *ddb,
 				   struct skl_ddb_entry *alloc, /* out */
 				   int *num_active /* out */)
@@ -4139,7 +4139,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 	return 0;
 }
 
-static unsigned int
+static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 			     const struct drm_plane_state *pstate,
 			     const int plane)
@@ -4151,6 +4151,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 	struct drm_framebuffer *fb;
 	u32 format;
 	uint_fixed_16_16_t down_scale_amount;
+	u64 rate;
 
 	if (!intel_pstate->base.visible)
 		return 0;
@@ -4177,28 +4178,26 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 		height /= 2;
 	}
 
-	data_rate = width * height * fb->format->cpp[plane];
+	data_rate = width * height;
 
 	down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
 
-	return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
+	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
+
+	rate *= fb->format->cpp[plane];
+	return rate;
 }
 
-/*
- * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
- * a 8192x4096@32bpp framebuffer:
- *   3 * 4096 * 8192  * 4 < 2^32
- */
-static unsigned int
+static u64
 skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
-				 unsigned int *plane_data_rate,
-				 unsigned int *uv_plane_data_rate)
+				 u64 *plane_data_rate,
+				 u64 *uv_plane_data_rate)
 {
 	struct drm_crtc_state *cstate = &intel_cstate->base;
 	struct drm_atomic_state *state = cstate->state;
 	struct drm_plane *plane;
 	const struct drm_plane_state *pstate;
-	unsigned int total_data_rate = 0;
+	u64 total_data_rate = 0;
 
 	if (WARN_ON(!state))
 		return 0;
@@ -4206,7 +4205,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
 	/* Calculate and cache data rate for each plane */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) {
 		enum plane_id plane_id = to_intel_plane(plane)->id;
-		unsigned int rate;
+		u64 rate;
 
 		/* packed/y */
 		rate = skl_plane_relative_data_rate(intel_cstate,
@@ -4325,11 +4324,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 	uint16_t alloc_size, start;
 	uint16_t minimum[I915_MAX_PLANES] = {};
 	uint16_t uv_minimum[I915_MAX_PLANES] = {};
-	unsigned int total_data_rate;
+	u64 total_data_rate;
 	enum plane_id plane_id;
 	int num_active;
-	unsigned int plane_data_rate[I915_MAX_PLANES] = {};
-	unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
+	u64 plane_data_rate[I915_MAX_PLANES] = {};
+	u64 uv_plane_data_rate[I915_MAX_PLANES] = {};
 	uint16_t total_min_blocks = 0;
 
 	/* Clear the partitioning for disabled planes. */
@@ -4388,7 +4387,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
 	start = alloc->start;
 	for_each_plane_id_on_crtc(intel_crtc, plane_id) {
-		unsigned int data_rate, uv_data_rate;
+		u64 data_rate, uv_data_rate;
 		uint16_t plane_blocks, uv_plane_blocks;
 
 		if (plane_id == PLANE_CURSOR)
@@ -4402,8 +4401,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		 * result is < available as data_rate / total_data_rate < 1
 		 */
 		plane_blocks = minimum[plane_id];
-		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
-					total_data_rate);
+		plane_blocks += div64_u64(alloc_size * data_rate, total_data_rate);
 
 		/* Leave disabled planes at (0,0) */
 		if (data_rate) {
@@ -4417,8 +4415,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		uv_data_rate = uv_plane_data_rate[plane_id];
 
 		uv_plane_blocks = uv_minimum[plane_id];
-		uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
-					   total_data_rate);
+		uv_plane_blocks += div64_u64(alloc_size * uv_data_rate, total_data_rate);
 
 		if (uv_data_rate) {
 			ddb->uv_plane[pipe][plane_id].start = start;
-- 
2.19.1

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

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

* ✓ Fi.CI.IGT: success for drm/i915/gen11: Add support for the NV12 format.
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (11 preceding siblings ...)
  2018-10-18 15:16 ` [PATCH v2 0/8] " Ville Syrjälä
@ 2018-10-22 10:52 ` Patchwork
  2018-10-22 15:28 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format. (rev4) Patchwork
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-22 10:52 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format.
URL   : https://patchwork.freedesktop.org/series/51178/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5005_full -> Patchwork_10503_full =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10503_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10503_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_10503_full:

  === IGT changes ===

    ==== Warnings ====

    igt@kms_cursor_legacy@nonblocking-modeset-vs-cursor-atomic:
      shard-snb:          PASS -> SKIP

    igt@perf_pmu@rc6:
      shard-kbl:          SKIP -> PASS

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_suspend@fence-restore-untiled:
      shard-kbl:          PASS -> INCOMPLETE (fdo#103665)

    igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-a:
      shard-skl:          NOTRUN -> DMESG-WARN (fdo#107956)

    igt@kms_color@pipe-c-ctm-max:
      shard-skl:          PASS -> FAIL (fdo#108147)

    igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
      shard-skl:          PASS -> FAIL (fdo#102670)

    igt@kms_fbcon_fbt@psr-suspend:
      shard-skl:          NOTRUN -> FAIL (fdo#107882)

    igt@kms_flip@flip-vs-expired-vblank:
      shard-glk:          PASS -> FAIL (fdo#105363, fdo#102887)

    igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-fullscreen:
      shard-hsw:          PASS -> DMESG-WARN (fdo#102614)

    igt@kms_plane_alpha_blend@pipe-c-alpha-transparant-fb:
      shard-skl:          NOTRUN -> FAIL (fdo#108145)

    igt@kms_plane_multiple@atomic-pipe-b-tiling-x:
      shard-glk:          PASS -> FAIL (fdo#103166)

    igt@perf_pmu@idle-no-semaphores-rcs0:
      shard-glk:          PASS -> DMESG-WARN (fdo#106538, fdo#105763) +1

    igt@pm_backlight@fade_with_suspend:
      shard-skl:          NOTRUN -> FAIL (fdo#107847)

    
    ==== Possible fixes ====

    igt@drv_suspend@shrink:
      shard-hsw:          INCOMPLETE (fdo#106886, fdo#103540) -> PASS

    igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-a:
      shard-apl:          DMESG-WARN (fdo#107956) -> PASS

    igt@kms_color@pipe-a-legacy-gamma:
      shard-apl:          FAIL (fdo#108145, fdo#104782) -> PASS

    igt@kms_cursor_crc@cursor-256x256-random:
      shard-apl:          FAIL (fdo#103232) -> PASS

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt:
      shard-apl:          FAIL (fdo#103167) -> PASS +1

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-cpu:
      shard-glk:          FAIL (fdo#103167) -> PASS

    igt@kms_plane@plane-position-covered-pipe-a-planes:
      shard-glk:          FAIL (fdo#103166) -> PASS +2

    igt@kms_setmode@basic:
      shard-apl:          FAIL (fdo#99912) -> PASS
      shard-kbl:          FAIL (fdo#99912) -> PASS

    igt@pm_rpm@dpms-non-lpsp:
      shard-skl:          INCOMPLETE (fdo#107807) -> SKIP

    igt@pm_rpm@gem-execbuf:
      shard-skl:          INCOMPLETE (fdo#107803, fdo#107807) -> PASS

    
  fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614
  fdo#102670 https://bugs.freedesktop.org/show_bug.cgi?id=102670
  fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887
  fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
  fdo#103540 https://bugs.freedesktop.org/show_bug.cgi?id=103540
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#104782 https://bugs.freedesktop.org/show_bug.cgi?id=104782
  fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
  fdo#105763 https://bugs.freedesktop.org/show_bug.cgi?id=105763
  fdo#106538 https://bugs.freedesktop.org/show_bug.cgi?id=106538
  fdo#106886 https://bugs.freedesktop.org/show_bug.cgi?id=106886
  fdo#107803 https://bugs.freedesktop.org/show_bug.cgi?id=107803
  fdo#107807 https://bugs.freedesktop.org/show_bug.cgi?id=107807
  fdo#107847 https://bugs.freedesktop.org/show_bug.cgi?id=107847
  fdo#107882 https://bugs.freedesktop.org/show_bug.cgi?id=107882
  fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
  fdo#108145 https://bugs.freedesktop.org/show_bug.cgi?id=108145
  fdo#108147 https://bugs.freedesktop.org/show_bug.cgi?id=108147
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912


== Participating hosts (6 -> 6) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_5005 -> Patchwork_10503

  CI_DRM_5005: 7a27ee6b5f714f6852abb0098990a05675bd9d55 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4683: 7766b1e2348b32cc8ed58a972c6fd53b20279549 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10503: 14968407636696c468f4da00b159adc0b447ff49 @ 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_10503/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH] drm/i915/gen11: Expose planar format support on gen11, v2.
  2018-10-18 16:20   ` Ville Syrjälä
@ 2018-10-22 13:45     ` Maarten Lankhorst
  2018-10-22 15:55       ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-22 13:45 UTC (permalink / raw)
  To: intel-gfx

Now that we implemented support for planar formats on gen11, we can
finally advertise it.

Changes since v1:
- Re-add change to skl_plane_has_planar(), was lost in rebase noise.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 drivers/gpu/drm/i915/intel_sprite.c  | 6 +-----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d035b04cd654..50b7ae99d0dd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14524,7 +14524,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 		break;
 	case DRM_FORMAT_NV12:
 		if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
-		    IS_BROXTON(dev_priv) || INTEL_GEN(dev_priv) >= 11) {
+		    IS_BROXTON(dev_priv)) {
 			DRM_DEBUG_KMS("unsupported pixel format: %s\n",
 				      drm_get_format_name(mode_cmd->pixel_format,
 							  &format_name));
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 5d04983a28ec..93f4b243b814 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1838,12 +1838,8 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
 				 enum pipe pipe, enum plane_id plane_id)
 {
-	/*
-	 * FIXME: ICL requires two hardware planes for scanning out NV12
-	 * framebuffers. Do not advertize support until this is implemented.
-	 */
 	if (INTEL_GEN(dev_priv) >= 11)
-		return false;
+		return plane_id <= PLANE_SPRITE3;
 
 	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
 		return false;
-- 
2.19.1

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

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

* [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
  2018-10-19 17:14       ` Ville Syrjälä
  2018-10-22 10:09         ` Maarten Lankhorst
@ 2018-10-22 13:51         ` Maarten Lankhorst
  2018-10-22 15:48           ` Ville Syrjälä
  1 sibling, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-22 13:51 UTC (permalink / raw)
  To: intel-gfx

To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.

The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.

Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
  a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
  it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c | 19 +++++
 drivers/gpu/drm/i915/intel_display.c      | 95 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++
 drivers/gpu/drm/i915/intel_pm.c           | 12 ++-
 4 files changed, 178 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index b957ad63cd87..7d3685075201 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -188,6 +188,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
 			trace_intel_update_plane(&plane->base, crtc);
 
 			plane->update_plane(plane, new_crtc_state, new_plane_state);
+		} else if (new_plane_state->slave) {
+			struct intel_plane *master =
+				new_plane_state->linked_plane;
+
+			/*
+			 * We update the slave plane from this function because
+			 * programming it from the master plane's update_plane
+			 * callback runs into issues when the Y plane is
+			 * reassigned, disabled or used by a different plane.
+			 *
+			 * The slave plane is updated with the master plane's
+			 * plane_state.
+			 */
+			new_plane_state =
+				intel_atomic_get_new_plane_state(old_state, master);
+
+			trace_intel_update_plane(&plane->base, crtc);
+
+			plane->update_slave(plane, new_crtc_state, new_plane_state);
 		} else {
 			trace_intel_disable_plane(&plane->base, crtc);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 68c9aeeee05c..680895982e4f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10723,6 +10723,95 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
 	return true;
 }
 
+static int icl_add_linked_planes(struct intel_atomic_state *state)
+{
+	struct intel_plane *plane, *linked;
+	struct intel_plane_state *plane_state, *linked_plane_state;
+	int i;
+
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		linked = plane_state->linked_plane;
+
+		if (!linked)
+			continue;
+
+		linked_plane_state = intel_atomic_get_plane_state(state, linked);
+		if (IS_ERR(linked_plane_state))
+			return PTR_ERR(linked_plane_state);
+	}
+
+	return 0;
+}
+
+static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
+	struct intel_plane *plane, *linked;
+	struct intel_plane_state *plane_state;
+	int i;
+
+	if (INTEL_GEN(dev_priv) < 11)
+		return 0;
+
+	/*
+	 * Destroy all old plane links and make the slave plane invisible
+	 * in the crtc_state->active_planes mask.
+	 */
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		if (plane->pipe != crtc->pipe || !plane_state->linked_plane)
+			continue;
+
+		plane_state->linked_plane = NULL;
+		if (plane_state->slave && !plane_state->base.visible)
+			crtc_state->active_planes &= ~BIT(plane->id);
+
+		plane_state->slave = false;
+	}
+
+	if (!crtc_state->nv12_planes)
+		return 0;
+
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		struct intel_plane_state *linked_state = NULL;
+
+		if (plane->pipe != crtc->pipe ||
+		    !(crtc_state->nv12_planes & BIT(plane->id)))
+			continue;
+
+		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, linked) {
+			if (!icl_is_nv12_y_plane(linked->id))
+				continue;
+
+			if (crtc_state->active_planes & BIT(linked->id))
+				continue;
+
+			linked_state = intel_atomic_get_plane_state(state, linked);
+			if (IS_ERR(linked_state))
+				return PTR_ERR(linked_state);
+
+			break;
+		}
+
+		if (!linked_state) {
+			DRM_DEBUG_KMS("Need %d free Y planes for NV12\n",
+				      hweight8(crtc_state->nv12_planes));
+
+			return -EINVAL;
+		}
+
+		plane_state->linked_plane = linked;
+
+		linked_state->slave = true;
+		linked_state->linked_plane = plane;
+		crtc_state->active_planes |= BIT(linked->id);
+		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
+	}
+
+	return 0;
+}
+
 static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 				   struct drm_crtc_state *crtc_state)
 {
@@ -10794,6 +10883,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 		if (mode_changed)
 			ret = skl_update_scaler_crtc(pipe_config);
 
+		if (!ret)
+			ret = icl_check_nv12_planes(pipe_config);
 		if (!ret)
 			ret = skl_check_pipe_max_pixel_rate(intel_crtc,
 							    pipe_config);
@@ -12460,6 +12551,10 @@ static int intel_atomic_check(struct drm_device *dev,
 		intel_state->cdclk.logical = dev_priv->cdclk.logical;
 	}
 
+	ret = icl_add_linked_planes(intel_state);
+	if (ret)
+		return ret;
+
 	ret = drm_atomic_helper_check_planes(dev, state);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0e9a926fca04..59b35293a5f6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -539,6 +539,26 @@ struct intel_plane_state {
 	 */
 	int scaler_id;
 
+	/*
+	 * linked_plane:
+	 *
+	 * ICL planar formats require 2 planes that are updated as pairs.
+	 * This member is used to make sure the other plane is also updated
+	 * when required, and for update_slave() to find the correct
+	 * plane_state to pass as argument.
+	 */
+	struct intel_plane *linked_plane;
+
+	/*
+	 * slave:
+	 * If set don't update use the linked plane's state for updating
+	 * this plane during atomic commit with the update_slave() callback.
+	 *
+	 * It's also used by the watermark code to ignore wm calculations on
+	 * this plane. They're calculated by the linked plane's wm code.
+	 */
+	bool slave;
+
 	struct drm_intel_sprite_colorkey ckey;
 };
 
@@ -983,6 +1003,9 @@ struct intel_plane {
 	void (*update_plane)(struct intel_plane *plane,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct intel_plane_state *plane_state);
+	void (*update_slave)(struct intel_plane *plane,
+			     const struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *plane_state);
 	void (*disable_plane)(struct intel_plane *plane,
 			      struct intel_crtc *crtc);
 	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
@@ -1351,6 +1374,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
 }
 
+static inline struct intel_plane_state *
+intel_atomic_get_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)
+{
+	struct drm_plane_state *ret =
+		drm_atomic_get_plane_state(&state->base, &plane->base);
+
+	if (IS_ERR(ret))
+		return ERR_CAST(ret);
+
+	return to_intel_plane_state(ret);
+}
+
+static inline struct intel_plane_state *
+intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)
+{
+	return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
+								   &plane->base));
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
 				 struct intel_plane *plane)
@@ -2158,6 +2202,15 @@ struct intel_plane *
 skl_universal_plane_create(struct drm_i915_private *dev_priv,
 			   enum pipe pipe, enum plane_id plane_id);
 
+static inline bool icl_is_nv12_y_plane(enum plane_id id)
+{
+	/* Don't need to do a gen check, these planes are only available on gen11 */
+	if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
+		return true;
+
+	return false;
+}
+
 /* intel_tv.c */
 void intel_tv_init(struct drm_i915_private *dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f42b8c319046..9ba39a9c7d1c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5153,11 +5153,12 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
 	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
-	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	enum pipe pipe = intel_crtc->pipe;
 
 	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
+		struct drm_plane_state *plane_state;
+		struct intel_plane *linked;
 		enum plane_id plane_id = to_intel_plane(plane)->id;
 
 		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
@@ -5169,6 +5170,15 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state))
 			return PTR_ERR(plane_state);
+
+		/* Make sure linked plane is updated too */
+		linked = to_intel_plane_state(plane_state)->linked_plane;
+		if (!linked)
+			continue;
+
+		plane_state = drm_atomic_get_plane_state(state, &linked->base);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
 	}
 
 	return 0;
-- 
2.19.1

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

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

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format. (rev4)
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (12 preceding siblings ...)
  2018-10-22 10:52 ` ✓ Fi.CI.IGT: success for " Patchwork
@ 2018-10-22 15:28 ` Patchwork
  2018-10-22 15:32 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-22 15:28 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format. (rev4)
URL   : https://patchwork.freedesktop.org/series/51178/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
e63515ae7751 drm/i915: Fix unsigned overflow when calculating total data rate, v2.
-:43: CHECK:CAMELCASE: Avoid CamelCase: <GBps>
#43: FILE: drivers/gpu/drm/i915/intel_pm.c:3806:
+	if (num_active > 1 || total_data_bw >= GBps(12)) {

total: 0 errors, 0 warnings, 1 checks, 130 lines checked
770267f9b2b9 drm/i915/gen11: Enable 6 sprites on gen11
a76a2e2aed7b drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
-:18: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#18: 
- Put all the state updating login in intel_plane_atomic_check_with_state().

-:213: CHECK:BOOL_MEMBER: Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384
#213: FILE: drivers/gpu/drm/i915/intel_drv.h:560:
+	bool slave;

-:234: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#234: FILE: drivers/gpu/drm/i915/intel_drv.h:1379:
+intel_atomic_get_plane_state(struct intel_atomic_state *state,
+				 struct intel_plane *plane)

total: 0 errors, 1 warnings, 2 checks, 243 lines checked
d03837d789bc drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
be5e77cdbaf7 drm/i915/gen11: Program the scalers correctly for planar formats, v3.
6be5b1b2fe9f drm/i915/gen11: Program the chroma upsampler for HDR planes.
-:50: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#50: FILE: drivers/gpu/drm/i915/i915_reg.h:6707:
+#define PLANE_CUS_CTL(pipe, plane)   \
+	_MMIO_PLANE(plane, _PLANE_CUS_CTL_1(pipe), _PLANE_CUS_CTL_2(pipe))

total: 0 errors, 0 warnings, 1 checks, 68 lines checked
0df7e71ff240 drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
8ff51f2481a0 drm/i915/gen11: Expose planar format support on gen11, v2.

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

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

* ✗ Fi.CI.SPARSE: warning for drm/i915/gen11: Add support for the NV12 format. (rev4)
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (13 preceding siblings ...)
  2018-10-22 15:28 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format. (rev4) Patchwork
@ 2018-10-22 15:32 ` Patchwork
  2018-10-22 15:53 ` ✓ Fi.CI.BAT: success " Patchwork
  2018-10-22 19:02 ` ✓ Fi.CI.IGT: " Patchwork
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-22 15:32 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format. (rev4)
URL   : https://patchwork.freedesktop.org/series/51178/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Fix unsigned overflow when calculating total data rate, v2.
Okay!

Commit: drm/i915/gen11: Enable 6 sprites on gen11
Okay!

Commit: drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
Okay!

Commit: drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
Okay!

Commit: drm/i915/gen11: Program the scalers correctly for planar formats, v3.
Okay!

Commit: drm/i915/gen11: Program the chroma upsampler for HDR planes.
Okay!

Commit: drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
+drivers/gpu/drm/i915/intel_sprite.c:462:1: warning: symbol 'skl_update_plane' was not declared. Should it be static?
+drivers/gpu/drm/i915/intel_sprite.c:487:1: warning: symbol 'skl_disable_plane' was not declared. Should it be static?

Commit: drm/i915/gen11: Expose planar format support on gen11, v2.
Okay!

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

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

* Re: [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
  2018-10-22 13:51         ` [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5 Maarten Lankhorst
@ 2018-10-22 15:48           ` Ville Syrjälä
  2018-10-23 14:25             ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-22 15:48 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Mon, Oct 22, 2018 at 03:51:52PM +0200, Maarten Lankhorst wrote:
> To make NV12 working on icl, we need to update 2 planes simultaneously.
> I've chosen to do this in the CRTC step after plane validation is done,
> so we know what planes are (in)visible. The linked Y plane will get
> updated in intel_plane_update_planes_on_crtc(), by the call to
> update_slave, which gets the master's plane_state as argument.
> 
> The link requires both planes for atomic_update to work,
> so make sure skl_ddb_add_affected_planes() adds both states.
> 
> Changes since v1:
> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
> - Put all the state updating login in intel_plane_atomic_check_with_state().
> - Clean up changes in intel_plane_atomic_check().
> Changes since v2:
> - Fix intel_atomic_get_old_plane_state() to actually return old state.
> - Move visibility changes to preparation patch.
> - Only try to find a Y plane on gen11, earlier platforms only require
>   a single plane.
> Changes since v3:
> - Fix checkpatch warning about to_intel_crtc() usage.
> - Add affected planes from icl_add_linked_planes() before check_planes(),
>   it's a cleaner way to do this. (Ville)
> Changes since v4:
> - Clear plane links in icl_check_nv12_planes() for clarity.
> - Only pass crtc_state to icl_check_nv12_planes().
> - Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
> - Rename aux to linked. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c | 19 +++++
>  drivers/gpu/drm/i915/intel_display.c      | 95 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++
>  drivers/gpu/drm/i915/intel_pm.c           | 12 ++-
>  4 files changed, 178 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index b957ad63cd87..7d3685075201 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -188,6 +188,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>  			trace_intel_update_plane(&plane->base, crtc);
>  
>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
> +		} else if (new_plane_state->slave) {
> +			struct intel_plane *master =
> +				new_plane_state->linked_plane;
> +
> +			/*
> +			 * We update the slave plane from this function because
> +			 * programming it from the master plane's update_plane
> +			 * callback runs into issues when the Y plane is
> +			 * reassigned, disabled or used by a different plane.
> +			 *
> +			 * The slave plane is updated with the master plane's
> +			 * plane_state.
> +			 */
> +			new_plane_state =
> +				intel_atomic_get_new_plane_state(old_state, master);
> +
> +			trace_intel_update_plane(&plane->base, crtc);
> +
> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
>  		} else {
>  			trace_intel_disable_plane(&plane->base, crtc);
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 68c9aeeee05c..680895982e4f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10723,6 +10723,95 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>  	return true;
>  }
>  
> +static int icl_add_linked_planes(struct intel_atomic_state *state)
> +{
> +	struct intel_plane *plane, *linked;
> +	struct intel_plane_state *plane_state, *linked_plane_state;
> +	int i;
> +
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		linked = plane_state->linked_plane;
> +
> +		if (!linked)
> +			continue;
> +
> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> +		if (IS_ERR(linked_plane_state))
> +			return PTR_ERR(linked_plane_state);

WARN_ON(linked_plane_state->linked != plane);
WARN_ON(linked_plane_state->slave == plane_state->slave);

perhaps?

> +	}
> +
> +	return 0;
> +}
> +
> +static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
> +	struct intel_plane *plane, *linked;
> +	struct intel_plane_state *plane_state;
> +	int i;
> +
> +	if (INTEL_GEN(dev_priv) < 11)
> +		return 0;
> +
> +	/*
> +	 * Destroy all old plane links and make the slave plane invisible
> +	 * in the crtc_state->active_planes mask.
> +	 */
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		if (plane->pipe != crtc->pipe || !plane_state->linked_plane)
> +			continue;
> +
> +		plane_state->linked_plane = NULL;
> +		if (plane_state->slave && !plane_state->base.visible)

Hmm. Was confused for a moment here. Since we do this after the check_plane()
we could indeed have a visible slave plane here.

I wonder if it would be cleaner to do this in icl_add_linked_planes()
instead? Not sure.

Feel free to ignore my bikesheds you think this is better.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +			crtc_state->active_planes &= ~BIT(plane->id);
> +
> +		plane_state->slave = false;
> +	}
> +
> +	if (!crtc_state->nv12_planes)
> +		return 0;
> +
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		struct intel_plane_state *linked_state = NULL;
> +
> +		if (plane->pipe != crtc->pipe ||
> +		    !(crtc_state->nv12_planes & BIT(plane->id)))
> +			continue;
> +
> +		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, linked) {
> +			if (!icl_is_nv12_y_plane(linked->id))
> +				continue;
> +
> +			if (crtc_state->active_planes & BIT(linked->id))
> +				continue;
> +
> +			linked_state = intel_atomic_get_plane_state(state, linked);
> +			if (IS_ERR(linked_state))
> +				return PTR_ERR(linked_state);
> +
> +			break;
> +		}
> +
> +		if (!linked_state) {
> +			DRM_DEBUG_KMS("Need %d free Y planes for NV12\n",
> +				      hweight8(crtc_state->nv12_planes));
> +
> +			return -EINVAL;
> +		}
> +
> +		plane_state->linked_plane = linked;
> +
> +		linked_state->slave = true;
> +		linked_state->linked_plane = plane;
> +		crtc_state->active_planes |= BIT(linked->id);
> +		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
> +	}
> +
> +	return 0;
> +}
> +
>  static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  				   struct drm_crtc_state *crtc_state)
>  {
> @@ -10794,6 +10883,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>  		if (mode_changed)
>  			ret = skl_update_scaler_crtc(pipe_config);
>  
> +		if (!ret)
> +			ret = icl_check_nv12_planes(pipe_config);
>  		if (!ret)
>  			ret = skl_check_pipe_max_pixel_rate(intel_crtc,
>  							    pipe_config);
> @@ -12460,6 +12551,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  		intel_state->cdclk.logical = dev_priv->cdclk.logical;
>  	}
>  
> +	ret = icl_add_linked_planes(intel_state);
> +	if (ret)
> +		return ret;
> +
>  	ret = drm_atomic_helper_check_planes(dev, state);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 0e9a926fca04..59b35293a5f6 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -539,6 +539,26 @@ struct intel_plane_state {
>  	 */
>  	int scaler_id;
>  
> +	/*
> +	 * linked_plane:
> +	 *
> +	 * ICL planar formats require 2 planes that are updated as pairs.
> +	 * This member is used to make sure the other plane is also updated
> +	 * when required, and for update_slave() to find the correct
> +	 * plane_state to pass as argument.
> +	 */
> +	struct intel_plane *linked_plane;
> +
> +	/*
> +	 * slave:
> +	 * If set don't update use the linked plane's state for updating
> +	 * this plane during atomic commit with the update_slave() callback.
> +	 *
> +	 * It's also used by the watermark code to ignore wm calculations on
> +	 * this plane. They're calculated by the linked plane's wm code.
> +	 */
> +	bool slave;
> +
>  	struct drm_intel_sprite_colorkey ckey;
>  };
>  
> @@ -983,6 +1003,9 @@ struct intel_plane {
>  	void (*update_plane)(struct intel_plane *plane,
>  			     const struct intel_crtc_state *crtc_state,
>  			     const struct intel_plane_state *plane_state);
> +	void (*update_slave)(struct intel_plane *plane,
> +			     const struct intel_crtc_state *crtc_state,
> +			     const struct intel_plane_state *plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
>  			      struct intel_crtc *crtc);
>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
> @@ -1351,6 +1374,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
>  	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
>  }
>  
> +static inline struct intel_plane_state *
> +intel_atomic_get_plane_state(struct intel_atomic_state *state,
> +				 struct intel_plane *plane)
> +{
> +	struct drm_plane_state *ret =
> +		drm_atomic_get_plane_state(&state->base, &plane->base);
> +
> +	if (IS_ERR(ret))
> +		return ERR_CAST(ret);
> +
> +	return to_intel_plane_state(ret);
> +}
> +
> +static inline struct intel_plane_state *
> +intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
> +				 struct intel_plane *plane)
> +{
> +	return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
> +								   &plane->base));
> +}
> +
>  static inline struct intel_plane_state *
>  intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
>  				 struct intel_plane *plane)
> @@ -2158,6 +2202,15 @@ struct intel_plane *
>  skl_universal_plane_create(struct drm_i915_private *dev_priv,
>  			   enum pipe pipe, enum plane_id plane_id);
>  
> +static inline bool icl_is_nv12_y_plane(enum plane_id id)
> +{
> +	/* Don't need to do a gen check, these planes are only available on gen11 */
> +	if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
> +		return true;
> +
> +	return false;
> +}
> +
>  /* intel_tv.c */
>  void intel_tv_init(struct drm_i915_private *dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f42b8c319046..9ba39a9c7d1c 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5153,11 +5153,12 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>  	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
>  	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> -	struct drm_plane_state *plane_state;
>  	struct drm_plane *plane;
>  	enum pipe pipe = intel_crtc->pipe;
>  
>  	drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) {
> +		struct drm_plane_state *plane_state;
> +		struct intel_plane *linked;
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>  
>  		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
> @@ -5169,6 +5170,15 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
>  		plane_state = drm_atomic_get_plane_state(state, plane);
>  		if (IS_ERR(plane_state))
>  			return PTR_ERR(plane_state);
> +
> +		/* Make sure linked plane is updated too */
> +		linked = to_intel_plane_state(plane_state)->linked_plane;
> +		if (!linked)
> +			continue;
> +
> +		plane_state = drm_atomic_get_plane_state(state, &linked->base);
> +		if (IS_ERR(plane_state))
> +			return PTR_ERR(plane_state);
>  	}
>  
>  	return 0;
> -- 
> 2.19.1

-- 
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] 42+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915/gen11: Add support for the NV12 format. (rev4)
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (14 preceding siblings ...)
  2018-10-22 15:32 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-10-22 15:53 ` Patchwork
  2018-10-22 19:02 ` ✓ Fi.CI.IGT: " Patchwork
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-22 15:53 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format. (rev4)
URL   : https://patchwork.freedesktop.org/series/51178/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5017 -> Patchwork_10524 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/51178/revisions/4/mbox/

== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_exec_suspend@basic-s3:
      fi-kbl-soraka:      NOTRUN -> INCOMPLETE (fdo#107556, fdo#107859, fdo#107774)

    igt@gem_mmap@basic-small-bo:
      fi-icl-u2:          NOTRUN -> DMESG-WARN (fdo#107732) +1

    igt@kms_flip@basic-flip-vs-modeset:
      fi-skl-6700hq:      PASS -> DMESG-WARN (fdo#105998)

    
    ==== Possible fixes ====

    igt@gem_exec_suspend@basic-s4-devices:
      fi-kbl-7500u:       DMESG-WARN (fdo#107139, fdo#105128) -> PASS

    igt@kms_frontbuffer_tracking@basic:
      fi-byt-clapper:     FAIL (fdo#103167) -> PASS

    igt@prime_vgem@basic-fence-flip:
      fi-cfl-8700k:       FAIL (fdo#104008) -> PASS

    
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008
  fdo#105128 https://bugs.freedesktop.org/show_bug.cgi?id=105128
  fdo#105998 https://bugs.freedesktop.org/show_bug.cgi?id=105998
  fdo#107139 https://bugs.freedesktop.org/show_bug.cgi?id=107139
  fdo#107556 https://bugs.freedesktop.org/show_bug.cgi?id=107556
  fdo#107732 https://bugs.freedesktop.org/show_bug.cgi?id=107732
  fdo#107774 https://bugs.freedesktop.org/show_bug.cgi?id=107774
  fdo#107859 https://bugs.freedesktop.org/show_bug.cgi?id=107859


== Participating hosts (51 -> 47) ==

  Additional (1): fi-kbl-soraka 
  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 


== Build changes ==

    * Linux: CI_DRM_5017 -> Patchwork_10524

  CI_DRM_5017: 9510f8e44127260f92b5b6c3127aafa22b15f741 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4685: 78619fde4008424c472906041edb1d204e014f7c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10524: 8ff51f2481a0719da63289bb0a7911f89ea8af7e @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

8ff51f2481a0 drm/i915/gen11: Expose planar format support on gen11, v2.
0df7e71ff240 drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3.
6be5b1b2fe9f drm/i915/gen11: Program the chroma upsampler for HDR planes.
be5e77cdbaf7 drm/i915/gen11: Program the scalers correctly for planar formats, v3.
d03837d789bc drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2.
a76a2e2aed7b drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
770267f9b2b9 drm/i915/gen11: Enable 6 sprites on gen11
e63515ae7751 drm/i915: Fix unsigned overflow when calculating total data rate, v2.

== Logs ==

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

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

* Re: [PATCH] drm/i915/gen11: Expose planar format support on gen11, v2.
  2018-10-22 13:45     ` [PATCH] drm/i915/gen11: Expose planar format support on gen11, v2 Maarten Lankhorst
@ 2018-10-22 15:55       ` Ville Syrjälä
  0 siblings, 0 replies; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-22 15:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Mon, Oct 22, 2018 at 03:45:14PM +0200, Maarten Lankhorst wrote:
> Now that we implemented support for planar formats on gen11, we can
> finally advertise it.
> 
> Changes since v1:
> - Re-add change to skl_plane_has_planar(), was lost in rebase noise.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 2 +-
>  drivers/gpu/drm/i915/intel_sprite.c  | 6 +-----
>  2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index d035b04cd654..50b7ae99d0dd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14524,7 +14524,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
>  		break;
>  	case DRM_FORMAT_NV12:
>  		if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
> -		    IS_BROXTON(dev_priv) || INTEL_GEN(dev_priv) >= 11) {
> +		    IS_BROXTON(dev_priv)) {
>  			DRM_DEBUG_KMS("unsupported pixel format: %s\n",
>  				      drm_get_format_name(mode_cmd->pixel_format,
>  							  &format_name));
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 5d04983a28ec..93f4b243b814 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1838,12 +1838,8 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
>  static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
>  				 enum pipe pipe, enum plane_id plane_id)
>  {
> -	/*
> -	 * FIXME: ICL requires two hardware planes for scanning out NV12
> -	 * framebuffers. Do not advertize support until this is implemented.
> -	 */
>  	if (INTEL_GEN(dev_priv) >= 11)
> -		return false;
> +		return plane_id <= PLANE_SPRITE3;

!is_y_plane() ?

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

>  
>  	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
>  		return false;
> -- 
> 2.19.1

-- 
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] 42+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915/gen11: Add support for the NV12 format. (rev4)
  2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
                   ` (15 preceding siblings ...)
  2018-10-22 15:53 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-10-22 19:02 ` Patchwork
  16 siblings, 0 replies; 42+ messages in thread
From: Patchwork @ 2018-10-22 19:02 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/gen11: Add support for the NV12 format. (rev4)
URL   : https://patchwork.freedesktop.org/series/51178/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5017_full -> Patchwork_10524_full =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10524_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10524_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_10524_full:

  === IGT changes ===

    ==== Warnings ====

    igt@kms_chv_cursor_fail@pipe-b-256x256-right-edge:
      shard-snb:          PASS -> SKIP

    igt@pm_rc6_residency@rc6-accuracy:
      shard-snb:          SKIP -> PASS

    igt@pm_rpm@modeset-stress-extra-wait:
      shard-apl:          PASS -> SKIP +39

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_exec_await@wide-contexts:
      shard-glk:          PASS -> FAIL (fdo#106680)

    igt@gem_exec_suspend@basic-s3:
      shard-skl:          PASS -> INCOMPLETE (fdo#107773, fdo#104108)

    igt@gem_userptr_blits@readonly-unsync:
      shard-skl:          NOTRUN -> INCOMPLETE (fdo#108074)

    igt@gem_workarounds@suspend-resume:
      shard-kbl:          PASS -> INCOMPLETE (fdo#103665)

    igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-b:
      shard-skl:          NOTRUN -> DMESG-WARN (fdo#107956)

    igt@kms_cursor_crc@cursor-256x256-sliding:
      shard-glk:          PASS -> FAIL (fdo#103232)

    igt@kms_cursor_crc@cursor-size-change:
      shard-apl:          PASS -> FAIL (fdo#103232)

    igt@kms_draw_crc@draw-method-xrgb2101010-render-untiled:
      shard-skl:          PASS -> FAIL (fdo#103184)

    igt@kms_flip@flip-vs-dpms-off-vs-modeset:
      shard-apl:          PASS -> DMESG-WARN (fdo#105602, fdo#103558) +6

    igt@kms_flip_tiling@flip-yf-tiled:
      shard-skl:          NOTRUN -> FAIL (fdo#108145) +1

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
      shard-apl:          PASS -> FAIL (fdo#103167)

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-wc:
      shard-glk:          PASS -> FAIL (fdo#103167) +3

    igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
      shard-skl:          NOTRUN -> FAIL (fdo#108145, fdo#107815)

    igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
      shard-glk:          PASS -> FAIL (fdo#103166) +1

    igt@pm_rpm@gem-pread:
      shard-skl:          PASS -> INCOMPLETE (fdo#107807)

    igt@pm_rpm@system-suspend:
      shard-skl:          PASS -> INCOMPLETE (fdo#107807, fdo#104108)

    igt@syncobj_wait@wait-for-submit-complex:
      shard-skl:          NOTRUN -> INCOMPLETE (fdo#108490)

    
    ==== Possible fixes ====

    igt@gem_ctx_isolation@bcs0-s3:
      shard-kbl:          INCOMPLETE (fdo#103665) -> PASS

    igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-b:
      shard-skl:          DMESG-WARN (fdo#107956) -> PASS

    igt@kms_cursor_crc@cursor-64x21-onscreen:
      shard-glk:          FAIL (fdo#103232) -> PASS

    igt@kms_flip@flip-vs-expired-vblank:
      shard-skl:          FAIL (fdo#105363) -> PASS

    igt@kms_flip@flip-vs-expired-vblank-interruptible:
      shard-apl:          FAIL (fdo#102887, fdo#105363) -> PASS

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-fullscreen:
      shard-apl:          FAIL (fdo#103167) -> PASS +1

    igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
      shard-apl:          FAIL (fdo#108146) -> SKIP

    igt@kms_plane_multiple@atomic-pipe-a-tiling-y:
      shard-glk:          FAIL (fdo#103166) -> PASS

    igt@kms_plane_multiple@atomic-pipe-b-tiling-x:
      shard-apl:          FAIL (fdo#103166) -> PASS

    igt@kms_setmode@basic:
      shard-apl:          FAIL (fdo#99912) -> PASS
      shard-hsw:          FAIL (fdo#99912) -> PASS

    igt@pm_rps@reset:
      shard-glk:          FAIL (fdo#102250) -> PASS
      shard-apl:          FAIL (fdo#102250) -> PASS

    
  fdo#102250 https://bugs.freedesktop.org/show_bug.cgi?id=102250
  fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887
  fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103184 https://bugs.freedesktop.org/show_bug.cgi?id=103184
  fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
  fdo#103558 https://bugs.freedesktop.org/show_bug.cgi?id=103558
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#104108 https://bugs.freedesktop.org/show_bug.cgi?id=104108
  fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
  fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602
  fdo#106680 https://bugs.freedesktop.org/show_bug.cgi?id=106680
  fdo#107773 https://bugs.freedesktop.org/show_bug.cgi?id=107773
  fdo#107807 https://bugs.freedesktop.org/show_bug.cgi?id=107807
  fdo#107815 https://bugs.freedesktop.org/show_bug.cgi?id=107815
  fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
  fdo#108074 https://bugs.freedesktop.org/show_bug.cgi?id=108074
  fdo#108145 https://bugs.freedesktop.org/show_bug.cgi?id=108145
  fdo#108146 https://bugs.freedesktop.org/show_bug.cgi?id=108146
  fdo#108490 https://bugs.freedesktop.org/show_bug.cgi?id=108490
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912


== Participating hosts (6 -> 6) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_5017 -> Patchwork_10524

  CI_DRM_5017: 9510f8e44127260f92b5b6c3127aafa22b15f741 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4685: 78619fde4008424c472906041edb1d204e014f7c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10524: 8ff51f2481a0719da63289bb0a7911f89ea8af7e @ 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_10524/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
  2018-10-22 15:48           ` Ville Syrjälä
@ 2018-10-23 14:25             ` Maarten Lankhorst
  2018-10-23 14:36               ` Ville Syrjälä
  0 siblings, 1 reply; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-23 14:25 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 22-10-18 om 17:48 schreef Ville Syrjälä:
> On Mon, Oct 22, 2018 at 03:51:52PM +0200, Maarten Lankhorst wrote:
>> To make NV12 working on icl, we need to update 2 planes simultaneously.
>> I've chosen to do this in the CRTC step after plane validation is done,
>> so we know what planes are (in)visible. The linked Y plane will get
>> updated in intel_plane_update_planes_on_crtc(), by the call to
>> update_slave, which gets the master's plane_state as argument.
>>
>> The link requires both planes for atomic_update to work,
>> so make sure skl_ddb_add_affected_planes() adds both states.
>>
>> Changes since v1:
>> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
>> - Put all the state updating login in intel_plane_atomic_check_with_state().
>> - Clean up changes in intel_plane_atomic_check().
>> Changes since v2:
>> - Fix intel_atomic_get_old_plane_state() to actually return old state.
>> - Move visibility changes to preparation patch.
>> - Only try to find a Y plane on gen11, earlier platforms only require
>>   a single plane.
>> Changes since v3:
>> - Fix checkpatch warning about to_intel_crtc() usage.
>> - Add affected planes from icl_add_linked_planes() before check_planes(),
>>   it's a cleaner way to do this. (Ville)
>> Changes since v4:
>> - Clear plane links in icl_check_nv12_planes() for clarity.
>> - Only pass crtc_state to icl_check_nv12_planes().
>> - Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
>> - Rename aux to linked. (Ville)
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_atomic_plane.c | 19 +++++
>>  drivers/gpu/drm/i915/intel_display.c      | 95 +++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++
>>  drivers/gpu/drm/i915/intel_pm.c           | 12 ++-
>>  4 files changed, 178 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> index b957ad63cd87..7d3685075201 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> @@ -188,6 +188,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>>  			trace_intel_update_plane(&plane->base, crtc);
>>  
>>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
>> +		} else if (new_plane_state->slave) {
>> +			struct intel_plane *master =
>> +				new_plane_state->linked_plane;
>> +
>> +			/*
>> +			 * We update the slave plane from this function because
>> +			 * programming it from the master plane's update_plane
>> +			 * callback runs into issues when the Y plane is
>> +			 * reassigned, disabled or used by a different plane.
>> +			 *
>> +			 * The slave plane is updated with the master plane's
>> +			 * plane_state.
>> +			 */
>> +			new_plane_state =
>> +				intel_atomic_get_new_plane_state(old_state, master);
>> +
>> +			trace_intel_update_plane(&plane->base, crtc);
>> +
>> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
>>  		} else {
>>  			trace_intel_disable_plane(&plane->base, crtc);
>>  
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 68c9aeeee05c..680895982e4f 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -10723,6 +10723,95 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>>  	return true;
>>  }
>>  
>> +static int icl_add_linked_planes(struct intel_atomic_state *state)
>> +{
>> +	struct intel_plane *plane, *linked;
>> +	struct intel_plane_state *plane_state, *linked_plane_state;
>> +	int i;
>> +
>> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
>> +		linked = plane_state->linked_plane;
>> +
>> +		if (!linked)
>> +			continue;
>> +
>> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
>> +		if (IS_ERR(linked_plane_state))
>> +			return PTR_ERR(linked_plane_state);
> WARN_ON(linked_plane_state->linked != plane);
> WARN_ON(linked_plane_state->slave == plane_state->slave);
>
> perhaps?
Those will trigger because linked_plane_state might already have been cleared. :)

Thanks for the reviews, tested on fi-icl-u and seems the smalll changes didn't break stuff, so will push it in an hour.

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

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

* Re: [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
  2018-10-23 14:25             ` Maarten Lankhorst
@ 2018-10-23 14:36               ` Ville Syrjälä
  2018-10-23 14:58                 ` Maarten Lankhorst
  0 siblings, 1 reply; 42+ messages in thread
From: Ville Syrjälä @ 2018-10-23 14:36 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Tue, Oct 23, 2018 at 04:25:14PM +0200, Maarten Lankhorst wrote:
> Op 22-10-18 om 17:48 schreef Ville Syrjälä:
> > On Mon, Oct 22, 2018 at 03:51:52PM +0200, Maarten Lankhorst wrote:
> >> To make NV12 working on icl, we need to update 2 planes simultaneously.
> >> I've chosen to do this in the CRTC step after plane validation is done,
> >> so we know what planes are (in)visible. The linked Y plane will get
> >> updated in intel_plane_update_planes_on_crtc(), by the call to
> >> update_slave, which gets the master's plane_state as argument.
> >>
> >> The link requires both planes for atomic_update to work,
> >> so make sure skl_ddb_add_affected_planes() adds both states.
> >>
> >> Changes since v1:
> >> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
> >> - Put all the state updating login in intel_plane_atomic_check_with_state().
> >> - Clean up changes in intel_plane_atomic_check().
> >> Changes since v2:
> >> - Fix intel_atomic_get_old_plane_state() to actually return old state.
> >> - Move visibility changes to preparation patch.
> >> - Only try to find a Y plane on gen11, earlier platforms only require
> >>   a single plane.
> >> Changes since v3:
> >> - Fix checkpatch warning about to_intel_crtc() usage.
> >> - Add affected planes from icl_add_linked_planes() before check_planes(),
> >>   it's a cleaner way to do this. (Ville)
> >> Changes since v4:
> >> - Clear plane links in icl_check_nv12_planes() for clarity.
> >> - Only pass crtc_state to icl_check_nv12_planes().
> >> - Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
> >> - Rename aux to linked. (Ville)
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_atomic_plane.c | 19 +++++
> >>  drivers/gpu/drm/i915/intel_display.c      | 95 +++++++++++++++++++++++
> >>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++
> >>  drivers/gpu/drm/i915/intel_pm.c           | 12 ++-
> >>  4 files changed, 178 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> index b957ad63cd87..7d3685075201 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> @@ -188,6 +188,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
> >>  			trace_intel_update_plane(&plane->base, crtc);
> >>  
> >>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
> >> +		} else if (new_plane_state->slave) {
> >> +			struct intel_plane *master =
> >> +				new_plane_state->linked_plane;
> >> +
> >> +			/*
> >> +			 * We update the slave plane from this function because
> >> +			 * programming it from the master plane's update_plane
> >> +			 * callback runs into issues when the Y plane is
> >> +			 * reassigned, disabled or used by a different plane.
> >> +			 *
> >> +			 * The slave plane is updated with the master plane's
> >> +			 * plane_state.
> >> +			 */
> >> +			new_plane_state =
> >> +				intel_atomic_get_new_plane_state(old_state, master);
> >> +
> >> +			trace_intel_update_plane(&plane->base, crtc);
> >> +
> >> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
> >>  		} else {
> >>  			trace_intel_disable_plane(&plane->base, crtc);
> >>  
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 68c9aeeee05c..680895982e4f 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -10723,6 +10723,95 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
> >>  	return true;
> >>  }
> >>  
> >> +static int icl_add_linked_planes(struct intel_atomic_state *state)
> >> +{
> >> +	struct intel_plane *plane, *linked;
> >> +	struct intel_plane_state *plane_state, *linked_plane_state;
> >> +	int i;
> >> +
> >> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> >> +		linked = plane_state->linked_plane;
> >> +
> >> +		if (!linked)
> >> +			continue;
> >> +
> >> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> >> +		if (IS_ERR(linked_plane_state))
> >> +			return PTR_ERR(linked_plane_state);
> > WARN_ON(linked_plane_state->linked != plane);
> > WARN_ON(linked_plane_state->slave == plane_state->slave);
> >
> > perhaps?
> Those will trigger because linked_plane_state might already have been cleared. :)

OK, I'm totally confused now. Who cleared them? And why did they clear them
only half way?

> 
> Thanks for the reviews, tested on fi-icl-u and seems the smalll changes didn't break stuff, so will push it in an hour.
> 
> ~Maarten

-- 
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] 42+ messages in thread

* Re: [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
  2018-10-23 14:36               ` Ville Syrjälä
@ 2018-10-23 14:58                 ` Maarten Lankhorst
  0 siblings, 0 replies; 42+ messages in thread
From: Maarten Lankhorst @ 2018-10-23 14:58 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 23-10-18 om 16:36 schreef Ville Syrjälä:
> On Tue, Oct 23, 2018 at 04:25:14PM +0200, Maarten Lankhorst wrote:
>> Op 22-10-18 om 17:48 schreef Ville Syrjälä:
>>> On Mon, Oct 22, 2018 at 03:51:52PM +0200, Maarten Lankhorst wrote:
>>>> To make NV12 working on icl, we need to update 2 planes simultaneously.
>>>> I've chosen to do this in the CRTC step after plane validation is done,
>>>> so we know what planes are (in)visible. The linked Y plane will get
>>>> updated in intel_plane_update_planes_on_crtc(), by the call to
>>>> update_slave, which gets the master's plane_state as argument.
>>>>
>>>> The link requires both planes for atomic_update to work,
>>>> so make sure skl_ddb_add_affected_planes() adds both states.
>>>>
>>>> Changes since v1:
>>>> - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
>>>> - Put all the state updating login in intel_plane_atomic_check_with_state().
>>>> - Clean up changes in intel_plane_atomic_check().
>>>> Changes since v2:
>>>> - Fix intel_atomic_get_old_plane_state() to actually return old state.
>>>> - Move visibility changes to preparation patch.
>>>> - Only try to find a Y plane on gen11, earlier platforms only require
>>>>   a single plane.
>>>> Changes since v3:
>>>> - Fix checkpatch warning about to_intel_crtc() usage.
>>>> - Add affected planes from icl_add_linked_planes() before check_planes(),
>>>>   it's a cleaner way to do this. (Ville)
>>>> Changes since v4:
>>>> - Clear plane links in icl_check_nv12_planes() for clarity.
>>>> - Only pass crtc_state to icl_check_nv12_planes().
>>>> - Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
>>>> - Rename aux to linked. (Ville)
>>>>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>> ---
>>>>  drivers/gpu/drm/i915/intel_atomic_plane.c | 19 +++++
>>>>  drivers/gpu/drm/i915/intel_display.c      | 95 +++++++++++++++++++++++
>>>>  drivers/gpu/drm/i915/intel_drv.h          | 53 +++++++++++++
>>>>  drivers/gpu/drm/i915/intel_pm.c           | 12 ++-
>>>>  4 files changed, 178 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> index b957ad63cd87..7d3685075201 100644
>>>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>>> @@ -188,6 +188,25 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
>>>>  			trace_intel_update_plane(&plane->base, crtc);
>>>>  
>>>>  			plane->update_plane(plane, new_crtc_state, new_plane_state);
>>>> +		} else if (new_plane_state->slave) {
>>>> +			struct intel_plane *master =
>>>> +				new_plane_state->linked_plane;
>>>> +
>>>> +			/*
>>>> +			 * We update the slave plane from this function because
>>>> +			 * programming it from the master plane's update_plane
>>>> +			 * callback runs into issues when the Y plane is
>>>> +			 * reassigned, disabled or used by a different plane.
>>>> +			 *
>>>> +			 * The slave plane is updated with the master plane's
>>>> +			 * plane_state.
>>>> +			 */
>>>> +			new_plane_state =
>>>> +				intel_atomic_get_new_plane_state(old_state, master);
>>>> +
>>>> +			trace_intel_update_plane(&plane->base, crtc);
>>>> +
>>>> +			plane->update_slave(plane, new_crtc_state, new_plane_state);
>>>>  		} else {
>>>>  			trace_intel_disable_plane(&plane->base, crtc);
>>>>  
>>>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>>>> index 68c9aeeee05c..680895982e4f 100644
>>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>>> @@ -10723,6 +10723,95 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>>>>  	return true;
>>>>  }
>>>>  
>>>> +static int icl_add_linked_planes(struct intel_atomic_state *state)
>>>> +{
>>>> +	struct intel_plane *plane, *linked;
>>>> +	struct intel_plane_state *plane_state, *linked_plane_state;
>>>> +	int i;
>>>> +
>>>> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
>>>> +		linked = plane_state->linked_plane;
>>>> +
>>>> +		if (!linked)
>>>> +			continue;
>>>> +
>>>> +		linked_plane_state = intel_atomic_get_plane_state(state, linked);
>>>> +		if (IS_ERR(linked_plane_state))
>>>> +			return PTR_ERR(linked_plane_state);
>>> WARN_ON(linked_plane_state->linked != plane);
>>> WARN_ON(linked_plane_state->slave == plane_state->slave);
>>>
>>> perhaps?
>> Those will trigger because linked_plane_state might already have been cleared. :)
> OK, I'm totally confused now. Who cleared them? And why did they clear them
> only half way?
>
>> Thanks for the reviews, tested on fi-icl-u and seems the smalll changes didn't break stuff, so will push it in an hour.
>>
>> ~Maarten

Oh oops looked at wrong function, yeah should be ok to add them there, will try. :)

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

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

end of thread, other threads:[~2018-10-23 14:58 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-18 11:51 [PATCH v2 0/8] drm/i915/gen11: Add support for the NV12 format Maarten Lankhorst
2018-10-18 11:51 ` [PATCH v2 1/8] drm/i915: Fix unsigned overflow when calculating total data rate Maarten Lankhorst
2018-10-18 14:53   ` Ville Syrjälä
2018-10-19 12:58     ` Maarten Lankhorst
2018-10-18 15:11   ` Ville Syrjälä
2018-10-19 13:03     ` Maarten Lankhorst
2018-10-19 13:06       ` Chris Wilson
2018-10-19 14:15         ` Maarten Lankhorst
2018-10-22 10:20         ` [PATCH] drm/i915: Fix unsigned overflow when calculating total data rate, v2 Maarten Lankhorst
2018-10-18 11:51 ` [PATCH v2 2/8] drm/i915/gen11: Enable 6 sprites on gen11 Maarten Lankhorst
2018-10-18 11:51 ` [PATCH v2 3/8] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v4 Maarten Lankhorst
2018-10-18 16:00   ` Ville Syrjälä
2018-10-19 14:22     ` Maarten Lankhorst
2018-10-19 17:14       ` Ville Syrjälä
2018-10-22 10:09         ` Maarten Lankhorst
2018-10-22 13:51         ` [PATCH] drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5 Maarten Lankhorst
2018-10-22 15:48           ` Ville Syrjälä
2018-10-23 14:25             ` Maarten Lankhorst
2018-10-23 14:36               ` Ville Syrjälä
2018-10-23 14:58                 ` Maarten Lankhorst
2018-10-18 11:51 ` [PATCH v2 4/8] drm/i915/gen11: Handle watermarks correctly for separate Y/UV planes, v2 Maarten Lankhorst
2018-10-18 16:17   ` Ville Syrjälä
2018-10-18 11:51 ` [PATCH v2 5/8] drm/i915/gen11: Program the scalers correctly for planar formats, v3 Maarten Lankhorst
2018-10-18 14:47   ` Ville Syrjälä
2018-10-18 11:51 ` [PATCH v2 6/8] drm/i915/gen11: Program the chroma upsampler for HDR planes Maarten Lankhorst
2018-10-18 14:50   ` Ville Syrjälä
2018-10-18 11:51 ` [PATCH v2 7/8] drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3 Maarten Lankhorst
2018-10-18 14:51   ` Ville Syrjälä
2018-10-18 11:51 ` [PATCH v2 8/8] drm/i915/gen11: Expose planar format support on gen11 Maarten Lankhorst
2018-10-18 16:20   ` Ville Syrjälä
2018-10-22 13:45     ` [PATCH] drm/i915/gen11: Expose planar format support on gen11, v2 Maarten Lankhorst
2018-10-22 15:55       ` Ville Syrjälä
2018-10-18 12:03 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format Patchwork
2018-10-18 12:06 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-18 12:19 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-18 15:16 ` [PATCH v2 0/8] " Ville Syrjälä
2018-10-18 16:20   ` Maarten Lankhorst
2018-10-22 10:52 ` ✓ Fi.CI.IGT: success for " Patchwork
2018-10-22 15:28 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/gen11: Add support for the NV12 format. (rev4) Patchwork
2018-10-22 15:32 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-22 15:53 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-22 19:02 ` ✓ 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.