All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] drm/i915: SKL+ render decompression support
@ 2017-03-21 18:12 ville.syrjala
  2017-03-21 18:12 ` [PATCH 1/5] drm: Share the code to compute color plane dimesions ville.syrjala
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Another iteration of the i915 CCS support. Main change is lifting the
fb dimensions hsub/vsub alignment restrictions from the core. Without that
userspace would have to align the fb size be a multiple of 8x16 pixels
which isn't something they are interested in doing.

Ville Syrjälä (5):
  drm: Share the code to compute color plane dimesions
  drm: Remove fb hsub/vsub alignment requirement
  drm: Add mode_config .get_format_info() hook
  drm/i915: Implement .get_format_info() hook for CCS
  drm/i915: Add render decompression support

 drivers/gpu/drm/drm_fb_cma_helper.c  |   2 +-
 drivers/gpu/drm/drm_fourcc.c         |  25 +++
 drivers/gpu/drm/drm_framebuffer.c    |  45 ++++--
 drivers/gpu/drm/drm_modeset_helper.c |   2 +-
 drivers/gpu/drm/i915/i915_reg.h      |  23 +++
 drivers/gpu/drm/i915/intel_display.c | 284 ++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_pm.c      |  29 +++-
 drivers/gpu/drm/i915/intel_sprite.c  |   5 +
 include/drm/drm_fourcc.h             |   6 +
 include/drm/drm_mode_config.h        |  14 ++
 include/uapi/drm/drm_fourcc.h        |  20 +++
 11 files changed, 420 insertions(+), 35 deletions(-)

-- 
2.10.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 1/5] drm: Share the code to compute color plane dimesions
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
@ 2017-03-21 18:12 ` ville.syrjala
  2017-03-21 18:12 ` [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement ville.syrjala
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ben Widawsky, dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

framebuffer_check() has some hand rolled code to compute the color plane
dimensions based on the subsampled information. Let's share the code
between framebuffer_check() and drm_framebuffer_plane_{width,height}().

Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_framebuffer.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index e4909aef75d7..1138f90a7d5d 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -126,6 +126,24 @@ int drm_mode_addfb(struct drm_device *dev,
 	return 0;
 }
 
+static int fb_plane_width(int width,
+			  const struct drm_format_info *format, int plane)
+{
+	if (plane == 0)
+		return width;
+
+	return width / format->hsub;
+}
+
+static int fb_plane_height(int height,
+			   const struct drm_format_info *format, int plane)
+{
+	if (plane == 0)
+		return height;
+
+	return height / format->vsub;
+}
+
 static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 {
 	const struct drm_format_info *info;
@@ -151,8 +169,8 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 	}
 
 	for (i = 0; i < info->num_planes; i++) {
-		unsigned int width = r->width / (i != 0 ? info->hsub : 1);
-		unsigned int height = r->height / (i != 0 ? info->vsub : 1);
+		unsigned int width = fb_plane_width(r->width, info, i);
+		unsigned int height = fb_plane_height(r->height, info, i);
 		unsigned int cpp = info->cpp[i];
 
 		if (!r->handles[i]) {
@@ -816,10 +834,7 @@ int drm_framebuffer_plane_width(int width,
 	if (plane >= fb->format->num_planes)
 		return 0;
 
-	if (plane == 0)
-		return width;
-
-	return width / fb->format->hsub;
+	return fb_plane_width(width, fb->format, plane);
 }
 EXPORT_SYMBOL(drm_framebuffer_plane_width);
 
@@ -838,9 +853,6 @@ int drm_framebuffer_plane_height(int height,
 	if (plane >= fb->format->num_planes)
 		return 0;
 
-	if (plane == 0)
-		return height;
-
-	return height / fb->format->vsub;
+	return fb_plane_height(height, fb->format, plane);
 }
 EXPORT_SYMBOL(drm_framebuffer_plane_height);
-- 
2.10.2

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

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

* [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
  2017-03-21 18:12 ` [PATCH 1/5] drm: Share the code to compute color plane dimesions ville.syrjala
@ 2017-03-21 18:12 ` ville.syrjala
  2017-03-21 20:26   ` Ben Widawsky
  2017-03-21 18:12 ` [PATCH v3 3/5] drm: Add mode_config .get_format_info() hook ville.syrjala
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ben Widawsky, Jason Ekstrand, dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Allow framebuffers dimesions to be misaligned w.r.t. the subsampling
factors. No real reason the core should have to enforce this, and
it definitely starts to cause us issues with the i915 CCS support.
So let's just lift the restriction.

Let's start to round up when computing the color plane dimesions
so that we'll not end up with too low an estimate for the memory
requirements and whatnot.

Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_framebuffer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 1138f90a7d5d..69e4c1487420 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -132,7 +132,7 @@ static int fb_plane_width(int width,
 	if (plane == 0)
 		return width;
 
-	return width / format->hsub;
+	return DIV_ROUND_UP(width, format->hsub);
 }
 
 static int fb_plane_height(int height,
@@ -141,7 +141,7 @@ static int fb_plane_height(int height,
 	if (plane == 0)
 		return height;
 
-	return height / format->vsub;
+	return DIV_ROUND_UP(height, format->vsub);
 }
 
 static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
@@ -158,12 +158,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 		return -EINVAL;
 	}
 
-	if (r->width == 0 || r->width % info->hsub) {
+	if (r->width == 0) {
 		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
 		return -EINVAL;
 	}
 
-	if (r->height == 0 || r->height % info->vsub) {
+	if (r->height == 0) {
 		DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
 		return -EINVAL;
 	}
-- 
2.10.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v3 3/5] drm: Add mode_config .get_format_info() hook
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
  2017-03-21 18:12 ` [PATCH 1/5] drm: Share the code to compute color plane dimesions ville.syrjala
  2017-03-21 18:12 ` [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement ville.syrjala
@ 2017-03-21 18:12 ` ville.syrjala
  2017-03-21 18:12 ` [PATCH v4 4/5] drm/i915: Implement .get_format_info() hook for CCS ville.syrjala
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jason Ekstrand, Ben Widawsky, Laurent Pinchart, dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Allow drivers to return a custom drm_format_info structure for special
fb layouts. We'll use this for the compression control surface in i915.

v2: Fix drm_get_format_info() kernel doc (Laurent)
    Don't pass 'dev' to the new hook (Laurent)
v3: s/compresssion/compression/ (Ben)

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/drm_fb_cma_helper.c  |  2 +-
 drivers/gpu/drm/drm_fourcc.c         | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/drm_framebuffer.c    |  9 +++++++--
 drivers/gpu/drm/drm_modeset_helper.c |  2 +-
 include/drm/drm_fourcc.h             |  6 ++++++
 include/drm/drm_mode_config.h        | 14 ++++++++++++++
 6 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 74cd393a6407..50abd1faf38f 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -177,7 +177,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
 	int ret;
 	int i;
 
-	info = drm_format_info(mode_cmd->pixel_format);
+	info = drm_get_format_info(dev, mode_cmd);
 	if (!info)
 		return ERR_PTR(-EINVAL);
 
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 92bf3306d4b3..9c0152df45ad 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -207,6 +207,31 @@ const struct drm_format_info *drm_format_info(u32 format)
 EXPORT_SYMBOL(drm_format_info);
 
 /**
+ * drm_get_format_info - query information for a given framebuffer configuration
+ * @dev: DRM device
+ * @mode_cmd: metadata from the userspace fb creation request
+ *
+ * Returns:
+ * The instance of struct drm_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct drm_format_info *
+drm_get_format_info(struct drm_device *dev,
+		    const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	const struct drm_format_info *info = NULL;
+
+	if (dev->mode_config.funcs->get_format_info)
+		info = dev->mode_config.funcs->get_format_info(mode_cmd);
+
+	if (!info)
+		info = drm_format_info(mode_cmd->pixel_format);
+
+	return info;
+}
+EXPORT_SYMBOL(drm_get_format_info);
+
+/**
  * drm_format_num_planes - get the number of planes for format
  * @format: pixel format (DRM_FORMAT_*)
  *
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 69e4c1487420..e8f9c13a0afd 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -144,11 +144,13 @@ static int fb_plane_height(int height,
 	return DIV_ROUND_UP(height, format->vsub);
 }
 
-static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
+static int framebuffer_check(struct drm_device *dev,
+			     const struct drm_mode_fb_cmd2 *r)
 {
 	const struct drm_format_info *info;
 	int i;
 
+	/* check if the format is supported at all */
 	info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
 	if (!info) {
 		struct drm_format_name_buf format_name;
@@ -158,6 +160,9 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 		return -EINVAL;
 	}
 
+	/* now let the driver pick its own format info */
+	info = drm_get_format_info(dev, r);
+
 	if (r->width == 0) {
 		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
 		return -EINVAL;
@@ -281,7 +286,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
 		return ERR_PTR(-EINVAL);
 	}
 
-	ret = framebuffer_check(r);
+	ret = framebuffer_check(dev, r);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index cc44a9a4b004..2b33825f2f93 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -78,7 +78,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
 	int i;
 
 	fb->dev = dev;
-	fb->format = drm_format_info(mode_cmd->pixel_format);
+	fb->format = drm_get_format_info(dev, mode_cmd);
 	fb->width = mode_cmd->width;
 	fb->height = mode_cmd->height;
 	for (i = 0; i < 4; i++) {
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index fcc08da850c8..6942e84b6edd 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -25,6 +25,9 @@
 #include <linux/types.h>
 #include <uapi/drm/drm_fourcc.h>
 
+struct drm_device;
+struct drm_mode_fb_cmd2;
+
 /**
  * struct drm_format_info - information about a DRM format
  * @format: 4CC format identifier (DRM_FORMAT_*)
@@ -55,6 +58,9 @@ struct drm_format_name_buf {
 
 const struct drm_format_info *__drm_format_info(u32 format);
 const struct drm_format_info *drm_format_info(u32 format);
+const struct drm_format_info *
+drm_get_format_info(struct drm_device *dev,
+		    const struct drm_mode_fb_cmd2 *mode_cmd);
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 int drm_format_num_planes(uint32_t format);
 int drm_format_plane_cpp(uint32_t format, int plane);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index ea169a90b3c4..579070ff06ef 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -34,6 +34,7 @@ struct drm_file;
 struct drm_device;
 struct drm_atomic_state;
 struct drm_mode_fb_cmd2;
+struct drm_format_info;
 
 /**
  * struct drm_mode_config_funcs - basic driver provided mode setting functions
@@ -70,6 +71,19 @@ struct drm_mode_config_funcs {
 					     const struct drm_mode_fb_cmd2 *mode_cmd);
 
 	/**
+	 * @get_format_info:
+	 *
+	 * Allows a driver to return custom format information for special
+	 * fb layouts (eg. ones with auxiliary compression control planes).
+	 *
+	 * RETURNS:
+	 *
+	 * The format information specific to the given fb metadata, or
+	 * NULL if none is found.
+	 */
+	const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
+
+	/**
 	 * @output_poll_changed:
 	 *
 	 * Callback used by helpers to inform the driver of output configuration
-- 
2.10.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 4/5] drm/i915: Implement .get_format_info() hook for CCS
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
                   ` (2 preceding siblings ...)
  2017-03-21 18:12 ` [PATCH v3 3/5] drm: Add mode_config .get_format_info() hook ville.syrjala
@ 2017-03-21 18:12 ` ville.syrjala
  2017-03-21 18:12 ` [PATCH v4 5/5] drm/i915: Add render decompression support ville.syrjala
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ben Widawsky, dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

SKL+ display engine can scan out certain kinds of compressed surfaces
produced by the render engine. This involved telling the display engine
the location of the color control surfae (CCS) which describes which
parts of the main surface are compressed and which are not. The location
of CCS is provided by userspace as just another plane with its own offset.

By providing our own format information for the CCS formats, we should
be able to make framebuffer_check() do the right thing for the CCS
surface as well.

Note that we'll return the same format info for both Y and Yf tiled
format as that's what happens with the non-CCS Y vs. Yf as well. If
desired, we could potentially return a unique pointer for each
pixel_format+tiling+ccs combination, in which case we immediately be
able to tell if any of that stuff changed by just comparing the
pointers. But that does sound a bit wasteful space wise.

v2: Drop the 'dev' argument from the hook
v3: Include the description of the CCS surface layout
v4: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason)

Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (v3)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 43 ++++++++++++++++++++++++++++++++++++
 include/uapi/drm/drm_fourcc.h        | 20 +++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 010e5ddb198a..033d8d62cccb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2420,6 +2420,48 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
 	}
 }
 
+/*
+ * 1 byte of CCS actually corresponds to 16x8 pixels on the main
+ * surface, and the memory layout for the CCS tile us 64x64 bytes.
+ * But since we're pretending the CCS tile is 128 bytes wide we
+ * adjust hsub/vsub here accordingly to 8x16 so that the
+ * bytes<->x/y conversions come out correct.
+ */
+static const struct drm_format_info ccs_formats[] = {
+	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+	{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+};
+
+static const struct drm_format_info *
+lookup_format_info(const struct drm_format_info formats[],
+		   int num_formats, u32 format)
+{
+	int i;
+
+	for (i = 0; i < num_formats; i++) {
+		if (formats[i].format == format)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static const struct drm_format_info *
+intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
+{
+	switch (cmd->modifier[0]) {
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		return lookup_format_info(ccs_formats,
+					  ARRAY_SIZE(ccs_formats),
+					  cmd->pixel_format);
+	default:
+		return NULL;
+	}
+}
+
 static int
 intel_fill_fb_info(struct drm_i915_private *dev_priv,
 		   struct drm_framebuffer *fb)
@@ -14530,6 +14572,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state)
 
 static const struct drm_mode_config_funcs intel_mode_funcs = {
 	.fb_create = intel_user_framebuffer_create,
+	.get_format_info = intel_get_format_info,
 	.output_poll_changed = intel_fbdev_output_poll_changed,
 	.atomic_check = intel_atomic_check,
 	.atomic_commit = intel_atomic_commit,
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 995c8f9c692f..f18c53d95833 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -252,6 +252,26 @@ extern "C" {
 #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
 
 /*
+ * Intel color control surface (CCS) for render compression
+ *
+ * The framebuffer format must be one of the 8:8:8:8 RGB formats.
+ * The main surface will be plane index 0 and must be Y/Yf-tiled,
+ * the CCS will be plane index 1.
+ *
+ * Each CCS tile matches a 1024x512 pixel area of the main surface.
+ * To match certain aspects of the 3D hardware the CCS is
+ * considered to be made up of normal 128Bx32 Y tiles, Thus
+ * the CCS pitch must be specified in multiples of 128 bytes.
+ *
+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed
+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.
+ * But that fact is not relevant unless the memory is accessed
+ * directly.
+ */
+#define I915_FORMAT_MOD_Y_TILED_CCS	fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS	fourcc_mod_code(INTEL, 5)
+
+/*
  * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
  *
  * Macroblocks are laid in a Z-shape, and each pixel data is following the
-- 
2.10.2

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

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

* [PATCH v4 5/5] drm/i915: Add render decompression support
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
                   ` (3 preceding siblings ...)
  2017-03-21 18:12 ` [PATCH v4 4/5] drm/i915: Implement .get_format_info() hook for CCS ville.syrjala
@ 2017-03-21 18:12 ` ville.syrjala
  2017-03-21 19:02 ` ✗ Fi.CI.BAT: failure for drm/i915: SKL+ render decompression support (rev4) Patchwork
  2017-03-23 14:28 ` [PATCH v3 0/5] drm/i915: SKL+ render decompression support Daniel Stone
  6 siblings, 0 replies; 10+ messages in thread
From: ville.syrjala @ 2017-03-21 18:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ben Widawsky, Paulo Zanoni, dri-devel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

SKL+ display engine can scan out certain kinds of compressed surfaces
produced by the render engine. This involved telling the display engine
the location of the color control surfae (CCS) which describes
which parts of the main surface are compressed and which are not. The
location of CCS is provided by userspace as just another plane with its
own offset.

Add the required stuff to validate the user provided AUX plane metadata
and convert the user provided linear offset into something the hardware
can consume.

Due to hardware limitations we require that the main surface and
the AUX surface (CCS) be part of the same bo. The hardware also
makes life hard by not allowing you to provide separate x/y offsets
for the main and AUX surfaces (excpet with NV12), so finding suitable
offsets for both requires a bit of work. Assuming we still want keep
playing tricks with the offsets. I've just gone with a dumb "search
backward for suitable offsets" approach, which is far from optimal,
but it works.

Also not all planes will be capable of scanning out compressed surfaces,
and eg. 90/270 degree rotation is not supported in combination with
decompression either.

This patch may contain work from at least the following people:
* Vandana Kannan <vandana.kannan@intel.com>
* Daniel Vetter <daniel@ffwll.ch>
* Ben Widawsky <ben@bwidawsk.net>

v2: Deal with display workarounds 0390, 0531, 1125 (Paulo)
v3: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason)
    Put the AUX register defines to the correct place
    Fix up the slightly bogus rotation check
v4: Use I915_WRITE_FW() due to plane update locking changes
    s/return -EINVAL/goto err/ in intel_framebuffer_init()
    Eliminate a bunch hardcoded numbers in CCS code

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (v1)
---
 drivers/gpu/drm/i915/i915_reg.h      |  23 ++++
 drivers/gpu/drm/i915/intel_display.c | 241 ++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_pm.c      |  29 ++++-
 drivers/gpu/drm/i915/intel_sprite.c  |   5 +
 4 files changed, 279 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 04c8f69fcc62..7582d630f4a1 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5903,6 +5903,10 @@ enum {
 #define _PLANE_KEYMSK_2_A			0x70298
 #define _PLANE_KEYMAX_1_A			0x701a0
 #define _PLANE_KEYMAX_2_A			0x702a0
+#define _PLANE_AUX_DIST_1_A			0x701c0
+#define _PLANE_AUX_DIST_2_A			0x702c0
+#define _PLANE_AUX_OFFSET_1_A			0x701c4
+#define _PLANE_AUX_OFFSET_2_A			0x702c4
 #define _PLANE_COLOR_CTL_1_A			0x701CC /* GLK+ */
 #define _PLANE_COLOR_CTL_2_A			0x702CC /* GLK+ */
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
@@ -6009,6 +6013,24 @@ enum {
 #define PLANE_NV12_BUF_CFG(pipe, plane)	\
 	_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
 
+#define _PLANE_AUX_DIST_1_B		0x711c0
+#define _PLANE_AUX_DIST_2_B		0x712c0
+#define _PLANE_AUX_DIST_1(pipe) \
+			_PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B)
+#define _PLANE_AUX_DIST_2(pipe) \
+			_PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DIST(pipe, plane)     \
+	_MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe))
+
+#define _PLANE_AUX_OFFSET_1_B		0x711c4
+#define _PLANE_AUX_OFFSET_2_B		0x712c4
+#define _PLANE_AUX_OFFSET_1(pipe)       \
+		_PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B)
+#define _PLANE_AUX_OFFSET_2(pipe)       \
+		_PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
+#define PLANE_AUX_OFFSET(pipe, plane)   \
+	_MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
+
 #define _PLANE_COLOR_CTL_1_B			0x711CC
 #define _PLANE_COLOR_CTL_2_B			0x712CC
 #define _PLANE_COLOR_CTL_3_B			0x713CC
@@ -6492,6 +6514,7 @@ enum {
 # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
 
 #define CHICKEN_PAR1_1		_MMIO(0x42080)
+#define  SKL_RC_HASH_OUTSIDE	(1 << 15)
 #define  DPA_MASK_VBLANK_SRD	(1 << 15)
 #define  FORCE_ARB_IDLE_PLANES	(1 << 14)
 #define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 033d8d62cccb..33a9b9d79ca3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2004,11 +2004,19 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
 			return 128;
 		else
 			return 512;
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+		if (plane == 1)
+			return 128;
+		/* fall through */
 	case I915_FORMAT_MOD_Y_TILED:
 		if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
 			return 128;
 		else
 			return 512;
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		if (plane == 1)
+			return 128;
+		/* fall through */
 	case I915_FORMAT_MOD_Yf_TILED:
 		switch (cpp) {
 		case 1:
@@ -2103,7 +2111,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
 	struct drm_i915_private *dev_priv = to_i915(fb->dev);
 
 	/* AUX_DIST needs only 4K alignment */
-	if (fb->format->format == DRM_FORMAT_NV12 && plane == 1)
+	if (plane == 1)
 		return 4096;
 
 	switch (fb->modifier) {
@@ -2113,6 +2121,8 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
 		if (INTEL_GEN(dev_priv) >= 9)
 			return 256 * 1024;
 		return 0;
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Yf_TILED:
 		return 1 * 1024 * 1024;
@@ -2414,6 +2424,7 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
 	case I915_FORMAT_MOD_X_TILED:
 		return I915_TILING_X;
 	case I915_FORMAT_MOD_Y_TILED:
+	case I915_FORMAT_MOD_Y_TILED_CCS:
 		return I915_TILING_Y;
 	default:
 		return I915_TILING_NONE;
@@ -2485,6 +2496,36 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 
 		intel_fb_offset_to_xy(&x, &y, fb, i);
 
+		if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+		     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == 1) {
+			int hsub = fb->format->hsub;
+			int vsub = fb->format->vsub;
+			int tile_width, tile_height;
+			int main_x, main_y;
+			int ccs_x, ccs_y;
+
+			intel_tile_dims(fb, i, &tile_width, &tile_height);
+
+			ccs_x = (x * hsub) % (tile_width * hsub);
+			ccs_y = (y * vsub) % (tile_height * vsub);
+			main_x = intel_fb->normal[0].x % (tile_width * hsub);
+			main_y = intel_fb->normal[0].y % (tile_height * vsub);
+
+			/*
+			 * CCS doesn't have its own x/y offset register, so the intra CCS tile
+			 * x/y offsets must match between CCS and the main surface.
+			 */
+			if (main_x != ccs_x || main_y != ccs_y) {
+				DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
+					      main_x, main_y,
+					      ccs_x, ccs_y,
+					      intel_fb->normal[0].x,
+					      intel_fb->normal[0].y,
+					      x, y);
+				return -EINVAL;
+			}
+		}
+
 		/*
 		 * The fence (if used) is aligned to the start of the object
 		 * so having the framebuffer wrap around across the edge of the
@@ -2859,6 +2900,9 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
 			break;
 		}
 		break;
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		/* FIXME AUX plane? */
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Yf_TILED:
 		switch (cpp) {
@@ -2881,6 +2925,44 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
 	return 2048;
 }
 
+static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
+					   int main_x, int main_y, u32 main_offset)
+{
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	int hsub = fb->format->hsub;
+	int vsub = fb->format->vsub;
+	int aux_x = plane_state->aux.x;
+	int aux_y = plane_state->aux.y;
+	u32 aux_offset = plane_state->aux.offset;
+	u32 alignment = intel_surf_alignment(fb, 1);
+
+	while (aux_offset >= main_offset && aux_y <= main_y) {
+		int x, y;
+
+		if (aux_x == main_x && aux_y == main_y)
+			break;
+
+		if (aux_offset == 0)
+			break;
+
+		x = aux_x / hsub;
+		y = aux_y / vsub;
+		aux_offset = intel_adjust_tile_offset(&x, &y, plane_state, 1,
+						      aux_offset, aux_offset - alignment);
+		aux_x = x * hsub + aux_x % hsub;
+		aux_y = y * vsub + aux_y % vsub;
+	}
+
+	if (aux_x != main_x || aux_y != main_y)
+		return false;
+
+	plane_state->aux.offset = aux_offset;
+	plane_state->aux.x = aux_x;
+	plane_state->aux.y = aux_y;
+
+	return true;
+}
+
 static int skl_check_main_surface(struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2923,7 +3005,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 
 		while ((x + w) * cpp > fb->pitches[0]) {
 			if (offset == 0) {
-				DRM_DEBUG_KMS("Unable to find suitable display surface offset\n");
+				DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
 				return -EINVAL;
 			}
 
@@ -2932,6 +3014,26 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 		}
 	}
 
+	/*
+	 * CCS AUX surface doesn't have its own x/y offsets, we must make sure
+	 * they match with the main surface x/y offsets.
+	 */
+	if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+	    fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+		while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+			if (offset == 0)
+				break;
+
+			offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
+							  offset, offset - alignment);
+		}
+
+		if (x != plane_state->aux.x || y != plane_state->aux.y) {
+			DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n");
+			return -EINVAL;
+		}
+	}
+
 	plane_state->main.offset = offset;
 	plane_state->main.x = x;
 	plane_state->main.y = y;
@@ -2968,6 +3070,49 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 	return 0;
 }
 
+static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
+{
+	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+	struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	int src_x = plane_state->base.src.x1 >> 16;
+	int src_y = plane_state->base.src.y1 >> 16;
+	int hsub = fb->format->hsub;
+	int vsub = fb->format->vsub;
+	int x = src_x / hsub;
+	int y = src_y / vsub;
+	u32 offset;
+
+	switch (plane->id) {
+	case PLANE_PRIMARY:
+	case PLANE_SPRITE0:
+		break;
+	default:
+		DRM_DEBUG_KMS("RC support only on plane 1 and 2\n");
+		return -EINVAL;
+	}
+
+	if (crtc->pipe == PIPE_C) {
+		DRM_DEBUG_KMS("No RC support on pipe C\n");
+		return -EINVAL;
+	}
+
+	if (plane_state->base.rotation & ~(DRM_ROTATE_0 | DRM_ROTATE_180)) {
+		DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
+			      plane_state->base.rotation);
+		return -EINVAL;
+	}
+
+	intel_add_fb_offsets(&x, &y, plane_state, 1);
+	offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
+
+	plane_state->aux.offset = offset;
+	plane_state->aux.x = x * hsub + src_x % hsub;
+	plane_state->aux.y = y * vsub + src_y % vsub;
+
+	return 0;
+}
+
 int skl_check_plane_surface(struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2991,6 +3136,11 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
 		ret = skl_check_nv12_aux_surface(plane_state);
 		if (ret)
 			return ret;
+	} else if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+		   fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+		ret = skl_check_ccs_aux_surface(plane_state);
+		if (ret)
+			return ret;
 	} else {
 		plane_state->aux.offset = ~0xfff;
 		plane_state->aux.x = 0;
@@ -3346,8 +3496,12 @@ u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
 		return PLANE_CTL_TILED_X;
 	case I915_FORMAT_MOD_Y_TILED:
 		return PLANE_CTL_TILED_Y;
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+		return PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
 	case I915_FORMAT_MOD_Yf_TILED:
 		return PLANE_CTL_TILED_YF;
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		return PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
 	default:
 		MISSING_CASE(fb_modifier);
 	}
@@ -3390,6 +3544,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
 	u32 plane_ctl;
 	unsigned int rotation = plane_state->base.rotation;
 	u32 stride = skl_plane_stride(fb, 0, rotation);
+	u32 aux_stride = skl_plane_stride(fb, 1, rotation);
 	u32 surf_addr = plane_state->main.offset;
 	int scaler_id = plane_state->scaler_id;
 	int src_x = plane_state->main.x;
@@ -3439,6 +3594,10 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
 	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x);
 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+		      (plane_state->aux.offset - surf_addr) | aux_stride);
+	I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+		      (plane_state->aux.y << 16) | plane_state->aux.x);
 
 	if (scaler_id >= 0) {
 		uint32_t ps_ctrl = 0;
@@ -8455,10 +8614,16 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 		fb->modifier = I915_FORMAT_MOD_X_TILED;
 		break;
 	case PLANE_CTL_TILED_Y:
-		fb->modifier = I915_FORMAT_MOD_Y_TILED;
+		if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+			fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
+		else
+			fb->modifier = I915_FORMAT_MOD_Y_TILED;
 		break;
 	case PLANE_CTL_TILED_YF:
-		fb->modifier = I915_FORMAT_MOD_Yf_TILED;
+		if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+			fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
+		else
+			fb->modifier = I915_FORMAT_MOD_Yf_TILED;
 		break;
 	default:
 		MISSING_CASE(tiling);
@@ -10394,7 +10559,7 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
 	u32 ctl, stride = skl_plane_stride(fb, 0, rotation);
 
 	ctl = I915_READ(PLANE_CTL(pipe, 0));
-	ctl &= ~PLANE_CTL_TILED_MASK;
+	ctl &= ~(PLANE_CTL_TILED_MASK | PLANE_CTL_DECOMPRESSION_ENABLE);
 	switch (fb->modifier) {
 	case DRM_FORMAT_MOD_NONE:
 		break;
@@ -10404,9 +10569,15 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
 	case I915_FORMAT_MOD_Y_TILED:
 		ctl |= PLANE_CTL_TILED_Y;
 		break;
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+		ctl |= PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
+		break;
 	case I915_FORMAT_MOD_Yf_TILED:
 		ctl |= PLANE_CTL_TILED_YF;
 		break;
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		ctl |= PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
+		break;
 	default:
 		MISSING_CASE(fb->modifier);
 	}
@@ -14370,10 +14541,12 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 				  struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct drm_framebuffer *fb = &intel_fb->base;
 	struct drm_format_name_buf format_name;
-	u32 pitch_limit, stride_alignment;
+	u32 pitch_limit;
 	unsigned int tiling, stride;
 	int ret = -EINVAL;
+	int i;
 
 	i915_gem_object_lock(obj);
 	obj->framebuffer_references++;
@@ -14402,6 +14575,19 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 
 	/* Passed in modifier sanity checking. */
 	switch (mode_cmd->modifier[0]) {
+	case I915_FORMAT_MOD_Y_TILED_CCS:
+	case I915_FORMAT_MOD_Yf_TILED_CCS:
+		switch (mode_cmd->pixel_format) {
+		case DRM_FORMAT_XBGR8888:
+		case DRM_FORMAT_ABGR8888:
+		case DRM_FORMAT_XRGB8888:
+		case DRM_FORMAT_ARGB8888:
+			break;
+		default:
+			DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n");
+			goto err;
+		}
+		/* fall through */
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Yf_TILED:
 		if (INTEL_GEN(dev_priv) < 9) {
@@ -14506,25 +14692,46 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 	if (mode_cmd->offsets[0] != 0)
 		goto err;
 
-	drm_helper_mode_fill_fb_struct(&dev_priv->drm,
-				       &intel_fb->base, mode_cmd);
+	drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
 
-	stride_alignment = intel_fb_stride_alignment(&intel_fb->base, 0);
-	if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
-		DRM_DEBUG_KMS("pitch (%d) must be at least %u byte aligned\n",
-			      mode_cmd->pitches[0], stride_alignment);
-		goto err;
+	for (i = 0; i < fb->format->num_planes; i++) {
+		u32 stride_alignment;
+
+		if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
+			DRM_DEBUG_KMS("bad plane %d handle\n", i);
+			return -EINVAL;
+		}
+
+		stride_alignment = intel_fb_stride_alignment(fb, i);
+
+		/*
+		 * Display WA #0531: skl,bxt,kbl,glk
+		 *
+		 * Render decompression and plane width > 3840
+		 * combined with horizontal panning requires the
+		 * plane stride to be a multiple of 4. We'll just
+		 * require the entire fb to accommodate that to avoid
+		 * potential runtime errors at plane configuration time.
+		 */
+		if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 &&
+		    (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+		     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+			stride_alignment *= 4;
+
+		if (fb->pitches[i] & (stride_alignment - 1)) {
+			DRM_DEBUG_KMS("plane %d pitch (%d) must be at least %u byte aligned\n",
+				      i, fb->pitches[i], stride_alignment);
+			goto err;
+		}
 	}
 
 	intel_fb->obj = obj;
 
-	ret = intel_fill_fb_info(dev_priv, &intel_fb->base);
+	ret = intel_fill_fb_info(dev_priv, fb);
 	if (ret)
 		goto err;
 
-	ret = drm_framebuffer_init(obj->base.dev,
-				   &intel_fb->base,
-				   &intel_fb_funcs);
+	ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs);
 	if (ret) {
 		DRM_ERROR("framebuffer init failed %d\n", ret);
 		goto err;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index aece0ff88a5d..306268a27df7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -62,6 +62,20 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
 	I915_WRITE(CHICKEN_PAR1_1,
 		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
 
+	/*
+	 * Display WA#0390: skl,bxt,kbl,glk
+	 *
+	 * Must match Sampler, Pixel Back End, and Media
+	 * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27 and 31).
+	 *
+	 * Including bits outside the page in the hash would
+	 * require 2 (or 4?) MiB alignment of resources. Just
+	 * assume the defaul hashing mode which only uses bits
+	 * within the page.
+	 */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE);
+
 	I915_WRITE(GEN8_CONFIG0,
 		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
 
@@ -3476,7 +3490,9 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 	/* For Non Y-tile return 8-blocks */
 	if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
-	    fb->modifier != I915_FORMAT_MOD_Yf_TILED)
+	    fb->modifier != I915_FORMAT_MOD_Yf_TILED &&
+	    fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS &&
+	    fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS)
 		return 8;
 
 	src_w = drm_rect_width(&intel_pstate->base.src) >> 16;
@@ -3752,7 +3768,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	}
 
 	y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
-		  fb->modifier == I915_FORMAT_MOD_Yf_TILED;
+		  fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
+		  fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+		  fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
 	x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
 
 	/* Display WA #1141: kbl. */
@@ -3837,6 +3855,13 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	res_lines = DIV_ROUND_UP(selected_result.val,
 				 plane_blocks_per_line.val);
 
+	/* Display WA #1125: skl,bxt,kbl,glk */
+	if (level == 0 &&
+	    (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+		res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum);
+
+	/* Display WA #1126: skl,bxt,kbl,glk */
 	if (level >= 1 && level <= 7) {
 		if (y_tiled) {
 			res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b931d0bd7a64..b495a4778cc5 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -222,6 +222,7 @@ skl_update_plane(struct drm_plane *drm_plane,
 	u32 surf_addr = plane_state->main.offset;
 	unsigned int rotation = plane_state->base.rotation;
 	u32 stride = skl_plane_stride(fb, 0, rotation);
+	u32 aux_stride = skl_plane_stride(fb, 1, rotation);
 	int crtc_x = plane_state->base.dst.x1;
 	int crtc_y = plane_state->base.dst.y1;
 	uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
@@ -274,6 +275,10 @@ skl_update_plane(struct drm_plane *drm_plane,
 	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+		      (plane_state->aux.offset - surf_addr) | aux_stride);
+	I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+		      (plane_state->aux.y << 16) | plane_state->aux.x);
 
 	/* program plane scaler */
 	if (plane_state->scaler_id >= 0) {
-- 
2.10.2

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

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

* ✗ Fi.CI.BAT: failure for drm/i915: SKL+ render decompression support (rev4)
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
                   ` (4 preceding siblings ...)
  2017-03-21 18:12 ` [PATCH v4 5/5] drm/i915: Add render decompression support ville.syrjala
@ 2017-03-21 19:02 ` Patchwork
  2017-03-23 14:28 ` [PATCH v3 0/5] drm/i915: SKL+ render decompression support Daniel Stone
  6 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-03-21 19:02 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: SKL+ render decompression support (rev4)
URL   : https://patchwork.freedesktop.org/series/17507/
State : failure

== Summary ==

Series 17507v4 drm/i915: SKL+ render decompression support
https://patchwork.freedesktop.org/api/1.0/series/17507/revisions/4/mbox/

Test gem_exec_basic:
        Subgroup basic-bsd:
                pass       -> INCOMPLETE (fi-byt-j1900)
Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-uc:
                pass       -> FAIL       (fi-snb-2600) fdo#100007
Test kms_force_connector_basic:
        Subgroup force-connector-state:
                pass       -> SKIP       (fi-ivb-3520m)
        Subgroup force-edid:
                pass       -> SKIP       (fi-ivb-3520m)
        Subgroup force-load-detect:
                pass       -> SKIP       (fi-ivb-3520m)
        Subgroup prune-stale-modes:
                pass       -> SKIP       (fi-ivb-3520m)
Test kms_pipe_crc_basic:
        Subgroup nonblocking-crc-pipe-a-frame-sequence:
                pass       -> FAIL       (fi-skl-6770hq)

fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007

fi-bdw-5557u     total:278  pass:267  dwarn:0   dfail:0   fail:0   skip:11  time: 459s
fi-bsw-n3050     total:278  pass:239  dwarn:0   dfail:0   fail:0   skip:39  time: 575s
fi-bxt-j4205     total:278  pass:259  dwarn:0   dfail:0   fail:0   skip:19  time: 533s
fi-bxt-t5700     total:278  pass:258  dwarn:0   dfail:0   fail:0   skip:20  time: 547s
fi-byt-j1900     total:24   pass:23   dwarn:0   dfail:0   fail:0   skip:0   time: 0s
fi-byt-n2820     total:278  pass:247  dwarn:0   dfail:0   fail:0   skip:31  time: 504s
fi-hsw-4770      total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time: 436s
fi-hsw-4770r     total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time: 428s
fi-ilk-650       total:278  pass:228  dwarn:0   dfail:0   fail:0   skip:50  time: 437s
fi-ivb-3520m     total:278  pass:256  dwarn:0   dfail:0   fail:0   skip:22  time: 515s
fi-ivb-3770      total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time: 488s
fi-kbl-7500u     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time: 484s
fi-skl-6260u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time: 484s
fi-skl-6700hq    total:278  pass:261  dwarn:0   dfail:0   fail:0   skip:17  time: 594s
fi-skl-6700k     total:278  pass:256  dwarn:4   dfail:0   fail:0   skip:18  time: 495s
fi-skl-6770hq    total:278  pass:267  dwarn:0   dfail:0   fail:1   skip:10  time: 525s
fi-snb-2520m     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time: 545s
fi-snb-2600      total:278  pass:248  dwarn:0   dfail:0   fail:1   skip:29  time: 419s

d17b31b3444ecffa68be0c331a4b20078fd10ccf drm-tip: 2017y-03m-21d-17h-36m-49s UTC integration manifest
9fd0009 drm/i915: Add render decompression support
4b2c0ce drm/i915: Implement .get_format_info() hook for CCS
6476a9b drm: Add mode_config .get_format_info() hook
b5a4722 drm: Remove fb hsub/vsub alignment requirement
d33c387 drm: Share the code to compute color plane dimesions

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4252/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement
  2017-03-21 18:12 ` [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement ville.syrjala
@ 2017-03-21 20:26   ` Ben Widawsky
  2017-03-22 18:33     ` Ville Syrjälä
  0 siblings, 1 reply; 10+ messages in thread
From: Ben Widawsky @ 2017-03-21 20:26 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx, Jason Ekstrand, dri-devel

On 17-03-21 20:12:15, Ville Syrjälä wrote:
>From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
>Allow framebuffers dimesions to be misaligned w.r.t. the subsampling
>factors. No real reason the core should have to enforce this, and
>it definitely starts to cause us issues with the i915 CCS support.
>So let's just lift the restriction.
>
>Let's start to round up when computing the color plane dimesions
>so that we'll not end up with too low an estimate for the memory
>requirements and whatnot.
>
>Cc: Ben Widawsky <ben@bwidawsk.net>
>Cc: Jason Ekstrand <jason@jlekstrand.net>
>Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Both 1 and 2 are:
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>

>---
> drivers/gpu/drm/drm_framebuffer.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
>index 1138f90a7d5d..69e4c1487420 100644
>--- a/drivers/gpu/drm/drm_framebuffer.c
>+++ b/drivers/gpu/drm/drm_framebuffer.c
>@@ -132,7 +132,7 @@ static int fb_plane_width(int width,
> 	if (plane == 0)
> 		return width;
>
>-	return width / format->hsub;
>+	return DIV_ROUND_UP(width, format->hsub);
> }
>
> static int fb_plane_height(int height,
>@@ -141,7 +141,7 @@ static int fb_plane_height(int height,
> 	if (plane == 0)
> 		return height;
>
>-	return height / format->vsub;
>+	return DIV_ROUND_UP(height, format->vsub);
> }
>
> static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
>@@ -158,12 +158,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
> 		return -EINVAL;
> 	}
>
>-	if (r->width == 0 || r->width % info->hsub) {
>+	if (r->width == 0) {
> 		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
> 		return -EINVAL;
> 	}
>
>-	if (r->height == 0 || r->height % info->vsub) {
>+	if (r->height == 0) {
> 		DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
> 		return -EINVAL;
> 	}
>-- 
>2.10.2
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement
  2017-03-21 20:26   ` Ben Widawsky
@ 2017-03-22 18:33     ` Ville Syrjälä
  0 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2017-03-22 18:33 UTC (permalink / raw)
  To: Ben Widawsky; +Cc: intel-gfx, Jason Ekstrand, dri-devel

On Tue, Mar 21, 2017 at 01:26:23PM -0700, Ben Widawsky wrote:
> On 17-03-21 20:12:15, Ville Syrjälä wrote:
> >From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> >Allow framebuffers dimesions to be misaligned w.r.t. the subsampling
> >factors. No real reason the core should have to enforce this, and
> >it definitely starts to cause us issues with the i915 CCS support.
> >So let's just lift the restriction.
> >
> >Let's start to round up when computing the color plane dimesions
> >so that we'll not end up with too low an estimate for the memory
> >requirements and whatnot.
> >
> >Cc: Ben Widawsky <ben@bwidawsk.net>
> >Cc: Jason Ekstrand <jason@jlekstrand.net>
> >Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Both 1 and 2 are:
> Reviewed-by: Ben Widawsky <ben@bwidawsk.net>

Thanks. I've pushed patches 1-3 to drm-misc-next. That just leaves
us with the i915 stuff to deal with.

> 
> >---
> > drivers/gpu/drm/drm_framebuffer.c | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
> >index 1138f90a7d5d..69e4c1487420 100644
> >--- a/drivers/gpu/drm/drm_framebuffer.c
> >+++ b/drivers/gpu/drm/drm_framebuffer.c
> >@@ -132,7 +132,7 @@ static int fb_plane_width(int width,
> > 	if (plane == 0)
> > 		return width;
> >
> >-	return width / format->hsub;
> >+	return DIV_ROUND_UP(width, format->hsub);
> > }
> >
> > static int fb_plane_height(int height,
> >@@ -141,7 +141,7 @@ static int fb_plane_height(int height,
> > 	if (plane == 0)
> > 		return height;
> >
> >-	return height / format->vsub;
> >+	return DIV_ROUND_UP(height, format->vsub);
> > }
> >
> > static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
> >@@ -158,12 +158,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
> > 		return -EINVAL;
> > 	}
> >
> >-	if (r->width == 0 || r->width % info->hsub) {
> >+	if (r->width == 0) {
> > 		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
> > 		return -EINVAL;
> > 	}
> >
> >-	if (r->height == 0 || r->height % info->vsub) {
> >+	if (r->height == 0) {
> > 		DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
> > 		return -EINVAL;
> > 	}
> >-- 
> >2.10.2
> >

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v3 0/5] drm/i915: SKL+ render decompression support
  2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
                   ` (5 preceding siblings ...)
  2017-03-21 19:02 ` ✗ Fi.CI.BAT: failure for drm/i915: SKL+ render decompression support (rev4) Patchwork
@ 2017-03-23 14:28 ` Daniel Stone
  6 siblings, 0 replies; 10+ messages in thread
From: Daniel Stone @ 2017-03-23 14:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

Hi Ville,

On 21 March 2017 at 18:12,  <ville.syrjala@linux.intel.com> wrote:
> Another iteration of the i915 CCS support. Main change is lifting the
> fb dimensions hsub/vsub alignment restrictions from the core. Without that
> userspace would have to align the fb size be a multiple of 8x16 pixels
> which isn't something they are interested in doing.

With a rebase of Ben's GBM branch[0], and my last Weston atomic
series, for Y_CCS this series is:
Tested-by: Daniel Stone <daniels@collabora.com>

I had to disable Yf_CCS due to complaints about the kernel's idea of
the tiling mode not matching the modifier. Not sure if this is
something which has subsequently been fixed, or ...

Cheers,
Daniel

[0]: https://git.collabora.com/cgit/user/daniels/mesa.git/log/?h=wip/2017-03/modifiers-v9-rebased
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-03-23 14:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21 18:12 [PATCH v3 0/5] drm/i915: SKL+ render decompression support ville.syrjala
2017-03-21 18:12 ` [PATCH 1/5] drm: Share the code to compute color plane dimesions ville.syrjala
2017-03-21 18:12 ` [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement ville.syrjala
2017-03-21 20:26   ` Ben Widawsky
2017-03-22 18:33     ` Ville Syrjälä
2017-03-21 18:12 ` [PATCH v3 3/5] drm: Add mode_config .get_format_info() hook ville.syrjala
2017-03-21 18:12 ` [PATCH v4 4/5] drm/i915: Implement .get_format_info() hook for CCS ville.syrjala
2017-03-21 18:12 ` [PATCH v4 5/5] drm/i915: Add render decompression support ville.syrjala
2017-03-21 19:02 ` ✗ Fi.CI.BAT: failure for drm/i915: SKL+ render decompression support (rev4) Patchwork
2017-03-23 14:28 ` [PATCH v3 0/5] drm/i915: SKL+ render decompression support Daniel Stone

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.